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