pytree_utils_test.py 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  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. import unittest
  16. from yapf_third_party._ylib2to3 import pygram
  17. from yapf_third_party._ylib2to3 import pytree
  18. from yapf_third_party._ylib2to3.pgen2 import token
  19. from yapf.pytree import pytree_utils
  20. # More direct access to the symbol->number mapping living within the grammar
  21. # module.
  22. _GRAMMAR_SYMBOL2NUMBER = pygram.python_grammar.symbol2number
  23. _FOO = 'foo'
  24. _FOO1 = 'foo1'
  25. _FOO2 = 'foo2'
  26. _FOO3 = 'foo3'
  27. _FOO4 = 'foo4'
  28. _FOO5 = 'foo5'
  29. class NodeNameTest(unittest.TestCase):
  30. def testNodeNameForLeaf(self):
  31. leaf = pytree.Leaf(token.LPAR, '(')
  32. self.assertEqual('LPAR', pytree_utils.NodeName(leaf))
  33. def testNodeNameForNode(self):
  34. leaf = pytree.Leaf(token.LPAR, '(')
  35. node = pytree.Node(pygram.python_grammar.symbol2number['suite'], [leaf])
  36. self.assertEqual('suite', pytree_utils.NodeName(node))
  37. class ParseCodeToTreeTest(unittest.TestCase):
  38. def testParseCodeToTree(self):
  39. # Since ParseCodeToTree is a thin wrapper around underlying lib2to3
  40. # functionality, only a sanity test here...
  41. tree = pytree_utils.ParseCodeToTree('foo = 2\n')
  42. self.assertEqual('file_input', pytree_utils.NodeName(tree))
  43. self.assertEqual(2, len(tree.children))
  44. self.assertEqual('simple_stmt', pytree_utils.NodeName(tree.children[0]))
  45. def testPrintFunctionToTree(self):
  46. tree = pytree_utils.ParseCodeToTree(
  47. 'print("hello world", file=sys.stderr)\n')
  48. self.assertEqual('file_input', pytree_utils.NodeName(tree))
  49. self.assertEqual(2, len(tree.children))
  50. self.assertEqual('simple_stmt', pytree_utils.NodeName(tree.children[0]))
  51. def testPrintStatementToTree(self):
  52. with self.assertRaises(SyntaxError):
  53. pytree_utils.ParseCodeToTree('print "hello world"\n')
  54. def testClassNotLocal(self):
  55. with self.assertRaises(SyntaxError):
  56. pytree_utils.ParseCodeToTree('class nonlocal: pass\n')
  57. class InsertNodesBeforeAfterTest(unittest.TestCase):
  58. def _BuildSimpleTree(self):
  59. # Builds a simple tree we can play with in the tests.
  60. # The tree looks like this:
  61. #
  62. # suite:
  63. # LPAR
  64. # LPAR
  65. # simple_stmt:
  66. # NAME('foo')
  67. #
  68. lpar1 = pytree.Leaf(token.LPAR, '(')
  69. lpar2 = pytree.Leaf(token.LPAR, '(')
  70. simple_stmt = pytree.Node(_GRAMMAR_SYMBOL2NUMBER['simple_stmt'],
  71. [pytree.Leaf(token.NAME, 'foo')])
  72. return pytree.Node(_GRAMMAR_SYMBOL2NUMBER['suite'],
  73. [lpar1, lpar2, simple_stmt])
  74. def _MakeNewNodeRPAR(self):
  75. return pytree.Leaf(token.RPAR, ')')
  76. def setUp(self):
  77. self._simple_tree = self._BuildSimpleTree()
  78. def testInsertNodesBefore(self):
  79. # Insert before simple_stmt and make sure it went to the right place
  80. pytree_utils.InsertNodesBefore([self._MakeNewNodeRPAR()],
  81. self._simple_tree.children[2])
  82. self.assertEqual(4, len(self._simple_tree.children))
  83. self.assertEqual('RPAR',
  84. pytree_utils.NodeName(self._simple_tree.children[2]))
  85. self.assertEqual('simple_stmt',
  86. pytree_utils.NodeName(self._simple_tree.children[3]))
  87. def testInsertNodesBeforeFirstChild(self):
  88. # Insert before the first child of its parent
  89. simple_stmt = self._simple_tree.children[2]
  90. foo_child = simple_stmt.children[0]
  91. pytree_utils.InsertNodesBefore([self._MakeNewNodeRPAR()], foo_child)
  92. self.assertEqual(3, len(self._simple_tree.children))
  93. self.assertEqual(2, len(simple_stmt.children))
  94. self.assertEqual('RPAR', pytree_utils.NodeName(simple_stmt.children[0]))
  95. self.assertEqual('NAME', pytree_utils.NodeName(simple_stmt.children[1]))
  96. def testInsertNodesAfter(self):
  97. # Insert after and make sure it went to the right place
  98. pytree_utils.InsertNodesAfter([self._MakeNewNodeRPAR()],
  99. self._simple_tree.children[2])
  100. self.assertEqual(4, len(self._simple_tree.children))
  101. self.assertEqual('simple_stmt',
  102. pytree_utils.NodeName(self._simple_tree.children[2]))
  103. self.assertEqual('RPAR',
  104. pytree_utils.NodeName(self._simple_tree.children[3]))
  105. def testInsertNodesAfterLastChild(self):
  106. # Insert after the last child of its parent
  107. simple_stmt = self._simple_tree.children[2]
  108. foo_child = simple_stmt.children[0]
  109. pytree_utils.InsertNodesAfter([self._MakeNewNodeRPAR()], foo_child)
  110. self.assertEqual(3, len(self._simple_tree.children))
  111. self.assertEqual(2, len(simple_stmt.children))
  112. self.assertEqual('NAME', pytree_utils.NodeName(simple_stmt.children[0]))
  113. self.assertEqual('RPAR', pytree_utils.NodeName(simple_stmt.children[1]))
  114. def testInsertNodesWhichHasParent(self):
  115. # Try to insert an existing tree node into another place and fail.
  116. with self.assertRaises(RuntimeError):
  117. pytree_utils.InsertNodesAfter([self._simple_tree.children[1]],
  118. self._simple_tree.children[0])
  119. class AnnotationsTest(unittest.TestCase):
  120. def setUp(self):
  121. self._leaf = pytree.Leaf(token.LPAR, '(')
  122. self._node = pytree.Node(_GRAMMAR_SYMBOL2NUMBER['simple_stmt'],
  123. [pytree.Leaf(token.NAME, 'foo')])
  124. def testGetWhenNone(self):
  125. self.assertIsNone(pytree_utils.GetNodeAnnotation(self._leaf, _FOO))
  126. def testSetWhenNone(self):
  127. pytree_utils.SetNodeAnnotation(self._leaf, _FOO, 20)
  128. self.assertEqual(pytree_utils.GetNodeAnnotation(self._leaf, _FOO), 20)
  129. def testSetAgain(self):
  130. pytree_utils.SetNodeAnnotation(self._leaf, _FOO, 20)
  131. self.assertEqual(pytree_utils.GetNodeAnnotation(self._leaf, _FOO), 20)
  132. pytree_utils.SetNodeAnnotation(self._leaf, _FOO, 30)
  133. self.assertEqual(pytree_utils.GetNodeAnnotation(self._leaf, _FOO), 30)
  134. def testMultiple(self):
  135. pytree_utils.SetNodeAnnotation(self._leaf, _FOO, 20)
  136. pytree_utils.SetNodeAnnotation(self._leaf, _FOO1, 1)
  137. pytree_utils.SetNodeAnnotation(self._leaf, _FOO2, 2)
  138. pytree_utils.SetNodeAnnotation(self._leaf, _FOO3, 3)
  139. pytree_utils.SetNodeAnnotation(self._leaf, _FOO4, 4)
  140. pytree_utils.SetNodeAnnotation(self._leaf, _FOO5, 5)
  141. self.assertEqual(pytree_utils.GetNodeAnnotation(self._leaf, _FOO), 20)
  142. self.assertEqual(pytree_utils.GetNodeAnnotation(self._leaf, _FOO1), 1)
  143. self.assertEqual(pytree_utils.GetNodeAnnotation(self._leaf, _FOO2), 2)
  144. self.assertEqual(pytree_utils.GetNodeAnnotation(self._leaf, _FOO3), 3)
  145. self.assertEqual(pytree_utils.GetNodeAnnotation(self._leaf, _FOO4), 4)
  146. self.assertEqual(pytree_utils.GetNodeAnnotation(self._leaf, _FOO5), 5)
  147. def testSubtype(self):
  148. pytree_utils.AppendNodeAnnotation(self._leaf,
  149. pytree_utils.Annotation.SUBTYPE, _FOO)
  150. self.assertSetEqual(
  151. pytree_utils.GetNodeAnnotation(self._leaf,
  152. pytree_utils.Annotation.SUBTYPE), {_FOO})
  153. pytree_utils.RemoveSubtypeAnnotation(self._leaf, _FOO)
  154. self.assertSetEqual(
  155. pytree_utils.GetNodeAnnotation(self._leaf,
  156. pytree_utils.Annotation.SUBTYPE), set())
  157. def testSetOnNode(self):
  158. pytree_utils.SetNodeAnnotation(self._node, _FOO, 20)
  159. self.assertEqual(pytree_utils.GetNodeAnnotation(self._node, _FOO), 20)
  160. if __name__ == '__main__':
  161. unittest.main()