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
26
27from yapf.yapflib import py3compat
28from yapf.yapflib import style
29from yapf.yapflib import yapf_api
30
31from yapftests import utils
32
33ROOT_DIR = os.path.dirname(os.path.abspath(os.path.dirname(__file__)))
34
35# Verification is turned off by default, but want to enable it for testing.
36YAPF_BINARY = [sys.executable, '-m', 'yapf', '--verify', '--no-local-style']
37
38
39class FormatCodeTest(unittest.TestCase):
40
41  def _Check(self, unformatted_code, expected_formatted_code):
42    formatted_code, _ = yapf_api.FormatCode(
43        unformatted_code, style_config='chromium')
44    self.assertEqual(expected_formatted_code, formatted_code)
45
46  def testSimple(self):
47    unformatted_code = textwrap.dedent("""\
48        print('foo')
49        """)
50    self._Check(unformatted_code, unformatted_code)
51
52  def testNoEndingNewline(self):
53    unformatted_code = textwrap.dedent("""\
54        if True:
55          pass""")
56    expected_formatted_code = textwrap.dedent("""\
57        if True:
58          pass
59        """)
60    self._Check(unformatted_code, expected_formatted_code)
61
62
63class FormatFileTest(unittest.TestCase):
64
65  def setUp(self):
66    self.test_tmpdir = tempfile.mkdtemp()
67
68  def tearDown(self):
69    shutil.rmtree(self.test_tmpdir)
70
71  def assertCodeEqual(self, expected_code, code):
72    if code != expected_code:
73      msg = 'Code format mismatch:\n'
74      msg += 'Expected:\n >'
75      msg += '\n > '.join(expected_code.splitlines())
76      msg += '\nActual:\n >'
77      msg += '\n > '.join(code.splitlines())
78      # TODO(sbc): maybe using difflib here to produce easy to read deltas?
79      self.fail(msg)
80
81  def testFormatFile(self):
82    unformatted_code = textwrap.dedent(u"""\
83        if True:
84         pass
85        """)
86    expected_formatted_code_pep8 = textwrap.dedent(u"""\
87        if True:
88            pass
89        """)
90    expected_formatted_code_chromium = textwrap.dedent(u"""\
91        if True:
92          pass
93        """)
94    with utils.TempFileContents(self.test_tmpdir, unformatted_code) as filepath:
95      formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='pep8')
96      self.assertCodeEqual(expected_formatted_code_pep8, formatted_code)
97
98      formatted_code, _, _ = yapf_api.FormatFile(
99          filepath, style_config='chromium')
100      self.assertCodeEqual(expected_formatted_code_chromium, formatted_code)
101
102  def testDisableLinesPattern(self):
103    unformatted_code = textwrap.dedent(u"""\
104        if a:    b
105
106        # yapf: disable
107        if f:    g
108
109        if h:    i
110        """)
111    expected_formatted_code = textwrap.dedent(u"""\
112        if a: b
113
114        # yapf: disable
115        if f:    g
116
117        if h:    i
118        """)
119    with utils.TempFileContents(self.test_tmpdir, unformatted_code) as filepath:
120      formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='pep8')
121      self.assertCodeEqual(expected_formatted_code, formatted_code)
122
123  def testDisableAndReenableLinesPattern(self):
124    unformatted_code = textwrap.dedent(u"""\
125        if a:    b
126
127        # yapf: disable
128        if f:    g
129        # yapf: enable
130
131        if h:    i
132        """)
133    expected_formatted_code = textwrap.dedent(u"""\
134        if a: b
135
136        # yapf: disable
137        if f:    g
138        # yapf: enable
139
140        if h: i
141        """)
142    with utils.TempFileContents(self.test_tmpdir, unformatted_code) as filepath:
143      formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='pep8')
144      self.assertCodeEqual(expected_formatted_code, formatted_code)
145
146  def testDisablePartOfMultilineComment(self):
147    unformatted_code = textwrap.dedent(u"""\
148        if a:    b
149
150        # This is a multiline comment that disables YAPF.
151        # yapf: disable
152        if f:    g
153        # yapf: enable
154        # This is a multiline comment that enables YAPF.
155
156        if h:    i
157        """)
158
159    expected_formatted_code = textwrap.dedent(u"""\
160        if a: b
161
162        # This is a multiline comment that disables YAPF.
163        # yapf: disable
164        if f:    g
165        # yapf: enable
166        # This is a multiline comment that enables YAPF.
167
168        if h: i
169        """)
170    with utils.TempFileContents(self.test_tmpdir, unformatted_code) as filepath:
171      formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='pep8')
172      self.assertCodeEqual(expected_formatted_code, formatted_code)
173
174    code = textwrap.dedent(u"""\
175      def foo_function():
176          # some comment
177          # yapf: disable
178
179          foo(
180          bar,
181          baz
182          )
183
184          # yapf: enable
185      """)
186    with utils.TempFileContents(self.test_tmpdir, code) as filepath:
187      formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='pep8')
188      self.assertCodeEqual(code, formatted_code)
189
190  def testFormatFileLinesSelection(self):
191    unformatted_code = textwrap.dedent(u"""\
192        if a:    b
193
194        if f:    g
195
196        if h:    i
197        """)
198    expected_formatted_code_lines1and2 = textwrap.dedent(u"""\
199        if a: b
200
201        if f:    g
202
203        if h:    i
204        """)
205    expected_formatted_code_lines3 = textwrap.dedent(u"""\
206        if a:    b
207
208        if f: g
209
210        if h:    i
211        """)
212    with utils.TempFileContents(self.test_tmpdir, unformatted_code) as filepath:
213      formatted_code, _, _ = yapf_api.FormatFile(
214          filepath, style_config='pep8', lines=[(1, 2)])
215      self.assertCodeEqual(expected_formatted_code_lines1and2, formatted_code)
216      formatted_code, _, _ = yapf_api.FormatFile(
217          filepath, style_config='pep8', lines=[(3, 3)])
218      self.assertCodeEqual(expected_formatted_code_lines3, formatted_code)
219
220  def testFormatFileDiff(self):
221    unformatted_code = textwrap.dedent(u"""\
222        if True:
223         pass
224        """)
225    with utils.TempFileContents(self.test_tmpdir, unformatted_code) as filepath:
226      diff, _, _ = yapf_api.FormatFile(filepath, print_diff=True)
227      self.assertTrue(u'+  pass' in diff)
228
229  def testFormatFileInPlace(self):
230    unformatted_code = u'True==False\n'
231    formatted_code = u'True == False\n'
232    with utils.TempFileContents(self.test_tmpdir, unformatted_code) as filepath:
233      result, _, _ = yapf_api.FormatFile(filepath, in_place=True)
234      self.assertEqual(result, None)
235      with open(filepath) as fd:
236        if sys.version_info[0] <= 2:
237          self.assertCodeEqual(formatted_code, fd.read().decode('ascii'))
238        else:
239          self.assertCodeEqual(formatted_code, fd.read())
240
241      self.assertRaises(
242          ValueError,
243          yapf_api.FormatFile,
244          filepath,
245          in_place=True,
246          print_diff=True)
247
248  def testNoFile(self):
249    stream = py3compat.StringIO()
250    handler = logging.StreamHandler(stream)
251    logger = logging.getLogger('mylogger')
252    logger.addHandler(handler)
253    self.assertRaises(
254        IOError, yapf_api.FormatFile, 'not_a_file.py', logger=logger.error)
255    self.assertEqual(stream.getvalue(),
256                     "[Errno 2] No such file or directory: 'not_a_file.py'\n")
257
258  def testCommentsUnformatted(self):
259    code = textwrap.dedent(u"""\
260        foo = [# A list of things
261               # bork
262            'one',
263            # quark
264            'two'] # yapf: disable
265        """)
266    with utils.TempFileContents(self.test_tmpdir, code) as filepath:
267      formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='pep8')
268      self.assertCodeEqual(code, formatted_code)
269
270  def testDisabledHorizontalFormattingOnNewLine(self):
271    code = textwrap.dedent(u"""\
272        # yapf: disable
273        a = [
274        1]
275        # yapf: enable
276        """)
277    with utils.TempFileContents(self.test_tmpdir, code) as filepath:
278      formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='pep8')
279      self.assertCodeEqual(code, formatted_code)
280
281  def testSplittingSemicolonStatements(self):
282    unformatted_code = textwrap.dedent(u"""\
283        def f():
284          x = y + 42 ; z = n * 42
285          if True: a += 1 ; b += 1; c += 1
286        """)
287    expected_formatted_code = textwrap.dedent(u"""\
288        def f():
289            x = y + 42
290            z = n * 42
291            if True:
292                a += 1
293                b += 1
294                c += 1
295        """)
296    with utils.TempFileContents(self.test_tmpdir, unformatted_code) as filepath:
297      formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='pep8')
298      self.assertCodeEqual(expected_formatted_code, formatted_code)
299
300  def testSemicolonStatementsDisabled(self):
301    unformatted_code = textwrap.dedent(u"""\
302        def f():
303          x = y + 42 ; z = n * 42  # yapf: disable
304          if True: a += 1 ; b += 1; c += 1
305        """)
306    expected_formatted_code = textwrap.dedent(u"""\
307        def f():
308            x = y + 42 ; z = n * 42  # yapf: disable
309            if True:
310                a += 1
311                b += 1
312                c += 1
313        """)
314    with utils.TempFileContents(self.test_tmpdir, unformatted_code) as filepath:
315      formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='pep8')
316      self.assertCodeEqual(expected_formatted_code, formatted_code)
317
318  def testDisabledSemiColonSeparatedStatements(self):
319    code = textwrap.dedent(u"""\
320        # yapf: disable
321        if True: a ; b
322        """)
323    with utils.TempFileContents(self.test_tmpdir, code) as filepath:
324      formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='pep8')
325      self.assertCodeEqual(code, formatted_code)
326
327  def testDisabledMultilineStringInDictionary(self):
328    code = textwrap.dedent(u"""\
329        # yapf: disable
330
331        A = [
332            {
333                "aaaaaaaaaaaaaaaaaaa": '''
334        bbbbbbbbbbb: "ccccccccccc"
335        dddddddddddddd: 1
336        eeeeeeee: 0
337        ffffffffff: "ggggggg"
338        ''',
339            },
340        ]
341        """)
342    with utils.TempFileContents(self.test_tmpdir, code) as filepath:
343      formatted_code, _, _ = yapf_api.FormatFile(
344          filepath, style_config='chromium')
345      self.assertCodeEqual(code, formatted_code)
346
347  def testDisabledWithPrecedingText(self):
348    code = textwrap.dedent(u"""\
349        # TODO(fix formatting): 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(
364          filepath, style_config='chromium')
365      self.assertCodeEqual(code, formatted_code)
366
367  def testCRLFLineEnding(self):
368    code = u'class _():\r\n  pass\r\n'
369    with utils.TempFileContents(self.test_tmpdir, code) as filepath:
370      formatted_code, _, _ = yapf_api.FormatFile(
371          filepath, style_config='chromium')
372      self.assertCodeEqual(code, formatted_code)
373
374
375class CommandLineTest(unittest.TestCase):
376  """Test how calling yapf from the command line acts."""
377
378  @classmethod
379  def setUpClass(cls):
380    cls.test_tmpdir = tempfile.mkdtemp()
381
382  @classmethod
383  def tearDownClass(cls):
384    shutil.rmtree(cls.test_tmpdir)
385
386  def assertYapfReformats(self,
387                          unformatted,
388                          expected,
389                          extra_options=None,
390                          env=None):
391    """Check that yapf reformats the given code as expected.
392
393    Invokes yapf in a subprocess, piping the unformatted code into its stdin.
394    Checks that the formatted output is as expected.
395
396    Arguments:
397      unformatted: unformatted code - input to yapf
398      expected: expected formatted code at the output of yapf
399      extra_options: iterable of extra command-line options to pass to yapf
400      env: dict of environment variables.
401    """
402    cmdline = YAPF_BINARY + (extra_options or [])
403    p = subprocess.Popen(
404        cmdline,
405        stdout=subprocess.PIPE,
406        stdin=subprocess.PIPE,
407        stderr=subprocess.PIPE,
408        env=env)
409    reformatted_code, stderrdata = p.communicate(unformatted.encode('utf-8'))
410    self.assertEqual(stderrdata, b'')
411    self.assertMultiLineEqual(reformatted_code.decode('utf-8'), expected)
412
413  def testUnicodeEncodingPipedToFile(self):
414    unformatted_code = textwrap.dedent(u"""\
415        def foo():
416            print('⇒')
417        """)
418    with utils.NamedTempFile(
419        dirname=self.test_tmpdir, suffix='.py') as (out, _):
420      with utils.TempFileContents(
421          self.test_tmpdir, unformatted_code, suffix='.py') as filepath:
422        subprocess.check_call(YAPF_BINARY + ['--diff', filepath], stdout=out)
423
424  def testInPlaceReformatting(self):
425    unformatted_code = textwrap.dedent(u"""\
426        def foo():
427          x = 37
428        """)
429    expected_formatted_code = textwrap.dedent("""\
430        def foo():
431            x = 37
432        """)
433    with utils.TempFileContents(
434        self.test_tmpdir, unformatted_code, suffix='.py') as filepath:
435      p = subprocess.Popen(YAPF_BINARY + ['--in-place', filepath])
436      p.wait()
437      with io.open(filepath, mode='r', newline='') as fd:
438        reformatted_code = fd.read()
439    self.assertEqual(reformatted_code, expected_formatted_code)
440
441  def testInPlaceReformattingBlank(self):
442    unformatted_code = u'\n\n'
443    expected_formatted_code = u'\n'
444    with utils.TempFileContents(
445        self.test_tmpdir, unformatted_code, suffix='.py') as filepath:
446      p = subprocess.Popen(YAPF_BINARY + ['--in-place', filepath])
447      p.wait()
448      with io.open(filepath, mode='r', encoding='utf-8', newline='') as fd:
449        reformatted_code = fd.read()
450    self.assertEqual(reformatted_code, expected_formatted_code)
451
452  def testInPlaceReformattingEmpty(self):
453    unformatted_code = u''
454    expected_formatted_code = u''
455    with utils.TempFileContents(
456        self.test_tmpdir, unformatted_code, suffix='.py') as filepath:
457      p = subprocess.Popen(YAPF_BINARY + ['--in-place', filepath])
458      p.wait()
459      with io.open(filepath, mode='r', encoding='utf-8', newline='') as fd:
460        reformatted_code = fd.read()
461    self.assertEqual(reformatted_code, expected_formatted_code)
462
463  def testReadFromStdin(self):
464    unformatted_code = textwrap.dedent("""\
465        def foo():
466          x = 37
467        """)
468    expected_formatted_code = textwrap.dedent("""\
469        def foo():
470            x = 37
471        """)
472    self.assertYapfReformats(unformatted_code, expected_formatted_code)
473
474  def testReadFromStdinWithEscapedStrings(self):
475    unformatted_code = textwrap.dedent("""\
476        s =   "foo\\nbar"
477        """)
478    expected_formatted_code = textwrap.dedent("""\
479        s = "foo\\nbar"
480        """)
481    self.assertYapfReformats(unformatted_code, expected_formatted_code)
482
483  def testSetChromiumStyle(self):
484    unformatted_code = textwrap.dedent("""\
485        def foo(): # trail
486            x = 37
487        """)
488    expected_formatted_code = textwrap.dedent("""\
489        def foo():  # trail
490          x = 37
491        """)
492    self.assertYapfReformats(
493        unformatted_code,
494        expected_formatted_code,
495        extra_options=['--style=chromium'])
496
497  def testSetCustomStyleBasedOnChromium(self):
498    unformatted_code = textwrap.dedent("""\
499        def foo(): # trail
500            x = 37
501        """)
502    expected_formatted_code = textwrap.dedent("""\
503        def foo():    # trail
504          x = 37
505        """)
506    style_file = textwrap.dedent(u'''\
507        [style]
508        based_on_style = chromium
509        SPACES_BEFORE_COMMENT = 4
510        ''')
511    with utils.TempFileContents(self.test_tmpdir, style_file) as stylepath:
512      self.assertYapfReformats(
513          unformatted_code,
514          expected_formatted_code,
515          extra_options=['--style={0}'.format(stylepath)])
516
517  def testReadSingleLineCodeFromStdin(self):
518    unformatted_code = textwrap.dedent("""\
519        if True: pass
520        """)
521    expected_formatted_code = textwrap.dedent("""\
522        if True: pass
523        """)
524    self.assertYapfReformats(unformatted_code, expected_formatted_code)
525
526  def testEncodingVerification(self):
527    unformatted_code = textwrap.dedent(u"""\
528        '''The module docstring.'''
529        # -*- coding: utf-8 -*-
530        def f():
531            x = 37
532        """)
533
534    with utils.NamedTempFile(
535        suffix='.py', dirname=self.test_tmpdir) as (out, _):
536      with utils.TempFileContents(
537          self.test_tmpdir, unformatted_code, suffix='.py') as filepath:
538        try:
539          subprocess.check_call(YAPF_BINARY + ['--diff', filepath], stdout=out)
540        except subprocess.CalledProcessError as e:
541          self.assertEqual(e.returncode, 1)  # Indicates the text changed.
542
543  def testReformattingSpecificLines(self):
544    unformatted_code = textwrap.dedent("""\
545        def h():
546            if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'):
547                pass
548
549
550        def g():
551            if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'):
552                pass
553        """)
554    expected_formatted_code = textwrap.dedent("""\
555        def h():
556            if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and
557                    xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'):
558                pass
559
560
561        def g():
562            if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'):
563                pass
564        """)
565    # TODO(ambv): the `expected_formatted_code` here is not PEP8 compliant,
566    # raising "E129 visually indented line with same indent as next logical
567    # line" with flake8.
568    self.assertYapfReformats(
569        unformatted_code,
570        expected_formatted_code,
571        extra_options=['--lines', '1-2'])
572
573  def testOmitFormattingLinesBeforeDisabledFunctionComment(self):
574    unformatted_code = textwrap.dedent("""\
575        import sys
576
577        # Comment
578        def some_func(x):
579            x = ["badly" , "formatted","line" ]
580        """)
581    expected_formatted_code = textwrap.dedent("""\
582        import sys
583
584        # Comment
585        def some_func(x):
586            x = ["badly", "formatted", "line"]
587        """)
588    self.assertYapfReformats(
589        unformatted_code,
590        expected_formatted_code,
591        extra_options=['--lines', '5-5'])
592
593  def testReformattingSkippingLines(self):
594    unformatted_code = textwrap.dedent("""\
595        def h():
596            if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'):
597                pass
598
599        # yapf: disable
600        def g():
601            if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'):
602                pass
603        # yapf: enable
604        """)
605    expected_formatted_code = textwrap.dedent("""\
606        def h():
607            if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and
608                    xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'):
609                pass
610
611
612        # yapf: disable
613        def g():
614            if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'):
615                pass
616        # yapf: enable
617        """)
618    self.assertYapfReformats(unformatted_code, expected_formatted_code)
619
620  def testReformattingSkippingToEndOfFile(self):
621    unformatted_code = textwrap.dedent("""\
622        def h():
623            if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'):
624                pass
625
626        # yapf: disable
627        def g():
628            if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'):
629                pass
630
631        def f():
632            def e():
633                while (xxxxxxxxxxxxxxxxxxxxx(yyyyyyyyyyyyy[zzzzz]) == 'aaaaaaaaaaa' and
634                       xxxxxxxxxxxxxxxxxxxxx(yyyyyyyyyyyyy[zzzzz].aaaaaaaa[0]) ==
635                       'bbbbbbb'):
636                    pass
637        """)
638    expected_formatted_code = textwrap.dedent("""\
639        def h():
640            if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and
641                    xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'):
642                pass
643
644
645        # yapf: disable
646        def g():
647            if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'):
648                pass
649
650        def f():
651            def e():
652                while (xxxxxxxxxxxxxxxxxxxxx(yyyyyyyyyyyyy[zzzzz]) == 'aaaaaaaaaaa' and
653                       xxxxxxxxxxxxxxxxxxxxx(yyyyyyyyyyyyy[zzzzz].aaaaaaaa[0]) ==
654                       'bbbbbbb'):
655                    pass
656        """)
657    self.assertYapfReformats(unformatted_code, expected_formatted_code)
658
659  def testReformattingSkippingSingleLine(self):
660    unformatted_code = textwrap.dedent("""\
661        def h():
662            if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'):
663                pass
664
665        def g():
666            if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'):  # yapf: disable
667                pass
668        """)
669    expected_formatted_code = textwrap.dedent("""\
670        def h():
671            if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and
672                    xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'):
673                pass
674
675
676        def g():
677            if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'):  # yapf: disable
678                pass
679        """)
680    self.assertYapfReformats(unformatted_code, expected_formatted_code)
681
682  def testDisableWholeDataStructure(self):
683    unformatted_code = textwrap.dedent("""\
684        A = set([
685            'hello',
686            'world',
687        ])  # yapf: disable
688        """)
689    expected_formatted_code = textwrap.dedent("""\
690        A = set([
691            'hello',
692            'world',
693        ])  # yapf: disable
694        """)
695    self.assertYapfReformats(unformatted_code, expected_formatted_code)
696
697  def testDisableButAdjustIndentations(self):
698    unformatted_code = textwrap.dedent("""\
699        class SplitPenaltyTest(unittest.TestCase):
700          def testUnbreakable(self):
701            self._CheckPenalties(tree, [
702            ])  # yapf: disable
703        """)
704    expected_formatted_code = textwrap.dedent("""\
705        class SplitPenaltyTest(unittest.TestCase):
706            def testUnbreakable(self):
707                self._CheckPenalties(tree, [
708                ])  # yapf: disable
709        """)
710    self.assertYapfReformats(unformatted_code, expected_formatted_code)
711
712  def testRetainingHorizontalWhitespace(self):
713    unformatted_code = textwrap.dedent("""\
714        def h():
715            if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'):
716                pass
717
718        def g():
719            if (xxxxxxxxxxxx.yyyyyyyy        (zzzzzzzzzzzzz  [0]) ==     'aaaaaaaaaaa' and    xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'):  # yapf: disable
720                pass
721        """)
722    expected_formatted_code = textwrap.dedent("""\
723        def h():
724            if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and
725                    xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'):
726                pass
727
728
729        def g():
730            if (xxxxxxxxxxxx.yyyyyyyy        (zzzzzzzzzzzzz  [0]) ==     'aaaaaaaaaaa' and    xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'):  # yapf: disable
731                pass
732        """)
733    self.assertYapfReformats(unformatted_code, expected_formatted_code)
734
735  def testRetainingVerticalWhitespace(self):
736    unformatted_code = textwrap.dedent("""\
737        def h():
738            if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'):
739                pass
740
741        def g():
742
743
744            if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'):
745
746                pass
747        """)
748    expected_formatted_code = textwrap.dedent("""\
749        def h():
750            if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and
751                    xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'):
752                pass
753
754        def g():
755
756
757            if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'):
758
759                pass
760        """)
761    self.assertYapfReformats(
762        unformatted_code,
763        expected_formatted_code,
764        extra_options=['--lines', '1-2'])
765
766    unformatted_code = textwrap.dedent("""\
767
768
769        if a:     b
770
771
772        if c:
773            to_much      + indent
774
775            same
776
777
778
779        #comment
780
781        #   trailing whitespace
782        """)
783    expected_formatted_code = textwrap.dedent("""\
784        if a: b
785
786
787        if c:
788            to_much      + indent
789
790            same
791
792
793
794        #comment
795
796        #   trailing whitespace
797        """)
798    self.assertYapfReformats(
799        unformatted_code,
800        expected_formatted_code,
801        extra_options=['--lines', '3-3', '--lines', '13-13'])
802
803    unformatted_code = textwrap.dedent("""\
804        '''
805        docstring
806
807        '''
808
809        import blah
810        """)
811
812    self.assertYapfReformats(
813        unformatted_code, unformatted_code, extra_options=['--lines', '2-2'])
814
815  def testRetainingSemicolonsWhenSpecifyingLines(self):
816    unformatted_code = textwrap.dedent("""\
817        a = line_to_format
818        def f():
819            x = y + 42; z = n * 42
820            if True: a += 1 ; b += 1 ; c += 1
821        """)
822    expected_formatted_code = textwrap.dedent("""\
823        a = line_to_format
824
825
826        def f():
827            x = y + 42; z = n * 42
828            if True: a += 1 ; b += 1 ; c += 1
829        """)
830    self.assertYapfReformats(
831        unformatted_code,
832        expected_formatted_code,
833        extra_options=['--lines', '1-1'])
834
835  def testDisabledMultilineStrings(self):
836    unformatted_code = textwrap.dedent('''\
837        foo=42
838        def f():
839            email_text += """<html>This is a really long docstring that goes over the column limit and is multi-line.<br><br>
840        <b>Czar: </b>"""+despot["Nicholas"]+"""<br>
841        <b>Minion: </b>"""+serf["Dmitri"]+"""<br>
842        <b>Residence: </b>"""+palace["Winter"]+"""<br>
843        </body>
844        </html>"""
845        ''')
846    expected_formatted_code = textwrap.dedent('''\
847        foo = 42
848
849
850        def f():
851            email_text += """<html>This is a really long docstring that goes over the column limit and is multi-line.<br><br>
852        <b>Czar: </b>"""+despot["Nicholas"]+"""<br>
853        <b>Minion: </b>"""+serf["Dmitri"]+"""<br>
854        <b>Residence: </b>"""+palace["Winter"]+"""<br>
855        </body>
856        </html>"""
857        ''')
858    self.assertYapfReformats(
859        unformatted_code,
860        expected_formatted_code,
861        extra_options=['--lines', '1-1'])
862
863  def testDisableWhenSpecifyingLines(self):
864    unformatted_code = textwrap.dedent("""\
865        # yapf: disable
866        A = set([
867            'hello',
868            'world',
869        ])
870        # yapf: enable
871        B = set([
872            'hello',
873            'world',
874        ])  # yapf: disable
875        """)
876    expected_formatted_code = textwrap.dedent("""\
877        # yapf: disable
878        A = set([
879            'hello',
880            'world',
881        ])
882        # yapf: enable
883        B = set([
884            'hello',
885            'world',
886        ])  # yapf: disable
887        """)
888    self.assertYapfReformats(
889        unformatted_code,
890        expected_formatted_code,
891        extra_options=['--lines', '1-10'])
892
893  def testDisableFormattingInDataLiteral(self):
894    unformatted_code = textwrap.dedent("""\
895        def horrible():
896          oh_god()
897          why_would_you()
898          [
899             'do',
900
901              'that',
902          ]
903
904        def still_horrible():
905            oh_god()
906            why_would_you()
907            [
908                'do',
909
910                'that'
911            ]
912        """)
913    expected_formatted_code = textwrap.dedent("""\
914        def horrible():
915            oh_god()
916            why_would_you()
917            [
918               'do',
919
920                'that',
921            ]
922
923        def still_horrible():
924            oh_god()
925            why_would_you()
926            ['do', 'that']
927        """)
928    self.assertYapfReformats(
929        unformatted_code,
930        expected_formatted_code,
931        extra_options=['--lines', '14-15'])
932
933  def testRetainVerticalFormattingBetweenDisabledAndEnabledLines(self):
934    unformatted_code = textwrap.dedent("""\
935        class A(object):
936            def aaaaaaaaaaaaa(self):
937                c = bbbbbbbbb.ccccccccc('challenge', 0, 1, 10)
938                self.assertEqual(
939                    ('ddddddddddddddddddddddddd',
940             'eeeeeeeeeeeeeeeeeeeeeeeee.%s' %
941                     c.ffffffffffff),
942             gggggggggggg.hhhhhhhhh(c, c.ffffffffffff))
943                iiiii = jjjjjjjjjjjjjj.iiiii
944        """)
945    expected_formatted_code = textwrap.dedent("""\
946        class A(object):
947            def aaaaaaaaaaaaa(self):
948                c = bbbbbbbbb.ccccccccc('challenge', 0, 1, 10)
949                self.assertEqual(('ddddddddddddddddddddddddd',
950                                  'eeeeeeeeeeeeeeeeeeeeeeeee.%s' % c.ffffffffffff),
951                                 gggggggggggg.hhhhhhhhh(c, c.ffffffffffff))
952                iiiii = jjjjjjjjjjjjjj.iiiii
953        """)
954    self.assertYapfReformats(
955        unformatted_code,
956        expected_formatted_code,
957        extra_options=['--lines', '4-7'])
958
959  def testFormatLinesSpecifiedInMiddleOfExpression(self):
960    unformatted_code = textwrap.dedent("""\
961        class A(object):
962            def aaaaaaaaaaaaa(self):
963                c = bbbbbbbbb.ccccccccc('challenge', 0, 1, 10)
964                self.assertEqual(
965                    ('ddddddddddddddddddddddddd',
966             'eeeeeeeeeeeeeeeeeeeeeeeee.%s' %
967                     c.ffffffffffff),
968             gggggggggggg.hhhhhhhhh(c, c.ffffffffffff))
969                iiiii = jjjjjjjjjjjjjj.iiiii
970        """)
971    expected_formatted_code = textwrap.dedent("""\
972        class A(object):
973            def aaaaaaaaaaaaa(self):
974                c = bbbbbbbbb.ccccccccc('challenge', 0, 1, 10)
975                self.assertEqual(('ddddddddddddddddddddddddd',
976                                  'eeeeeeeeeeeeeeeeeeeeeeeee.%s' % c.ffffffffffff),
977                                 gggggggggggg.hhhhhhhhh(c, c.ffffffffffff))
978                iiiii = jjjjjjjjjjjjjj.iiiii
979        """)
980    self.assertYapfReformats(
981        unformatted_code,
982        expected_formatted_code,
983        extra_options=['--lines', '5-6'])
984
985  def testCommentFollowingMultilineString(self):
986    unformatted_code = textwrap.dedent("""\
987        def foo():
988            '''First line.
989            Second line.
990            '''  # comment
991            x = '''hello world'''  # second comment
992            return 42  # another comment
993        """)
994    expected_formatted_code = textwrap.dedent("""\
995        def foo():
996            '''First line.
997            Second line.
998            '''  # comment
999            x = '''hello world'''  # second comment
1000            return 42  # another comment
1001        """)
1002    self.assertYapfReformats(
1003        unformatted_code,
1004        expected_formatted_code,
1005        extra_options=['--lines', '1-1'])
1006
1007  def testDedentClosingBracket(self):
1008    # no line-break on the first argument, not dedenting closing brackets
1009    unformatted_code = textwrap.dedent("""\
1010      def overly_long_function_name(first_argument_on_the_same_line,
1011      second_argument_makes_the_line_too_long):
1012        pass
1013    """)
1014    expected_formatted_code = textwrap.dedent("""\
1015      def overly_long_function_name(first_argument_on_the_same_line,
1016                                    second_argument_makes_the_line_too_long):
1017          pass
1018    """)
1019    self.assertYapfReformats(
1020        unformatted_code,
1021        expected_formatted_code,
1022        extra_options=['--style=pep8'])
1023
1024    # TODO(ambv): currently the following produces the closing bracket on a new
1025    # line but indented to the opening bracket which is the worst of both
1026    # worlds. Expected behaviour would be to format as --style=pep8 does in
1027    # this case.
1028    # self.assertYapfReformats(unformatted_code, expected_formatted_code,
1029    #                          extra_options=['--style=facebook'])
1030
1031    # line-break before the first argument, dedenting closing brackets if set
1032    unformatted_code = textwrap.dedent("""\
1033      def overly_long_function_name(
1034        first_argument_on_the_same_line,
1035        second_argument_makes_the_line_too_long):
1036        pass
1037    """)
1038    # expected_formatted_pep8_code = textwrap.dedent("""\
1039    #   def overly_long_function_name(
1040    #           first_argument_on_the_same_line,
1041    #           second_argument_makes_the_line_too_long):
1042    #       pass
1043    # """)
1044    expected_formatted_fb_code = textwrap.dedent("""\
1045      def overly_long_function_name(
1046          first_argument_on_the_same_line, second_argument_makes_the_line_too_long
1047      ):
1048          pass
1049    """)
1050    self.assertYapfReformats(
1051        unformatted_code,
1052        expected_formatted_fb_code,
1053        extra_options=['--style=facebook'])
1054    # TODO(ambv): currently the following produces code that is not PEP8
1055    # compliant, raising "E125 continuation line with same indent as next
1056    # logical line" with flake8. Expected behaviour for PEP8 would be to use
1057    # double-indentation here.
1058    # self.assertYapfReformats(unformatted_code, expected_formatted_pep8_code,
1059    #                          extra_options=['--style=pep8'])
1060
1061  def testCoalesceBrackets(self):
1062    unformatted_code = textwrap.dedent("""\
1063       some_long_function_name_foo(
1064           {
1065               'first_argument_of_the_thing': id,
1066               'second_argument_of_the_thing': "some thing"
1067           }
1068       )""")
1069    expected_formatted_code = textwrap.dedent("""\
1070       some_long_function_name_foo({
1071           'first_argument_of_the_thing': id,
1072           'second_argument_of_the_thing': "some thing"
1073       })
1074       """)
1075    with utils.NamedTempFile(dirname=self.test_tmpdir, mode='w') as (f, name):
1076      f.write(
1077          textwrap.dedent(u'''\
1078          [style]
1079          column_limit=82
1080          coalesce_brackets = True
1081          '''))
1082      f.flush()
1083      self.assertYapfReformats(
1084          unformatted_code,
1085          expected_formatted_code,
1086          extra_options=['--style={0}'.format(name)])
1087
1088  def testPseudoParenSpaces(self):
1089    unformatted_code = textwrap.dedent("""\
1090        def foo():
1091          def bar():
1092            return {msg_id: author for author, msg_id in reader}
1093        """)
1094    expected_formatted_code = textwrap.dedent("""\
1095        def foo():
1096
1097          def bar():
1098            return {msg_id: author for author, msg_id in reader}
1099        """)
1100    self.assertYapfReformats(
1101        unformatted_code,
1102        expected_formatted_code,
1103        extra_options=['--lines', '1-1', '--style', 'chromium'])
1104
1105  def testMultilineCommentFormattingDisabled(self):
1106    unformatted_code = textwrap.dedent("""\
1107        # This is a comment
1108        FOO = {
1109            aaaaaaaa.ZZZ: [
1110                bbbbbbbbbb.Pop(),
1111                # Multiline comment.
1112                # Line two.
1113                bbbbbbbbbb.Pop(),
1114            ],
1115            'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx':
1116                ('yyyyy', zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz),
1117            '#': lambda x: x  # do nothing
1118        }
1119        """)
1120    expected_formatted_code = textwrap.dedent("""\
1121        # This is a comment
1122        FOO = {
1123            aaaaaaaa.ZZZ: [
1124                bbbbbbbbbb.Pop(),
1125                # Multiline comment.
1126                # Line two.
1127                bbbbbbbbbb.Pop(),
1128            ],
1129            'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx':
1130                ('yyyyy', zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz),
1131            '#': lambda x: x  # do nothing
1132        }
1133        """)
1134    self.assertYapfReformats(
1135        unformatted_code,
1136        expected_formatted_code,
1137        extra_options=['--lines', '1-1', '--style', 'chromium'])
1138
1139  def testTrailingCommentsWithDisabledFormatting(self):
1140    unformatted_code = textwrap.dedent("""\
1141        import os
1142
1143        SCOPES = [
1144            'hello world'  # This is a comment.
1145        ]
1146        """)
1147    expected_formatted_code = textwrap.dedent("""\
1148        import os
1149
1150        SCOPES = [
1151            'hello world'  # This is a comment.
1152        ]
1153        """)
1154    self.assertYapfReformats(
1155        unformatted_code,
1156        expected_formatted_code,
1157        extra_options=['--lines', '1-1', '--style', 'chromium'])
1158
1159  def testUseTabs(self):
1160    unformatted_code = """\
1161def foo_function():
1162 if True:
1163  pass
1164"""
1165    expected_formatted_code = """\
1166def foo_function():
1167	if True:
1168		pass
1169"""
1170    style_contents = u"""\
1171[style]
1172based_on_style = chromium
1173USE_TABS = true
1174INDENT_WIDTH=1
1175"""
1176    with utils.TempFileContents(self.test_tmpdir, style_contents) as stylepath:
1177      self.assertYapfReformats(
1178          unformatted_code,
1179          expected_formatted_code,
1180          extra_options=['--style={0}'.format(stylepath)])
1181
1182  def testUseTabsWith(self):
1183    unformatted_code = """\
1184def f():
1185  return ['hello', 'world',]
1186"""
1187    expected_formatted_code = """\
1188def f():
1189	return [
1190	    'hello',
1191	    'world',
1192	]
1193"""
1194    style_contents = u"""\
1195[style]
1196based_on_style = chromium
1197USE_TABS = true
1198INDENT_WIDTH=1
1199"""
1200    with utils.TempFileContents(self.test_tmpdir, style_contents) as stylepath:
1201      self.assertYapfReformats(
1202          unformatted_code,
1203          expected_formatted_code,
1204          extra_options=['--style={0}'.format(stylepath)])
1205
1206  def testUseTabsContinuationAlignStyleFixed(self):
1207    unformatted_code = """\
1208def foo_function(arg1, arg2, arg3):
1209  return ['hello', 'world',]
1210"""
1211    expected_formatted_code = """\
1212def foo_function(arg1, arg2,
1213		arg3):
1214	return [
1215			'hello',
1216			'world',
1217	]
1218"""
1219    style_contents = u"""\
1220[style]
1221based_on_style = chromium
1222USE_TABS = true
1223COLUMN_LIMIT=32
1224INDENT_WIDTH=4
1225CONTINUATION_INDENT_WIDTH=8
1226CONTINUATION_ALIGN_STYLE = fixed
1227"""
1228    with utils.TempFileContents(self.test_tmpdir, style_contents) as stylepath:
1229      self.assertYapfReformats(
1230          unformatted_code,
1231          expected_formatted_code,
1232          extra_options=['--style={0}'.format(stylepath)])
1233
1234  def testUseTabsContinuationAlignStyleVAlignRight(self):
1235    unformatted_code = """\
1236def foo_function(arg1, arg2, arg3):
1237  return ['hello', 'world',]
1238"""
1239    expected_formatted_code = """\
1240def foo_function(arg1, arg2,
1241					arg3):
1242	return [
1243			'hello',
1244			'world',
1245	]
1246"""
1247    style_contents = u"""\
1248[style]
1249based_on_style = chromium
1250USE_TABS = true
1251COLUMN_LIMIT=32
1252INDENT_WIDTH=4
1253CONTINUATION_INDENT_WIDTH=8
1254CONTINUATION_ALIGN_STYLE = valign-right
1255"""
1256    with utils.TempFileContents(self.test_tmpdir, style_contents) as stylepath:
1257      self.assertYapfReformats(
1258          unformatted_code,
1259          expected_formatted_code,
1260          extra_options=['--style={0}'.format(stylepath)])
1261
1262  def testStyleOutputRoundTrip(self):
1263    unformatted_code = textwrap.dedent("""\
1264        def foo_function():
1265          pass
1266        """)
1267    expected_formatted_code = textwrap.dedent("""\
1268        def foo_function():
1269            pass
1270        """)
1271
1272    with utils.NamedTempFile(dirname=self.test_tmpdir) as (stylefile,
1273                                                           stylepath):
1274      p = subprocess.Popen(
1275          YAPF_BINARY + ['--style-help'],
1276          stdout=stylefile,
1277          stdin=subprocess.PIPE,
1278          stderr=subprocess.PIPE)
1279      _, stderrdata = p.communicate()
1280      self.assertEqual(stderrdata, b'')
1281      self.assertYapfReformats(
1282          unformatted_code,
1283          expected_formatted_code,
1284          extra_options=['--style={0}'.format(stylepath)])
1285
1286  def testSpacingBeforeComments(self):
1287    unformatted_code = textwrap.dedent("""\
1288        A = 42
1289
1290
1291        # A comment
1292        def x():
1293            pass
1294        def _():
1295            pass
1296        """)
1297    expected_formatted_code = textwrap.dedent("""\
1298        A = 42
1299
1300
1301        # A comment
1302        def x():
1303            pass
1304        def _():
1305            pass
1306        """)
1307    self.assertYapfReformats(
1308        unformatted_code,
1309        expected_formatted_code,
1310        extra_options=['--lines', '1-2'])
1311
1312  def testSpacingBeforeCommentsInDicts(self):
1313    unformatted_code = textwrap.dedent("""\
1314        A=42
1315
1316        X = {
1317            # 'Valid' statuses.
1318            PASSED:  # Passed
1319                'PASSED',
1320            FAILED:  # Failed
1321                'FAILED',
1322            TIMED_OUT:  # Timed out.
1323                'FAILED',
1324            BORKED:  # Broken.
1325                'BROKEN'
1326        }
1327        """)
1328    expected_formatted_code = textwrap.dedent("""\
1329        A = 42
1330
1331        X = {
1332            # 'Valid' statuses.
1333            PASSED:  # Passed
1334                'PASSED',
1335            FAILED:  # Failed
1336                'FAILED',
1337            TIMED_OUT:  # Timed out.
1338                'FAILED',
1339            BORKED:  # Broken.
1340                'BROKEN'
1341        }
1342        """)
1343    self.assertYapfReformats(
1344        unformatted_code,
1345        expected_formatted_code,
1346        extra_options=['--style', 'chromium', '--lines', '1-1'])
1347
1348  @unittest.skipUnless(py3compat.PY36, 'Requires Python 3.6')
1349  def testCP936Encoding(self):
1350    unformatted_code = 'print("中文")\n'
1351    expected_formatted_code = 'print("中文")\n'
1352    self.assertYapfReformats(
1353        unformatted_code,
1354        expected_formatted_code,
1355        env={'PYTHONIOENCODING': 'cp936'})
1356
1357
1358class BadInputTest(unittest.TestCase):
1359  """Test yapf's behaviour when passed bad input."""
1360
1361  def testBadSyntax(self):
1362    code = '  a = 1\n'
1363    self.assertRaises(SyntaxError, yapf_api.FormatCode, code)
1364
1365
1366class DiffIndentTest(unittest.TestCase):
1367
1368  @staticmethod
1369  def _OwnStyle():
1370    my_style = style.CreatePEP8Style()
1371    my_style['INDENT_WIDTH'] = 3
1372    my_style['CONTINUATION_INDENT_WIDTH'] = 3
1373    return my_style
1374
1375  def _Check(self, unformatted_code, expected_formatted_code):
1376    formatted_code, _ = yapf_api.FormatCode(
1377        unformatted_code, style_config=style.SetGlobalStyle(self._OwnStyle()))
1378    self.assertEqual(expected_formatted_code, formatted_code)
1379
1380  def testSimple(self):
1381    unformatted_code = textwrap.dedent("""\
1382        for i in range(5):
1383         print('bar')
1384         """)
1385    expected_formatted_code = textwrap.dedent("""\
1386        for i in range(5):
1387           print('bar')
1388           """)
1389    self._Check(unformatted_code, expected_formatted_code)
1390
1391
1392if __name__ == '__main__':
1393  unittest.main()
1394