1 | import assert from 'assert'
|
2 | import parse from '../src/tag_expression_parser'
|
3 |
|
4 | describe('TagExpressionParser', () => {
|
5 | describe('#parse', () => {
|
6 | ;[
|
7 | ['', 'true'],
|
8 | ['a and b', '( a and b )'],
|
9 | ['a or b', '( a or b )'],
|
10 | ['not a', 'not ( a )'],
|
11 | ['( a and b ) or ( c and d )', '( ( a and b ) or ( c and d ) )'],
|
12 | [
|
13 | 'not a or b and not c or not d or e and f',
|
14 | '( ( ( not ( a ) or ( b and not ( c ) ) ) or not ( d ) ) or ( e and f ) )',
|
15 | ],
|
16 | [
|
17 | 'not a\\(\\) or b and not c or not d or e and f',
|
18 | '( ( ( not ( a\\(\\) ) or ( b and not ( c ) ) ) or not ( d ) ) or ( e and f ) )',
|
19 | ],
|
20 |
|
21 | ].forEach(function(inOut) {
|
22 | it(inOut[0], function() {
|
23 | const infix = inOut[0]
|
24 | const expr = parse(infix)
|
25 | assert.strictEqual(expr.toString(), inOut[1])
|
26 |
|
27 | const roundtripTokens = expr.toString()
|
28 | const roundtripExpr = parse(roundtripTokens)
|
29 | assert.strictEqual(roundtripExpr.toString(), inOut[1])
|
30 | })
|
31 | })
|
32 | ;[
|
33 | ['@a @b or', 'Syntax error. Expected operator'],
|
34 | ['@a and (@b not)', 'Syntax error. Expected operator'],
|
35 | ['@a and (@b @c) or', 'Syntax error. Expected operator'],
|
36 | ['@a and or', 'Syntax error. Expected operand'],
|
37 | ['or or', 'Syntax error. Expected operand'],
|
38 | ['a b', 'Syntax error. Expected operator'],
|
39 | ['( a and b ) )', 'Syntax error. Unmatched )'],
|
40 | ['( ( a and b )', 'Syntax error. Unmatched ('],
|
41 |
|
42 | ].forEach(function(inOut) {
|
43 | it(inOut[0] + ' fails', function() {
|
44 | const infix = inOut[0]
|
45 | try {
|
46 | parse(infix)
|
47 | throw new Error('Expected syntax error')
|
48 | } catch (expected) {
|
49 | assert.strictEqual(expected.message, inOut[1])
|
50 | }
|
51 | })
|
52 | })
|
53 |
|
54 |
|
55 |
|
56 | it('evaluates not', function() {
|
57 | const expr = parse('not x')
|
58 | assert.strictEqual(expr.evaluate(['x']), false)
|
59 | assert.strictEqual(expr.evaluate(['y']), true)
|
60 | })
|
61 |
|
62 | it('evaluates and', function() {
|
63 | const expr = parse('x and y')
|
64 | assert.strictEqual(expr.evaluate(['x', 'y']), true)
|
65 | assert.strictEqual(expr.evaluate(['y']), false)
|
66 | assert.strictEqual(expr.evaluate(['x']), false)
|
67 | })
|
68 |
|
69 | it('evaluates or', function() {
|
70 | const expr = parse(' x or(y) ')
|
71 | assert.strictEqual(expr.evaluate([]), false)
|
72 | assert.strictEqual(expr.evaluate(['y']), true)
|
73 | assert.strictEqual(expr.evaluate(['x']), true)
|
74 | })
|
75 |
|
76 | it('evaluates expressions with escaped chars', function() {
|
77 | const expr = parse(' x\\(1\\) or(y\\(2\\)) ')
|
78 | assert.strictEqual(expr.evaluate([]), false)
|
79 | assert.strictEqual(expr.evaluate(['y(2)']), true)
|
80 | assert.strictEqual(expr.evaluate(['x(1)']), true)
|
81 | assert.strictEqual(expr.evaluate(['y']), false)
|
82 | assert.strictEqual(expr.evaluate(['x']), false)
|
83 | })
|
84 |
|
85 | it('evaluates empty expressions to true', function() {
|
86 | const expr = parse('')
|
87 | assert.strictEqual(expr.evaluate([]), true)
|
88 | assert.strictEqual(expr.evaluate(['y']), true)
|
89 | assert.strictEqual(expr.evaluate(['x']), true)
|
90 | })
|
91 | })
|
92 | })
|