• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# -*- coding: utf-8 -*-
2# Copyright 2015 Google Inc. All Rights Reserved.
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8#     http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15"""Tests for yapf.yapf."""
16
17import io
18import logging
19import os
20import shutil
21import subprocess
22import sys
23import tempfile
24import textwrap
25import unittest
26from io import StringIO
27
28from yapf_third_party._ylib2to3.pgen2 import tokenize
29
30from yapf.yapflib import errors
31from yapf.yapflib import style
32from yapf.yapflib import yapf_api
33
34from yapftests import utils
35from yapftests import yapf_test_helper
36
37YAPF_BINARY = [sys.executable, '-m', 'yapf', '--no-local-style']
38
39
40class FormatCodeTest(yapf_test_helper.YAPFTest):
41
42  def _Check(self, unformatted_code, expected_formatted_code):
43    formatted_code, _ = yapf_api.FormatCode(
44        unformatted_code, style_config='yapf')
45    self.assertCodeEqual(expected_formatted_code, formatted_code)
46
47  def testSimple(self):
48    unformatted_code = textwrap.dedent("""\
49        print('foo')
50    """)
51    self._Check(unformatted_code, unformatted_code)
52
53  def testNoEndingNewline(self):
54    unformatted_code = textwrap.dedent("""\
55        if True:
56          pass""")
57    expected_formatted_code = textwrap.dedent("""\
58        if True:
59          pass
60    """)
61    self._Check(unformatted_code, expected_formatted_code)
62
63
64class FormatFileTest(yapf_test_helper.YAPFTest):
65
66  def setUp(self):  # pylint: disable=g-missing-super-call
67    self.test_tmpdir = tempfile.mkdtemp()
68
69  def tearDown(self):  # pylint: disable=g-missing-super-call
70    shutil.rmtree(self.test_tmpdir)
71
72  def testFormatFile(self):
73    unformatted_code = textwrap.dedent("""\
74        if True:
75         pass
76    """)
77    expected_formatted_code_pep8 = textwrap.dedent("""\
78        if True:
79            pass
80    """)
81    expected_formatted_code_yapf = textwrap.dedent("""\
82        if True:
83          pass
84    """)
85    with utils.TempFileContents(self.test_tmpdir, unformatted_code) as filepath:
86      formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='pep8')
87      self.assertCodeEqual(expected_formatted_code_pep8, formatted_code)
88
89      formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='yapf')
90      self.assertCodeEqual(expected_formatted_code_yapf, formatted_code)
91
92  def testDisableLinesPattern(self):
93    unformatted_code = textwrap.dedent("""\
94        if a:    b
95
96        # yapf: disable
97        if f:    g
98
99        if h:    i
100    """)
101    expected_formatted_code = textwrap.dedent("""\
102        if a: b
103
104        # yapf: disable
105        if f:    g
106
107        if h:    i
108    """)
109    with utils.TempFileContents(self.test_tmpdir, unformatted_code) as filepath:
110      formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='pep8')
111      self.assertCodeEqual(expected_formatted_code, formatted_code)
112
113  def testDisableAndReenableLinesPattern(self):
114    unformatted_code = textwrap.dedent("""\
115        if a:    b
116
117        # yapf: disable
118        if f:    g
119        # yapf: enable
120
121        if h:    i
122    """)
123    expected_formatted_code = textwrap.dedent("""\
124        if a: b
125
126        # yapf: disable
127        if f:    g
128        # yapf: enable
129
130        if h: i
131    """)
132    with utils.TempFileContents(self.test_tmpdir, unformatted_code) as filepath:
133      formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='pep8')
134      self.assertCodeEqual(expected_formatted_code, formatted_code)
135
136  def testFmtOnOff(self):
137    unformatted_code = textwrap.dedent("""\
138        if a:    b
139
140        # fmt: off
141        if f:    g
142        # fmt: on
143
144        if h:    i
145    """)
146    expected_formatted_code = textwrap.dedent("""\
147        if a: b
148
149        # fmt: off
150        if f:    g
151        # fmt: on
152
153        if h: i
154    """)
155    with utils.TempFileContents(self.test_tmpdir, unformatted_code) as filepath:
156      formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='pep8')
157      self.assertCodeEqual(expected_formatted_code, formatted_code)
158
159  def testDisablePartOfMultilineComment(self):
160    unformatted_code = textwrap.dedent("""\
161        if a:    b
162
163        # This is a multiline comment that disables YAPF.
164        # yapf: disable
165        if f:    g
166        # yapf: enable
167        # This is a multiline comment that enables YAPF.
168
169        if h:    i
170    """)
171    expected_formatted_code = textwrap.dedent("""\
172        if a: b
173
174        # This is a multiline comment that disables YAPF.
175        # yapf: disable
176        if f:    g
177        # yapf: enable
178        # This is a multiline comment that enables YAPF.
179
180        if h: i
181    """)
182    with utils.TempFileContents(self.test_tmpdir, unformatted_code) as filepath:
183      formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='pep8')
184      self.assertCodeEqual(expected_formatted_code, formatted_code)
185
186    code = textwrap.dedent("""\
187      def foo_function():
188          # some comment
189          # yapf: disable
190
191          foo(
192          bar,
193          baz
194          )
195
196          # yapf: enable
197    """)
198    with utils.TempFileContents(self.test_tmpdir, code) as filepath:
199      formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='pep8')
200      self.assertCodeEqual(code, formatted_code)
201
202  def testEnabledDisabledSameComment(self):
203    code = textwrap.dedent("""\
204        # yapf: disable
205        a(bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, ccccccccccccccccccccccccccccccc, ddddddddddddddddddddddd, eeeeeeeeeeeeeeeeeeeeeeeeeee)
206        # yapf: enable
207        # yapf: disable
208        a(bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, ccccccccccccccccccccccccccccccc, ddddddddddddddddddddddd, eeeeeeeeeeeeeeeeeeeeeeeeeee)
209        # yapf: enable
210    """)  # noqa
211    with utils.TempFileContents(self.test_tmpdir, code) as filepath:
212      formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='pep8')
213      self.assertCodeEqual(code, formatted_code)
214
215  def testFormatFileLinesSelection(self):
216    unformatted_code = textwrap.dedent("""\
217        if a:    b
218
219        if f:    g
220
221        if h:    i
222    """)
223    expected_formatted_code_lines1and2 = textwrap.dedent("""\
224        if a: b
225
226        if f:    g
227
228        if h:    i
229    """)
230    expected_formatted_code_lines3 = textwrap.dedent("""\
231        if a:    b
232
233        if f: g
234
235        if h:    i
236    """)
237    with utils.TempFileContents(self.test_tmpdir, unformatted_code) as filepath:
238      formatted_code, _, _ = yapf_api.FormatFile(
239          filepath, style_config='pep8', lines=[(1, 2)])
240      self.assertCodeEqual(expected_formatted_code_lines1and2, formatted_code)
241      formatted_code, _, _ = yapf_api.FormatFile(
242          filepath, style_config='pep8', lines=[(3, 3)])
243      self.assertCodeEqual(expected_formatted_code_lines3, formatted_code)
244
245  def testFormatFileDiff(self):
246    unformatted_code = textwrap.dedent("""\
247        if True:
248         pass
249    """)
250    with utils.TempFileContents(self.test_tmpdir, unformatted_code) as filepath:
251      diff, _, _ = yapf_api.FormatFile(filepath, print_diff=True)
252      self.assertIn('+  pass', diff)
253
254  def testFormatFileInPlace(self):
255    unformatted_code = 'True==False\n'
256    formatted_code = 'True == False\n'
257    with utils.TempFileContents(self.test_tmpdir, unformatted_code) as filepath:
258      result, _, _ = yapf_api.FormatFile(filepath, in_place=True)
259      self.assertEqual(result, None)
260      with open(filepath) as fd:
261        self.assertCodeEqual(formatted_code, fd.read())
262
263      self.assertRaises(
264          ValueError,
265          yapf_api.FormatFile,
266          filepath,
267          in_place=True,
268          print_diff=True)
269
270  def testNoFile(self):
271    with self.assertRaises(IOError) as context:
272      yapf_api.FormatFile('not_a_file.py')
273
274    self.assertEqual(
275        str(context.exception),
276        "[Errno 2] No such file or directory: 'not_a_file.py'")
277
278  def testCommentsUnformatted(self):
279    code = textwrap.dedent("""\
280        foo = [# A list of things
281               # bork
282            'one',
283            # quark
284            'two'] # yapf: disable
285    """)
286    with utils.TempFileContents(self.test_tmpdir, code) as filepath:
287      formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='pep8')
288      self.assertCodeEqual(code, formatted_code)
289
290  def testDisabledHorizontalFormattingOnNewLine(self):
291    code = textwrap.dedent("""\
292        # yapf: disable
293        a = [
294        1]
295        # yapf: enable
296    """)
297    with utils.TempFileContents(self.test_tmpdir, code) as filepath:
298      formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='pep8')
299      self.assertCodeEqual(code, formatted_code)
300
301  def testSplittingSemicolonStatements(self):
302    unformatted_code = textwrap.dedent("""\
303        def f():
304          x = y + 42 ; z = n * 42
305          if True: a += 1 ; b += 1; c += 1
306    """)
307    expected_formatted_code = textwrap.dedent("""\
308        def f():
309            x = y + 42
310            z = n * 42
311            if True:
312                a += 1
313                b += 1
314                c += 1
315    """)
316    with utils.TempFileContents(self.test_tmpdir, unformatted_code) as filepath:
317      formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='pep8')
318      self.assertCodeEqual(expected_formatted_code, formatted_code)
319
320  def testSemicolonStatementsDisabled(self):
321    unformatted_code = textwrap.dedent("""\
322        def f():
323          x = y + 42 ; z = n * 42  # yapf: disable
324          if True: a += 1 ; b += 1; c += 1
325    """)
326    expected_formatted_code = textwrap.dedent("""\
327        def f():
328            x = y + 42 ; z = n * 42  # yapf: disable
329            if True:
330                a += 1
331                b += 1
332                c += 1
333    """)
334    with utils.TempFileContents(self.test_tmpdir, unformatted_code) as filepath:
335      formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='pep8')
336      self.assertCodeEqual(expected_formatted_code, formatted_code)
337
338  def testDisabledSemiColonSeparatedStatements(self):
339    code = textwrap.dedent("""\
340        # yapf: disable
341        if True: a ; b
342    """)
343    with utils.TempFileContents(self.test_tmpdir, code) as filepath:
344      formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='pep8')
345      self.assertCodeEqual(code, formatted_code)
346
347  def testDisabledMultilineStringInDictionary(self):
348    code = textwrap.dedent("""\
349        # yapf: disable
350
351        A = [
352            {
353                "aaaaaaaaaaaaaaaaaaa": '''
354        bbbbbbbbbbb: "ccccccccccc"
355        dddddddddddddd: 1
356        eeeeeeee: 0
357        ffffffffff: "ggggggg"
358        ''',
359            },
360        ]
361    """)
362    with utils.TempFileContents(self.test_tmpdir, code) as filepath:
363      formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='yapf')
364      self.assertCodeEqual(code, formatted_code)
365
366  def testDisabledWithPrecedingText(self):
367    code = textwrap.dedent("""\
368        # TODO(fix formatting): yapf: disable
369
370        A = [
371            {
372                "aaaaaaaaaaaaaaaaaaa": '''
373        bbbbbbbbbbb: "ccccccccccc"
374        dddddddddddddd: 1
375        eeeeeeee: 0
376        ffffffffff: "ggggggg"
377        ''',
378            },
379        ]
380    """)
381    with utils.TempFileContents(self.test_tmpdir, code) as filepath:
382      formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='yapf')
383      self.assertCodeEqual(code, formatted_code)
384
385  def testCRLFLineEnding(self):
386    code = 'class _():\r\n  pass\r\n'
387    with utils.TempFileContents(self.test_tmpdir, code) as filepath:
388      formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='yapf')
389      self.assertCodeEqual(code, formatted_code)
390
391
392class CommandLineTest(yapf_test_helper.YAPFTest):
393  """Test how calling yapf from the command line acts."""
394
395  @classmethod
396  def setUpClass(cls):  # pylint: disable=g-missing-super-call
397    cls.test_tmpdir = tempfile.mkdtemp()
398
399  @classmethod
400  def tearDownClass(cls):  # pylint: disable=g-missing-super-call
401    shutil.rmtree(cls.test_tmpdir)
402
403  def assertYapfReformats(self,
404                          unformatted,
405                          expected,
406                          extra_options=None,
407                          env=None):
408    """Check that yapf reformats the given code as expected.
409
410    Invokes yapf in a subprocess, piping the unformatted code into its stdin.
411    Checks that the formatted output is as expected.
412
413    Arguments:
414      unformatted: unformatted code - input to yapf
415      expected: expected formatted code at the output of yapf
416      extra_options: iterable of extra command-line options to pass to yapf
417      env: dict of environment variables.
418    """
419    cmdline = YAPF_BINARY + (extra_options or [])
420    p = subprocess.Popen(
421        cmdline,
422        stdout=subprocess.PIPE,
423        stdin=subprocess.PIPE,
424        stderr=subprocess.PIPE,
425        env=env)
426    reformatted_code, stderrdata = p.communicate(
427        unformatted.encode('utf-8-sig'))
428    self.assertEqual(stderrdata, b'')
429    self.assertMultiLineEqual(reformatted_code.decode('utf-8'), expected)
430
431  def testInPlaceReformatting(self):
432    unformatted_code = textwrap.dedent("""\
433        def foo():
434          x = 37
435    """)
436    expected_formatted_code = textwrap.dedent("""\
437        def foo():
438            x = 37
439    """)
440    with utils.TempFileContents(
441        self.test_tmpdir, unformatted_code, suffix='.py') as filepath:
442      p = subprocess.Popen(YAPF_BINARY + ['--in-place', filepath])
443      p.wait()
444      with io.open(filepath, mode='r', newline='') as fd:
445        reformatted_code = fd.read()
446    self.assertEqual(reformatted_code, expected_formatted_code)
447
448  def testInPlaceReformattingBlank(self):
449    unformatted_code = '\n\n'
450    expected_formatted_code = '\n'
451    with utils.TempFileContents(
452        self.test_tmpdir, unformatted_code, suffix='.py') as filepath:
453      p = subprocess.Popen(YAPF_BINARY + ['--in-place', filepath])
454      p.wait()
455      with io.open(filepath, mode='r', encoding='utf-8', newline='') as fd:
456        reformatted_code = fd.read()
457    self.assertEqual(reformatted_code, expected_formatted_code)
458
459  def testInPlaceReformattingWindowsNewLine(self):
460    unformatted_code = '\r\n\r\n'
461    expected_formatted_code = '\r\n'
462    with utils.TempFileContents(
463        self.test_tmpdir, unformatted_code, suffix='.py') as filepath:
464      p = subprocess.Popen(YAPF_BINARY + ['--in-place', filepath])
465      p.wait()
466      with io.open(filepath, mode='r', encoding='utf-8', newline='') as fd:
467        reformatted_code = fd.read()
468    self.assertEqual(reformatted_code, expected_formatted_code)
469
470  def testInPlaceReformattingNoNewLine(self):
471    unformatted_code = textwrap.dedent('def foo(): x = 37')
472    expected_formatted_code = textwrap.dedent("""\
473        def foo():
474            x = 37
475    """)
476    with utils.TempFileContents(
477        self.test_tmpdir, unformatted_code, suffix='.py') as filepath:
478      p = subprocess.Popen(YAPF_BINARY + ['--in-place', filepath])
479      p.wait()
480      with io.open(filepath, mode='r', newline='') as fd:
481        reformatted_code = fd.read()
482    self.assertEqual(reformatted_code, expected_formatted_code)
483
484  def testInPlaceReformattingEmpty(self):
485    unformatted_code = ''
486    expected_formatted_code = ''
487    with utils.TempFileContents(
488        self.test_tmpdir, unformatted_code, suffix='.py') as filepath:
489      p = subprocess.Popen(YAPF_BINARY + ['--in-place', filepath])
490      p.wait()
491      with io.open(filepath, mode='r', encoding='utf-8', newline='') as fd:
492        reformatted_code = fd.read()
493    self.assertEqual(reformatted_code, expected_formatted_code)
494
495  def testPrintModified(self):
496    for unformatted_code, has_change in [('1==2', True), ('1 == 2', False)]:
497      with utils.TempFileContents(
498          self.test_tmpdir, unformatted_code, suffix='.py') as filepath:
499        output = subprocess.check_output(
500            YAPF_BINARY + ['--in-place', '--print-modified', filepath],
501            text=True)
502        check = self.assertIn if has_change else self.assertNotIn
503        check(f'Formatted {filepath}', output)
504
505  def testReadFromStdin(self):
506    unformatted_code = textwrap.dedent("""\
507        def foo():
508          x = 37
509    """)
510    expected_formatted_code = textwrap.dedent("""\
511        def foo():
512            x = 37
513    """)
514    self.assertYapfReformats(unformatted_code, expected_formatted_code)
515
516  def testReadFromStdinWithEscapedStrings(self):
517    unformatted_code = textwrap.dedent("""\
518        s =   "foo\\nbar"
519    """)
520    expected_formatted_code = textwrap.dedent("""\
521        s = "foo\\nbar"
522    """)
523    self.assertYapfReformats(unformatted_code, expected_formatted_code)
524
525  def testSetYapfStyle(self):
526    unformatted_code = textwrap.dedent("""\
527        def foo(): # trail
528            x = 37
529    """)
530    expected_formatted_code = textwrap.dedent("""\
531        def foo():  # trail
532          x = 37
533    """)
534    self.assertYapfReformats(
535        unformatted_code,
536        expected_formatted_code,
537        extra_options=['--style=yapf'])
538
539  def testSetCustomStyleBasedOnYapf(self):
540    unformatted_code = textwrap.dedent("""\
541        def foo(): # trail
542            x = 37
543    """)
544    expected_formatted_code = textwrap.dedent("""\
545        def foo():    # trail
546          x = 37
547    """)
548    style_file = textwrap.dedent("""\
549        [style]
550        based_on_style = yapf
551        spaces_before_comment = 4
552    """)
553    with utils.TempFileContents(self.test_tmpdir, style_file) as stylepath:
554      self.assertYapfReformats(
555          unformatted_code,
556          expected_formatted_code,
557          extra_options=['--style={0}'.format(stylepath)])
558
559  def testSetCustomStyleSpacesBeforeComment(self):
560    unformatted_code = textwrap.dedent("""\
561        a_very_long_statement_that_extends_way_beyond # Comment
562        short # This is a shorter statement
563    """)
564    expected_formatted_code = textwrap.dedent("""\
565        a_very_long_statement_that_extends_way_beyond # Comment
566        short                                         # This is a shorter statement
567    """)  # noqa
568    style_file = textwrap.dedent("""\
569        [style]
570        spaces_before_comment = 15, 20
571    """)
572    with utils.TempFileContents(self.test_tmpdir, style_file) as stylepath:
573      self.assertYapfReformats(
574          unformatted_code,
575          expected_formatted_code,
576          extra_options=['--style={0}'.format(stylepath)])
577
578  def testReadSingleLineCodeFromStdin(self):
579    unformatted_code = textwrap.dedent("""\
580        if True: pass
581    """)
582    expected_formatted_code = textwrap.dedent("""\
583        if True: pass
584    """)
585    self.assertYapfReformats(unformatted_code, expected_formatted_code)
586
587  def testEncodingVerification(self):
588    unformatted_code = textwrap.dedent("""\
589        '''The module docstring.'''
590        # -*- coding: utf-8 -*-
591        def f():
592            x = 37
593    """)
594
595    with utils.NamedTempFile(
596        suffix='.py', dirname=self.test_tmpdir) as (out, _):
597      with utils.TempFileContents(
598          self.test_tmpdir, unformatted_code, suffix='.py') as filepath:
599        try:
600          subprocess.check_call(YAPF_BINARY + ['--diff', filepath], stdout=out)
601        except subprocess.CalledProcessError as e:
602          # Indicates the text changed.
603          self.assertEqual(e.returncode, 1)  # pylint: disable=g-assert-in-except # noqa
604
605  def testReformattingSpecificLines(self):
606    unformatted_code = textwrap.dedent("""\
607        def h():
608            if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'):
609                pass
610
611
612        def g():
613            if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'):
614                pass
615        """)  # noqa
616    expected_formatted_code = textwrap.dedent("""\
617        def h():
618            if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and
619                    xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'):
620                pass
621
622
623        def g():
624            if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'):
625                pass
626    """)  # noqa
627    # TODO(ambv): the `expected_formatted_code` here is not PEP8 compliant,
628    # raising "E129 visually indented line with same indent as next logical
629    # line" with flake8.
630    self.assertYapfReformats(
631        unformatted_code,
632        expected_formatted_code,
633        extra_options=['--lines', '1-2'])
634
635  def testOmitFormattingLinesBeforeDisabledFunctionComment(self):
636    unformatted_code = textwrap.dedent("""\
637        import sys
638
639        # Comment
640        def some_func(x):
641            x = ["badly" , "formatted","line" ]
642    """)
643    expected_formatted_code = textwrap.dedent("""\
644        import sys
645
646        # Comment
647        def some_func(x):
648            x = ["badly", "formatted", "line"]
649    """)
650    self.assertYapfReformats(
651        unformatted_code,
652        expected_formatted_code,
653        extra_options=['--lines', '5-5'])
654
655  def testReformattingSkippingLines(self):
656    unformatted_code = textwrap.dedent("""\
657        def h():
658            if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'):
659                pass
660
661        # yapf: disable
662        def g():
663            if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'):
664                pass
665        # yapf: enable
666    """)  # noqa
667    expected_formatted_code = textwrap.dedent("""\
668        def h():
669            if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and
670                    xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'):
671                pass
672
673
674        # yapf: disable
675        def g():
676            if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'):
677                pass
678        # yapf: enable
679    """)  # noqa
680    self.assertYapfReformats(unformatted_code, expected_formatted_code)
681
682  def testReformattingSkippingToEndOfFile(self):
683    unformatted_code = textwrap.dedent("""\
684        def h():
685            if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'):
686                pass
687
688        # yapf: disable
689        def g():
690            if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'):
691                pass
692
693        def f():
694            def e():
695                while (xxxxxxxxxxxxxxxxxxxxx(yyyyyyyyyyyyy[zzzzz]) == 'aaaaaaaaaaa' and
696                       xxxxxxxxxxxxxxxxxxxxx(yyyyyyyyyyyyy[zzzzz].aaaaaaaa[0]) ==
697                       'bbbbbbb'):
698                    pass
699    """)  # noqa
700    expected_formatted_code = textwrap.dedent("""\
701        def h():
702            if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and
703                    xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'):
704                pass
705
706
707        # yapf: disable
708        def g():
709            if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'):
710                pass
711
712        def f():
713            def e():
714                while (xxxxxxxxxxxxxxxxxxxxx(yyyyyyyyyyyyy[zzzzz]) == 'aaaaaaaaaaa' and
715                       xxxxxxxxxxxxxxxxxxxxx(yyyyyyyyyyyyy[zzzzz].aaaaaaaa[0]) ==
716                       'bbbbbbb'):
717                    pass
718    """)  # noqa
719    self.assertYapfReformats(unformatted_code, expected_formatted_code)
720
721  def testReformattingSkippingSingleLine(self):
722    unformatted_code = textwrap.dedent("""\
723        def h():
724            if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'):
725                pass
726
727        def g():
728            if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'):  # yapf: disable
729                pass
730    """)  # noqa
731    expected_formatted_code = textwrap.dedent("""\
732        def h():
733            if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and
734                    xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'):
735                pass
736
737
738        def g():
739            if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'):  # yapf: disable
740                pass
741    """)  # noqa
742    self.assertYapfReformats(unformatted_code, expected_formatted_code)
743
744  def testDisableWholeDataStructure(self):
745    unformatted_code = textwrap.dedent("""\
746        A = set([
747            'hello',
748            'world',
749        ])  # yapf: disable
750    """)
751    expected_formatted_code = textwrap.dedent("""\
752        A = set([
753            'hello',
754            'world',
755        ])  # yapf: disable
756    """)
757    self.assertYapfReformats(unformatted_code, expected_formatted_code)
758
759  def testDisableButAdjustIndentations(self):
760    unformatted_code = textwrap.dedent("""\
761        class SplitPenaltyTest(unittest.TestCase):
762
763          def testUnbreakable(self):
764            self._CheckPenalties(tree, [
765            ])  # yapf: disable
766    """)
767    expected_formatted_code = textwrap.dedent("""\
768        class SplitPenaltyTest(unittest.TestCase):
769
770            def testUnbreakable(self):
771                self._CheckPenalties(tree, [
772                ])  # yapf: disable
773    """)
774    self.assertYapfReformats(unformatted_code, expected_formatted_code)
775
776  def testRetainingHorizontalWhitespace(self):
777    unformatted_code = textwrap.dedent("""\
778        def h():
779            if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'):
780                pass
781
782        def g():
783            if (xxxxxxxxxxxx.yyyyyyyy        (zzzzzzzzzzzzz  [0]) ==     'aaaaaaaaaaa' and    xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'):  # yapf: disable
784                pass
785    """)  # noqa
786    expected_formatted_code = textwrap.dedent("""\
787        def h():
788            if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and
789                    xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'):
790                pass
791
792
793        def g():
794            if (xxxxxxxxxxxx.yyyyyyyy        (zzzzzzzzzzzzz  [0]) ==     'aaaaaaaaaaa' and    xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'):  # yapf: disable
795                pass
796    """)  # noqa
797    self.assertYapfReformats(unformatted_code, expected_formatted_code)
798
799  def testRetainingVerticalWhitespace(self):
800    unformatted_code = textwrap.dedent("""\
801        def h():
802            if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'):
803                pass
804
805        def g():
806
807
808            if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'):
809
810                pass
811    """)  # noqa
812    expected_formatted_code = textwrap.dedent("""\
813        def h():
814            if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and
815                    xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'):
816                pass
817
818        def g():
819
820
821            if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'):
822
823                pass
824    """)  # noqa
825    self.assertYapfReformats(
826        unformatted_code,
827        expected_formatted_code,
828        extra_options=['--lines', '1-2'])
829
830    unformatted_code = textwrap.dedent("""\
831
832
833        if a:     b
834
835
836        if c:
837            to_much      + indent
838
839            same
840
841
842
843        #comment
844
845        #   trailing whitespace
846    """)
847    expected_formatted_code = textwrap.dedent("""\
848        if a: b
849
850
851        if c:
852            to_much      + indent
853
854            same
855
856
857
858        #comment
859
860        #   trailing whitespace
861    """)
862    self.assertYapfReformats(
863        unformatted_code,
864        expected_formatted_code,
865        extra_options=['--lines', '3-3', '--lines', '13-13'])
866
867    unformatted_code = textwrap.dedent("""\
868        '''
869        docstring
870
871        '''
872
873        import blah
874    """)
875
876    self.assertYapfReformats(
877        unformatted_code, unformatted_code, extra_options=['--lines', '2-2'])
878
879  def testVerticalSpacingWithCommentWithContinuationMarkers(self):
880    unformatted_code = textwrap.dedent("""\
881        # \\
882        # \\
883        # \\
884
885        x = {
886        }
887    """)
888    expected_formatted_code = textwrap.dedent("""\
889        # \\
890        # \\
891        # \\
892
893        x = {
894        }
895    """)
896    self.assertYapfReformats(
897        unformatted_code,
898        expected_formatted_code,
899        extra_options=['--lines', '1-1'])
900
901  def testRetainingSemicolonsWhenSpecifyingLines(self):
902    unformatted_code = textwrap.dedent("""\
903        a = line_to_format
904        def f():
905            x = y + 42; z = n * 42
906            if True: a += 1 ; b += 1 ; c += 1
907    """)
908    expected_formatted_code = textwrap.dedent("""\
909        a = line_to_format
910        def f():
911            x = y + 42; z = n * 42
912            if True: a += 1 ; b += 1 ; c += 1
913    """)
914    self.assertYapfReformats(
915        unformatted_code,
916        expected_formatted_code,
917        extra_options=['--lines', '1-1'])
918
919  def testDisabledMultilineStrings(self):
920    unformatted_code = textwrap.dedent('''\
921        foo=42
922        def f():
923            email_text += """<html>This is a really long docstring that goes over the column limit and is multi-line.<br><br>
924        <b>Czar: </b>"""+despot["Nicholas"]+"""<br>
925        <b>Minion: </b>"""+serf["Dmitri"]+"""<br>
926        <b>Residence: </b>"""+palace["Winter"]+"""<br>
927        </body>
928        </html>"""
929    ''')  # noqa
930    expected_formatted_code = textwrap.dedent('''\
931        foo = 42
932        def f():
933            email_text += """<html>This is a really long docstring that goes over the column limit and is multi-line.<br><br>
934        <b>Czar: </b>"""+despot["Nicholas"]+"""<br>
935        <b>Minion: </b>"""+serf["Dmitri"]+"""<br>
936        <b>Residence: </b>"""+palace["Winter"]+"""<br>
937        </body>
938        </html>"""
939    ''')  # noqa
940    self.assertYapfReformats(
941        unformatted_code,
942        expected_formatted_code,
943        extra_options=['--lines', '1-1'])
944
945  def testDisableWhenSpecifyingLines(self):
946    unformatted_code = textwrap.dedent("""\
947        # yapf: disable
948        A = set([
949            'hello',
950            'world',
951        ])
952        # yapf: enable
953        B = set([
954            'hello',
955            'world',
956        ])  # yapf: disable
957    """)
958    expected_formatted_code = textwrap.dedent("""\
959        # yapf: disable
960        A = set([
961            'hello',
962            'world',
963        ])
964        # yapf: enable
965        B = set([
966            'hello',
967            'world',
968        ])  # yapf: disable
969    """)
970    self.assertYapfReformats(
971        unformatted_code,
972        expected_formatted_code,
973        extra_options=['--lines', '1-10'])
974
975  def testDisableFormattingInDataLiteral(self):
976    unformatted_code = textwrap.dedent("""\
977        def horrible():
978          oh_god()
979          why_would_you()
980          [
981             'do',
982
983              'that',
984          ]
985
986        def still_horrible():
987            oh_god()
988            why_would_you()
989            [
990                'do',
991
992                'that'
993            ]
994    """)
995    expected_formatted_code = textwrap.dedent("""\
996        def horrible():
997            oh_god()
998            why_would_you()
999            [
1000               'do',
1001
1002                'that',
1003            ]
1004
1005        def still_horrible():
1006            oh_god()
1007            why_would_you()
1008            ['do', 'that']
1009    """)
1010    self.assertYapfReformats(
1011        unformatted_code,
1012        expected_formatted_code,
1013        extra_options=['--lines', '14-15'])
1014
1015  def testRetainVerticalFormattingBetweenDisabledAndEnabledLines(self):
1016    unformatted_code = textwrap.dedent("""\
1017        class A(object):
1018            def aaaaaaaaaaaaa(self):
1019                c = bbbbbbbbb.ccccccccc('challenge', 0, 1, 10)
1020                self.assertEqual(
1021                    ('ddddddddddddddddddddddddd',
1022             'eeeeeeeeeeeeeeeeeeeeeeeee.%s' %
1023                     c.ffffffffffff),
1024             gggggggggggg.hhhhhhhhh(c, c.ffffffffffff))
1025                iiiii = jjjjjjjjjjjjjj.iiiii
1026    """)
1027    expected_formatted_code = textwrap.dedent("""\
1028        class A(object):
1029            def aaaaaaaaaaaaa(self):
1030                c = bbbbbbbbb.ccccccccc('challenge', 0, 1, 10)
1031                self.assertEqual(('ddddddddddddddddddddddddd',
1032                                  'eeeeeeeeeeeeeeeeeeeeeeeee.%s' % c.ffffffffffff),
1033                                 gggggggggggg.hhhhhhhhh(c, c.ffffffffffff))
1034                iiiii = jjjjjjjjjjjjjj.iiiii
1035    """)  # noqa
1036    self.assertYapfReformats(
1037        unformatted_code,
1038        expected_formatted_code,
1039        extra_options=['--lines', '4-7'])
1040
1041  def testRetainVerticalFormattingBetweenDisabledLines(self):
1042    unformatted_code = textwrap.dedent("""\
1043        class A(object):
1044            def aaaaaaaaaaaaa(self):
1045                pass
1046
1047
1048            def bbbbbbbbbbbbb(self):  # 5
1049                pass
1050    """)
1051    expected_formatted_code = textwrap.dedent("""\
1052        class A(object):
1053            def aaaaaaaaaaaaa(self):
1054                pass
1055
1056
1057            def bbbbbbbbbbbbb(self):  # 5
1058                pass
1059    """)
1060    self.assertYapfReformats(
1061        unformatted_code,
1062        expected_formatted_code,
1063        extra_options=['--lines', '4-4'])
1064
1065  def testFormatLinesSpecifiedInMiddleOfExpression(self):
1066    unformatted_code = textwrap.dedent("""\
1067        class A(object):
1068            def aaaaaaaaaaaaa(self):
1069                c = bbbbbbbbb.ccccccccc('challenge', 0, 1, 10)
1070                self.assertEqual(
1071                    ('ddddddddddddddddddddddddd',
1072             'eeeeeeeeeeeeeeeeeeeeeeeee.%s' %
1073                     c.ffffffffffff),
1074             gggggggggggg.hhhhhhhhh(c, c.ffffffffffff))
1075                iiiii = jjjjjjjjjjjjjj.iiiii
1076    """)
1077    expected_formatted_code = textwrap.dedent("""\
1078        class A(object):
1079            def aaaaaaaaaaaaa(self):
1080                c = bbbbbbbbb.ccccccccc('challenge', 0, 1, 10)
1081                self.assertEqual(('ddddddddddddddddddddddddd',
1082                                  'eeeeeeeeeeeeeeeeeeeeeeeee.%s' % c.ffffffffffff),
1083                                 gggggggggggg.hhhhhhhhh(c, c.ffffffffffff))
1084                iiiii = jjjjjjjjjjjjjj.iiiii
1085    """)  # noqa
1086    self.assertYapfReformats(
1087        unformatted_code,
1088        expected_formatted_code,
1089        extra_options=['--lines', '5-6'])
1090
1091  def testCommentFollowingMultilineString(self):
1092    unformatted_code = textwrap.dedent("""\
1093        def foo():
1094            '''First line.
1095            Second line.
1096            '''  # comment
1097            x = '''hello world'''  # second comment
1098            return 42  # another comment
1099    """)
1100    expected_formatted_code = textwrap.dedent("""\
1101        def foo():
1102            '''First line.
1103            Second line.
1104            '''  # comment
1105            x = '''hello world'''  # second comment
1106            return 42  # another comment
1107    """)
1108    self.assertYapfReformats(
1109        unformatted_code,
1110        expected_formatted_code,
1111        extra_options=['--lines', '1-1'])
1112
1113  def testDedentClosingBracket(self):
1114    # no line-break on the first argument, not dedenting closing brackets
1115    unformatted_code = textwrap.dedent("""\
1116        def overly_long_function_name(first_argument_on_the_same_line,
1117        second_argument_makes_the_line_too_long):
1118          pass
1119    """)
1120    expected_formatted_code = textwrap.dedent("""\
1121        def overly_long_function_name(first_argument_on_the_same_line,
1122                                      second_argument_makes_the_line_too_long):
1123            pass
1124    """)  # noqa
1125    self.assertYapfReformats(
1126        unformatted_code,
1127        expected_formatted_code,
1128        extra_options=['--style=pep8'])
1129
1130    # TODO(ambv): currently the following produces the closing bracket on a new
1131    # line but indented to the opening bracket which is the worst of both
1132    # worlds. Expected behaviour would be to format as --style=pep8 does in
1133    # this case.
1134    # self.assertYapfReformats(unformatted_code, expected_formatted_code,
1135    #                          extra_options=['--style=facebook'])
1136
1137    # line-break before the first argument, dedenting closing brackets if set
1138    unformatted_code = textwrap.dedent("""\
1139        def overly_long_function_name(
1140          first_argument_on_the_same_line,
1141          second_argument_makes_the_line_too_long):
1142          pass
1143    """)
1144    # expected_formatted_pep8_code = textwrap.dedent("""\
1145    #   def overly_long_function_name(
1146    #           first_argument_on_the_same_line,
1147    #           second_argument_makes_the_line_too_long):
1148    #       pass
1149    # """)
1150    expected_formatted_fb_code = textwrap.dedent("""\
1151        def overly_long_function_name(
1152            first_argument_on_the_same_line, second_argument_makes_the_line_too_long
1153        ):
1154            pass
1155    """)  # noqa
1156    self.assertYapfReformats(
1157        unformatted_code,
1158        expected_formatted_fb_code,
1159        extra_options=['--style=facebook'])
1160    # TODO(ambv): currently the following produces code that is not PEP8
1161    # compliant, raising "E125 continuation line with same indent as next
1162    # logical line" with flake8. Expected behaviour for PEP8 would be to use
1163    # double-indentation here.
1164    # self.assertYapfReformats(unformatted_code, expected_formatted_pep8_code,
1165    #                          extra_options=['--style=pep8'])
1166
1167  def testCoalesceBrackets(self):
1168    unformatted_code = textwrap.dedent("""\
1169       some_long_function_name_foo(
1170           {
1171               'first_argument_of_the_thing': id,
1172               'second_argument_of_the_thing': "some thing"
1173           }
1174       )
1175    """)
1176    expected_formatted_code = textwrap.dedent("""\
1177       some_long_function_name_foo({
1178           'first_argument_of_the_thing': id,
1179           'second_argument_of_the_thing': "some thing"
1180       })
1181    """)
1182    with utils.NamedTempFile(dirname=self.test_tmpdir, mode='w') as (f, name):
1183      f.write(
1184          textwrap.dedent("""\
1185          [style]
1186          column_limit=82
1187          coalesce_brackets = True
1188      """))
1189      f.flush()
1190      self.assertYapfReformats(
1191          unformatted_code,
1192          expected_formatted_code,
1193          extra_options=['--style={0}'.format(name)])
1194
1195  def testPseudoParenSpaces(self):
1196    unformatted_code = textwrap.dedent("""\
1197        def   foo():
1198          def bar():
1199            return {msg_id: author for author, msg_id in reader}
1200    """)
1201    expected_formatted_code = textwrap.dedent("""\
1202        def foo():
1203          def bar():
1204            return {msg_id: author for author, msg_id in reader}
1205    """)
1206    self.assertYapfReformats(
1207        unformatted_code,
1208        expected_formatted_code,
1209        extra_options=['--lines', '1-1', '--style', 'yapf'])
1210
1211  def testMultilineCommentFormattingDisabled(self):
1212    unformatted_code = textwrap.dedent("""\
1213        # This is a comment
1214        FOO = {
1215            aaaaaaaa.ZZZ: [
1216                bbbbbbbbbb.Pop(),
1217                # Multiline comment.
1218                # Line two.
1219                bbbbbbbbbb.Pop(),
1220            ],
1221            'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx':
1222                ('yyyyy', zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz),
1223            '#': lambda x: x  # do nothing
1224        }
1225    """)
1226    expected_formatted_code = textwrap.dedent("""\
1227        # This is a comment
1228        FOO = {
1229            aaaaaaaa.ZZZ: [
1230                bbbbbbbbbb.Pop(),
1231                # Multiline comment.
1232                # Line two.
1233                bbbbbbbbbb.Pop(),
1234            ],
1235            'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx':
1236                ('yyyyy', zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz),
1237            '#': lambda x: x  # do nothing
1238        }
1239    """)
1240    self.assertYapfReformats(
1241        unformatted_code,
1242        expected_formatted_code,
1243        extra_options=['--lines', '1-1', '--style', 'yapf'])
1244
1245  def testTrailingCommentsWithDisabledFormatting(self):
1246    unformatted_code = textwrap.dedent("""\
1247        import os
1248
1249        SCOPES = [
1250            'hello world'  # This is a comment.
1251        ]
1252    """)
1253    expected_formatted_code = textwrap.dedent("""\
1254        import os
1255
1256        SCOPES = [
1257            'hello world'  # This is a comment.
1258        ]
1259    """)
1260    self.assertYapfReformats(
1261        unformatted_code,
1262        expected_formatted_code,
1263        extra_options=['--lines', '1-1', '--style', 'yapf'])
1264
1265  def testUseTabs(self):
1266    unformatted_code = textwrap.dedent("""\
1267        def foo_function():
1268         if True:
1269          pass
1270    """)
1271    expected_formatted_code = """\
1272def foo_function():
1273	if True:
1274		pass
1275"""  # noqa: W191,E101
1276    style_contents = textwrap.dedent("""\
1277        [style]
1278        based_on_style = yapf
1279        use_tabs = true
1280        indent_width = 1
1281    """)
1282    with utils.TempFileContents(self.test_tmpdir, style_contents) as stylepath:
1283      self.assertYapfReformats(
1284          unformatted_code,
1285          expected_formatted_code,
1286          extra_options=['--style={0}'.format(stylepath)])
1287
1288  def testUseTabsWith(self):
1289    unformatted_code = """\
1290def f():
1291  return ['hello', 'world',]
1292"""
1293    expected_formatted_code = """\
1294def f():
1295	return [
1296	    'hello',
1297	    'world',
1298	]
1299"""  # noqa: W191,E101
1300    style_contents = textwrap.dedent("""\
1301        [style]
1302        based_on_style = yapf
1303        use_tabs = true
1304        indent_width = 1
1305    """)
1306    with utils.TempFileContents(self.test_tmpdir, style_contents) as stylepath:
1307      self.assertYapfReformats(
1308          unformatted_code,
1309          expected_formatted_code,
1310          extra_options=['--style={0}'.format(stylepath)])
1311
1312  def testUseTabsContinuationAlignStyleFixed(self):
1313    unformatted_code = """\
1314def foo_function(arg1, arg2, arg3):
1315  return ['hello', 'world',]
1316"""
1317    expected_formatted_code = """\
1318def foo_function(
1319		arg1, arg2, arg3):
1320	return [
1321			'hello',
1322			'world',
1323	]
1324"""  # noqa: W191,E101
1325    style_contents = textwrap.dedent("""\
1326        [style]
1327        based_on_style = yapf
1328        use_tabs = true
1329        column_limit=32
1330        indent_width=4
1331        continuation_indent_width=8
1332        continuation_align_style = fixed
1333    """)
1334    with utils.TempFileContents(self.test_tmpdir, style_contents) as stylepath:
1335      self.assertYapfReformats(
1336          unformatted_code,
1337          expected_formatted_code,
1338          extra_options=['--style={0}'.format(stylepath)])
1339
1340  def testUseTabsContinuationAlignStyleVAlignRight(self):
1341    unformatted_code = """\
1342def foo_function(arg1, arg2, arg3):
1343  return ['hello', 'world',]
1344"""
1345    expected_formatted_code = """\
1346def foo_function(arg1, arg2,
1347					arg3):
1348	return [
1349			'hello',
1350			'world',
1351	]
1352"""  # noqa: W191,E101
1353    style_contents = textwrap.dedent("""\
1354        [style]
1355        based_on_style = yapf
1356        use_tabs = true
1357        column_limit = 32
1358        indent_width = 4
1359        continuation_indent_width = 8
1360        continuation_align_style = valign-right
1361    """)
1362    with utils.TempFileContents(self.test_tmpdir, style_contents) as stylepath:
1363      self.assertYapfReformats(
1364          unformatted_code,
1365          expected_formatted_code,
1366          extra_options=['--style={0}'.format(stylepath)])
1367
1368  def testUseSpacesContinuationAlignStyleFixed(self):
1369    unformatted_code = textwrap.dedent("""\
1370        def foo_function(arg1, arg2, arg3):
1371          return ['hello', 'world',]
1372    """)
1373    expected_formatted_code = textwrap.dedent("""\
1374        def foo_function(
1375                arg1, arg2, arg3):
1376            return [
1377                    'hello',
1378                    'world',
1379            ]
1380    """)
1381    style_contents = textwrap.dedent("""\
1382        [style]
1383        based_on_style = yapf
1384        column_limit = 32
1385        indent_width = 4
1386        continuation_indent_width = 8
1387        continuation_align_style = fixed
1388    """)
1389    with utils.TempFileContents(self.test_tmpdir, style_contents) as stylepath:
1390      self.assertYapfReformats(
1391          unformatted_code,
1392          expected_formatted_code,
1393          extra_options=['--style={0}'.format(stylepath)])
1394
1395  def testUseSpacesContinuationAlignStyleVAlignRight(self):
1396    unformatted_code = textwrap.dedent("""\
1397        def foo_function(arg1, arg2, arg3):
1398          return ['hello', 'world',]
1399    """)
1400    expected_formatted_code = textwrap.dedent("""\
1401        def foo_function(arg1, arg2,
1402                            arg3):
1403            return [
1404                    'hello',
1405                    'world',
1406            ]
1407    """)
1408    style_contents = textwrap.dedent("""\
1409        [style]
1410        based_on_style = yapf
1411        column_limit = 32
1412        indent_width = 4
1413        continuation_indent_width = 8
1414        continuation_align_style = valign-right
1415    """)
1416    with utils.TempFileContents(self.test_tmpdir, style_contents) as stylepath:
1417      self.assertYapfReformats(
1418          unformatted_code,
1419          expected_formatted_code,
1420          extra_options=['--style={0}'.format(stylepath)])
1421
1422  def testStyleOutputRoundTrip(self):
1423    unformatted_code = textwrap.dedent("""\
1424        def foo_function():
1425          pass
1426    """)
1427    expected_formatted_code = textwrap.dedent("""\
1428        def foo_function():
1429            pass
1430    """)
1431
1432    with utils.NamedTempFile(dirname=self.test_tmpdir) as (stylefile,
1433                                                           stylepath):
1434      p = subprocess.Popen(
1435          YAPF_BINARY + ['--style-help'],
1436          stdout=stylefile,
1437          stdin=subprocess.PIPE,
1438          stderr=subprocess.PIPE)
1439      _, stderrdata = p.communicate()
1440      self.assertEqual(stderrdata, b'')
1441      self.assertYapfReformats(
1442          unformatted_code,
1443          expected_formatted_code,
1444          extra_options=['--style={0}'.format(stylepath)])
1445
1446  def testSpacingBeforeComments(self):
1447    unformatted_code = textwrap.dedent("""\
1448        A = 42
1449
1450
1451        # A comment
1452        def x():
1453            pass
1454        def _():
1455            pass
1456    """)
1457    expected_formatted_code = textwrap.dedent("""\
1458        A = 42
1459
1460
1461        # A comment
1462        def x():
1463            pass
1464        def _():
1465            pass
1466    """)
1467    self.assertYapfReformats(
1468        unformatted_code,
1469        expected_formatted_code,
1470        extra_options=['--lines', '1-2'])
1471
1472  def testSpacingBeforeCommentsInDicts(self):
1473    unformatted_code = textwrap.dedent("""\
1474        A=42
1475
1476        X = {
1477            # 'Valid' statuses.
1478            PASSED:  # Passed
1479                'PASSED',
1480            FAILED:  # Failed
1481                'FAILED',
1482            TIMED_OUT:  # Timed out.
1483                'FAILED',
1484            BORKED:  # Broken.
1485                'BROKEN'
1486        }
1487    """)
1488    expected_formatted_code = textwrap.dedent("""\
1489        A = 42
1490
1491        X = {
1492            # 'Valid' statuses.
1493            PASSED:  # Passed
1494                'PASSED',
1495            FAILED:  # Failed
1496                'FAILED',
1497            TIMED_OUT:  # Timed out.
1498                'FAILED',
1499            BORKED:  # Broken.
1500                'BROKEN'
1501        }
1502    """)
1503    self.assertYapfReformats(
1504        unformatted_code,
1505        expected_formatted_code,
1506        extra_options=['--style', 'yapf', '--lines', '1-1'])
1507
1508  def testDisableWithLinesOption(self):
1509    unformatted_code = textwrap.dedent("""\
1510        # yapf_lines_bug.py
1511        # yapf: disable
1512        def outer_func():
1513            def inner_func():
1514                return
1515            return
1516        # yapf: enable
1517    """)
1518    expected_formatted_code = textwrap.dedent("""\
1519        # yapf_lines_bug.py
1520        # yapf: disable
1521        def outer_func():
1522            def inner_func():
1523                return
1524            return
1525        # yapf: enable
1526    """)
1527    self.assertYapfReformats(
1528        unformatted_code,
1529        expected_formatted_code,
1530        extra_options=['--lines', '1-8'])
1531
1532  def testDisableWithLineRanges(self):
1533    unformatted_code = textwrap.dedent("""\
1534        # yapf: disable
1535        a = [
1536            1,
1537            2,
1538
1539            3
1540        ]
1541    """)
1542    expected_formatted_code = textwrap.dedent("""\
1543        # yapf: disable
1544        a = [
1545            1,
1546            2,
1547
1548            3
1549        ]
1550    """)
1551    self.assertYapfReformats(
1552        unformatted_code,
1553        expected_formatted_code,
1554        extra_options=['--style', 'yapf', '--lines', '1-100'])
1555
1556
1557class BadInputTest(yapf_test_helper.YAPFTest):
1558  """Test yapf's behaviour when passed bad input."""
1559
1560  def testBadSyntax(self):
1561    code = '  a = 1\n'
1562    self.assertRaises(errors.YapfError, yapf_api.FormatCode, code)
1563
1564  def testBadCode(self):
1565    code = 'x = """hello\n'
1566    self.assertRaises(errors.YapfError, yapf_api.FormatCode, code)
1567
1568
1569class DiffIndentTest(yapf_test_helper.YAPFTest):
1570
1571  @staticmethod
1572  def _OwnStyle():
1573    my_style = style.CreatePEP8Style()
1574    my_style['INDENT_WIDTH'] = 3
1575    my_style['CONTINUATION_INDENT_WIDTH'] = 3
1576    return my_style
1577
1578  def _Check(self, unformatted_code, expected_formatted_code):
1579    formatted_code, _ = yapf_api.FormatCode(
1580        unformatted_code, style_config=style.SetGlobalStyle(self._OwnStyle()))
1581    self.assertEqual(expected_formatted_code, formatted_code)
1582
1583  def testSimple(self):
1584    unformatted_code = textwrap.dedent("""\
1585        for i in range(5):
1586         print('bar')
1587    """)
1588    expected_formatted_code = textwrap.dedent("""\
1589        for i in range(5):
1590           print('bar')
1591    """)
1592    self._Check(unformatted_code, expected_formatted_code)
1593
1594
1595class HorizontallyAlignedTrailingCommentsTest(yapf_test_helper.YAPFTest):
1596
1597  @staticmethod
1598  def _OwnStyle():
1599    my_style = style.CreatePEP8Style()
1600    my_style['SPACES_BEFORE_COMMENT'] = [
1601        15,
1602        25,
1603        35,
1604    ]
1605    return my_style
1606
1607  def _Check(self, unformatted_code, expected_formatted_code):
1608    formatted_code, _ = yapf_api.FormatCode(
1609        unformatted_code, style_config=style.SetGlobalStyle(self._OwnStyle()))
1610    self.assertCodeEqual(expected_formatted_code, formatted_code)
1611
1612  def testSimple(self):
1613    unformatted_code = textwrap.dedent("""\
1614        foo = '1' # Aligned at first list value
1615
1616        foo = '2__<15>' # Aligned at second list value
1617
1618        foo = '3____________<25>' # Aligned at third list value
1619
1620        foo = '4______________________<35>' # Aligned beyond list values
1621    """)
1622    expected_formatted_code = textwrap.dedent("""\
1623        foo = '1'     # Aligned at first list value
1624
1625        foo = '2__<15>'         # Aligned at second list value
1626
1627        foo = '3____________<25>'         # Aligned at third list value
1628
1629        foo = '4______________________<35>' # Aligned beyond list values
1630    """)
1631    self._Check(unformatted_code, expected_formatted_code)
1632
1633  def testBlock(self):
1634    unformatted_code = textwrap.dedent("""\
1635        func(1)     # Line 1
1636        func(2) # Line 2
1637        # Line 3
1638        func(3)                             # Line 4
1639                                            # Line 5
1640                                            # Line 6
1641    """)
1642    expected_formatted_code = textwrap.dedent("""\
1643        func(1)       # Line 1
1644        func(2)       # Line 2
1645                      # Line 3
1646        func(3)       # Line 4
1647                      # Line 5
1648                      # Line 6
1649    """)
1650    self._Check(unformatted_code, expected_formatted_code)
1651
1652  def testBlockWithLongLine(self):
1653    unformatted_code = textwrap.dedent("""\
1654        func(1)     # Line 1
1655        func___________________(2) # Line 2
1656        # Line 3
1657        func(3)                             # Line 4
1658                                            # Line 5
1659                                            # Line 6
1660    """)
1661    expected_formatted_code = textwrap.dedent("""\
1662        func(1)                           # Line 1
1663        func___________________(2)        # Line 2
1664                                          # Line 3
1665        func(3)                           # Line 4
1666                                          # Line 5
1667                                          # Line 6
1668    """)
1669    self._Check(unformatted_code, expected_formatted_code)
1670
1671  def testBlockFuncSuffix(self):
1672    unformatted_code = textwrap.dedent("""\
1673        func(1)     # Line 1
1674        func(2) # Line 2
1675        # Line 3
1676        func(3)                             # Line 4
1677                                        # Line 5
1678                                    # Line 6
1679
1680        def Func():
1681            pass
1682    """)
1683    expected_formatted_code = textwrap.dedent("""\
1684        func(1)       # Line 1
1685        func(2)       # Line 2
1686                      # Line 3
1687        func(3)       # Line 4
1688                      # Line 5
1689                      # Line 6
1690
1691
1692        def Func():
1693            pass
1694    """)
1695    self._Check(unformatted_code, expected_formatted_code)
1696
1697  def testBlockCommentSuffix(self):
1698    unformatted_code = textwrap.dedent("""\
1699        func(1)     # Line 1
1700        func(2) # Line 2
1701        # Line 3
1702        func(3)                             # Line 4
1703                                        # Line 5 - SpliceComments makes this part of the previous block
1704                                    # Line 6
1705
1706                                            # Aligned with prev comment block
1707    """)  # noqa
1708    expected_formatted_code = textwrap.dedent("""\
1709        func(1)       # Line 1
1710        func(2)       # Line 2
1711                      # Line 3
1712        func(3)       # Line 4
1713                      # Line 5 - SpliceComments makes this part of the previous block
1714                      # Line 6
1715
1716                      # Aligned with prev comment block
1717    """)  # noqa
1718    self._Check(unformatted_code, expected_formatted_code)
1719
1720  def testBlockIndentedFuncSuffix(self):
1721    unformatted_code = textwrap.dedent("""\
1722        if True:
1723            func(1)     # Line 1
1724            func(2) # Line 2
1725            # Line 3
1726            func(3)                             # Line 4
1727                                                # Line 5 - SpliceComments makes this a new block
1728                                                # Line 6
1729
1730                                                # Aligned with Func
1731
1732            def Func():
1733                pass
1734    """)  # noqa
1735    expected_formatted_code = textwrap.dedent("""\
1736        if True:
1737            func(1)   # Line 1
1738            func(2)   # Line 2
1739                      # Line 3
1740            func(3)   # Line 4
1741
1742            # Line 5 - SpliceComments makes this a new block
1743            # Line 6
1744
1745            # Aligned with Func
1746
1747
1748            def Func():
1749                pass
1750    """)
1751    self._Check(unformatted_code, expected_formatted_code)
1752
1753  def testBlockIndentedCommentSuffix(self):
1754    unformatted_code = textwrap.dedent("""\
1755        if True:
1756            func(1)     # Line 1
1757            func(2) # Line 2
1758            # Line 3
1759            func(3)                             # Line 4
1760                                                # Line 5
1761                                                # Line 6
1762
1763                                                # Not aligned
1764    """)
1765    expected_formatted_code = textwrap.dedent("""\
1766        if True:
1767            func(1)   # Line 1
1768            func(2)   # Line 2
1769                      # Line 3
1770            func(3)   # Line 4
1771                      # Line 5
1772                      # Line 6
1773
1774            # Not aligned
1775    """)
1776    self._Check(unformatted_code, expected_formatted_code)
1777
1778  def testBlockMultiIndented(self):
1779    unformatted_code = textwrap.dedent("""\
1780        if True:
1781            if True:
1782                if True:
1783                    func(1)     # Line 1
1784                    func(2) # Line 2
1785                    # Line 3
1786                    func(3)                             # Line 4
1787                                                        # Line 5
1788                                                        # Line 6
1789
1790                                                        # Not aligned
1791    """)  # noqa
1792    expected_formatted_code = textwrap.dedent("""\
1793        if True:
1794            if True:
1795                if True:
1796                    func(1)     # Line 1
1797                    func(2)     # Line 2
1798                                # Line 3
1799                    func(3)     # Line 4
1800                                # Line 5
1801                                # Line 6
1802
1803                    # Not aligned
1804    """)
1805    self._Check(unformatted_code, expected_formatted_code)
1806
1807  def testArgs(self):
1808    unformatted_code = textwrap.dedent("""\
1809        def MyFunc(
1810            arg1,   # Desc 1
1811            arg2,   # Desc 2
1812            a_longer_var_name,  # Desc 3
1813            arg4,
1814            arg5,   # Desc 5
1815            arg6,
1816        ):
1817            pass
1818    """)
1819    expected_formatted_code = textwrap.dedent("""\
1820        def MyFunc(
1821            arg1,               # Desc 1
1822            arg2,               # Desc 2
1823            a_longer_var_name,  # Desc 3
1824            arg4,
1825            arg5,               # Desc 5
1826            arg6,
1827        ):
1828            pass
1829    """)
1830    self._Check(unformatted_code, expected_formatted_code)
1831
1832  def testDisableBlock(self):
1833    unformatted_code = textwrap.dedent("""\
1834        a() # comment 1
1835        b() # comment 2
1836
1837        # yapf: disable
1838        c() # comment 3
1839        d()   # comment 4
1840        # yapf: enable
1841
1842        e() # comment 5
1843        f() # comment 6
1844    """)
1845    expected_formatted_code = textwrap.dedent("""\
1846        a()           # comment 1
1847        b()           # comment 2
1848
1849        # yapf: disable
1850        c() # comment 3
1851        d()   # comment 4
1852        # yapf: enable
1853
1854        e()           # comment 5
1855        f()           # comment 6
1856    """)
1857    self._Check(unformatted_code, expected_formatted_code)
1858
1859  def testDisabledLine(self):
1860    unformatted_code = textwrap.dedent("""\
1861        short # comment 1
1862        do_not_touch1 # yapf: disable
1863        do_not_touch2   # yapf: disable
1864        a_longer_statement # comment 2
1865    """)
1866    expected_formatted_code = textwrap.dedent("""\
1867        short                   # comment 1
1868        do_not_touch1 # yapf: disable
1869        do_not_touch2   # yapf: disable
1870        a_longer_statement      # comment 2
1871    """)
1872    self._Check(unformatted_code, expected_formatted_code)
1873
1874
1875class _SpacesAroundDictListTupleTestImpl(yapf_test_helper.YAPFTest):
1876
1877  @staticmethod
1878  def _OwnStyle():
1879    my_style = style.CreatePEP8Style()
1880    my_style['DISABLE_ENDING_COMMA_HEURISTIC'] = True
1881    my_style['SPLIT_ALL_COMMA_SEPARATED_VALUES'] = False
1882    my_style['SPLIT_ARGUMENTS_WHEN_COMMA_TERMINATED'] = False
1883    return my_style
1884
1885  def _Check(self, unformatted_code, expected_formatted_code):
1886    formatted_code, _ = yapf_api.FormatCode(
1887        unformatted_code, style_config=style.SetGlobalStyle(self._OwnStyle()))
1888    self.assertEqual(expected_formatted_code, formatted_code)
1889
1890  def setUp(self):
1891    self.maxDiff = None
1892
1893
1894class SpacesAroundDictTest(_SpacesAroundDictListTupleTestImpl):
1895
1896  @classmethod
1897  def _OwnStyle(cls):
1898    style = super(SpacesAroundDictTest, cls)._OwnStyle()
1899    style['SPACES_AROUND_DICT_DELIMITERS'] = True
1900
1901    return style
1902
1903  def testStandard(self):
1904    unformatted_code = textwrap.dedent("""\
1905        {1 : 2}
1906        {k:v for k, v in other.items()}
1907        {k for k in [1, 2, 3]}
1908
1909        # The following statements should not change
1910        {}
1911        {1 : 2} # yapf: disable
1912
1913        # yapf: disable
1914        {1 : 2}
1915        # yapf: enable
1916
1917        # Dict settings should not impact lists or tuples
1918        [1, 2]
1919        (3, 4)
1920    """)
1921    expected_formatted_code = textwrap.dedent("""\
1922        { 1: 2 }
1923        { k: v for k, v in other.items() }
1924        { k for k in [1, 2, 3] }
1925
1926        # The following statements should not change
1927        {}
1928        {1 : 2} # yapf: disable
1929
1930        # yapf: disable
1931        {1 : 2}
1932        # yapf: enable
1933
1934        # Dict settings should not impact lists or tuples
1935        [1, 2]
1936        (3, 4)
1937    """)
1938    self._Check(unformatted_code, expected_formatted_code)
1939
1940
1941class SpacesAroundListTest(_SpacesAroundDictListTupleTestImpl):
1942
1943  @classmethod
1944  def _OwnStyle(cls):
1945    style = super(SpacesAroundListTest, cls)._OwnStyle()
1946    style['SPACES_AROUND_LIST_DELIMITERS'] = True
1947
1948    return style
1949
1950  def testStandard(self):
1951    unformatted_code = textwrap.dedent("""\
1952        [a,b,c]
1953        [4,5,]
1954        [6, [7, 8], 9]
1955        [v for v in [1,2,3] if v & 1]
1956
1957        # The following statements should not change
1958        index[0]
1959        index[a, b]
1960        []
1961        [v for v in [1,2,3] if v & 1] # yapf: disable
1962
1963        # yapf: disable
1964        [a,b,c]
1965        [4,5,]
1966        # yapf: enable
1967
1968        # List settings should not impact dicts or tuples
1969        {a: b}
1970        (1, 2)
1971    """)
1972    expected_formatted_code = textwrap.dedent("""\
1973        [ a, b, c ]
1974        [ 4, 5, ]
1975        [ 6, [ 7, 8 ], 9 ]
1976        [ v for v in [ 1, 2, 3 ] if v & 1 ]
1977
1978        # The following statements should not change
1979        index[0]
1980        index[a, b]
1981        []
1982        [v for v in [1,2,3] if v & 1] # yapf: disable
1983
1984        # yapf: disable
1985        [a,b,c]
1986        [4,5,]
1987        # yapf: enable
1988
1989        # List settings should not impact dicts or tuples
1990        {a: b}
1991        (1, 2)
1992    """)
1993    self._Check(unformatted_code, expected_formatted_code)
1994
1995
1996class SpacesAroundTupleTest(_SpacesAroundDictListTupleTestImpl):
1997
1998  @classmethod
1999  def _OwnStyle(cls):
2000    style = super(SpacesAroundTupleTest, cls)._OwnStyle()
2001    style['SPACES_AROUND_TUPLE_DELIMITERS'] = True
2002
2003    return style
2004
2005  def testStandard(self):
2006    unformatted_code = textwrap.dedent("""\
2007        (0, 1)
2008        (2, 3)
2009        (4, 5, 6,)
2010        func((7, 8), 9)
2011
2012        # The following statements should not change
2013        func(1, 2)
2014        (this_func or that_func)(3, 4)
2015        if (True and False): pass
2016        ()
2017
2018        (0, 1) # yapf: disable
2019
2020        # yapf: disable
2021        (0, 1)
2022        (2, 3)
2023        # yapf: enable
2024
2025        # Tuple settings should not impact dicts or lists
2026        {a: b}
2027        [3, 4]
2028    """)
2029    expected_formatted_code = textwrap.dedent("""\
2030        ( 0, 1 )
2031        ( 2, 3 )
2032        ( 4, 5, 6, )
2033        func(( 7, 8 ), 9)
2034
2035        # The following statements should not change
2036        func(1, 2)
2037        (this_func or that_func)(3, 4)
2038        if (True and False): pass
2039        ()
2040
2041        (0, 1) # yapf: disable
2042
2043        # yapf: disable
2044        (0, 1)
2045        (2, 3)
2046        # yapf: enable
2047
2048        # Tuple settings should not impact dicts or lists
2049        {a: b}
2050        [3, 4]
2051    """)
2052    self._Check(unformatted_code, expected_formatted_code)
2053
2054
2055if __name__ == '__main__':
2056  unittest.main()
2057