1 | #!/usr/bin/env python2
|
2 | """front_end_test.py: Tests for front_end.py."""
|
3 | from __future__ import print_function
|
4 |
|
5 | import cStringIO
|
6 | import unittest
|
7 |
|
8 | from asdl import front_end # module under test
|
9 | from asdl import ast
|
10 | from asdl import format as fmt
|
11 |
|
12 |
|
13 | class 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("""
|
60 | module 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("""
|
136 | module 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("""
|
154 | module 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 |
|
183 | if __name__ == '__main__':
|
184 | unittest.main()
|