-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Expand file tree
/
Copy pathtest_lint_module_output_update.py
More file actions
141 lines (119 loc) · 5.47 KB
/
test_lint_module_output_update.py
File metadata and controls
141 lines (119 loc) · 5.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
# For details: https://github.com/pylint-dev/pylint/blob/main/LICENSE
# Copyright (c) https://github.com/pylint-dev/pylint/blob/main/CONTRIBUTORS.txt
# pylint: disable=redefined-outer-name
from __future__ import annotations
import shutil
from collections.abc import Callable
from pathlib import Path
import pytest
from pylint.testutils import FunctionalTestFile, LintModuleTest
from pylint.testutils.functional import LintModuleOutputUpdate
FIXTURE_DIRECTORY = Path(__file__).parent / "data/functional"
DIRECTORIES = list(FIXTURE_DIRECTORY.iterdir())
@pytest.fixture()
def lint_module_fixture(
tmp_path: Path,
) -> Callable[[str], tuple[Path, Path, LintModuleOutputUpdate]]:
def inner(base: str) -> tuple[Path, Path, LintModuleOutputUpdate]:
filename = tmp_path / f"{base}.py"
expected_output_file = tmp_path / f"{base}.txt"
lmou = LintModuleOutputUpdate(
test_file=FunctionalTestFile(str(tmp_path), str(filename))
)
return filename, expected_output_file, lmou
return inner
def test_lint_module_output_update_fail_before(
lint_module_fixture: Callable[[str], tuple[Path, Path, LintModuleOutputUpdate]],
) -> None:
"""There is a fail before the output need to be updated."""
filename, expected_output_file, lmou = lint_module_fixture("foo")
filename.write_text("", encoding="utf8")
assert not expected_output_file.exists()
with pytest.raises(AssertionError, match="1: disallowed-name"):
lmou.runTest()
assert not expected_output_file.exists()
def test_lint_module_output_update_effective(
lint_module_fixture: Callable[[str], tuple[Path, Path, LintModuleOutputUpdate]],
) -> None:
"""The file is updated following a successful tests with wrong output."""
filename, expected_output_file, lmou = lint_module_fixture("foo")
filename.write_text("# [disallowed-name]\n", encoding="utf8")
lmou.runTest()
assert (expected_output_file).exists()
assert (
expected_output_file.read_text(encoding="utf8")
== 'disallowed-name:1:0:None:None::"Disallowed name ""foo""":HIGH\n'
)
def test_lint_module_output_update_remove_useless_txt(
lint_module_fixture: Callable[[str], tuple[Path, Path, LintModuleOutputUpdate]],
) -> None:
"""The file is updated following a successful tests with wrong output."""
filename, expected_output_file, lmou = lint_module_fixture("fine_name")
expected_output_file.write_text("", encoding="utf8")
filename.write_text("", encoding="utf8")
lmou.runTest()
assert not expected_output_file.exists()
@pytest.mark.parametrize(
"directory_path", DIRECTORIES, ids=[str(p) for p in DIRECTORIES]
)
def test_update_of_functional_output(directory_path: Path, tmp_path: Path) -> None:
"""Functional test for the functional tests' helper."""
def _check_expected_output(_ftf: FunctionalTestFile) -> None:
new_output_path = _ftf.expected_output
assert Path(
new_output_path
).exists(), "The expected output file does not exists"
with open(new_output_path, encoding="utf8") as f:
new_output = f.read()
assert (
new_output == "exec-used:7:0:7:14::Use of exec:UNDEFINED\n"
), f"The content was wrongly updated in {new_output_path}"
def _assert_behavior_is_correct(
_ftf: FunctionalTestFile,
_lint_module: LintModuleTest,
_lint_module_output_update: LintModuleOutputUpdate,
_new_path: Path,
) -> None:
new_path_str = str(_new_path)
if "wrong_test" in new_path_str:
expected = r'Wrong message\(s\) raised for "exec_used.py"'
with pytest.raises(AssertionError, match=expected):
_lint_module.runTest()
# When the tests are wrong we do not update the output at all
# and the test should fail
with pytest.raises(AssertionError, match=expected):
_lint_module_output_update.runTest()
elif "ok_test" in new_path_str:
if any(f"{x}_output" in new_path_str for x in ("wrong", "no", "broken")):
with pytest.raises(
AssertionError, match=r'Wrong output for "exec_used\.txt"'
):
_lint_module.runTest()
elif "ok_output" in new_path_str:
_lint_module.runTest()
_check_expected_output(_ftf)
else:
raise AssertionError(f"Unhandled test case: {new_path_str}")
# When the tests are ok we update the output whatever it's state
# was originally
_lint_module_output_update.runTest()
_check_expected_output(_ftf)
else:
raise AssertionError(
f"Do not pollute '{FIXTURE_DIRECTORY}' with unrelated "
f"or badly named test files."
)
new_path = tmp_path / directory_path.name
shutil.copytree(directory_path, new_path)
for filename in new_path.iterdir():
if filename.suffix != ".py":
continue
ftf = FunctionalTestFile(directory=str(new_path), filename=filename.name)
# Standard functional test helper
lint_module = LintModuleTest(ftf)
# Functional test helper that automatically update the output
lint_module_output_update = LintModuleOutputUpdate(ftf)
_assert_behavior_is_correct(
ftf, lint_module, lint_module_output_update, new_path
)