# Copyright (c) 2014-2018, 2020 Claudiu Popa # Copyright (c) 2014 Google, Inc. # Copyright (c) 2014 Michal Nowikowski # Copyright (c) 2014 LOGILAB S.A. (Paris, FRANCE) # Copyright (c) 2015 Ionel Cristian Maries # Copyright (c) 2016 Łukasz Rogalski # Copyright (c) 2016 Derek Gustafson # Copyright (c) 2018 Lucas Cimon # Copyright (c) 2018 Ville Skyttä # Copyright (c) 2019-2020 Pierre Sassoulas # Copyright (c) 2019 Mr. Senko # Copyright (c) 2019 Hugo van Kemenade # Copyright (c) 2019 Ashley Whetter # Copyright (c) 2020 Damien Baty # Copyright (c) 2020 Anthony Sottile # Copyright (c) 2020 bernie gray # Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html # For details: https://github.com/PyCQA/pylint/blob/master/COPYING """Functional full-module tests for PyLint.""" import csv import os import sys import pytest from pylint import testutils from pylint.testutils import UPDATE_FILE, UPDATE_OPTION from pylint.utils import HAS_ISORT_5 # Notes: # - for the purpose of this test, the confidence levels HIGH and UNDEFINED # are treated as the same. # TODOs # - implement exhaustivity tests class LintModuleOutputUpdate(testutils.LintModuleTest): """If message files should be updated instead of checked.""" class TestDialect(csv.excel): delimiter = ":" lineterminator = "\n" csv.register_dialect("test", TestDialect) def _get_expected(self): with self._open_source_file() as f: expected_msgs = self.get_expected_messages(f) return expected_msgs, [] def _check_output_text(self, _, expected_output, actual_output): if expected_output == actual_output: return with open(self._test_file.expected_output, "w") as f: writer = csv.writer(f, dialect="test") for line in actual_output: writer.writerow(line.to_csv()) def get_tests(): input_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "functional") suite = [] for dirpath, _, filenames in os.walk(input_dir): if dirpath.endswith("__pycache__"): continue for filename in filenames: if filename != "__init__.py" and filename.endswith(".py"): # isort 5 has slightly different rules as isort 4. Testing # both would be hard: test with isort 5 only. if filename == "wrong_import_order.py" and not HAS_ISORT_5: continue suite.append(testutils.FunctionalTestFile(dirpath, filename)) return suite TESTS = get_tests() TESTS_NAMES = [t.base for t in TESTS] TEST_WITH_EXPECTED_DEPRECATION = [ "future_unicode_literals", "anomalous_unicode_escape_py3", ] @pytest.mark.parametrize("test_file", TESTS, ids=TESTS_NAMES) def test_functional(test_file, recwarn): if UPDATE_FILE.exists(): lint_test = LintModuleOutputUpdate(test_file) else: lint_test = testutils.LintModuleTest(test_file) lint_test.setUp() lint_test._runTest() warning = None try: # Catch :x: DeprecationWarning: invalid escape sequence # so it's not shown during tests warning = recwarn.pop() except AssertionError: pass if warning is not None: if ( test_file.base in TEST_WITH_EXPECTED_DEPRECATION and sys.version_info.minor > 5 ): assert issubclass(warning.category, DeprecationWarning) assert "invalid escape sequence" in str(warning.message) if __name__ == "__main__": if UPDATE_OPTION in sys.argv: UPDATE_FILE.touch() sys.argv.remove(UPDATE_OPTION) try: pytest.main(sys.argv) finally: if UPDATE_FILE.exists(): UPDATE_FILE.unlink()