OILS / opy / _regtest / src / asdl / arith_ast_test.py View on Github | oilshell.org

197 lines, 113 significant
1#!/usr/bin/env python
2from __future__ import print_function
3"""
4arith_ast_test.py: Tests for arith_ast.py
5"""
6
7import cStringIO
8import unittest
9
10from asdl import py_meta
11from asdl import asdl_
12from asdl import const
13from asdl import encode
14
15from asdl import arith_ast # module under test
16
17# Sanity check. Doesn't pass because this unit test exposes implementation
18# details, like the concrete classes.
19#from _tmp import arith_ast_asdl as arith_ast
20
21
22ArithVar = arith_ast.ArithVar
23ArithUnary = arith_ast.ArithUnary
24ArithBinary = arith_ast.ArithBinary
25Const = arith_ast.Const
26Slice = arith_ast.Slice
27arith_expr = arith_ast.arith_expr
28source_location = arith_ast.source_location
29op_id_e = arith_ast.op_id_e
30
31cflow_e = arith_ast.cflow_e
32#cflow_t = arith_ast.cflow_t
33
34
35class ArithAstTest(unittest.TestCase):
36
37 def testFieldDefaults(self):
38 s = arith_ast.Slice()
39 s.a = ArithVar('foo')
40 self.assertEqual(None, s.begin)
41 self.assertEqual(None, s.end)
42 self.assertEqual(None, s.stride)
43 print(s)
44
45 func = arith_ast.FuncCall()
46 func.name = 'f'
47 self.assertEqual([], func.args)
48 print(func)
49
50 t = arith_ast.token(5, 'x')
51 self.assertEqual(5, t.id)
52 self.assertEqual('x', t.value)
53 self.assertEqual(const.NO_INTEGER, t.span_id)
54
55 def testTypeCheck(self):
56 v = ArithVar('name')
57 # Integer is not allowed
58 self.assertRaises(AssertionError, ArithVar, 1)
59
60 v = ArithUnary(op_id_e.Minus, Const(99))
61 # Raw integer is not allowed
62 self.assertRaises(AssertionError, ArithUnary, op_id_e.Minus, 99)
63
64 v = ArithUnary(op_id_e.Minus, Const(99))
65 # Raw integer is not allowed
66 #self.assertRaises(AssertionError, ArithUnary, op_id_e.Minus, op_id_e.Plus)
67
68 def testExtraFields(self):
69 v = ArithVar('z')
70
71 # TODO: Attach this to EVERY non-simple constructor? Those are subclasses
72 # of Sum types.
73 # What about product types?
74 #print(v.xspans)
75
76 def testEncode(self):
77 obj = arith_ast.Const(99)
78 print('Encoding into binary:')
79 print(obj)
80
81 enc = encode.Params()
82 f = cStringIO.StringIO()
83 out = encode.BinOutput(f)
84 encode.EncodeRoot(obj, enc, out)
85 e = f.getvalue()
86
87 #print(repr(e))
88 #print(e[0:4], e[4:8], e[8:])
89
90 # Header is OHP version 1
91 self.assertEqual(b'OHP\x01', e[0:4])
92
93 self.assertEqual(b'\x04', e[4:5]) # alignment 4
94
95 # TODO: Fix after spids
96 return
97 self.assertEqual(b'\x02\x00\x00', e[5:8]) # root ref 2
98
99 self.assertEqual(b'\x01', e[8:9]) # tag 1 is const
100 self.assertEqual(b'\x63\x00\x00', e[9:12]) # 0x63 = 99
101
102 def testConstructorType(self):
103 n1 = ArithVar('x')
104 n2 = ArithVar(name='y')
105 print(n1)
106 print(n2)
107
108 # Not good because not assigned?
109 n3 = ArithVar()
110
111 # NOTE: You cannot instantiate a product type directly? It's just used for
112 # type checking. What about OCaml?
113 # That means you just need to create classes for the records (Constructor).
114 # They all descend from Obj. They don't need
115
116 n3 = ArithVar()
117 try:
118 n4 = ArithVar('x', name='X')
119 except TypeError as e:
120 pass
121 else:
122 raise AssertionError("Should have failed")
123
124 def testProductType(self):
125 print()
126 print('-- PRODUCT --')
127 print()
128
129 s = source_location()
130 s.path = 'hi'
131 s.line = 1
132 s.col = 2
133 s.length = 3
134 print(s)
135
136 assert isinstance(s.ASDL_TYPE, asdl_.Product)
137
138 # Implementation detail for dynamic type checking
139 assert isinstance(s, py_meta.CompoundObj)
140
141 def testSimpleSumType(self):
142 # TODO: Should be op_id_i.Plus -- instance
143 # Should be op_id_s.Plus
144
145 print()
146 print('-- SIMPLE SUM --')
147 print()
148
149 o = op_id_e.Plus
150 assert isinstance(o, py_meta.SimpleObj)
151
152 # Implementation detail for dynamic type checking
153 assert isinstance(o.ASDL_TYPE, asdl_.Sum)
154
155 def testCompoundSumType(self):
156 print()
157 print('-- COMPOUND SUM --')
158 print()
159
160 # TODO: Should be cflow_t.Break() and cflow_i.Break
161 c = arith_ast.Break()
162 assert isinstance(c, arith_ast.Break)
163 assert isinstance(c, arith_ast.cflow)
164 assert isinstance(c, py_meta.CompoundObj)
165
166 # Implementation detail for dynamic type checking
167 assert isinstance(c.ASDL_TYPE, asdl_.Constructor), c.ASDL_TYPE
168
169 def testOtherTypes(self):
170 c = Const(66)
171 print(c)
172
173 print((Slice(Const(1), Const(5), Const(2))))
174
175 print((op_id_e.Plus))
176
177 # Class for sum type
178 print(arith_expr)
179
180 # Invalid because only half were assigned
181 #print(ArithBinary(op_id_e.Plus, Const(5)))
182
183 n = ArithBinary()
184 #n.CheckUnassigned()
185 n.op_id = op_id_e.Plus
186 n.left = Const(5)
187 #n.CheckUnassigned()
188 n.right = Const(6)
189 n.CheckUnassigned()
190
191 arith_expr_e = arith_ast.arith_expr_e
192 self.assertEqual(arith_expr_e.Const, c.tag)
193 self.assertEqual(arith_expr_e.ArithBinary, n.tag)
194
195
196if __name__ == '__main__':
197 unittest.main()