OILS / asdl / front_end_test.py View on Github | oils.pub

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