]>
Commit | Line | Data |
---|---|---|
53e6db90 DC |
1 | # Copyright 2015 Google Inc. All Rights Reserved. |
2 | # | |
3 | # Licensed under the Apache License, Version 2.0 (the "License"); | |
4 | # you may not use this file except in compliance with the License. | |
5 | # You may obtain a copy of the License at | |
6 | # | |
7 | # http://www.apache.org/licenses/LICENSE-2.0 | |
8 | # | |
9 | # Unless required by applicable law or agreed to in writing, software | |
10 | # distributed under the License is distributed on an "AS IS" BASIS, | |
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
12 | # See the License for the specific language governing permissions and | |
13 | # limitations under the License. | |
14 | """Tests for yapf.pytree_utils.""" | |
15 | ||
16 | import unittest | |
17 | ||
18 | from yapf_third_party._ylib2to3 import pygram | |
19 | from yapf_third_party._ylib2to3 import pytree | |
20 | from yapf_third_party._ylib2to3.pgen2 import token | |
21 | ||
22 | from yapf.pytree import pytree_utils | |
23 | ||
24 | from yapftests import yapf_test_helper | |
25 | ||
26 | # More direct access to the symbol->number mapping living within the grammar | |
27 | # module. | |
28 | _GRAMMAR_SYMBOL2NUMBER = pygram.python_grammar.symbol2number | |
29 | ||
30 | _FOO = 'foo' | |
31 | _FOO1 = 'foo1' | |
32 | _FOO2 = 'foo2' | |
33 | _FOO3 = 'foo3' | |
34 | _FOO4 = 'foo4' | |
35 | _FOO5 = 'foo5' | |
36 | ||
37 | ||
38 | class NodeNameTest(yapf_test_helper.YAPFTest): | |
39 | ||
40 | def testNodeNameForLeaf(self): | |
41 | leaf = pytree.Leaf(token.LPAR, '(') | |
42 | self.assertEqual('LPAR', pytree_utils.NodeName(leaf)) | |
43 | ||
44 | def testNodeNameForNode(self): | |
45 | leaf = pytree.Leaf(token.LPAR, '(') | |
46 | node = pytree.Node(pygram.python_grammar.symbol2number['suite'], [leaf]) | |
47 | self.assertEqual('suite', pytree_utils.NodeName(node)) | |
48 | ||
49 | ||
50 | class ParseCodeToTreeTest(yapf_test_helper.YAPFTest): | |
51 | ||
52 | def testParseCodeToTree(self): | |
53 | # Since ParseCodeToTree is a thin wrapper around underlying lib2to3 | |
54 | # functionality, only a sanity test here... | |
55 | tree = pytree_utils.ParseCodeToTree('foo = 2\n') | |
56 | self.assertEqual('file_input', pytree_utils.NodeName(tree)) | |
57 | self.assertEqual(2, len(tree.children)) | |
58 | self.assertEqual('simple_stmt', pytree_utils.NodeName(tree.children[0])) | |
59 | ||
60 | def testPrintFunctionToTree(self): | |
61 | tree = pytree_utils.ParseCodeToTree( | |
62 | 'print("hello world", file=sys.stderr)\n') | |
63 | self.assertEqual('file_input', pytree_utils.NodeName(tree)) | |
64 | self.assertEqual(2, len(tree.children)) | |
65 | self.assertEqual('simple_stmt', pytree_utils.NodeName(tree.children[0])) | |
66 | ||
67 | def testPrintStatementToTree(self): | |
68 | with self.assertRaises(SyntaxError): | |
69 | pytree_utils.ParseCodeToTree('print "hello world"\n') | |
70 | ||
71 | def testClassNotLocal(self): | |
72 | with self.assertRaises(SyntaxError): | |
73 | pytree_utils.ParseCodeToTree('class nonlocal: pass\n') | |
74 | ||
75 | ||
76 | class InsertNodesBeforeAfterTest(yapf_test_helper.YAPFTest): | |
77 | ||
78 | def _BuildSimpleTree(self): | |
79 | # Builds a simple tree we can play with in the tests. | |
80 | # The tree looks like this: | |
81 | # | |
82 | # suite: | |
83 | # LPAR | |
84 | # LPAR | |
85 | # simple_stmt: | |
86 | # NAME('foo') | |
87 | # | |
88 | lpar1 = pytree.Leaf(token.LPAR, '(') | |
89 | lpar2 = pytree.Leaf(token.LPAR, '(') | |
90 | simple_stmt = pytree.Node(_GRAMMAR_SYMBOL2NUMBER['simple_stmt'], | |
91 | [pytree.Leaf(token.NAME, 'foo')]) | |
92 | return pytree.Node(_GRAMMAR_SYMBOL2NUMBER['suite'], | |
93 | [lpar1, lpar2, simple_stmt]) | |
94 | ||
95 | def _MakeNewNodeRPAR(self): | |
96 | return pytree.Leaf(token.RPAR, ')') | |
97 | ||
98 | def setUp(self): | |
99 | self._simple_tree = self._BuildSimpleTree() | |
100 | ||
101 | def testInsertNodesBefore(self): | |
102 | # Insert before simple_stmt and make sure it went to the right place | |
103 | pytree_utils.InsertNodesBefore([self._MakeNewNodeRPAR()], | |
104 | self._simple_tree.children[2]) | |
105 | self.assertEqual(4, len(self._simple_tree.children)) | |
106 | self.assertEqual('RPAR', | |
107 | pytree_utils.NodeName(self._simple_tree.children[2])) | |
108 | self.assertEqual('simple_stmt', | |
109 | pytree_utils.NodeName(self._simple_tree.children[3])) | |
110 | ||
111 | def testInsertNodesBeforeFirstChild(self): | |
112 | # Insert before the first child of its parent | |
113 | simple_stmt = self._simple_tree.children[2] | |
114 | foo_child = simple_stmt.children[0] | |
115 | pytree_utils.InsertNodesBefore([self._MakeNewNodeRPAR()], foo_child) | |
116 | self.assertEqual(3, len(self._simple_tree.children)) | |
117 | self.assertEqual(2, len(simple_stmt.children)) | |
118 | self.assertEqual('RPAR', pytree_utils.NodeName(simple_stmt.children[0])) | |
119 | self.assertEqual('NAME', pytree_utils.NodeName(simple_stmt.children[1])) | |
120 | ||
121 | def testInsertNodesAfter(self): | |
122 | # Insert after and make sure it went to the right place | |
123 | pytree_utils.InsertNodesAfter([self._MakeNewNodeRPAR()], | |
124 | self._simple_tree.children[2]) | |
125 | self.assertEqual(4, len(self._simple_tree.children)) | |
126 | self.assertEqual('simple_stmt', | |
127 | pytree_utils.NodeName(self._simple_tree.children[2])) | |
128 | self.assertEqual('RPAR', | |
129 | pytree_utils.NodeName(self._simple_tree.children[3])) | |
130 | ||
131 | def testInsertNodesAfterLastChild(self): | |
132 | # Insert after the last child of its parent | |
133 | simple_stmt = self._simple_tree.children[2] | |
134 | foo_child = simple_stmt.children[0] | |
135 | pytree_utils.InsertNodesAfter([self._MakeNewNodeRPAR()], foo_child) | |
136 | self.assertEqual(3, len(self._simple_tree.children)) | |
137 | self.assertEqual(2, len(simple_stmt.children)) | |
138 | self.assertEqual('NAME', pytree_utils.NodeName(simple_stmt.children[0])) | |
139 | self.assertEqual('RPAR', pytree_utils.NodeName(simple_stmt.children[1])) | |
140 | ||
141 | def testInsertNodesWhichHasParent(self): | |
142 | # Try to insert an existing tree node into another place and fail. | |
143 | with self.assertRaises(RuntimeError): | |
144 | pytree_utils.InsertNodesAfter([self._simple_tree.children[1]], | |
145 | self._simple_tree.children[0]) | |
146 | ||
147 | ||
148 | class AnnotationsTest(yapf_test_helper.YAPFTest): | |
149 | ||
150 | def setUp(self): | |
151 | self._leaf = pytree.Leaf(token.LPAR, '(') | |
152 | self._node = pytree.Node(_GRAMMAR_SYMBOL2NUMBER['simple_stmt'], | |
153 | [pytree.Leaf(token.NAME, 'foo')]) | |
154 | ||
155 | def testGetWhenNone(self): | |
156 | self.assertIsNone(pytree_utils.GetNodeAnnotation(self._leaf, _FOO)) | |
157 | ||
158 | def testSetWhenNone(self): | |
159 | pytree_utils.SetNodeAnnotation(self._leaf, _FOO, 20) | |
160 | self.assertEqual(pytree_utils.GetNodeAnnotation(self._leaf, _FOO), 20) | |
161 | ||
162 | def testSetAgain(self): | |
163 | pytree_utils.SetNodeAnnotation(self._leaf, _FOO, 20) | |
164 | self.assertEqual(pytree_utils.GetNodeAnnotation(self._leaf, _FOO), 20) | |
165 | pytree_utils.SetNodeAnnotation(self._leaf, _FOO, 30) | |
166 | self.assertEqual(pytree_utils.GetNodeAnnotation(self._leaf, _FOO), 30) | |
167 | ||
168 | def testMultiple(self): | |
169 | pytree_utils.SetNodeAnnotation(self._leaf, _FOO, 20) | |
170 | pytree_utils.SetNodeAnnotation(self._leaf, _FOO1, 1) | |
171 | pytree_utils.SetNodeAnnotation(self._leaf, _FOO2, 2) | |
172 | pytree_utils.SetNodeAnnotation(self._leaf, _FOO3, 3) | |
173 | pytree_utils.SetNodeAnnotation(self._leaf, _FOO4, 4) | |
174 | pytree_utils.SetNodeAnnotation(self._leaf, _FOO5, 5) | |
175 | ||
176 | self.assertEqual(pytree_utils.GetNodeAnnotation(self._leaf, _FOO), 20) | |
177 | self.assertEqual(pytree_utils.GetNodeAnnotation(self._leaf, _FOO1), 1) | |
178 | self.assertEqual(pytree_utils.GetNodeAnnotation(self._leaf, _FOO2), 2) | |
179 | self.assertEqual(pytree_utils.GetNodeAnnotation(self._leaf, _FOO3), 3) | |
180 | self.assertEqual(pytree_utils.GetNodeAnnotation(self._leaf, _FOO4), 4) | |
181 | self.assertEqual(pytree_utils.GetNodeAnnotation(self._leaf, _FOO5), 5) | |
182 | ||
183 | def testSubtype(self): | |
184 | pytree_utils.AppendNodeAnnotation(self._leaf, | |
185 | pytree_utils.Annotation.SUBTYPE, _FOO) | |
186 | ||
187 | self.assertSetEqual( | |
188 | pytree_utils.GetNodeAnnotation(self._leaf, | |
189 | pytree_utils.Annotation.SUBTYPE), {_FOO}) | |
190 | ||
191 | pytree_utils.RemoveSubtypeAnnotation(self._leaf, _FOO) | |
192 | ||
193 | self.assertSetEqual( | |
194 | pytree_utils.GetNodeAnnotation(self._leaf, | |
195 | pytree_utils.Annotation.SUBTYPE), set()) | |
196 | ||
197 | def testSetOnNode(self): | |
198 | pytree_utils.SetNodeAnnotation(self._node, _FOO, 20) | |
199 | self.assertEqual(pytree_utils.GetNodeAnnotation(self._node, _FOO), 20) | |
200 | ||
201 | ||
202 | if __name__ == '__main__': | |
203 | unittest.main() |