99import importlib .machinery
1010import unittest
1111from unittest import mock
12+ import shutil
13+ import subprocess
1214import sysconfig
1315import tempfile
16+ import textwrap
1417from test import support
15- from test .script_helper import assert_python_ok
18+ from test .script_helper import assert_python_ok , temp_dir
1619
1720if not sysconfig .is_python_build ():
1821 # XXX some installers do contain the tools, should we detect that
@@ -36,6 +39,327 @@ def test_help(self):
3639 self .assertGreater (err , b'' )
3740
3841
42+ class PindentTests (unittest .TestCase ):
43+ script = os .path .join (scriptsdir , 'pindent.py' )
44+
45+ def assertFileEqual (self , fn1 , fn2 ):
46+ with open (fn1 ) as f1 , open (fn2 ) as f2 :
47+ self .assertEqual (f1 .readlines (), f2 .readlines ())
48+
49+ def pindent (self , source , * args ):
50+ with subprocess .Popen (
51+ (sys .executable , self .script ) + args ,
52+ stdin = subprocess .PIPE , stdout = subprocess .PIPE ,
53+ universal_newlines = True ) as proc :
54+ out , err = proc .communicate (source )
55+ self .assertIsNone (err )
56+ return out
57+
58+ def lstriplines (self , data ):
59+ return '\n ' .join (line .lstrip () for line in data .splitlines ()) + '\n '
60+
61+ def test_selftest (self ):
62+ with temp_dir () as directory :
63+ data_path = os .path .join (directory , '_test.py' )
64+ with open (self .script ) as f :
65+ closed = f .read ()
66+ with open (data_path , 'w' ) as f :
67+ f .write (closed )
68+
69+ rc , out , err = assert_python_ok (self .script , '-d' , data_path )
70+ self .assertEqual (out , b'' )
71+ self .assertEqual (err , b'' )
72+ backup = data_path + '~'
73+ self .assertTrue (os .path .exists (backup ))
74+ with open (backup ) as f :
75+ self .assertEqual (f .read (), closed )
76+ with open (data_path ) as f :
77+ clean = f .read ()
78+ compile (clean , '_test.py' , 'exec' )
79+ self .assertEqual (self .pindent (clean , '-c' ), closed )
80+ self .assertEqual (self .pindent (closed , '-d' ), clean )
81+
82+ rc , out , err = assert_python_ok (self .script , '-c' , data_path )
83+ self .assertEqual (out , b'' )
84+ self .assertEqual (err , b'' )
85+ with open (backup ) as f :
86+ self .assertEqual (f .read (), clean )
87+ with open (data_path ) as f :
88+ self .assertEqual (f .read (), closed )
89+
90+ broken = self .lstriplines (closed )
91+ with open (data_path , 'w' ) as f :
92+ f .write (broken )
93+ rc , out , err = assert_python_ok (self .script , '-r' , data_path )
94+ self .assertEqual (out , b'' )
95+ self .assertEqual (err , b'' )
96+ with open (backup ) as f :
97+ self .assertEqual (f .read (), broken )
98+ with open (data_path ) as f :
99+ indented = f .read ()
100+ compile (indented , '_test.py' , 'exec' )
101+ self .assertEqual (self .pindent (broken , '-r' ), indented )
102+
103+ def pindent_test (self , clean , closed ):
104+ self .assertEqual (self .pindent (clean , '-c' ), closed )
105+ self .assertEqual (self .pindent (closed , '-d' ), clean )
106+ broken = self .lstriplines (closed )
107+ self .assertEqual (self .pindent (broken , '-r' , '-e' , '-s' , '4' ), closed )
108+
109+ def test_statements (self ):
110+ clean = textwrap .dedent ("""\
111+ if a:
112+ pass
113+
114+ if a:
115+ pass
116+ else:
117+ pass
118+
119+ if a:
120+ pass
121+ elif:
122+ pass
123+ else:
124+ pass
125+
126+ while a:
127+ break
128+
129+ while a:
130+ break
131+ else:
132+ pass
133+
134+ for i in a:
135+ break
136+
137+ for i in a:
138+ break
139+ else:
140+ pass
141+
142+ try:
143+ pass
144+ finally:
145+ pass
146+
147+ try:
148+ pass
149+ except TypeError:
150+ pass
151+ except ValueError:
152+ pass
153+ else:
154+ pass
155+
156+ try:
157+ pass
158+ except TypeError:
159+ pass
160+ except ValueError:
161+ pass
162+ finally:
163+ pass
164+
165+ with a:
166+ pass
167+
168+ class A:
169+ pass
170+
171+ def f():
172+ pass
173+ """ )
174+
175+ closed = textwrap .dedent ("""\
176+ if a:
177+ pass
178+ # end if
179+
180+ if a:
181+ pass
182+ else:
183+ pass
184+ # end if
185+
186+ if a:
187+ pass
188+ elif:
189+ pass
190+ else:
191+ pass
192+ # end if
193+
194+ while a:
195+ break
196+ # end while
197+
198+ while a:
199+ break
200+ else:
201+ pass
202+ # end while
203+
204+ for i in a:
205+ break
206+ # end for
207+
208+ for i in a:
209+ break
210+ else:
211+ pass
212+ # end for
213+
214+ try:
215+ pass
216+ finally:
217+ pass
218+ # end try
219+
220+ try:
221+ pass
222+ except TypeError:
223+ pass
224+ except ValueError:
225+ pass
226+ else:
227+ pass
228+ # end try
229+
230+ try:
231+ pass
232+ except TypeError:
233+ pass
234+ except ValueError:
235+ pass
236+ finally:
237+ pass
238+ # end try
239+
240+ with a:
241+ pass
242+ # end with
243+
244+ class A:
245+ pass
246+ # end class A
247+
248+ def f():
249+ pass
250+ # end def f
251+ """ )
252+ self .pindent_test (clean , closed )
253+
254+ def test_multilevel (self ):
255+ clean = textwrap .dedent ("""\
256+ def foobar(a, b):
257+ if a == b:
258+ a = a+1
259+ elif a < b:
260+ b = b-1
261+ if b > a: a = a-1
262+ else:
263+ print 'oops!'
264+ """ )
265+ closed = textwrap .dedent ("""\
266+ def foobar(a, b):
267+ if a == b:
268+ a = a+1
269+ elif a < b:
270+ b = b-1
271+ if b > a: a = a-1
272+ # end if
273+ else:
274+ print 'oops!'
275+ # end if
276+ # end def foobar
277+ """ )
278+ self .pindent_test (clean , closed )
279+
280+ def test_preserve_indents (self ):
281+ clean = textwrap .dedent ("""\
282+ if a:
283+ if b:
284+ pass
285+ """ )
286+ closed = textwrap .dedent ("""\
287+ if a:
288+ if b:
289+ pass
290+ # end if
291+ # end if
292+ """ )
293+ self .assertEqual (self .pindent (clean , '-c' ), closed )
294+ self .assertEqual (self .pindent (closed , '-d' ), clean )
295+ broken = self .lstriplines (closed )
296+ self .assertEqual (self .pindent (broken , '-r' , '-e' , '-s' , '9' ), closed )
297+ clean = textwrap .dedent ("""\
298+ if a:
299+ \t if b:
300+ \t \t pass
301+ """ )
302+ closed = textwrap .dedent ("""\
303+ if a:
304+ \t if b:
305+ \t \t pass
306+ \t # end if
307+ # end if
308+ """ )
309+ self .assertEqual (self .pindent (clean , '-c' ), closed )
310+ self .assertEqual (self .pindent (closed , '-d' ), clean )
311+ broken = self .lstriplines (closed )
312+ self .assertEqual (self .pindent (broken , '-r' ), closed )
313+
314+ def test_escaped_newline (self ):
315+ clean = textwrap .dedent ("""\
316+ class\\
317+ \\
318+ A:
319+ def\
320+ \\
321+ f:
322+ pass
323+ """ )
324+ closed = textwrap .dedent ("""\
325+ class\\
326+ \\
327+ A:
328+ def\
329+ \\
330+ f:
331+ pass
332+ # end def f
333+ # end class A
334+ """ )
335+ self .assertEqual (self .pindent (clean , '-c' ), closed )
336+ self .assertEqual (self .pindent (closed , '-d' ), clean )
337+
338+ def test_empty_line (self ):
339+ clean = textwrap .dedent ("""\
340+ if a:
341+
342+ pass
343+ """ )
344+ closed = textwrap .dedent ("""\
345+ if a:
346+
347+ pass
348+ # end if
349+ """ )
350+ self .pindent_test (clean , closed )
351+
352+ def test_oneline (self ):
353+ clean = textwrap .dedent ("""\
354+ if a: pass
355+ """ )
356+ closed = textwrap .dedent ("""\
357+ if a: pass
358+ # end if
359+ """ )
360+ self .pindent_test (clean , closed )
361+
362+
39363class TestSundryScripts (unittest .TestCase ):
40364 # At least make sure the rest don't have syntax errors. When tests are
41365 # added for a script it should be added to the whitelist below.
0 commit comments