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