Home | History | Annotate | Download | only in test
      1 """Tests for scripts in the Tools directory.
      2 
      3 This file contains regression tests for some of the scripts found in the
      4 Tools directory of a Python checkout or tarball, such as reindent.py.
      5 """
      6 
      7 import os
      8 import sys
      9 import unittest
     10 import shutil
     11 import subprocess
     12 import sysconfig
     13 import tempfile
     14 import textwrap
     15 from test import test_support
     16 from test.script_helper import assert_python_ok, temp_dir
     17 
     18 if not sysconfig.is_python_build():
     19     # XXX some installers do contain the tools, should we detect that
     20     # and run the tests in that case too?
     21     raise unittest.SkipTest('test irrelevant for an installed Python')
     22 
     23 basepath = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))),
     24                         'Tools')
     25 scriptsdir = os.path.join(basepath, 'scripts')
     26 
     27 
     28 class ReindentTests(unittest.TestCase):
     29     script = os.path.join(scriptsdir, 'reindent.py')
     30 
     31     def test_noargs(self):
     32         assert_python_ok(self.script)
     33 
     34     def test_help(self):
     35         rc, out, err = assert_python_ok(self.script, '-h')
     36         self.assertEqual(out, b'')
     37         self.assertGreater(err, b'')
     38 
     39 
     40 class PindentTests(unittest.TestCase):
     41     script = os.path.join(scriptsdir, 'pindent.py')
     42 
     43     def assertFileEqual(self, fn1, fn2):
     44         with open(fn1) as f1, open(fn2) as f2:
     45             self.assertEqual(f1.readlines(), f2.readlines())
     46 
     47     def pindent(self, source, *args):
     48         proc = subprocess.Popen(
     49                 (sys.executable, self.script) + args,
     50                 stdin=subprocess.PIPE, stdout=subprocess.PIPE,
     51                 universal_newlines=True)
     52         out, err = proc.communicate(source)
     53         self.assertIsNone(err)
     54         return out
     55 
     56     def lstriplines(self, data):
     57         return '\n'.join(line.lstrip() for line in data.splitlines()) + '\n'
     58 
     59     def test_selftest(self):
     60         self.maxDiff = None
     61         with temp_dir() as directory:
     62             data_path = os.path.join(directory, '_test.py')
     63             with open(self.script) as f:
     64                 closed = f.read()
     65             with open(data_path, 'w') as f:
     66                 f.write(closed)
     67 
     68             rc, out, err = assert_python_ok(self.script, '-d', data_path)
     69             self.assertEqual(out, b'')
     70             self.assertEqual(err, b'')
     71             backup = data_path + '~'
     72             self.assertTrue(os.path.exists(backup))
     73             with open(backup) as f:
     74                 self.assertEqual(f.read(), closed)
     75             with open(data_path) as f:
     76                 clean = f.read()
     77             compile(clean, '_test.py', 'exec')
     78             self.assertEqual(self.pindent(clean, '-c'), closed)
     79             self.assertEqual(self.pindent(closed, '-d'), clean)
     80 
     81             rc, out, err = assert_python_ok(self.script, '-c', data_path)
     82             self.assertEqual(out, b'')
     83             self.assertEqual(err, b'')
     84             with open(backup) as f:
     85                 self.assertEqual(f.read(), clean)
     86             with open(data_path) as f:
     87                 self.assertEqual(f.read(), closed)
     88 
     89             broken = self.lstriplines(closed)
     90             with open(data_path, 'w') as f:
     91                 f.write(broken)
     92             rc, out, err = assert_python_ok(self.script, '-r', data_path)
     93             self.assertEqual(out, b'')
     94             self.assertEqual(err, b'')
     95             with open(backup) as f:
     96                 self.assertEqual(f.read(), broken)
     97             with open(data_path) as f:
     98                 indented = f.read()
     99             compile(indented, '_test.py', 'exec')
    100             self.assertEqual(self.pindent(broken, '-r'), indented)
    101 
    102     def pindent_test(self, clean, closed):
    103         self.assertEqual(self.pindent(clean, '-c'), closed)
    104         self.assertEqual(self.pindent(closed, '-d'), clean)
    105         broken = self.lstriplines(closed)
    106         self.assertEqual(self.pindent(broken, '-r', '-e', '-s', '4'), closed)
    107 
    108     def test_statements(self):
    109         clean = textwrap.dedent("""\
    110             if a:
    111                 pass
    112 
    113             if a:
    114                 pass
    115             else:
    116                 pass
    117 
    118             if a:
    119                 pass
    120             elif:
    121                 pass
    122             else:
    123                 pass
    124 
    125             while a:
    126                 break
    127 
    128             while a:
    129                 break
    130             else:
    131                 pass
    132 
    133             for i in a:
    134                 break
    135 
    136             for i in a:
    137                 break
    138             else:
    139                 pass
    140 
    141             try:
    142                 pass
    143             finally:
    144                 pass
    145 
    146             try:
    147                 pass
    148             except TypeError:
    149                 pass
    150             except ValueError:
    151                 pass
    152             else:
    153                 pass
    154 
    155             try:
    156                 pass
    157             except TypeError:
    158                 pass
    159             except ValueError:
    160                 pass
    161             finally:
    162                 pass
    163 
    164             with a:
    165                 pass
    166 
    167             class A:
    168                 pass
    169 
    170             def f():
    171                 pass
    172             """)
    173 
    174         closed = textwrap.dedent("""\
    175             if a:
    176                 pass
    177             # end if
    178 
    179             if a:
    180                 pass
    181             else:
    182                 pass
    183             # end if
    184 
    185             if a:
    186                 pass
    187             elif:
    188                 pass
    189             else:
    190                 pass
    191             # end if
    192 
    193             while a:
    194                 break
    195             # end while
    196 
    197             while a:
    198                 break
    199             else:
    200                 pass
    201             # end while
    202 
    203             for i in a:
    204                 break
    205             # end for
    206 
    207             for i in a:
    208                 break
    209             else:
    210                 pass
    211             # end for
    212 
    213             try:
    214                 pass
    215             finally:
    216                 pass
    217             # end try
    218 
    219             try:
    220                 pass
    221             except TypeError:
    222                 pass
    223             except ValueError:
    224                 pass
    225             else:
    226                 pass
    227             # end try
    228 
    229             try:
    230                 pass
    231             except TypeError:
    232                 pass
    233             except ValueError:
    234                 pass
    235             finally:
    236                 pass
    237             # end try
    238 
    239             with a:
    240                 pass
    241             # end with
    242 
    243             class A:
    244                 pass
    245             # end class A
    246 
    247             def f():
    248                 pass
    249             # end def f
    250             """)
    251         self.pindent_test(clean, closed)
    252 
    253     def test_multilevel(self):
    254         clean = textwrap.dedent("""\
    255             def foobar(a, b):
    256                 if a == b:
    257                     a = a+1
    258                 elif a < b:
    259                     b = b-1
    260                     if b > a: a = a-1
    261                 else:
    262                     print 'oops!'
    263             """)
    264         closed = textwrap.dedent("""\
    265             def foobar(a, b):
    266                 if a == b:
    267                     a = a+1
    268                 elif a < b:
    269                     b = b-1
    270                     if b > a: a = a-1
    271                     # end if
    272                 else:
    273                     print 'oops!'
    274                 # end if
    275             # end def foobar
    276             """)
    277         self.pindent_test(clean, closed)
    278 
    279     def test_preserve_indents(self):
    280         clean = textwrap.dedent("""\
    281             if a:
    282                      if b:
    283                               pass
    284             """)
    285         closed = textwrap.dedent("""\
    286             if a:
    287                      if b:
    288                               pass
    289                      # end if
    290             # end if
    291             """)
    292         self.assertEqual(self.pindent(clean, '-c'), closed)
    293         self.assertEqual(self.pindent(closed, '-d'), clean)
    294         broken = self.lstriplines(closed)
    295         self.assertEqual(self.pindent(broken, '-r', '-e', '-s', '9'), closed)
    296         clean = textwrap.dedent("""\
    297             if a:
    298             \tif b:
    299             \t\tpass
    300             """)
    301         closed = textwrap.dedent("""\
    302             if a:
    303             \tif b:
    304             \t\tpass
    305             \t# end if
    306             # end if
    307             """)
    308         self.assertEqual(self.pindent(clean, '-c'), closed)
    309         self.assertEqual(self.pindent(closed, '-d'), clean)
    310         broken = self.lstriplines(closed)
    311         self.assertEqual(self.pindent(broken, '-r'), closed)
    312 
    313     def test_escaped_newline(self):
    314         clean = textwrap.dedent("""\
    315             class\\
    316             \\
    317              A:
    318                def\
    319             \\
    320             f:
    321                   pass
    322             """)
    323         closed = textwrap.dedent("""\
    324             class\\
    325             \\
    326              A:
    327                def\
    328             \\
    329             f:
    330                   pass
    331                # end def f
    332             # end class A
    333             """)
    334         self.assertEqual(self.pindent(clean, '-c'), closed)
    335         self.assertEqual(self.pindent(closed, '-d'), clean)
    336 
    337     def test_empty_line(self):
    338         clean = textwrap.dedent("""\
    339             if a:
    340 
    341                 pass
    342             """)
    343         closed = textwrap.dedent("""\
    344             if a:
    345 
    346                 pass
    347             # end if
    348             """)
    349         self.pindent_test(clean, closed)
    350 
    351     def test_oneline(self):
    352         clean = textwrap.dedent("""\
    353             if a: pass
    354             """)
    355         closed = textwrap.dedent("""\
    356             if a: pass
    357             # end if
    358             """)
    359         self.pindent_test(clean, closed)
    360 
    361 
    362 def test_main():
    363     test_support.run_unittest(*[obj for obj in globals().values()
    364                                     if isinstance(obj, type)])
    365 
    366 
    367 if __name__ == '__main__':
    368     unittest.main()
    369