OILS / asdl / front_end_test.py View on Github | oilshell.org

184 lines, 95 significant
1#!/usr/bin/env python2
2"""front_end_test.py: Tests for front_end.py."""
3from __future__ import print_function
4
5import cStringIO
6import unittest
7
8from asdl import front_end # module under test
9from asdl import ast
10from asdl import format as fmt
11
12
13class FrontEndTest(unittest.TestCase):
14
15 def testLoadSchema(self):
16 with open('asdl/examples/typed_demo.asdl') as f:
17 schema_ast = front_end.LoadSchema(f, {}, verbose=True)
18 print(schema_ast)
19
20 def testSharedVariant(self):
21 with open('asdl/examples/shared_variant.asdl') as f:
22 schema_ast = front_end.LoadSchema(f, {}, verbose=False)
23 print(schema_ast)
24
25 def testSharedVariantCode(self):
26 # generated by build/dev.sh minimal
27 from _devbuild.gen.shared_variant_asdl import (DoubleQuoted, expr,
28 expr_e, word_part,
29 word_part_e)
30 print(DoubleQuoted)
31
32 print(expr)
33 print(expr_e)
34
35 print(word_part)
36 print(word_part_e)
37
38 # These have the same value!
39 self.assertEqual(65, expr_e.DoubleQuoted)
40 self.assertEqual(expr_e.DoubleQuoted, word_part_e.DoubleQuoted)
41
42 d = DoubleQuoted(5, ['foo', 'bar'])
43 fmt.PrettyPrint(d)
44 print()
45
46 b = expr.Binary(d, d)
47 b.spids = [42, 43]
48 fmt.PrettyPrint(b)
49
50 def _assertParse(self, code_str):
51 f = cStringIO.StringIO(code_str)
52 p = front_end.ASDLParser()
53 schema_ast = p.parse(f)
54 print(schema_ast)
55 # For now just test its type
56 self.assert_(isinstance(schema_ast, ast.Module))
57
58 def testParse(self):
59 self._assertParse("""
60module foo {
61 -- these are invalid, but checked in name resolution stage
62 point = (int? x, int* y)
63
64 action = Foo | Bar(point z)
65
66 foo = (List[int] span_ids)
67 bar = (Dict[string, int] options)
68
69 -- this check happens later
70 does_not_resolve = (typo zz)
71
72 color = Red | Green
73
74 color2 = Red | Green generate []
75
76 color3 = Red | Green
77 generate [integers]
78
79 color4 = Blue | Purple
80 generate [uint16]
81
82 -- New optional lists
83 spam = (Optional[List[int]] pipe_status)
84 -- Nicer way of writing it
85 spam2 = (List[int]? pipe_status)
86}
87""")
88
89 def _assertParseError(self, code_str):
90 f = cStringIO.StringIO(code_str)
91 p = front_end.ASDLParser()
92 try:
93 schema_ast = p.parse(f)
94 except front_end.ASDLSyntaxError as e:
95 print(e)
96 else:
97 self.fail("Expected parse failure: %r" % code_str)
98
99 def testParseErrors(self):
100 # Need field name
101 self._assertParseError('module foo { t = (int) }')
102
103 # Need []
104 self._assertParseError('module foo { t = (List foo) }')
105
106 # Shouldn't have []
107 self._assertParseError('module foo { t = (string[string] a) }')
108
109 # Not enough params
110 self._assertParseError('module foo { t = (Dict[] a) }')
111 self._assertParseError('module foo { t = (Dict[string] a) }')
112 self._assertParseError('module foo { t = (Dict[string, ] a) }')
113
114 self._assertParseError('module foo { ( }')
115
116 # Abandoned syntax
117 self._assertParseError('module foo { simple: integers = A | B }')
118
119 self._assertParseError('module foo { integers = A | B generate }')
120
121 self._assertParseError(
122 'module foo { integers = A | B generate [integers, ,] }')
123
124 self._assertParseError(
125 'module foo { integers = A | B generate [invalid] }')
126
127 def _assertResolve(self, code_str):
128 f = cStringIO.StringIO(code_str)
129 schema_ast = front_end.LoadSchema(f, {})
130
131 print(type(schema_ast))
132 print(schema_ast)
133
134 def testResolve(self):
135 self._assertResolve("""
136module foo {
137 point = (int x, int y)
138 place = None | Two(point a, point b)
139 options = (Dict[string, int] names)
140}
141""")
142
143 def _assertResolveError(self, code_str):
144 f = cStringIO.StringIO(code_str)
145 try:
146 schema_ast = front_end.LoadSchema(f, {})
147 except front_end.ASDLSyntaxError as e:
148 print(e)
149 else:
150 self.fail("Expected name resolution error: %r" % code_str)
151
152 def testResolveErrors(self):
153 self._assertResolveError("""
154module foo {
155 place = None | Two(typo b)
156}
157""")
158
159 # Optional integer isn't allowed, because C++ can't express it
160 # Integers are initialized to -1
161 self._assertResolveError('module foo { t = (int? status) }')
162
163 # Optional simple sum isn't allowed
164 self._assertResolveError('''
165 module foo {
166 color = Red | Green
167 t = (color? status)
168 }
169 ''')
170
171 def testAstNodes(self):
172 # maybe[string]
173 n1 = ast.NamedType('string')
174 print(n1)
175
176 n2 = ast.ParameterizedType('Optional', [n1])
177 print(n2)
178
179 n3 = ast.ParameterizedType('Dict', [n1, ast.NamedType('int')])
180 print(n3)
181
182
183if __name__ == '__main__':
184 unittest.main()