1# Copyright 2016 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"""PEP8 tests for yapf.reformatter."""
15
16import textwrap
17import unittest
18
19from yapf.yapflib import reformatter
20from yapf.yapflib import style
21
22from yapftests import yapf_test_helper
23
24
25class TestsForPEP8Style(yapf_test_helper.YAPFTest):
26
27  @classmethod
28  def setUpClass(cls):
29    style.SetGlobalStyle(style.CreatePEP8Style())
30
31  def testIndent4(self):
32    unformatted_code = textwrap.dedent("""\
33        if a+b:
34          pass
35        """)
36    expected_formatted_code = textwrap.dedent("""\
37        if a + b:
38            pass
39        """)
40    uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
41    self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
42
43  def testSingleLineIfStatements(self):
44    code = textwrap.dedent("""\
45        if True: a = 42
46        elif False: b = 42
47        else: c = 42
48        """)
49    uwlines = yapf_test_helper.ParseAndUnwrap(code)
50    self.assertCodeEqual(code, reformatter.Reformat(uwlines))
51
52  def testNoBlankBetweenClassAndDef(self):
53    unformatted_code = textwrap.dedent("""\
54        class Foo:
55
56          def joe():
57            pass
58        """)
59    expected_formatted_code = textwrap.dedent("""\
60        class Foo:
61            def joe():
62                pass
63        """)
64    uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
65    self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
66
67  def testSingleWhiteBeforeTrailingComment(self):
68    unformatted_code = textwrap.dedent("""\
69        if a+b: # comment
70          pass
71        """)
72    expected_formatted_code = textwrap.dedent("""\
73        if a + b:  # comment
74            pass
75        """)
76    uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
77    self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
78
79  def testSpaceBetweenEndingCommandAndClosingBracket(self):
80    unformatted_code = textwrap.dedent("""\
81        a = (
82            1,
83        )
84        """)
85    expected_formatted_code = textwrap.dedent("""\
86        a = (1, )
87        """)
88    uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
89    self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
90
91  def testContinuedNonOutdentedLine(self):
92    code = textwrap.dedent("""\
93        class eld(d):
94            if str(geom.geom_type).upper(
95            ) != self.geom_type and not self.geom_type == 'GEOMETRY':
96                ror(code='om_type')
97        """)
98    uwlines = yapf_test_helper.ParseAndUnwrap(code)
99    self.assertCodeEqual(code, reformatter.Reformat(uwlines))
100
101  def testWrappingPercentExpressions(self):
102    unformatted_code = textwrap.dedent("""\
103        def f():
104            if True:
105                zzzzz = '%s-%s' % (xxxxxxxxxxxxxxxxxxxxxxxxxx + 1, xxxxxxxxxxxxxxxxx.yyy + 1)
106                zzzzz = '%s-%s'.ww(xxxxxxxxxxxxxxxxxxxxxxxxxx + 1, xxxxxxxxxxxxxxxxx.yyy + 1)
107                zzzzz = '%s-%s' % (xxxxxxxxxxxxxxxxxxxxxxx + 1, xxxxxxxxxxxxxxxxxxxxx + 1)
108                zzzzz = '%s-%s'.ww(xxxxxxxxxxxxxxxxxxxxxxx + 1, xxxxxxxxxxxxxxxxxxxxx + 1)
109        """)
110    expected_formatted_code = textwrap.dedent("""\
111        def f():
112            if True:
113                zzzzz = '%s-%s' % (xxxxxxxxxxxxxxxxxxxxxxxxxx + 1,
114                                   xxxxxxxxxxxxxxxxx.yyy + 1)
115                zzzzz = '%s-%s'.ww(xxxxxxxxxxxxxxxxxxxxxxxxxx + 1,
116                                   xxxxxxxxxxxxxxxxx.yyy + 1)
117                zzzzz = '%s-%s' % (xxxxxxxxxxxxxxxxxxxxxxx + 1,
118                                   xxxxxxxxxxxxxxxxxxxxx + 1)
119                zzzzz = '%s-%s'.ww(xxxxxxxxxxxxxxxxxxxxxxx + 1,
120                                   xxxxxxxxxxxxxxxxxxxxx + 1)
121        """)
122    uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
123    self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
124
125  def testAlignClosingBracketWithVisualIndentation(self):
126    unformatted_code = textwrap.dedent("""\
127        TEST_LIST = ('foo', 'bar',  # first comment
128                     'baz'  # second comment
129                    )
130        """)
131    expected_formatted_code = textwrap.dedent("""\
132        TEST_LIST = (
133            'foo',
134            'bar',  # first comment
135            'baz'  # second comment
136        )
137        """)
138    uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
139    self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
140
141    unformatted_code = textwrap.dedent("""\
142        def f():
143
144          def g():
145            while (xxxxxxxxxxxxxxxxxxxx(yyyyyyyyyyyyy[zzzzz]) == 'aaaaaaaaaaa' and
146                   xxxxxxxxxxxxxxxxxxxx(yyyyyyyyyyyyy[zzzzz].aaaaaaaa[0]) == 'bbbbbbb'
147                  ):
148              pass
149        """)
150    expected_formatted_code = textwrap.dedent("""\
151        def f():
152            def g():
153                while (xxxxxxxxxxxxxxxxxxxx(yyyyyyyyyyyyy[zzzzz]) == 'aaaaaaaaaaa'
154                       and xxxxxxxxxxxxxxxxxxxx(
155                           yyyyyyyyyyyyy[zzzzz].aaaaaaaa[0]) == 'bbbbbbb'):
156                    pass
157        """)
158    uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
159    self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
160
161  def testIndentSizeChanging(self):
162    unformatted_code = textwrap.dedent("""\
163        if True:
164          runtime_mins = (program_end_time - program_start_time).total_seconds() / 60.0
165        """)
166    expected_formatted_code = textwrap.dedent("""\
167        if True:
168            runtime_mins = (
169                program_end_time - program_start_time).total_seconds() / 60.0
170        """)
171    uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
172    self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
173
174  def testHangingIndentCollision(self):
175    unformatted_code = textwrap.dedent("""\
176        if (aaaaaaaaaaaaaa + bbbbbbbbbbbbbbbb == ccccccccccccccccc and xxxxxxxxxxxxx or yyyyyyyyyyyyyyyyy):
177            pass
178        elif (xxxxxxxxxxxxxxx(aaaaaaaaaaa, bbbbbbbbbbbbbb, cccccccccccc, dddddddddd=None)):
179            pass
180
181
182        def h():
183            if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'):
184                pass
185
186            for connection in itertools.chain(branch.contact, branch.address, morestuff.andmore.andmore.andmore.andmore.andmore.andmore.andmore):
187                dosomething(connection)
188        """)
189    expected_formatted_code = textwrap.dedent("""\
190        if (aaaaaaaaaaaaaa + bbbbbbbbbbbbbbbb == ccccccccccccccccc and xxxxxxxxxxxxx
191                or yyyyyyyyyyyyyyyyy):
192            pass
193        elif (xxxxxxxxxxxxxxx(
194                aaaaaaaaaaa, bbbbbbbbbbbbbb, cccccccccccc, dddddddddd=None)):
195            pass
196
197
198        def h():
199            if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and
200                    xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'):
201                pass
202
203            for connection in itertools.chain(
204                    branch.contact, branch.address,
205                    morestuff.andmore.andmore.andmore.andmore.andmore.andmore.andmore):
206                dosomething(connection)
207        """)
208    uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
209    self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
210
211  def testSplittingBeforeLogicalOperator(self):
212    try:
213      style.SetGlobalStyle(
214          style.CreateStyleFromConfig(
215              '{based_on_style: pep8, split_before_logical_operator: True}'))
216      unformatted_code = textwrap.dedent("""\
217          def foo():
218              return bool(update.message.new_chat_member or update.message.left_chat_member or
219                          update.message.new_chat_title or update.message.new_chat_photo or
220                          update.message.delete_chat_photo or update.message.group_chat_created or
221                          update.message.supergroup_chat_created or update.message.channel_chat_created
222                          or update.message.migrate_to_chat_id or update.message.migrate_from_chat_id or
223                          update.message.pinned_message)
224          """)
225      expected_formatted_code = textwrap.dedent("""\
226          def foo():
227              return bool(
228                  update.message.new_chat_member or update.message.left_chat_member
229                  or update.message.new_chat_title or update.message.new_chat_photo
230                  or update.message.delete_chat_photo
231                  or update.message.group_chat_created
232                  or update.message.supergroup_chat_created
233                  or update.message.channel_chat_created
234                  or update.message.migrate_to_chat_id
235                  or update.message.migrate_from_chat_id
236                  or update.message.pinned_message)
237          """)
238      uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
239      self.assertCodeEqual(expected_formatted_code,
240                           reformatter.Reformat(uwlines))
241    finally:
242      style.SetGlobalStyle(style.CreatePEP8Style())
243
244  def testContiguousListEndingWithComment(self):
245    unformatted_code = textwrap.dedent("""\
246        if True:
247            if True:
248                keys.append(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)  # may be unassigned.
249        """)
250    expected_formatted_code = textwrap.dedent("""\
251        if True:
252            if True:
253                keys.append(
254                    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)  # may be unassigned.
255        """)
256    uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
257    self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
258
259  def testSplittingBeforeFirstArgument(self):
260    try:
261      style.SetGlobalStyle(
262          style.CreateStyleFromConfig(
263              '{based_on_style: pep8, split_before_first_argument: True}'))
264      unformatted_code = textwrap.dedent("""\
265          a_very_long_function_name(long_argument_name_1=1, long_argument_name_2=2,
266                                    long_argument_name_3=3, long_argument_name_4=4)
267          """)
268      expected_formatted_code = textwrap.dedent("""\
269          a_very_long_function_name(
270              long_argument_name_1=1,
271              long_argument_name_2=2,
272              long_argument_name_3=3,
273              long_argument_name_4=4)
274          """)
275      uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
276      self.assertCodeEqual(expected_formatted_code,
277                           reformatter.Reformat(uwlines))
278    finally:
279      style.SetGlobalStyle(style.CreatePEP8Style())
280
281  def testSplittingExpressionsInsideSubscripts(self):
282    unformatted_code = textwrap.dedent("""\
283        def foo():
284            df = df[(df['campaign_status'] == 'LIVE') & (df['action_status'] == 'LIVE')]
285        """)
286    expected_formatted_code = textwrap.dedent("""\
287        def foo():
288            df = df[(df['campaign_status'] == 'LIVE')
289                    & (df['action_status'] == 'LIVE')]
290        """)
291    uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
292    self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
293
294  def testSplitListsAndDictSetMakersIfCommaTerminated(self):
295    unformatted_code = textwrap.dedent("""\
296        DJANGO_TEMPLATES_OPTIONS = {"context_processors": []}
297        DJANGO_TEMPLATES_OPTIONS = {"context_processors": [],}
298        x = ["context_processors"]
299        x = ["context_processors",]
300        """)
301    expected_formatted_code = textwrap.dedent("""\
302        DJANGO_TEMPLATES_OPTIONS = {"context_processors": []}
303        DJANGO_TEMPLATES_OPTIONS = {
304            "context_processors": [],
305        }
306        x = ["context_processors"]
307        x = [
308            "context_processors",
309        ]
310        """)
311    uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
312    self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
313
314  def testSplitAroundNamedAssigns(self):
315    unformatted_code = textwrap.dedent("""\
316        class a():
317            def a(): return a(
318             aaaaaaaaaa=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)
319        """)
320    expected_formatted_code = textwrap.dedent("""\
321        class a():
322            def a():
323                return a(
324                    aaaaaaaaaa=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
325                )
326        """)
327    uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
328    self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
329
330  def testUnaryOperator(self):
331    unformatted_code = textwrap.dedent("""\
332        if not -3 < x < 3:
333          pass
334        if -3 < x < 3:
335          pass
336        """)
337    expected_formatted_code = textwrap.dedent("""\
338        if not -3 < x < 3:
339            pass
340        if -3 < x < 3:
341            pass
342        """)
343    uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
344    self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines))
345
346  def testNoSplitBeforeDictValue(self):
347    try:
348      style.SetGlobalStyle(
349          style.CreateStyleFromConfig('{based_on_style: pep8, '
350                                      'allow_split_before_dict_value: false, '
351                                      'coalesce_brackets: true, '
352                                      'dedent_closing_brackets: true, '
353                                      'each_dict_entry_on_separate_line: true, '
354                                      'split_before_logical_operator: true}'))
355
356      unformatted_code = textwrap.dedent("""\
357          some_dict = {
358              'title': _("I am example data"),
359              'description': _("Lorem ipsum dolor met sit amet elit, si vis pacem para bellum "
360                               "elites nihi very long string."),
361          }
362          """)
363      expected_formatted_code = textwrap.dedent("""\
364          some_dict = {
365              'title': _("I am example data"),
366              'description': _(
367                  "Lorem ipsum dolor met sit amet elit, si vis pacem para bellum "
368                  "elites nihi very long string."
369              ),
370          }
371          """)
372      uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
373      self.assertCodeEqual(expected_formatted_code,
374                           reformatter.Reformat(uwlines))
375
376      unformatted_code = textwrap.dedent("""\
377          X = {'a': 1, 'b': 2, 'key': this_is_a_function_call_that_goes_over_the_column_limit_im_pretty_sure()}
378          """)
379      expected_formatted_code = textwrap.dedent("""\
380          X = {
381              'a': 1,
382              'b': 2,
383              'key': this_is_a_function_call_that_goes_over_the_column_limit_im_pretty_sure()
384          }
385          """)
386      uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
387      self.assertCodeEqual(expected_formatted_code,
388                           reformatter.Reformat(uwlines))
389
390      unformatted_code = textwrap.dedent("""\
391          attrs = {
392              'category': category,
393              'role': forms.ModelChoiceField(label=_("Role"), required=False, queryset=category_roles, initial=selected_role, empty_label=_("No access"),),
394          }
395          """)
396      expected_formatted_code = textwrap.dedent("""\
397          attrs = {
398              'category': category,
399              'role': forms.ModelChoiceField(
400                  label=_("Role"),
401                  required=False,
402                  queryset=category_roles,
403                  initial=selected_role,
404                  empty_label=_("No access"),
405              ),
406          }
407          """)
408      uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
409      self.assertCodeEqual(expected_formatted_code,
410                           reformatter.Reformat(uwlines))
411
412      unformatted_code = textwrap.dedent("""\
413          css_class = forms.CharField(
414              label=_("CSS class"),
415              required=False,
416              help_text=_("Optional CSS class used to customize this category appearance from templates."),
417          )
418          """)
419      expected_formatted_code = textwrap.dedent("""\
420          css_class = forms.CharField(
421              label=_("CSS class"),
422              required=False,
423              help_text=_(
424                  "Optional CSS class used to customize this category appearance from templates."
425              ),
426          )
427          """)
428      uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code)
429      self.assertCodeEqual(expected_formatted_code,
430                           reformatter.Reformat(uwlines))
431    finally:
432      style.SetGlobalStyle(style.CreatePEP8Style())
433
434
435if __name__ == '__main__':
436  unittest.main()
437