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( 85 parse('"string with #" != "string with # but not the same" # no match!') 86 ) 87 88 def test_not(self): 89 """ 90 Test the ! operator. 91 """ 92 self.assertTrue(parse("!false")) 93 self.assertTrue(parse("!(false)")) 94 self.assertFalse(parse("!true")) 95 self.assertFalse(parse("!(true)")) 96 self.assertTrue(parse("!true || true)")) 97 self.assertTrue(parse("true || !true)")) 98 self.assertFalse(parse("!true && true")) 99 self.assertFalse(parse("true && !true")) 100 101 def test_lesser_than(self): 102 """ 103 Test the < operator. 104 """ 105 self.assertTrue(parse("1 < 2")) 106 self.assertFalse(parse("3 < 2")) 107 self.assertTrue(parse("false || (1 < 2)")) 108 self.assertTrue(parse("1 < 2 && true")) 109 self.assertTrue(parse("true && 1 < 2")) 110 self.assertTrue(parse("!(5 < 1)")) 111 self.assertTrue(parse("'abc' < 'def'")) 112 self.assertFalse(parse("1 < 1")) 113 self.assertFalse(parse("'abc' < 'abc'")) 114 115 def test_greater_than(self): 116 """ 117 Test the > operator. 118 """ 119 self.assertTrue(parse("2 > 1")) 120 self.assertFalse(parse("2 > 3")) 121 self.assertTrue(parse("false || (2 > 1)")) 122 self.assertTrue(parse("2 > 1 && true")) 123 self.assertTrue(parse("true && 2 > 1")) 124 self.assertTrue(parse("!(1 > 5)")) 125 self.assertTrue(parse("'def' > 'abc'")) 126 self.assertFalse(parse("1 > 1")) 127 self.assertFalse(parse("'abc' > 'abc'")) 128 129 def test_lesser_or_equals_than(self): 130 """ 131 Test the <= operator. 132 """ 133 self.assertTrue(parse("1 <= 2")) 134 self.assertFalse(parse("3 <= 2")) 135 self.assertTrue(parse("false || (1 <= 2)")) 136 self.assertTrue(parse("1 < 2 && true")) 137 self.assertTrue(parse("true && 1 <= 2")) 138 self.assertTrue(parse("!(5 <= 1)")) 139 self.assertTrue(parse("'abc' <= 'def'")) 140 self.assertTrue(parse("1 <= 1")) 141 self.assertTrue(parse("'abc' <= 'abc'")) 142 143 def test_greater_or_equals_than(self): 144 """ 145 Test the > operator. 146 """ 147 self.assertTrue(parse("2 >= 1")) 148 self.assertFalse(parse("2 >= 3")) 149 self.assertTrue(parse("false || (2 >= 1)")) 150 self.assertTrue(parse("2 >= 1 && true")) 151 self.assertTrue(parse("true && 2 >= 1")) 152 self.assertTrue(parse("!(1 >= 5)")) 153 self.assertTrue(parse("'def' >= 'abc'")) 154 self.assertTrue(parse("1 >= 1")) 155 self.assertTrue(parse("'abc' >= 'abc'")) 156 157 158if __name__ == "__main__": 159 mozunit.main() 160