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

181 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 -- New optional lists
80 spam = (Optional[List[int]] pipe_status)
81 -- Nicer way of writing it
82 spam2 = (List[int]? pipe_status)
83}
84""")
85
86 def _assertParseError(self, code_str):
87 f = cStringIO.StringIO(code_str)
88 p = front_end.ASDLParser()
89 try:
90 schema_ast = p.parse(f)
91 except front_end.ASDLSyntaxError as e:
92 print(e)
93 else:
94 self.fail("Expected parse failure: %r" % code_str)
95
96 def testParseErrors(self):
97 # Need field name
98 self._assertParseError('module foo { t = (int) }')
99
100 # Need []
101 self._assertParseError('module foo { t = (List foo) }')
102
103 # Shouldn't have []
104 self._assertParseError('module foo { t = (string[string] a) }')
105
106 # Not enough params
107 self._assertParseError('module foo { t = (Dict[] a) }')
108 self._assertParseError('module foo { t = (Dict[string] a) }')
109 self._assertParseError('module foo { t = (Dict[string, ] a) }')
110
111 self._assertParseError('module foo { ( }')
112
113 # Abandoned syntax
114 self._assertParseError('module foo { simple: integers = A | B }')
115
116 self._assertParseError('module foo { integers = A | B generate }')
117
118 self._assertParseError(
119 'module foo { integers = A | B generate [integers, ,] }')
120
121 self._assertParseError(
122 'module foo { integers = A | B generate [invalid] }')
123
124 def _assertResolve(self, code_str):
125 f = cStringIO.StringIO(code_str)
126 schema_ast = front_end.LoadSchema(f, {})
127
128 print(type(schema_ast))
129 print(schema_ast)
130
131 def testResolve(self):
132 self._assertResolve("""
133module foo {
134 point = (int x, int y)
135 place = None | Two(point a, point b)
136 options = (Dict[string, int] names)
137}
138""")
139
140 def _assertResolveError(self, code_str):
141 f = cStringIO.StringIO(code_str)
142 try:
143 schema_ast = front_end.LoadSchema(f, {})
144 except front_end.ASDLSyntaxError as e:
145 print(e)
146 else:
147 self.fail("Expected name resolution error: %r" % code_str)
148
149 def testResolveErrors(self):
150 self._assertResolveError("""
151module foo {
152 place = None | Two(typo b)
153}
154""")
155
156 # Optional integer isn't allowed, because C++ can't express it
157 # Integers are initialized to -1
158 self._assertResolveError('module foo { t = (int? status) }')
159
160 # Optional simple sum isn't allowed
161 self._assertResolveError('''
162 module foo {
163 color = Red | Green
164 t = (color? status)
165 }
166 ''')
167
168 def testAstNodes(self):
169 # maybe[string]
170 n1 = ast.NamedType('string')
171 print(n1)
172
173 n2 = ast.ParameterizedType('Optional', [n1])
174 print(n2)
175
176 n3 = ast.ParameterizedType('Dict', [n1, ast.NamedType('int')])
177 print(n3)
178
179
180if __name__ == '__main__':
181 unittest.main()