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