diff options
author | Florent Xicluna <florent.xicluna@gmail.com> | 2013-03-02 00:24:54 +0100 |
---|---|---|
committer | Florent Xicluna <florent.xicluna@gmail.com> | 2013-03-02 00:24:54 +0100 |
commit | 7b590ade7ce794056cd9c612f12bbd357f8289b1 (patch) | |
tree | cdfe831b7c4c167f36bc876383dea7db8c5f8bfc | |
parent | 8be7ca6a8c06cddbae27f6420cb3997313f83cc2 (diff) | |
download | pep8-7b590ade7ce794056cd9c612f12bbd357f8289b1.tar.gz |
Add more tests for the CLI; issue #162
-rw-r--r-- | CHANGES.txt | 3 | ||||
-rwxr-xr-x | pep8.py | 2 | ||||
-rw-r--r-- | testsuite/support.py | 8 | ||||
-rw-r--r-- | testsuite/test_all.py | 81 | ||||
-rw-r--r-- | testsuite/test_api.py | 81 | ||||
-rw-r--r-- | testsuite/test_shell.py | 193 |
6 files changed, 288 insertions, 80 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index 7c196e0..c391bf6 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -20,7 +20,8 @@ Changelog * Do not report false E302 when the source file has a coding cookie or a comment on the first line. (Issue #174) -* Reorganize the tests and add basic tests for the API. (Issue #161) +* Reorganize the tests and add tests for the API and for the command line + usage and options. (Issues #161 and #162) 1.4.4 (2013-02-24) @@ -1845,7 +1845,7 @@ def _main(): options = pep8style.options if options.doctest or options.testsuite: from testsuite.support import run_tests - report = run_tests(pep8style, options.doctest, options.testsuite) + report = run_tests(pep8style) else: report = pep8style.check_files() if options.statistics: diff --git a/testsuite/support.py b/testsuite/support.py index bcdcc19..0c107c3 100644 --- a/testsuite/support.py +++ b/testsuite/support.py @@ -1,10 +1,12 @@ # -*- coding: utf-8 -*- +import os.path import re import sys from pep8 import Checker, BaseReport, StandardReport, readlines SELFTEST_REGEX = re.compile(r'\b(Okay|[EW]\d{3}):\s(.*)') +ROOT_DIR = os.path.dirname(os.path.dirname(__file__)) class TestReport(StandardReport): @@ -141,9 +143,9 @@ def init_tests(pep8style): init_tests.__test__ = False -def run_tests(style, doctest=True, testsuite=False): +def run_tests(style): options = style.options - if doctest: + if options.doctest: import doctest fail_d, done_d = doctest.testmod(report=False, verbose=options.verbose) fail_s, done_s = selftest(options) @@ -154,7 +156,7 @@ def run_tests(style, doctest=True, testsuite=False): print("Test failed." if count_failed else "Test passed.") if count_failed: sys.exit(1) - if testsuite: + if options.testsuite: init_tests(style) return style.check_files() run_tests.__test__ = False diff --git a/testsuite/test_all.py b/testsuite/test_all.py index f547c5f..2299f92 100644 --- a/testsuite/test_all.py +++ b/testsuite/test_all.py @@ -5,9 +5,7 @@ import sys import unittest import pep8 -from testsuite.support import init_tests, selftest - -ROOT_DIR = os.path.dirname(os.path.dirname(__file__)) +from testsuite.support import init_tests, selftest, ROOT_DIR # Note: please only use a subset of unittest methods which were present # in Python 2.5: assert(True|False|Equal|NotEqual|Raises) @@ -18,7 +16,7 @@ class Pep8TestCase(unittest.TestCase): def setUp(self): self._style = pep8.StyleGuide( - paths=[os.path.dirname(__file__)], + paths=[os.path.join(ROOT_DIR, 'testsuite')], ignore=None, quiet=True) def test_doctest(self): @@ -47,81 +45,14 @@ class Pep8TestCase(unittest.TestCase): msg='Failures: %s' % report.messages) -class APITestCase(unittest.TestCase): - """Test the public methods.""" - - def setUp(self): - self._saved_checks = pep8._checks - pep8._checks = dict((k, dict((f, (vals[0][:], vals[1])) - for (f, vals) in v.items())) - for (k, v) in self._saved_checks.items()) - - def tearDown(self): - pep8._checks = self._saved_checks - - def test_register_physical_check(self): - def check_dummy(physical_line, line_number): - if False: - yield - pep8.register_check(check_dummy, ['Z001']) - - self.assertTrue(check_dummy in pep8._checks['physical_line']) - codes, args = pep8._checks['physical_line'][check_dummy] - self.assertTrue('Z001' in codes) - self.assertEqual(args, ['physical_line', 'line_number']) - - def test_register_logical_check(self): - def check_dummy(logical_line, tokens): - if False: - yield - pep8.register_check(check_dummy, ['Z401']) - - self.assertTrue(check_dummy in pep8._checks['logical_line']) - codes, args = pep8._checks['logical_line'][check_dummy] - self.assertTrue('Z401' in codes) - self.assertEqual(args, ['logical_line', 'tokens']) - - def test_register_ast_check(self): - class DummyChecker(object): - def __init__(self, tree, filename): - pass - - def run(self): - if False: - yield - pep8.register_check(DummyChecker, ['Z701']) - - self.assertTrue(DummyChecker in pep8._checks['tree']) - codes, args = pep8._checks['tree'][DummyChecker] - self.assertTrue('Z701' in codes) - self.assertTrue(args is None) - - def test_register_invalid_check(self): - class DummyChecker(object): - def __init__(self, filename): - pass - - def run(self): - if False: - yield - pep8.register_check(DummyChecker, ['Z741']) - - def check_dummy(logical, tokens): - if False: - yield - pep8.register_check(check_dummy, ['Z441']) - - for checkers in pep8._checks.values(): - self.assertTrue(DummyChecker not in checkers) - self.assertTrue(check_dummy not in checkers) - - self.assertRaises(TypeError, pep8.register_check) - - def _main(): + from testsuite.test_api import APITestCase + from testsuite.test_shell import ShellTestCase + suite = unittest.TestSuite() suite.addTest(unittest.makeSuite(Pep8TestCase)) suite.addTest(unittest.makeSuite(APITestCase)) + suite.addTest(unittest.makeSuite(ShellTestCase)) runner = unittest.TextTestRunner(verbosity=2) return runner.run(suite) diff --git a/testsuite/test_api.py b/testsuite/test_api.py new file mode 100644 index 0000000..4fac0f5 --- /dev/null +++ b/testsuite/test_api.py @@ -0,0 +1,81 @@ +# -*- coding: utf-8 -*- +import unittest + +import pep8 + + +class APITestCase(unittest.TestCase): + """Test the public methods.""" + + def setUp(self): + self._saved_checks = pep8._checks + pep8._checks = dict((k, dict((f, (vals[0][:], vals[1])) + for (f, vals) in v.items())) + for (k, v) in self._saved_checks.items()) + + def tearDown(self): + pep8._checks = self._saved_checks + + def test_register_physical_check(self): + def check_dummy(physical_line, line_number): + if False: + yield + pep8.register_check(check_dummy, ['Z001']) + + self.assertTrue(check_dummy in pep8._checks['physical_line']) + codes, args = pep8._checks['physical_line'][check_dummy] + self.assertTrue('Z001' in codes) + self.assertEqual(args, ['physical_line', 'line_number']) + + def test_register_logical_check(self): + def check_dummy(logical_line, tokens): + if False: + yield + pep8.register_check(check_dummy, ['Z401']) + + self.assertTrue(check_dummy in pep8._checks['logical_line']) + codes, args = pep8._checks['logical_line'][check_dummy] + self.assertTrue('Z401' in codes) + self.assertEqual(args, ['logical_line', 'tokens']) + + pep8.register_check(check_dummy, []) + pep8.register_check(check_dummy, ['Z402', 'Z403']) + codes, args = pep8._checks['logical_line'][check_dummy] + self.assertEqual(codes, ['Z401', 'Z402', 'Z403']) + self.assertEqual(args, ['logical_line', 'tokens']) + + def test_register_ast_check(self): + class DummyChecker(object): + def __init__(self, tree, filename): + pass + + def run(self): + if False: + yield + pep8.register_check(DummyChecker, ['Z701']) + + self.assertTrue(DummyChecker in pep8._checks['tree']) + codes, args = pep8._checks['tree'][DummyChecker] + self.assertTrue('Z701' in codes) + self.assertTrue(args is None) + + def test_register_invalid_check(self): + class DummyChecker(object): + def __init__(self, filename): + pass + + def run(self): + if False: + yield + pep8.register_check(DummyChecker, ['Z741']) + + def check_dummy(logical, tokens): + if False: + yield + pep8.register_check(check_dummy, ['Z441']) + + for checkers in pep8._checks.values(): + self.assertTrue(DummyChecker not in checkers) + self.assertTrue(check_dummy not in checkers) + + self.assertRaises(TypeError, pep8.register_check) diff --git a/testsuite/test_shell.py b/testsuite/test_shell.py new file mode 100644 index 0000000..7c88efb --- /dev/null +++ b/testsuite/test_shell.py @@ -0,0 +1,193 @@ +# -*- coding: utf-8 -*- +import os.path +import sys +import unittest + +import pep8 +from testsuite.support import ROOT_DIR + + +class PseudoFile(list): + """Simplified file interface.""" + write = list.append + + def __str__(self): + return ''.join(self) + + +class ShellTestCase(unittest.TestCase): + """Test the usual CLI options and output.""" + + def setUp(self): + self._saved_argv = sys.argv + self._saved_stdout = sys.stdout + self._saved_stderr = sys.stderr + self._saved_pconfig = pep8.PROJECT_CONFIG + self._saved_cpread = pep8.RawConfigParser.read + self._saved_stdin_get_value = pep8.stdin_get_value + self._config_filenames = [] + self.stdin = '' + sys.argv = ['pep8'] + sys.stdout = PseudoFile() + sys.stderr = PseudoFile() + pep8.RawConfigParser.read = self._config_filenames.append + pep8.stdin_get_value = self.stdin_get_value + + def tearDown(self): + sys.argv = self._saved_argv + sys.stdout = self._saved_stdout + sys.stderr = self._saved_stderr + pep8.PROJECT_CONFIG = self._saved_pconfig + pep8.RawConfigParser.read = self._saved_cpread + pep8.stdin_get_value = self._saved_stdin_get_value + + def stdin_get_value(self): + return self.stdin + + def pep8(self, *args): + del sys.stdout[:], sys.stderr[:] + sys.argv[1:] = args + try: + pep8._main() + errorcode = None + except SystemExit: + errorcode = sys.exc_info()[1].code + return str(sys.stdout), str(sys.stderr), errorcode + + def test_print_usage(self): + stdout, stderr, errcode = self.pep8('--help') + self.assertFalse(errcode) + self.assertFalse(stderr) + self.assertTrue(stdout.startswith("Usage: pep8 [options] input")) + + stdout, stderr, errcode = self.pep8('--version') + self.assertFalse(errcode) + self.assertFalse(stderr) + self.assertEqual(stdout.count('\n'), 1) + + stdout, stderr, errcode = self.pep8('--obfuscated') + self.assertEqual(errcode, 2) + self.assertEqual(stderr.splitlines(), + ["Usage: pep8 [options] input ...", "", + "pep8: error: no such option: --obfuscated"]) + self.assertFalse(stdout) + + self.assertFalse(self._config_filenames) + + def test_check_simple(self): + E11 = os.path.join(ROOT_DIR, 'testsuite', 'E11.py') + stdout, stderr, errcode = self.pep8(E11) + stdout = stdout.splitlines() + self.assertEqual(errcode, 1) + self.assertFalse(stderr) + self.assertEqual(len(stdout), 4) + for line, num, col in zip(stdout, (3, 6, 9, 12), (3, 6, 1, 5)): + path, x, y, msg = line.split(':') + self.assertTrue(path.endswith(E11)) + self.assertEqual(x, str(num)) + self.assertEqual(y, str(col)) + self.assertTrue(msg.startswith(' E11')) + # Config file read from the pep8's tox.ini + (config_filename,) = self._config_filenames + self.assertTrue(config_filename.endswith('tox.ini')) + + def test_check_stdin(self): + pep8.PROJECT_CONFIG = () + stdout, stderr, errcode = self.pep8('-') + self.assertFalse(errcode) + self.assertFalse(stderr) + self.assertFalse(stdout) + + self.stdin = 'import os, sys\n' + stdout, stderr, errcode = self.pep8('-') + stdout = stdout.splitlines() + self.assertEqual(errcode, 1) + self.assertFalse(stderr) + self.assertEqual(stdout, + ['stdin:1:10: E401 multiple imports on one line']) + + def test_check_non_existent(self): + self.stdin = 'import os, sys\n' + stdout, stderr, errcode = self.pep8('fictitious.py') + self.assertEqual(errcode, 1) + self.assertFalse(stderr) + self.assertTrue(stdout.startswith('fictitious.py:1:1: E902 ')) + + def test_check_noarg(self): + # issue #170: do not read stdin by default + pep8.PROJECT_CONFIG = () + stdout, stderr, errcode = self.pep8() + self.assertEqual(errcode, 2) + self.assertEqual(stderr.splitlines(), + ["Usage: pep8 [options] input ...", "", + "pep8: error: input not specified"]) + self.assertFalse(self._config_filenames) + + def test_check_diff(self): + pep8.PROJECT_CONFIG = () + diff_lines = [ + "--- testsuite/E11.py 2006-06-01 08:49:50 +0500", + "+++ testsuite/E11.py 2008-04-06 17:36:29 +0500", + "@@ -2,4 +2,7 @@", + " if x > 2:", + " print x", + "+#: E111", + "+if True:", + "+ print", + " #: E112", + " if False:", + "", + ] + + self.stdin = '\n'.join(diff_lines) + stdout, stderr, errcode = self.pep8('--diff') + stdout = stdout.splitlines() + self.assertEqual(errcode, 1) + self.assertFalse(stderr) + for line, num, col in zip(stdout, (3, 6), (3, 6)): + path, x, y, msg = line.split(':') + self.assertEqual(x, str(num)) + self.assertEqual(y, str(col)) + self.assertTrue(msg.startswith(' E11')) + + diff_lines[:2] = ["--- a/testsuite/E11.py 2006-06-01 08:49 +0400", + "+++ b/testsuite/E11.py 2008-04-06 17:36 +0400"] + self.stdin = '\n'.join(diff_lines) + stdout, stderr, errcode = self.pep8('--diff') + stdout = stdout.splitlines() + self.assertEqual(errcode, 1) + self.assertFalse(stderr) + for line, num, col in zip(stdout, (3, 6), (3, 6)): + path, x, y, msg = line.split(':') + self.assertEqual(x, str(num)) + self.assertEqual(y, str(col)) + self.assertTrue(msg.startswith(' E11')) + + # issue #127, #137: one-line chunks + diff_lines[:-1] = ["diff --git a/testsuite/E11.py b/testsuite/E11.py", + "index 8735e25..2ecb529 100644", + "--- a/testsuite/E11.py", + "+++ b/testsuite/E11.py", + "@@ -5,0 +6 @@ if True:", + "+ print"] + self.stdin = '\n'.join(diff_lines) + stdout, stderr, errcode = self.pep8('--diff') + (stdout,) = stdout.splitlines() + self.assertEqual(errcode, 1) + self.assertFalse(stderr) + self.assertTrue('testsuite/E11.py:6:6: E111 ' in stdout) + + # missing '--diff' + self.stdin = '\n'.join(diff_lines) + stdout, stderr, errcode = self.pep8() + self.assertEqual(errcode, 2) + self.assertFalse(stdout) + self.assertTrue(stderr.startswith('Usage: pep8 [options] input ...')) + + # no matching file in the diff + diff_lines[3] = "+++ b/testsuite/lost/E11.py" + self.stdin = '\n'.join(diff_lines) + stdout, stderr, errcode = self.pep8('--diff') + self.assertFalse(errcode) + self.assertFalse(stdout) + self.assertFalse(stderr) |