|
|
@@ -1033,3 +1033,93 @@ describe("tokenization depth exhaustion", () => {
|
|
|
expect(result.content.length).toBeGreaterThan(0)
|
|
|
})
|
|
|
})
|
|
|
+
|
|
|
+describe("comark — block components", () => {
|
|
|
+ it("parses ::query{type=\"TODO\"} and produces BlockComponent in tree", () => {
|
|
|
+ const result = parseMarkdown("::query{type=\"TODO\"}\nResults\n::")
|
|
|
+ const names: string[] = []
|
|
|
+ result.tree.iterate({
|
|
|
+ enter: (n) => { names.push(n.type.name) },
|
|
|
+ })
|
|
|
+ expect(names).toContain("BlockComponent")
|
|
|
+ expect(names).toContain("ComponentName")
|
|
|
+ expect(names).toContain("ComponentAttrs")
|
|
|
+ expect(names).toContain("ComponentBody")
|
|
|
+ })
|
|
|
+
|
|
|
+ it("parses ::divider with no body or attrs", () => {
|
|
|
+ const result = parseMarkdown("::divider\n::")
|
|
|
+ const names: string[] = []
|
|
|
+ result.tree.iterate({
|
|
|
+ enter: (n) => { names.push(n.type.name) },
|
|
|
+ })
|
|
|
+ expect(names).toContain("BlockComponent")
|
|
|
+ })
|
|
|
+})
|
|
|
+
|
|
|
+describe("comark — inline components", () => {
|
|
|
+ it("parses :priority{value=\"high\"} and produces InlineComponent in tree", () => {
|
|
|
+ const result = parseMarkdown(":priority{value=\"high\"}")
|
|
|
+ const names: string[] = []
|
|
|
+ result.tree.iterate({
|
|
|
+ enter: (n) => { names.push(n.type.name) },
|
|
|
+ })
|
|
|
+ expect(names).toContain("InlineComponent")
|
|
|
+ expect(names).toContain("ComponentName")
|
|
|
+ expect(names).toContain("ComponentAttrs")
|
|
|
+ })
|
|
|
+
|
|
|
+ it("parses :badge[Active]{color=\"green\"} with body and attrs", () => {
|
|
|
+ const result = parseMarkdown(":badge[Active]{color=\"green\"}")
|
|
|
+ const names: string[] = []
|
|
|
+ result.tree.iterate({
|
|
|
+ enter: (n) => { names.push(n.type.name) },
|
|
|
+ })
|
|
|
+ expect(names).toContain("InlineComponent")
|
|
|
+ expect(names).toContain("ComponentBody")
|
|
|
+ expect(names).toContain("ComponentAttrs")
|
|
|
+ })
|
|
|
+
|
|
|
+ it("parses :icon-check as standalone component", () => {
|
|
|
+ const result = parseMarkdown(":icon-check")
|
|
|
+ const names: string[] = []
|
|
|
+ result.tree.iterate({
|
|
|
+ enter: (n) => { names.push(n.type.name) },
|
|
|
+ })
|
|
|
+ expect(names).toContain("InlineComponent")
|
|
|
+ expect(names).toContain("ComponentName")
|
|
|
+ expect(names).not.toContain("ComponentBody")
|
|
|
+ expect(names).not.toContain("ComponentAttrs")
|
|
|
+ })
|
|
|
+
|
|
|
+ it("does not match emoji syntax (:smile:)", () => {
|
|
|
+ const result = parseMarkdown(":smile:")
|
|
|
+ const names: string[] = []
|
|
|
+ result.tree.iterate({
|
|
|
+ enter: (n) => { names.push(n.type.name) },
|
|
|
+ })
|
|
|
+ expect(names).not.toContain("InlineComponent")
|
|
|
+ })
|
|
|
+})
|
|
|
+
|
|
|
+describe("comark — span attributes", () => {
|
|
|
+ it("parses [text]{.highlight} and produces Span in tree", () => {
|
|
|
+ const result = parseMarkdown("[text]{.highlight}")
|
|
|
+ const names: string[] = []
|
|
|
+ result.tree.iterate({
|
|
|
+ enter: (n) => { names.push(n.type.name) },
|
|
|
+ })
|
|
|
+ expect(names).toContain("Span")
|
|
|
+ expect(names).toContain("SpanBody")
|
|
|
+ expect(names).toContain("SpanAttrs")
|
|
|
+ })
|
|
|
+
|
|
|
+ it("does not match [text] {.class} with space before braces", () => {
|
|
|
+ const result = parseMarkdown("[text] {.class}")
|
|
|
+ const names: string[] = []
|
|
|
+ result.tree.iterate({
|
|
|
+ enter: (n) => { names.push(n.type.name) },
|
|
|
+ })
|
|
|
+ expect(names).not.toContain("Span")
|
|
|
+ })
|
|
|
+})
|