1import { parse } from './parser';
2
3const parseTag = (quasis, ...expressions) => parse(quasis, expressions);
4
5it('supports parsing expressions with quantifiers', () => {
6 let ast;
7
8 ast = parseTag`${1}?`;
9 expect(ast).toHaveProperty('0.quantifier', '?');
10
11 ast = parseTag`${1}+`;
12 expect(ast).toHaveProperty('0.quantifier', '+');
13
14 ast = parseTag`${1}*`;
15 expect(ast).toHaveProperty('0.quantifier', '*');
16});
17
18it('supports top-level alternations', () => {
19 let ast;
20
21 ast = parseTag`${1} | ${2}`;
22 expect(ast).toHaveProperty('length', 1);
23 expect(ast).toHaveProperty('0.expression', 1);
24 expect(ast).toHaveProperty('alternation.0.expression', 2);
25
26 ast = parseTag`${1}? | ${2}?`;
27 expect(ast).toHaveProperty('0.quantifier', '?');
28});
29
30it('supports groups with quantifiers', () => {
31 let ast;
32
33 ast = parseTag`(${1} ${2})`;
34 expect(ast).toHaveProperty('length', 1);
35 expect(ast).toHaveProperty('0.sequence.length', 2);
36 expect(ast).toHaveProperty('0.sequence.0.expression', 1);
37 expect(ast).toHaveProperty('0.sequence.1.expression', 2);
38
39 ast = parseTag`(${1} ${2}?)?`;
40 expect(ast).toHaveProperty('length', 1);
41 expect(ast).toHaveProperty('0.quantifier', '?');
42 expect(ast).toHaveProperty('0.sequence.0.quantifier', undefined);
43});
44
45describe('non-capturing syntax', () => {
46 it('supports regex-like syntax', () => {
47 const ast = parseTag`(?: ${1})`;
48 expect(ast).toHaveProperty('length', 1);
49 expect(ast).toHaveProperty('0.capture', ':');
50 expect(ast).toHaveProperty('0.sequence.length', 1);
51 });
52
53 it('supports shorthand', () => {
54 let ast = parseTag`:${1}`;
55 expect(ast).toHaveProperty('length', 1);
56 expect(ast).toHaveProperty('0.capture', ':');
57 expect(ast).toHaveProperty('0.expression', 1);
58 ast = parseTag`:(${1})`;
59 expect(ast).toHaveProperty('length', 1);
60 expect(ast).toHaveProperty('0.capture', ':');
61 expect(ast).toHaveProperty('0.sequence.length', 1);
62 });
63
64 it('fails on invalid usage', () => {
65 expect(() => parseTag`${1} : ${2}`).toThrow();
66 expect(() => parseTag`${1} :|${2}`).toThrow();
67 });
68});
69
70describe('positive lookaheads syntax', () => {
71 it('supports regex-like syntax', () => {
72 const ast = parseTag`(?= ${1})`;
73 expect(ast).toHaveProperty('length', 1);
74 expect(ast).toHaveProperty('0.capture', '=');
75 expect(ast).toHaveProperty('0.sequence.length', 1);
76 });
77
78 it('supports shorthand', () => {
79 let ast = parseTag`=${1}`;
80 expect(ast).toHaveProperty('length', 1);
81 expect(ast).toHaveProperty('0.capture', '=');
82 expect(ast).toHaveProperty('0.expression', 1);
83 ast = parseTag`=(${1})`;
84 expect(ast).toHaveProperty('length', 1);
85 expect(ast).toHaveProperty('0.capture', '=');
86 expect(ast).toHaveProperty('0.sequence.length', 1);
87 });
88});
89
90describe('negative lookaheads syntax', () => {
91 it('supports regex-like syntax', () => {
92 const ast = parseTag`(?! ${1})`;
93 expect(ast).toHaveProperty('length', 1);
94 expect(ast).toHaveProperty('0.capture', '!');
95 expect(ast).toHaveProperty('0.sequence.length', 1);
96 });
97
98 it('supports shorthand', () => {
99 let ast = parseTag`!${1}`;
100 expect(ast).toHaveProperty('length', 1);
101 expect(ast).toHaveProperty('0.capture', '!');
102 expect(ast).toHaveProperty('0.expression', 1);
103 ast = parseTag`!(${1})`;
104 expect(ast).toHaveProperty('length', 1);
105 expect(ast).toHaveProperty('0.capture', '!');
106 expect(ast).toHaveProperty('0.sequence.length', 1);
107 });
108});
109
110it('supports groups with alternates', () => {
111 expect(parseTag`(${1} | ${2}) ${3}`).toMatchInlineSnapshot(`
112 Array [
113 Object {
114 "capture": undefined,
115 "sequence": Array [
116 Object {
117 "capture": undefined,
118 "expression": 1,
119 },
120 ],
121 },
122 Object {
123 "capture": undefined,
124 "expression": 3,
125 },
126 ]
127 `);
128});