1#!/usr/bin/env python
2
3from __future__ import absolute_import
4
5import unittest
6
7import mozunit
8
9from manifestparser import parse
10
11
12class ExpressionParserTest(unittest.TestCase):
13    """Test the conditional expression parser."""
14
15    def test_basic(self):
16
17        self.assertEqual(parse("1"), 1)
18        self.assertEqual(parse("100"), 100)
19        self.assertEqual(parse("true"), True)
20        self.assertEqual(parse("false"), False)
21        self.assertEqual('', parse('""'))
22        self.assertEqual(parse('"foo bar"'), 'foo bar')
23        self.assertEqual(parse("'foo bar'"), 'foo bar')
24        self.assertEqual(parse("foo", foo=1), 1)
25        self.assertEqual(parse("bar", bar=True), True)
26        self.assertEqual(parse("abc123", abc123="xyz"), 'xyz')
27
28    def test_equality(self):
29
30        self.assertTrue(parse("true == true"))
31        self.assertTrue(parse("false == false"))
32        self.assertTrue(parse("1 == 1"))
33        self.assertTrue(parse("100 == 100"))
34        self.assertTrue(parse('"some text" == "some text"'))
35        self.assertTrue(parse("true != false"))
36        self.assertTrue(parse("1 != 2"))
37        self.assertTrue(parse('"text" != "other text"'))
38        self.assertTrue(parse("foo == true", foo=True))
39        self.assertTrue(parse("foo == 1", foo=1))
40        self.assertTrue(parse('foo == "bar"', foo='bar'))
41        self.assertTrue(parse("foo == bar", foo=True, bar=True))
42        self.assertTrue(parse("true == foo", foo=True))
43        self.assertTrue(parse("foo != true", foo=False))
44        self.assertTrue(parse("foo != 2", foo=1))
45        self.assertTrue(parse('foo != "bar"', foo='abc'))
46        self.assertTrue(parse("foo != bar", foo=True, bar=False))
47        self.assertTrue(parse("true != foo", foo=False))
48        self.assertTrue(parse("!false"))
49
50    def test_conjunctures(self):
51        self.assertTrue(parse("true && true"))
52        self.assertTrue(parse("true || false"))
53        self.assertFalse(parse("false || false"))
54        self.assertFalse(parse("true && false"))
55        self.assertTrue(parse("true || false && false"))
56
57    def test_parentheses(self):
58        self.assertTrue(parse("(true)"))
59        self.assertEqual(parse("(10)"), 10)
60        self.assertEqual(parse('("foo")'), 'foo')
61        self.assertEqual(parse("(foo)", foo=1), 1)
62        self.assertTrue(parse("(true == true)"), True)
63        self.assertTrue(parse("(true != false)"))
64        self.assertTrue(parse("(true && true)"))
65        self.assertTrue(parse("(true || false)"))
66        self.assertTrue(parse("(true && true || false)"))
67        self.assertFalse(parse("(true || false) && false"))
68        self.assertTrue(parse("(true || false) && true"))
69        self.assertTrue(parse("true && (true || false)"))
70        self.assertTrue(parse("true && (true || false)"))
71        self.assertTrue(parse("(true && false) || (true && (true || false))"))
72
73    def test_comments(self):
74        # comments in expressions work accidentally, via an implementation
75        # detail - the '#' character doesn't match any of the regular
76        # expressions we specify as tokens, and thus are ignored.
77        # However, having explicit tests for them means that should the
78        # implementation ever change, comments continue to work, even if that
79        # means a new implementation must handle them explicitly.
80        self.assertTrue(parse("true == true # it does!"))
81        self.assertTrue(parse("false == false # it does"))
82        self.assertTrue(parse("false != true # it doesnt"))
83        self.assertTrue(parse('"string with #" == "string with #" # really, it does'))
84        self.assertTrue(parse('"string with #" != "string with # but not the same" # no match!'))
85
86    def test_not(self):
87        """
88        Test the ! operator.
89        """
90        self.assertTrue(parse("!false"))
91        self.assertTrue(parse("!(false)"))
92        self.assertFalse(parse("!true"))
93        self.assertFalse(parse("!(true)"))
94        self.assertTrue(parse("!true || true)"))
95        self.assertTrue(parse("true || !true)"))
96        self.assertFalse(parse("!true && true"))
97        self.assertFalse(parse("true && !true"))
98
99    def test_lesser_than(self):
100        """
101        Test the < operator.
102        """
103        self.assertTrue(parse("1 < 2"))
104        self.assertFalse(parse("3 < 2"))
105        self.assertTrue(parse("false || (1 < 2)"))
106        self.assertTrue(parse("1 < 2 && true"))
107        self.assertTrue(parse("true && 1 < 2"))
108        self.assertTrue(parse("!(5 < 1)"))
109        self.assertTrue(parse("'abc' < 'def'"))
110        self.assertFalse(parse("1 < 1"))
111        self.assertFalse(parse("'abc' < 'abc'"))
112
113    def test_greater_than(self):
114        """
115        Test the > operator.
116        """
117        self.assertTrue(parse("2 > 1"))
118        self.assertFalse(parse("2 > 3"))
119        self.assertTrue(parse("false || (2 > 1)"))
120        self.assertTrue(parse("2 > 1 && true"))
121        self.assertTrue(parse("true && 2 > 1"))
122        self.assertTrue(parse("!(1 > 5)"))
123        self.assertTrue(parse("'def' > 'abc'"))
124        self.assertFalse(parse("1 > 1"))
125        self.assertFalse(parse("'abc' > 'abc'"))
126
127    def test_lesser_or_equals_than(self):
128        """
129        Test the <= operator.
130        """
131        self.assertTrue(parse("1 <= 2"))
132        self.assertFalse(parse("3 <= 2"))
133        self.assertTrue(parse("false || (1 <= 2)"))
134        self.assertTrue(parse("1 < 2 && true"))
135        self.assertTrue(parse("true && 1 <= 2"))
136        self.assertTrue(parse("!(5 <= 1)"))
137        self.assertTrue(parse("'abc' <= 'def'"))
138        self.assertTrue(parse("1 <= 1"))
139        self.assertTrue(parse("'abc' <= 'abc'"))
140
141    def test_greater_or_equals_than(self):
142        """
143        Test the > operator.
144        """
145        self.assertTrue(parse("2 >= 1"))
146        self.assertFalse(parse("2 >= 3"))
147        self.assertTrue(parse("false || (2 >= 1)"))
148        self.assertTrue(parse("2 >= 1 && true"))
149        self.assertTrue(parse("true && 2 >= 1"))
150        self.assertTrue(parse("!(1 >= 5)"))
151        self.assertTrue(parse("'def' >= 'abc'"))
152        self.assertTrue(parse("1 >= 1"))
153        self.assertTrue(parse("'abc' >= 'abc'"))
154
155
156if __name__ == '__main__':
157    mozunit.main()
158