1 # -*- coding: utf-8 -*-
8 from testsuite
.support
import ROOT_DIR
, PseudoFile
10 E11
= os
.path
.join(ROOT_DIR
, 'testsuite', 'E11.py')
13 class DummyChecker(object):
14 def __init__(self
, tree
, filename
):
22 class APITestCase(unittest
.TestCase
):
23 """Test the public methods."""
26 self
._saved
_stdout
= sys
.stdout
27 self
._saved
_stderr
= sys
.stderr
28 self
._saved
_checks
= pep8
._checks
29 sys
.stdout
= PseudoFile()
30 sys
.stderr
= PseudoFile()
31 pep8
._checks
= dict((k
, dict((f
, (vals
[0][:], vals
[1]))
32 for (f
, vals
) in v
.items()))
33 for (k
, v
) in self
._saved
_checks
.items())
36 sys
.stdout
= self
._saved
_stdout
37 sys
.stderr
= self
._saved
_stderr
38 pep8
._checks
= self
._saved
_checks
41 del sys
.stdout
[:], sys
.stderr
[:]
43 def test_register_physical_check(self
):
44 def check_dummy(physical_line
, line_number
):
47 pep8
.register_check(check_dummy
, ['Z001'])
49 self
.assertTrue(check_dummy
in pep8
._checks
['physical_line'])
50 codes
, args
= pep8
._checks
['physical_line'][check_dummy
]
51 self
.assertTrue('Z001' in codes
)
52 self
.assertEqual(args
, ['physical_line', 'line_number'])
54 options
= pep8
.StyleGuide().options
55 self
.assertTrue(any(func
== check_dummy
56 for name
, func
, args
in options
.physical_checks
))
58 def test_register_logical_check(self
):
59 def check_dummy(logical_line
, tokens
):
62 pep8
.register_check(check_dummy
, ['Z401'])
64 self
.assertTrue(check_dummy
in pep8
._checks
['logical_line'])
65 codes
, args
= pep8
._checks
['logical_line'][check_dummy
]
66 self
.assertTrue('Z401' in codes
)
67 self
.assertEqual(args
, ['logical_line', 'tokens'])
69 pep8
.register_check(check_dummy
, [])
70 pep8
.register_check(check_dummy
, ['Z402', 'Z403'])
71 codes
, args
= pep8
._checks
['logical_line'][check_dummy
]
72 self
.assertEqual(codes
, ['Z401', 'Z402', 'Z403'])
73 self
.assertEqual(args
, ['logical_line', 'tokens'])
75 options
= pep8
.StyleGuide().options
76 self
.assertTrue(any(func
== check_dummy
77 for name
, func
, args
in options
.logical_checks
))
79 def test_register_ast_check(self
):
80 pep8
.register_check(DummyChecker
, ['Z701'])
82 self
.assertTrue(DummyChecker
in pep8
._checks
['tree'])
83 codes
, args
= pep8
._checks
['tree'][DummyChecker
]
84 self
.assertTrue('Z701' in codes
)
85 self
.assertTrue(args
is None)
87 options
= pep8
.StyleGuide().options
88 self
.assertTrue(any(cls
== DummyChecker
89 for name
, cls
, args
in options
.ast_checks
))
91 def test_register_invalid_check(self
):
92 class InvalidChecker(DummyChecker
):
93 def __init__(self
, filename
):
96 def check_dummy(logical
, tokens
):
99 pep8
.register_check(InvalidChecker
, ['Z741'])
100 pep8
.register_check(check_dummy
, ['Z441'])
102 for checkers
in pep8
._checks
.values():
103 self
.assertTrue(DummyChecker
not in checkers
)
104 self
.assertTrue(check_dummy
not in checkers
)
106 self
.assertRaises(TypeError, pep8
.register_check
)
108 def test_styleguide(self
):
109 report
= pep8
.StyleGuide().check_files()
110 self
.assertEqual(report
.total_errors
, 0)
111 self
.assertFalse(sys
.stdout
)
112 self
.assertFalse(sys
.stderr
)
115 report
= pep8
.StyleGuide().check_files(['missing-file'])
116 stdout
= sys
.stdout
.getvalue().splitlines()
117 self
.assertEqual(len(stdout
), report
.total_errors
)
118 self
.assertEqual(report
.total_errors
, 1)
119 # < 3.3 returns IOError; >= 3.3 returns FileNotFoundError
120 self
.assertTrue(stdout
[0].startswith("missing-file:1:1: E902 "))
121 self
.assertFalse(sys
.stderr
)
124 report
= pep8
.StyleGuide().check_files([E11
])
125 stdout
= sys
.stdout
.getvalue().splitlines()
126 self
.assertEqual(len(stdout
), report
.total_errors
)
127 self
.assertEqual(report
.total_errors
, 17)
128 self
.assertFalse(sys
.stderr
)
131 # Passing the paths in the constructor gives same result
132 report
= pep8
.StyleGuide(paths
=[E11
]).check_files()
133 stdout
= sys
.stdout
.getvalue().splitlines()
134 self
.assertEqual(len(stdout
), report
.total_errors
)
135 self
.assertEqual(report
.total_errors
, 17)
136 self
.assertFalse(sys
.stderr
)
139 def test_styleguide_options(self
):
140 # Instanciate a simple checker
141 pep8style
= pep8
.StyleGuide(paths
=[E11
])
143 # Check style's attributes
144 self
.assertEqual(pep8style
.checker_class
, pep8
.Checker
)
145 self
.assertEqual(pep8style
.paths
, [E11
])
146 self
.assertEqual(pep8style
.runner
, pep8style
.input_file
)
147 self
.assertEqual(pep8style
.options
.ignore_code
, pep8style
.ignore_code
)
148 self
.assertEqual(pep8style
.options
.paths
, pep8style
.paths
)
150 # Check unset options
151 for o
in ('benchmark', 'config', 'count', 'diff',
152 'doctest', 'quiet', 'show_pep8', 'show_source',
153 'statistics', 'testsuite', 'verbose'):
154 oval
= getattr(pep8style
.options
, o
)
155 self
.assertTrue(oval
in (None, False), msg
='%s = %r' % (o
, oval
))
157 # Check default options
158 self
.assertTrue(pep8style
.options
.repeat
)
159 self
.assertEqual(pep8style
.options
.benchmark_keys
,
160 ['directories', 'files',
161 'logical lines', 'physical lines'])
162 self
.assertEqual(pep8style
.options
.exclude
,
163 ['.svn', 'CVS', '.bzr', '.hg',
164 '.git', '__pycache__', '.tox'])
165 self
.assertEqual(pep8style
.options
.filename
, ['*.py'])
166 self
.assertEqual(pep8style
.options
.format
, 'default')
167 self
.assertEqual(pep8style
.options
.select
, ())
168 self
.assertEqual(pep8style
.options
.ignore
, ('E226', 'E24'))
169 self
.assertEqual(pep8style
.options
.max_line_length
, 79)
171 def test_styleguide_ignore_code(self
):
172 def parse_argv(argstring
):
173 _saved_argv
= sys
.argv
174 sys
.argv
= shlex
.split('pep8 %s /dev/null' % argstring
)
176 return pep8
.StyleGuide(parse_argv
=True)
178 sys
.argv
= _saved_argv
180 options
= parse_argv('').options
181 self
.assertEqual(options
.select
, ())
184 ('E121', 'E123', 'E126', 'E226', 'E24', 'E704')
187 options
= parse_argv('--doctest').options
188 self
.assertEqual(options
.select
, ())
189 self
.assertEqual(options
.ignore
, ())
191 options
= parse_argv('--ignore E,W').options
192 self
.assertEqual(options
.select
, ())
193 self
.assertEqual(options
.ignore
, ('E', 'W'))
195 options
= parse_argv('--select E,W').options
196 self
.assertEqual(options
.select
, ('E', 'W'))
197 self
.assertEqual(options
.ignore
, ('',))
199 options
= parse_argv('--select E --ignore E24').options
200 self
.assertEqual(options
.select
, ('E',))
201 self
.assertEqual(options
.ignore
, ('',))
203 options
= parse_argv('--ignore E --select E24').options
204 self
.assertEqual(options
.select
, ('E24',))
205 self
.assertEqual(options
.ignore
, ('',))
207 options
= parse_argv('--ignore W --select E24').options
208 self
.assertEqual(options
.select
, ('E24',))
209 self
.assertEqual(options
.ignore
, ('',))
211 pep8style
= pep8
.StyleGuide(paths
=[E11
])
212 self
.assertFalse(pep8style
.ignore_code('E112'))
213 self
.assertFalse(pep8style
.ignore_code('W191'))
214 self
.assertTrue(pep8style
.ignore_code('E241'))
216 pep8style
= pep8
.StyleGuide(select
='E', paths
=[E11
])
217 self
.assertFalse(pep8style
.ignore_code('E112'))
218 self
.assertTrue(pep8style
.ignore_code('W191'))
219 self
.assertFalse(pep8style
.ignore_code('E241'))
221 pep8style
= pep8
.StyleGuide(select
='W', paths
=[E11
])
222 self
.assertTrue(pep8style
.ignore_code('E112'))
223 self
.assertFalse(pep8style
.ignore_code('W191'))
224 self
.assertTrue(pep8style
.ignore_code('E241'))
226 pep8style
= pep8
.StyleGuide(select
=('F401',), paths
=[E11
])
227 self
.assertEqual(pep8style
.options
.select
, ('F401',))
228 self
.assertEqual(pep8style
.options
.ignore
, ('',))
229 self
.assertFalse(pep8style
.ignore_code('F'))
230 self
.assertFalse(pep8style
.ignore_code('F401'))
231 self
.assertTrue(pep8style
.ignore_code('F402'))
233 def test_styleguide_excluded(self
):
234 pep8style
= pep8
.StyleGuide(paths
=[E11
])
236 self
.assertFalse(pep8style
.excluded('./foo/bar'))
237 self
.assertFalse(pep8style
.excluded('./foo/bar/main.py'))
239 self
.assertTrue(pep8style
.excluded('./CVS'))
240 self
.assertTrue(pep8style
.excluded('./.tox'))
241 self
.assertTrue(pep8style
.excluded('./subdir/CVS'))
242 self
.assertTrue(pep8style
.excluded('__pycache__'))
243 self
.assertTrue(pep8style
.excluded('./__pycache__'))
244 self
.assertTrue(pep8style
.excluded('subdir/__pycache__'))
246 self
.assertFalse(pep8style
.excluded('draftCVS'))
247 self
.assertFalse(pep8style
.excluded('./CVSoup'))
248 self
.assertFalse(pep8style
.excluded('./CVS/subdir'))
250 def test_styleguide_checks(self
):
251 pep8style
= pep8
.StyleGuide(paths
=[E11
])
253 # Default lists of checkers
254 self
.assertTrue(len(pep8style
.options
.physical_checks
) > 4)
255 self
.assertTrue(len(pep8style
.options
.logical_checks
) > 10)
256 self
.assertEqual(len(pep8style
.options
.ast_checks
), 0)
259 for name
, check
, args
in pep8style
.options
.physical_checks
:
260 self
.assertEqual(check
.__name
__, name
)
261 self
.assertEqual(args
[0], 'physical_line')
262 for name
, check
, args
in pep8style
.options
.logical_checks
:
263 self
.assertEqual(check
.__name
__, name
)
264 self
.assertEqual(args
[0], 'logical_line')
267 options
= pep8
.StyleGuide().options
268 self
.assertTrue(any(func
== pep8
.indentation
269 for name
, func
, args
in options
.logical_checks
))
270 options
= pep8
.StyleGuide(select
=['E']).options
271 self
.assertTrue(any(func
== pep8
.indentation
272 for name
, func
, args
in options
.logical_checks
))
273 options
= pep8
.StyleGuide(ignore
=['W']).options
274 self
.assertTrue(any(func
== pep8
.indentation
275 for name
, func
, args
in options
.logical_checks
))
276 options
= pep8
.StyleGuide(ignore
=['E12']).options
277 self
.assertTrue(any(func
== pep8
.indentation
278 for name
, func
, args
in options
.logical_checks
))
280 # Do not run E11 checks
281 options
= pep8
.StyleGuide(select
=['W']).options
282 self
.assertFalse(any(func
== pep8
.indentation
283 for name
, func
, args
in options
.logical_checks
))
284 options
= pep8
.StyleGuide(ignore
=['E']).options
285 self
.assertFalse(any(func
== pep8
.indentation
286 for name
, func
, args
in options
.logical_checks
))
287 options
= pep8
.StyleGuide(ignore
=['E11']).options
288 self
.assertFalse(any(func
== pep8
.indentation
289 for name
, func
, args
in options
.logical_checks
))
291 def test_styleguide_init_report(self
):
292 pep8style
= pep8
.StyleGuide(paths
=[E11
])
294 self
.assertEqual(pep8style
.options
.reporter
, pep8
.StandardReport
)
295 self
.assertEqual(type(pep8style
.options
.report
), pep8
.StandardReport
)
297 class MinorityReport(pep8
.BaseReport
):
300 report
= pep8style
.init_report(MinorityReport
)
301 self
.assertEqual(pep8style
.options
.report
, report
)
302 self
.assertEqual(type(report
), MinorityReport
)
304 pep8style
= pep8
.StyleGuide(paths
=[E11
], reporter
=MinorityReport
)
305 self
.assertEqual(type(pep8style
.options
.report
), MinorityReport
)
306 self
.assertEqual(pep8style
.options
.reporter
, MinorityReport
)
308 def test_styleguide_check_files(self
):
309 pep8style
= pep8
.StyleGuide(paths
=[E11
])
311 report
= pep8style
.check_files()
312 self
.assertTrue(report
.total_errors
)
314 self
.assertRaises(TypeError, pep8style
.check_files
, 42)
315 # < 3.3 raises TypeError; >= 3.3 raises AttributeError
316 self
.assertRaises(Exception, pep8style
.check_files
, [42])
318 def test_check_unicode(self
):
319 # Do not crash if lines are Unicode (Python 2.x)
320 pep8
.register_check(DummyChecker
, ['Z701'])
322 if hasattr(source
, 'decode'):
323 source
= source
.decode('ascii')
325 pep8style
= pep8
.StyleGuide()
326 count_errors
= pep8style
.input_file('stdin', lines
=[source
])
328 self
.assertFalse(sys
.stdout
)
329 self
.assertFalse(sys
.stderr
)
330 self
.assertEqual(count_errors
, 0)
332 def test_check_nullbytes(self
):
333 pep8
.register_check(DummyChecker
, ['Z701'])
335 pep8style
= pep8
.StyleGuide()
336 count_errors
= pep8style
.input_file('stdin', lines
=['\x00\n'])
338 stdout
= sys
.stdout
.getvalue()
339 if 'SyntaxError' in stdout
:
340 # PyPy 2.2 returns a SyntaxError
341 expected
= "stdin:1:2: E901 SyntaxError"
343 expected
= "stdin:1:1: E901 TypeError"
344 self
.assertTrue(stdout
.startswith(expected
),
345 msg
='Output %r does not start with %r' %
347 self
.assertFalse(sys
.stderr
)
348 self
.assertEqual(count_errors
, 1)
350 def test_styleguide_unmatched_triple_quotes(self
):
351 pep8
.register_check(DummyChecker
, ['Z701'])
354 ' """test docstring""\'\n',
357 pep8style
= pep8
.StyleGuide()
358 pep8style
.input_file('stdin', lines
=lines
)
359 stdout
= sys
.stdout
.getvalue()
361 expected
= 'stdin:2:5: E901 TokenError: EOF in multi-line string'
362 self
.assertTrue(expected
in stdout
)
364 def test_styleguide_continuation_line_outdented(self
):
365 pep8
.register_check(DummyChecker
, ['Z701'])
376 pep8style
= pep8
.StyleGuide()
377 count_errors
= pep8style
.input_file('stdin', lines
=lines
)
378 self
.assertEqual(count_errors
, 2)
379 stdout
= sys
.stdout
.getvalue()
382 'E122 continuation line missing indentation or outdented'
384 self
.assertTrue(expected
in stdout
)
385 expected
= 'stdin:6:1: E302 expected 2 blank lines, found 1'
386 self
.assertTrue(expected
in stdout
)