1#!/usr/bin/env python3
2
3#
4# Copyright (C) 2018 The Android Open Source Project
5#
6# Licensed under the Apache License, Version 2.0 (the "License");
7# you may not use this file except in compliance with the License.
8# You may obtain a copy of the License at
9#
10#      http://www.apache.org/licenses/LICENSE-2.0
11#
12# Unless required by applicable law or agreed to in writing, software
13# distributed under the License is distributed on an "AS IS" BASIS,
14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15# See the License for the specific language governing permissions and
16# limitations under the License.
17#
18
19"""This module contains the unit tests to check the AST classes."""
20
21import unittest
22
23from blueprint import Bool, Concat, Dict, Expr, Integer, List, String, VarRef
24
25
26#------------------------------------------------------------------------------
27# Expr
28#------------------------------------------------------------------------------
29
30class ExprTest(unittest.TestCase):
31    """Unit tests for the Expr class."""
32
33    def test_eval(self):
34        """Test whether Expr.eval() raises NotImplementedError."""
35
36        with self.assertRaises(NotImplementedError):
37            Expr().eval({})
38
39
40#------------------------------------------------------------------------------
41# Bool
42#------------------------------------------------------------------------------
43
44class BoolTest(unittest.TestCase):
45    """Unit tests for the Bool class."""
46
47    def test_bool(self):
48        """Test Bool.__init__(), Bool.__bool__(), and Bool.eval() methods."""
49
50        false_expr = Bool(False)
51        self.assertFalse(bool(false_expr))
52        self.assertFalse(false_expr.eval({}))
53
54        true_expr = Bool(True)
55        self.assertTrue(bool(true_expr))
56        self.assertTrue(true_expr.eval({}))
57
58        self.assertEqual(Bool(False), false_expr)
59        self.assertEqual(Bool(True), true_expr)
60
61
62    def test_equal(self):
63        """Test Bool.__eq__() method."""
64
65        false_expr1 = Bool(False)
66        false_expr2 = Bool(False)
67        true_expr1 = Bool(True)
68        true_expr2 = Bool(True)
69
70        self.assertIsNot(false_expr1, false_expr2)
71        self.assertEqual(false_expr1, false_expr2)
72
73        self.assertIsNot(true_expr1, true_expr2)
74        self.assertEqual(true_expr1, true_expr2)
75
76
77    def test_hash(self):
78        """Test Bool.__hash__() method."""
79
80        false_expr = Bool(False)
81        true_expr = Bool(True)
82
83        self.assertEqual(hash(Bool(False)), hash(false_expr))
84        self.assertEqual(hash(Bool(True)), hash(true_expr))
85
86
87    def test_repr(self):
88        """Test Bool.__repr__() method."""
89
90        self.assertEqual('False', repr(Bool(False)))
91        self.assertEqual('True', repr(Bool(True)))
92
93
94#------------------------------------------------------------------------------
95# Integer
96#------------------------------------------------------------------------------
97
98class IntegerTest(unittest.TestCase):
99    """Unit tests for the Integer class."""
100
101    def test_int(self):
102        """Test Integer.__init__(), Integer.__bool__(), Integer.__int__(), and
103        Integer.eval() methods."""
104
105        expr = Integer(0)
106        self.assertFalse(bool(expr))
107        self.assertEqual(0, int(expr))
108        self.assertEqual(0, int(expr.eval({})))
109
110        expr = Integer(1)
111        self.assertTrue(bool(expr))
112        self.assertEqual(1, int(expr))
113        self.assertEqual(1, int(expr.eval({})))
114
115        expr = Integer(2)
116        self.assertTrue(bool(expr))
117        self.assertEqual(2, int(expr))
118        self.assertEqual(2, int(expr.eval({})))
119
120
121    def test_equal(self):
122        """Test Integer.__eq__() method."""
123
124        expr_zero1 = Integer(0)
125        expr_zero2 = Integer(0)
126        expr_one1 = Integer(1)
127        expr_one2 = Integer(1)
128
129        self.assertIsNot(expr_zero1, expr_zero2)
130        self.assertEqual(expr_zero1, expr_zero2)
131
132        self.assertIsNot(expr_one1, expr_one2)
133        self.assertEqual(expr_one1, expr_one2)
134
135
136    def test_hash(self):
137        """Test Integer.__hash__() method."""
138
139        expr_zero = Integer(0)
140        expr_one = Integer(1)
141
142        self.assertEqual(hash(Integer(False)), hash(expr_zero))
143        self.assertEqual(hash(Integer(True)), hash(expr_one))
144
145
146    def test_repr(self):
147        """Test Integer.__repr__() method."""
148
149        self.assertEqual('0', repr(Integer(0)))
150        self.assertEqual('1', repr(Integer(1)))
151
152
153#------------------------------------------------------------------------------
154# String
155#------------------------------------------------------------------------------
156
157class StringTest(unittest.TestCase):
158    """Unit tests for the String class."""
159
160    def test_string(self):
161        """Test String.__init__() and String.eval() methods."""
162
163        expr = String('test')
164        self.assertEqual('test', expr.eval({}))
165
166
167#------------------------------------------------------------------------------
168# VarRef
169#------------------------------------------------------------------------------
170
171class VarRefTest(unittest.TestCase):
172    """Unit tests for the VarRef class."""
173
174    def test_var_ref(self):
175        """Test VarRef.__init__() and VarRef.eval() methods."""
176
177        expr = VarRef('a', String('b'))
178        self.assertEqual('a', expr.name)
179        self.assertEqual(String('b'), expr.value)
180        self.assertEqual('b', expr.eval({}))
181
182
183    def test_eval_with_value(self):
184        """Test evaluation of local variables."""
185        expr = VarRef('a', String('1'))
186        self.assertEqual('1', expr.eval({'a': String('2')}))
187
188
189    def test_eval_without_value(self):
190        """Test evaluation of external variables."""
191        expr = VarRef('a', None)
192        self.assertEqual('2', expr.eval({'a': String('2')}))
193
194
195    def test_eval_recursive(self):
196        """Test recursive evaluation."""
197        expr = VarRef('a', List([VarRef('x', None), VarRef('y', None)]))
198        expr_eval = expr.eval({'x': String('1'), 'y': String('2')})
199        self.assertIsInstance(expr_eval, List)
200        self.assertEqual('1', expr_eval[0])
201        self.assertEqual('2', expr_eval[1])
202
203
204#------------------------------------------------------------------------------
205# List
206#------------------------------------------------------------------------------
207
208class ListTest(unittest.TestCase):
209    """Unit tests for the List class."""
210
211    def test_list(self):
212        """Test List.__init__() and List.eval() methods."""
213
214        expr = List([String('a'), String('b')])
215        self.assertEqual(String('a'), expr[0])
216        self.assertEqual(String('b'), expr[1])
217
218        expr = List([VarRef('a', None), VarRef('b', None)])
219        expr_eval = expr.eval({'a': String('1'), 'b': String('2')})
220        self.assertEqual('1', expr_eval[0])
221        self.assertEqual('2', expr_eval[1])
222
223
224#------------------------------------------------------------------------------
225# Concatenation
226#------------------------------------------------------------------------------
227
228class ConcatTest(unittest.TestCase):
229    """Unit tests for the Concat class."""
230
231    def test_concat_list(self):
232        """Test Concat.__init__() and Concat.eval() methods for List."""
233
234        lhs = List([String('a'), String('b')])
235        rhs = List([String('c'), String('d')])
236        expr = Concat(lhs, rhs)
237
238        self.assertIs(expr.lhs, lhs)
239        self.assertIs(expr.rhs, rhs)
240
241        expr_eval = expr.eval({})
242        self.assertIsInstance(expr_eval, List)
243        self.assertEqual('a', expr_eval[0])
244        self.assertEqual('b', expr_eval[1])
245        self.assertEqual('c', expr_eval[2])
246        self.assertEqual('d', expr_eval[3])
247
248
249    def test_concat_string(self):
250        """Test Concat.__init__() and Concat.eval() methods for String."""
251
252        lhs = String('a')
253        rhs = String('b')
254        expr = Concat(lhs, rhs)
255
256        self.assertIs(expr.lhs, lhs)
257        self.assertIs(expr.rhs, rhs)
258
259        expr_eval = expr.eval({})
260        self.assertIsInstance(expr_eval, String)
261        self.assertEqual('ab', expr_eval)
262
263
264    def test_type_error(self):
265        """Test the type check in eval()."""
266
267        str_obj = String('a')
268        list_obj = List()
269
270        with self.assertRaises(TypeError):
271            Concat(str_obj, list_obj).eval({})
272
273        with self.assertRaises(TypeError):
274            Concat(list_obj, str_obj).eval({})
275
276
277#------------------------------------------------------------------------------
278# Dictionary
279#------------------------------------------------------------------------------
280
281class DictTest(unittest.TestCase):
282    """Unit tests for the Dict class."""
283
284    def test_dict(self):
285        """Test Dict.__init__() method."""
286
287        expr = Dict([('a', String('1')), ('b', Bool(True))])
288
289        self.assertIn('a', expr)
290        self.assertEqual(String('1'), expr['a'])
291
292        self.assertIn('b', expr)
293        self.assertEqual(Bool(True), expr['b'])
294
295
296    def test_eval(self):
297        """Test Dict.eval() method."""
298
299        expr = Dict([('a', VarRef('a', None)), ('b', VarRef('b', None))])
300        expr_eval = expr.eval({'a': String('1'), 'b': String('2')})
301
302        self.assertIn('a', expr_eval)
303        self.assertEqual('1', expr_eval['a'])
304
305        self.assertIn('b', expr_eval)
306        self.assertEqual('2', expr_eval['b'])
307
308
309if __name__ == '__main__':
310    unittest.main()
311