diff --git a/src/notcl.test.ts b/src/notcl.test.ts index 96f7887..f8cc471 100644 --- a/src/notcl.test.ts +++ b/src/notcl.test.ts @@ -2,7 +2,94 @@ import { parse } from "./notcl"; describe("Parsing Notcl", () => { describe("Commands", () => { - it("Can parse an empty script", () => + it("can parse an empty script", () => expect(parse("")).toEqual([true, []])); + + it("can parse a one-word command", () => + expect(parse("a")).toEqual([true, [[{ text: "a" }]]])); + + it("can parse a multi-word command", () => + expect(parse("a b c")).toEqual([ + true, + [[{ text: "a" }, { text: "b" }, { text: "c" }]], + ])); + + it("accepts newlines as command separators", () => + expect(parse("a\nb")).toEqual([ + true, + [[{ text: "a" }], [{ text: "b" }]], + ])); + it("does not split commands on folded newlines", () => + expect( + parse(String.raw`a\ + b`) + ).toEqual([true, [[{ text: "a" }, { text: "b" }]]])); + it.failing("does split commands on newlines with escaped backslashes", () => + expect( + parse(String.raw`a\\ + b`) + ).toEqual([true, [[{ text: "a" }], [{ text: "b" }]]]) + ); + it("does not split commands on folded newlines with escaped backslashes", () => + expect( + parse(String.raw`a\\\ + b`) + ).toEqual([true, [[{ text: "a\\\\" }, { text: "b" }]]])); + + it("accepts semicolons as command separators", () => + expect(parse("a;b")).toEqual([true, [[{ text: "a" }], [{ text: "b" }]]])); + + it("tolerates, and ignores, empty commands", () => + expect(parse("a;;b\n\nc")).toEqual([ + true, + [[{ text: "a" }], [{ text: "b" }], [{ text: "c" }]], + ])); + + test.each([[" a"], ["a "], ["a ;"], ["; a"]])( + "tolerates whitespace before and after commands {%s}", + (text) => expect(parse(text)).toEqual([true, [[{ text: "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, [[{ text: "a" }, { text: "#1" }]]])); + it("can have commands before a comment", () => + expect(parse("a ;#comment")).toEqual([true, [[{ text: "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, [[{ text: "b" }]]])); + it("continues the comment through a folded newline with escaped backslashes", () => + expect( + parse(String.raw`#a\\\ + b`) + ).toEqual([true, []])); + }); + + // Enchanted Words + + // Braces + // nesting + // escapes + // {, }, correct newline folding + + // "Quotes" + + // Interpolated words + // bare + // quotes + // variables- bare, brace + // command subst });