diff --git a/src/notcl.test.ts b/src/notcl.test.ts index 0856244..9e631de 100644 --- a/src/notcl.test.ts +++ b/src/notcl.test.ts @@ -102,6 +102,9 @@ b`) it("allows escaped quotes inside a quote", () => expect(parse('"a\\"b"')).toEqual([true, [[{ text: 'a"b' }]]])); + it("must close quoted words", () => + expect(parse('"a b')).toMatchObject([false, {}])); + it("does not allow trailing characters after a closing quote", () => expect(parse('""a')).toMatchObject([false, {}])); @@ -138,6 +141,9 @@ b`) it("can parse nested braces with text", () => expect(parse("{a{b}c}")).toEqual([true, [[{ text: "a{b}c" }]]])); + it("must be closed", () => + expect(parse("{a b")).toMatchObject([false, {}])); + it("does not allow trailing characters after a closing brace", () => expect(parse("{}a")).toMatchObject([false, {}])); @@ -168,6 +174,11 @@ b`) parse(String.raw`{\\\ }`) ).toEqual([true, [[{ text: "\\\\ " }]]])); + + test.each(['{"}"', '"{"}'])( + "does not permit overlapping braces and quotes {%s}", + (text) => expect(parse(text)).toMatchObject([false, {}]) + ); }); describe("Misc", () => { diff --git a/src/notcl.ts b/src/notcl.ts index 6b99b34..3bcf8e2 100644 --- a/src/notcl.ts +++ b/src/notcl.ts @@ -27,6 +27,7 @@ const BARE_WORD_CHAR = /[^\s\\;]+/y; function bareWordTmpl(charRegex: RegExp) { return Sequence( + Regex(/(?!["\{])/y), AtLeast( 1, Choose( @@ -36,7 +37,7 @@ function bareWordTmpl(charRegex: RegExp) { .map(([text]) => ({ text })) ) ) - ).map(([pieces]) => SimplifyWord(pieces)); + ).map(([, pieces]) => SimplifyWord(pieces)); } const QuotedWord = Sequence(