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