text: const assert = require("assert");
  const expect = require('chai').expect;
  const parser = require("./../../src/util/parser");
  
  const asString = (() => {
    const asStringRec = (input) => {
      if (Array.isArray(input)) {
        return `[${input.map(e => asStringRec(e)).join(",")}]`;
      }
      if (input instanceof Set) {
        return `{${[...input].map(e => asStringRec(e)).join(",")}}`;
      }
      assert(typeof input === "string");
      return `"${input}"`;
    };
    return input => asStringRec(parser(input));
  })();
  
  const checkError = (input, msg) => {
    let err;
    try {
      parser(input);
    } catch (e) {
      err = e;
    }
    expect(err.message).to.equal(msg);
  };
  
  describe("Testing Parser", () => {
    describe("Complex Use Cases", () => {
      it("Testing Path Groups", () => {
        expect(asString("{a,b.c}")).to.equal('{"a",["b","c"]}');
      });
  
      it("Testing Nested Groups", () => {
        expect(asString("{a,{b,c}}")).to.deep.equal('{"a",{"b","c"}}');
      });
  
      it("Testing Array Group Content", () => {
        expect(asString("[{1,{0,1}}]")).to.deep.equal('{"[1]",{"[0]","[1]"}}');
        expect(asString("[{{0,1},1}]")).to.deep.equal('{{"[0]","[1]"},"[1]"}');
      });
    });
  
    describe("Testing Simple Use Cases", () => {
      it("Testing Empty", () => {
        expect(parser("")).to.deep.equal("");
      });
  
      it("Testing Simple", () => {
        expect(parser("a")).to.deep.equal("a");
      });
  
      it("Testing Path", () => {
        expect(parser("a.b")).to.deep.equal(["a", "b"]);
      });
  
      it("Testing Array", () => {
        expect(parser("a[0]")).to.deep.equal(["a", "[0]"]);
      });
  
      it("Testing Or", () => {
        expect(parser("{a,b}")).to.deep.equal(new Set(["a", "b"]));
      });
  
      it("Testing Comma Outside Group", () => {
        expect(parser("a,b")).to.deep.equal(new Set(["a", "b"]));
        expect(parser("a.b,c.d")).to.deep.equal(new Set([["a", "b"], ["c", "d"]]));
      });
  
      it("Testing Or In Array", () => {
        expect(parser("[{0,1}]")).to.deep.equal(new Set(["[0]", "[1]"]));
      });
  
      it("Testing Array In Or", () => {
        expect(parser("{[0],[1]}")).to.deep.equal(new Set(["[0]", "[1]"]));
      });
  
      it("Testing Array in Path", () => {
        expect(parser("a.*.c[0]")).to.deep.equal(["a", "*", "c", "[0]"]);
      });
  
      it("Testing Array After Or", () => {
        expect(parser("{a,b}[0]")).to.deep.equal([new Set(['a', 'b']), '[0]']);
      });
    });
  
    describe("Testing Escaping", () => {
      it("Testing Path Escaped", () => {
        expect(parser("a\\.b")).to.deep.equal("a\\.b");
      });
  
      it("Testing Or Escaped", () => {
        expect(parser("{a\\,b}")).to.deep.equal("a\\,b");
      });
  
      it("Testing Escaped final Dot", () => {
        expect(parser("a.\\.")).to.deep.equal(["a", "\\."]);
      });
    });
  
    describe("Invalid Dot Selector", () => {
      it("Testing Starts with Dot", () => {
        checkError(".a", "Bad Path Separator: .a, char 0");
      });
  
      it("Testing Ends with Dot", () => {
        checkError("a.", "Bad Terminator: a., char 2");
      });
  
      it("Testing Double Dot", () => {
        checkError("a..b", "Bad Path Separator: a..b, char 2");
      });
    });
  
    describe("Array Selector", () => {
      it("Testing Empty Array", () => {
        checkError("[]", "Bad Array Terminator: [], char 1");
      });
  
      it("Testing Invalid Array Content", () => {
        checkError("[a]", "Bad Array Selector: [a], selector a");
      });
  
      it("Testing Invalid Array Group Content", () => {
        checkError("[{1,{0,1,a}}]", "Bad Array Selector: [{1,{0,1,a}}], selector a");
      });
  
      it("Testing Only Opening Bracket", () => {
        checkError("[{1}", "Non Terminated Array: [{1}");
      });
  
      it("Testing Starts with Bracket", () => {
        checkError("[a", "Bad Array Selector: [a, selector a");
      });
  
      it("Testing Ends with Bracket", () => {
        checkError("a]", "Bad Array Terminator: a], char 1");
      });
  
      it("Testing Nested Array Notation", () => {
        checkError("[[", "Bad Array Start: [[, char 1");
      });
  
      it("Testing Double Nested Array In Group", () => {
        checkError("[{1,[2]}]", "Bad Array Start: [{1,[2]}], char 4");
      });
  
      it("Testing Or In Array Escaped (Invalid Group)", () => {
        checkError("[{0\\,1}]", "Bad Array Selector: [{0\\,1}], selector 0\\,1");
      });
  
      it("Testing Array Escaped", () => {
        checkError("a\\[0]", "Bad Array Terminator: a\\[0], char 4");
      });
    });
  
    describe("Simple Group Selector", () => {
      it("Testing Starts with Curly Bracket", () => {
        checkError("{a", "Non Terminated Group: {a");
      });
  
      it("Testing Ends with Curly Bracket", () => {
        checkError("a}", "Unexpected Group Terminator: a}, char 1");
      });
  
      it("Testing Group Starts with Comma", () => {
        checkError("{,1,2}", "Bad Group Separator: {,1,2}, char 1");
      });
  
      it("Testing Group Ends with Comma", () => {
        checkError("{1,2,}", "Bad Group Terminator: {1,2,}, char 5");
      });
  
      it("Testing Group Stars After Element", () => {
        checkError("\\.{2,3}", "Bad Group Start: \\.{2,3}, char 2");
      });
  
      it("Testing Group Stars After Group", () => {
        checkError("{1,2}{2,3}", "Bad Group Start: {1,2}{2,3}, char 5");
      });
    });
  });
  