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