import assert from "assert"; import TreeRegexp from "../src/TreeRegexp"; describe("TreeRegexp", () => { it("exposes group source", () => { const tr = new TreeRegexp(/(a(?:b)?)(c)/); assert.deepStrictEqual(tr.groupBuilder.children.map(gb => gb.source), [ "a(?:b)?", "c" ]); }); it("builds tree", () => { const tr = new TreeRegexp(/(a(?:b)?)(c)/); const group = tr.match("ac"); assert.strictEqual(group.value, "ac"); assert.strictEqual(group.children[0].value, "a"); assert.deepStrictEqual(group.children[0].children, []); assert.strictEqual(group.children[1].value, "c"); }); it("ignores non-capturing groups", () => { const tr = new TreeRegexp(/(a(?:b)?)(c)/); const group = tr.match("ac"); assert.strictEqual(group.value, "ac"); assert.strictEqual(group.children[0].value, "a"); assert.deepStrictEqual(group.children[0].children, []); assert.strictEqual(group.children[1].value, "c"); }); it("matches optional group", () => { const tr = new TreeRegexp(/^Something( with an optional argument)?/); const group = tr.match("Something"); assert.strictEqual(group.children[0].value, null); }); it("matches nested groups", () => { const tr = new TreeRegexp( /^A (\d+) thick line from ((\d+),\s*(\d+),\s*(\d+)) to ((\d+),\s*(\d+),\s*(\d+))/ ); const group = tr.match("A 5 thick line from 10,20,30 to 40,50,60"); assert.strictEqual(group.children[0].value, "5"); assert.strictEqual(group.children[1].value, "10,20,30"); assert.strictEqual(group.children[1].children[0].value, "10"); assert.strictEqual(group.children[1].children[1].value, "20"); assert.strictEqual(group.children[1].children[2].value, "30"); assert.strictEqual(group.children[2].value, "40,50,60"); assert.strictEqual(group.children[2].children[0].value, "40"); assert.strictEqual(group.children[2].children[1].value, "50"); assert.strictEqual(group.children[2].children[2].value, "60"); }); it("detects multiple non capturing groups", () => { const tr = new TreeRegexp(/(?:a)(:b)(\?c)(d)/); const group = tr.match("a:b?cd"); assert.strictEqual(group.children.length, 3); }); it("works with escaped backslash", () => { const tr = new TreeRegexp(/foo\\(bar|baz)/); const group = tr.match("foo\\bar"); assert.strictEqual(group.children.length, 1); }); it("works with escaped slash", () => { const tr = new TreeRegexp(/^I go to '\/(.+)'$/); const group = tr.match("I go to '/hello'"); assert.strictEqual(group.children.length, 1); }); it("works with digit and word", () => { const tr = new TreeRegexp(/^(\d) (\w+)$/); const group = tr.match("2 you"); assert.strictEqual(group.children.length, 2); }); it("captures non capturing groups with capturing groups inside", () => { const tr = new TreeRegexp('the stdout(?: from "(.*?)")?'); const group = tr.match("the stdout"); assert.strictEqual(group.value, "the stdout"); assert.strictEqual(group.children[0].value, null); assert.strictEqual(group.children.length, 1); }); it("works with flags", () => { const tr = new TreeRegexp(/HELLO/i); const group = tr.match("hello"); assert.strictEqual(group.value, "hello"); }); it("does not consider parenthesis in character class as group", () => { const tr = new TreeRegexp(/^drawings: ([A-Z, ()]+)$/); const group = tr.match("drawings: ONE(TWO)"); assert.strictEqual(group.value, "drawings: ONE(TWO)"); assert.strictEqual(group.children.length, 1); assert.strictEqual(group.children[0].value, "ONE(TWO)"); }); });