88import sys
99import imp
1010import unittest
11+ import shutil
12+ import subprocess
1113import sysconfig
1214import tempfile
15+ import textwrap
1316from test import support
14- from test .script_helper import assert_python_ok
17+ from test .script_helper import assert_python_ok , temp_dir
1518
1619if not sysconfig .is_python_build ():
1720 # XXX some installers do contain the tools, should we detect that
@@ -35,6 +38,327 @@ def test_help(self):
3538 self .assertGreater (err , b'' )
3639
3740
41+ class PindentTests (unittest .TestCase ):
42+ script = os .path .join (scriptsdir , 'pindent.py' )
43+
44+ def assertFileEqual (self , fn1 , fn2 ):
45+ with open (fn1 ) as f1 , open (fn2 ) as f2 :
46+ self .assertEqual (f1 .readlines (), f2 .readlines ())
47+
48+ def pindent (self , source , * args ):
49+ with subprocess .Popen (
50+ (sys .executable , self .script ) + args ,
51+ stdin = subprocess .PIPE , stdout = subprocess .PIPE ,
52+ universal_newlines = True ) as proc :
53+ out , err = proc .communicate (source .encode ())
54+ self .assertIsNone (err )
55+ return out
56+
57+ def lstriplines (self , data ):
58+ return '\n ' .join (line .lstrip () for line in data .splitlines ()) + '\n '
59+
60+ def test_selftest (self ):
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+ \t if b:
299+ \t \t pass
300+ """ )
301+ closed = textwrap .dedent ("""\
302+ if a:
303+ \t if b:
304+ \t \t pass
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+
38362class TestSundryScripts (unittest .TestCase ):
39363 # At least make sure the rest don't have syntax errors. When tests are
40364 # added for a script it should be added to the whitelist below.
0 commit comments