import { parse } from "./notcl"; describe("Parsing Notcl", () => { describe("Commands", () => { it("can parse an empty script", () => expect(parse("")).toEqual([true, []])); it("can parse a one-word command", () => expect(parse("a")).toEqual([true, [[{ enchanted: "a" }]]])); it("can parse a multi-word command", () => expect(parse("a b c")).toEqual([ true, [[{ enchanted: "a" }, { enchanted: "b" }, { enchanted: "c" }]], ])); it("accepts newlines as command separators", () => expect(parse("a\nb")).toEqual([ true, [[{ enchanted: "a" }], [{ enchanted: "b" }]], ])); it("does not split commands on folded newlines", () => expect( parse(String.raw`a\ b`) ).toEqual([true, [[{ enchanted: "a" }, { enchanted: "b" }]]])); it("does split words on folded newlines", () => expect( parse(String.raw`a\ b`) ).toEqual([true, [[{ enchanted: "a" }, { enchanted: "b" }]]])); it("does split commands on newlines with escaped backslashes", () => expect( parse(String.raw`a\\ b`) ).toEqual([true, [[{ text: "a\\\\" }], [{ enchanted: "b" }]]])); it("does not split commands on folded newlines with escaped backslashes", () => expect( parse(String.raw`a\\\ b`) ).toEqual([true, [[{ text: "a\\\\" }, { enchanted: "b" }]]])); it("accepts semicolons as command separators", () => expect(parse("a;b")).toEqual([ true, [[{ enchanted: "a" }], [{ enchanted: "b" }]], ])); it("tolerates, and ignores, empty commands", () => expect(parse("a;;b\n\nc")).toEqual([ true, [[{ enchanted: "a" }], [{ enchanted: "b" }], [{ enchanted: "c" }]], ])); test.each([[" a"], ["a "], ["a ;"], ["; a"]])( "tolerates whitespace before and after commands {%s}", (text) => expect(parse(text)).toEqual([true, [[{ enchanted: "a" }]]]) ); }); describe("Comments", () => { it("ignores comments", () => expect(parse("#comment")).toEqual([true, []])); it("does not treat # in argument position as a comment", () => expect(parse("a #1")).toEqual([ true, [[{ enchanted: "a" }, { enchanted: "#1" }]], ])); it("can have commands before a comment", () => expect(parse("a ;#comment")).toEqual([true, [[{ enchanted: "a" }]]])); it("ignores the whole line after a comment", () => expect(parse("# comment ; not a command")).toEqual([true, []])); it("continues the comment through a folded newline", () => expect( parse(String.raw`#a\ b`) ).toEqual([true, []])); it("does not continue the comment through a newline with escaped backslashes", () => expect( parse(String.raw`#a\\ b`) ).toEqual([true, [[{ enchanted: "b" }]]])); it("continues the comment through a folded newline with escaped backslashes", () => expect( parse(String.raw`#a\\\ b`) ).toEqual([true, []])); }); describe("enchanted words", () => { // Enchanted Words // simple words // not braces // not quotes // not variables // not commands // not backslashes // yes before folded newline // no before folded newline that gives us backslashes }); describe("interpolated words", () => {}); describe("brace words", () => { it("can parse empty braces", () => expect(parse("{}")).toEqual([true, [[{ text: "" }]]])); it("can parse braces with text", () => expect(parse("{a b c}")).toEqual([true, [[{ text: "a b c" }]]])); it("can parse nested braces", () => expect(parse("{{}}")).toEqual([true, [[{ text: "{}" }]]])); it("can parse nested braces with text", () => expect(parse("{a{b}c}")).toEqual([true, [[{ text: "a{b}c" }]]])); it.failing("doesn't count suppressed braces for nesting", () => expect(parse(String.raw`{a\{b}`)).toEqual([true, [[{ text: "a\\{b" }]]]) ); it.failing("doesn't count suppressed braces for unnesting", () => expect(parse(String.raw`{a\}b}`)).toEqual([true, [[{ text: "a\\}b" }]]]) ); it("nests braces after suppressed backslashes", () => expect(parse(String.raw`{a\\{b}}`)).toEqual([ true, [[{ text: "a\\\\{b}" }]], ])); it("permits newlines in braces", () => expect(parse("{\n}")).toEqual([true, [[{ text: "\n" }]]])); it("folds newlines in braces", () => expect( parse(String.raw`{\ }`) ).toEqual([true, [[{ text: " " }]]])); it("doesn't fold newlines in braces with escaped backslashes", () => expect( parse(String.raw`{\\ }`) ).toEqual([true, [[{ text: "\\\\\n" }]]])); it("folds newlines in braces with escaped backslashes", () => expect( parse(String.raw`{\\\ }`) ).toEqual([true, [[{ text: "\\\\ " }]]])); }); // Braces // nesting // escapes // {, }, correct newline folding // no trailing chars // "Quotes" // no trailing chars // Interpolated words // bare // quotes // variables- bare, brace // command subst describe("Misc", () => { test("Big mess of markup", () => { expect( parse(String.raw` h1 "Hello, World!" para [2 + 2] block { This is a paragraph of text, with one [b bold] word. Yes, this means there has to be some magic in text processing... this won't work. } block -red "Beware!" para "All text should be quoted, it's clearer that way. & blockquotes already should contain paragraphs. (maybe normalize nested paragraphs)" block { First block } { Second block Is this markdown-parsed? [button "No we want to render UI" \\{noop}] } { Since we want escapes to work, these blocks [i will] be subject to substitutions. } # A comment para { line endings escaped\ one slash not escaped if \\ two slashes escaped with a slash if \\\ three slashes not escaped with two slashes if \\\\ four slashes escaped with two slashes if \\\\\ five slashes not escaped with three slashes if \\\\\\ six slashes } `) ).toMatchSnapshot(); }); }); });