pytree_unwrapper_test.py 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  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_unwrapper."""
  15. import textwrap
  16. import unittest
  17. from yapf.pytree import pytree_utils
  18. from yapftests import yapf_test_helper
  19. class PytreeUnwrapperTest(yapf_test_helper.YAPFTest):
  20. def _CheckLogicalLines(self, llines, list_of_expected):
  21. """Check that the given LogicalLines match expectations.
  22. Args:
  23. llines: list of LogicalLine
  24. list_of_expected: list of (depth, values) pairs. Non-semantic tokens are
  25. filtered out from the expected values.
  26. """
  27. actual = []
  28. for lline in llines:
  29. filtered_values = [
  30. ft.value
  31. for ft in lline.tokens
  32. if ft.name not in pytree_utils.NONSEMANTIC_TOKENS
  33. ]
  34. actual.append((lline.depth, filtered_values))
  35. self.assertEqual(list_of_expected, actual)
  36. def testSimpleFileScope(self):
  37. code = textwrap.dedent(r"""
  38. x = 1
  39. # a comment
  40. y = 2
  41. """)
  42. llines = yapf_test_helper.ParseAndUnwrap(code)
  43. self._CheckLogicalLines(llines, [
  44. (0, ['x', '=', '1']),
  45. (0, ['# a comment']),
  46. (0, ['y', '=', '2']),
  47. ])
  48. def testSimpleMultilineStatement(self):
  49. code = textwrap.dedent(r"""
  50. y = (1 +
  51. x)
  52. """)
  53. llines = yapf_test_helper.ParseAndUnwrap(code)
  54. self._CheckLogicalLines(llines, [
  55. (0, ['y', '=', '(', '1', '+', 'x', ')']),
  56. ])
  57. def testFileScopeWithInlineComment(self):
  58. code = textwrap.dedent(r"""
  59. x = 1 # a comment
  60. y = 2
  61. """)
  62. llines = yapf_test_helper.ParseAndUnwrap(code)
  63. self._CheckLogicalLines(llines, [
  64. (0, ['x', '=', '1', '# a comment']),
  65. (0, ['y', '=', '2']),
  66. ])
  67. def testSimpleIf(self):
  68. code = textwrap.dedent(r"""
  69. if foo:
  70. x = 1
  71. y = 2
  72. """)
  73. llines = yapf_test_helper.ParseAndUnwrap(code)
  74. self._CheckLogicalLines(llines, [
  75. (0, ['if', 'foo', ':']),
  76. (1, ['x', '=', '1']),
  77. (1, ['y', '=', '2']),
  78. ])
  79. def testSimpleIfWithComments(self):
  80. code = textwrap.dedent(r"""
  81. # c1
  82. if foo: # c2
  83. x = 1
  84. y = 2
  85. """)
  86. llines = yapf_test_helper.ParseAndUnwrap(code)
  87. self._CheckLogicalLines(llines, [
  88. (0, ['# c1']),
  89. (0, ['if', 'foo', ':', '# c2']),
  90. (1, ['x', '=', '1']),
  91. (1, ['y', '=', '2']),
  92. ])
  93. def testIfWithCommentsInside(self):
  94. code = textwrap.dedent(r"""
  95. if foo:
  96. # c1
  97. x = 1 # c2
  98. # c3
  99. y = 2
  100. """)
  101. llines = yapf_test_helper.ParseAndUnwrap(code)
  102. self._CheckLogicalLines(llines, [
  103. (0, ['if', 'foo', ':']),
  104. (1, ['# c1']),
  105. (1, ['x', '=', '1', '# c2']),
  106. (1, ['# c3']),
  107. (1, ['y', '=', '2']),
  108. ])
  109. def testIfElifElse(self):
  110. code = textwrap.dedent(r"""
  111. if x:
  112. x = 1 # c1
  113. elif y: # c2
  114. y = 1
  115. else:
  116. # c3
  117. z = 1
  118. """)
  119. llines = yapf_test_helper.ParseAndUnwrap(code)
  120. self._CheckLogicalLines(llines, [
  121. (0, ['if', 'x', ':']),
  122. (1, ['x', '=', '1', '# c1']),
  123. (0, ['elif', 'y', ':', '# c2']),
  124. (1, ['y', '=', '1']),
  125. (0, ['else', ':']),
  126. (1, ['# c3']),
  127. (1, ['z', '=', '1']),
  128. ])
  129. def testNestedCompoundTwoLevel(self):
  130. code = textwrap.dedent(r"""
  131. if x:
  132. x = 1 # c1
  133. while t:
  134. # c2
  135. j = 1
  136. k = 1
  137. """)
  138. llines = yapf_test_helper.ParseAndUnwrap(code)
  139. self._CheckLogicalLines(llines, [
  140. (0, ['if', 'x', ':']),
  141. (1, ['x', '=', '1', '# c1']),
  142. (1, ['while', 't', ':']),
  143. (2, ['# c2']),
  144. (2, ['j', '=', '1']),
  145. (1, ['k', '=', '1']),
  146. ])
  147. def testSimpleWhile(self):
  148. code = textwrap.dedent(r"""
  149. while x > 1: # c1
  150. # c2
  151. x = 1
  152. """)
  153. llines = yapf_test_helper.ParseAndUnwrap(code)
  154. self._CheckLogicalLines(llines, [
  155. (0, ['while', 'x', '>', '1', ':', '# c1']),
  156. (1, ['# c2']),
  157. (1, ['x', '=', '1']),
  158. ])
  159. def testSimpleTry(self):
  160. code = textwrap.dedent(r"""
  161. try:
  162. pass
  163. except:
  164. pass
  165. except:
  166. pass
  167. else:
  168. pass
  169. finally:
  170. pass
  171. """)
  172. llines = yapf_test_helper.ParseAndUnwrap(code)
  173. self._CheckLogicalLines(llines, [
  174. (0, ['try', ':']),
  175. (1, ['pass']),
  176. (0, ['except', ':']),
  177. (1, ['pass']),
  178. (0, ['except', ':']),
  179. (1, ['pass']),
  180. (0, ['else', ':']),
  181. (1, ['pass']),
  182. (0, ['finally', ':']),
  183. (1, ['pass']),
  184. ])
  185. def testSimpleFuncdef(self):
  186. code = textwrap.dedent(r"""
  187. def foo(x): # c1
  188. # c2
  189. return x
  190. """)
  191. llines = yapf_test_helper.ParseAndUnwrap(code)
  192. self._CheckLogicalLines(llines, [
  193. (0, ['def', 'foo', '(', 'x', ')', ':', '# c1']),
  194. (1, ['# c2']),
  195. (1, ['return', 'x']),
  196. ])
  197. def testTwoFuncDefs(self):
  198. code = textwrap.dedent(r"""
  199. def foo(x): # c1
  200. # c2
  201. return x
  202. def bar(): # c3
  203. # c4
  204. return x
  205. """)
  206. llines = yapf_test_helper.ParseAndUnwrap(code)
  207. self._CheckLogicalLines(llines, [
  208. (0, ['def', 'foo', '(', 'x', ')', ':', '# c1']),
  209. (1, ['# c2']),
  210. (1, ['return', 'x']),
  211. (0, ['def', 'bar', '(', ')', ':', '# c3']),
  212. (1, ['# c4']),
  213. (1, ['return', 'x']),
  214. ])
  215. def testSimpleClassDef(self):
  216. code = textwrap.dedent(r"""
  217. class Klass: # c1
  218. # c2
  219. p = 1
  220. """)
  221. llines = yapf_test_helper.ParseAndUnwrap(code)
  222. self._CheckLogicalLines(llines, [
  223. (0, ['class', 'Klass', ':', '# c1']),
  224. (1, ['# c2']),
  225. (1, ['p', '=', '1']),
  226. ])
  227. def testSingleLineStmtInFunc(self):
  228. code = textwrap.dedent(r"""
  229. def f(): return 37
  230. """)
  231. llines = yapf_test_helper.ParseAndUnwrap(code)
  232. self._CheckLogicalLines(llines, [
  233. (0, ['def', 'f', '(', ')', ':']),
  234. (1, ['return', '37']),
  235. ])
  236. def testMultipleComments(self):
  237. code = textwrap.dedent(r"""
  238. # Comment #1
  239. # Comment #2
  240. def f():
  241. pass
  242. """)
  243. llines = yapf_test_helper.ParseAndUnwrap(code)
  244. self._CheckLogicalLines(llines, [
  245. (0, ['# Comment #1']),
  246. (0, ['# Comment #2']),
  247. (0, ['def', 'f', '(', ')', ':']),
  248. (1, ['pass']),
  249. ])
  250. def testSplitListWithComment(self):
  251. code = textwrap.dedent(r"""
  252. a = [
  253. 'a',
  254. 'b',
  255. 'c', # hello world
  256. ]
  257. """)
  258. llines = yapf_test_helper.ParseAndUnwrap(code)
  259. self._CheckLogicalLines(llines, [(0, [
  260. 'a', '=', '[', "'a'", ',', "'b'", ',', "'c'", ',', '# hello world', ']'
  261. ])])
  262. class MatchBracketsTest(yapf_test_helper.YAPFTest):
  263. def _CheckMatchingBrackets(self, llines, list_of_expected):
  264. """Check that the tokens have the expected matching bracket.
  265. Arguments:
  266. llines: list of LogicalLine.
  267. list_of_expected: list of (index, index) pairs. The matching brackets at
  268. the indexes need to match. Non-semantic tokens are filtered out from the
  269. expected values.
  270. """
  271. actual = []
  272. for lline in llines:
  273. filtered_values = [(ft, ft.matching_bracket)
  274. for ft in lline.tokens
  275. if ft.name not in pytree_utils.NONSEMANTIC_TOKENS]
  276. if filtered_values:
  277. actual.append(filtered_values)
  278. for index, bracket_list in enumerate(list_of_expected):
  279. lline = actual[index]
  280. if not bracket_list:
  281. for value in lline:
  282. self.assertIsNone(value[1])
  283. else:
  284. for open_bracket, close_bracket in bracket_list:
  285. self.assertEqual(lline[open_bracket][0], lline[close_bracket][1])
  286. self.assertEqual(lline[close_bracket][0], lline[open_bracket][1])
  287. def testFunctionDef(self):
  288. code = textwrap.dedent("""\
  289. def foo(a, b=['w','d'], c=[42, 37]):
  290. pass
  291. """)
  292. llines = yapf_test_helper.ParseAndUnwrap(code)
  293. self._CheckMatchingBrackets(llines, [
  294. [(2, 20), (7, 11), (15, 19)],
  295. [],
  296. ])
  297. def testDecorator(self):
  298. code = textwrap.dedent("""\
  299. @bar()
  300. def foo(a, b, c):
  301. pass
  302. """)
  303. llines = yapf_test_helper.ParseAndUnwrap(code)
  304. self._CheckMatchingBrackets(llines, [
  305. [(2, 3)],
  306. [(2, 8)],
  307. [],
  308. ])
  309. def testClassDef(self):
  310. code = textwrap.dedent("""\
  311. class A(B, C, D):
  312. pass
  313. """)
  314. llines = yapf_test_helper.ParseAndUnwrap(code)
  315. self._CheckMatchingBrackets(llines, [
  316. [(2, 8)],
  317. [],
  318. ])
  319. if __name__ == '__main__':
  320. unittest.main()