-
Notifications
You must be signed in to change notification settings - Fork 20
/
test_cli.py
175 lines (130 loc) · 4.93 KB
/
test_cli.py
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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
"""Test the command line interface."""
import os
import re
from pathlib import Path
from textwrap import dedent
import pytest
from click.testing import CliRunner
from py._path.local import LocalPath
from autoimport.entrypoints.cli import cli
from autoimport.version import __version__
@pytest.fixture(name="runner")
def fixture_runner() -> CliRunner:
"""Configure the Click cli test runner."""
return CliRunner(mix_stderr=False)
def test_version(runner: CliRunner) -> None:
"""Prints program version when called with --version."""
result = runner.invoke(cli, ["--version"])
assert result.exit_code == 0
assert re.match(
fr" *autoimport version: {__version__}\n"
r" *python version: .*\n *platform: .*",
result.stdout,
)
def test_corrects_one_file(runner: CliRunner, tmpdir: LocalPath) -> None:
"""Correct the source code of a file."""
test_file = tmpdir / "source.py"
test_file.write("os.getcwd()")
fixed_source = dedent(
"""\
import os
os.getcwd()"""
)
result = runner.invoke(cli, [str(test_file)])
assert result.exit_code == 0
assert test_file.read() == fixed_source
@pytest.mark.secondary()
def test_corrects_three_files(runner: CliRunner, tmpdir: LocalPath) -> None:
"""Correct the source code of multiple files."""
test_files = []
for file_number in range(3):
test_file = tmpdir / f"source_{file_number}.py"
test_file.write("os.getcwd()")
test_files.append(test_file)
fixed_source = dedent(
"""\
import os
os.getcwd()"""
)
result = runner.invoke(cli, [str(test_file) for test_file in test_files])
assert result.exit_code == 0
for test_file in test_files:
assert test_file.read() == fixed_source
def test_correct_all_files_in_dir_recursively(
runner: CliRunner, test_dir: Path
) -> None:
"""Ensure files and dirs can be parsed and fixes associated files."""
result = runner.invoke(cli, [str(test_dir)])
assert result.exit_code == 0
fixed_source = "import os\n\nos.getcwd()"
assert (test_dir / "test_file1.py").read_text() == fixed_source
assert (test_dir / "subdir/test_file2.py").read_text() == fixed_source
def test_correct_mix_dir_and_files(
runner: CliRunner, test_dir: Path, tmpdir: LocalPath
) -> None:
"""Ensure all files in a given directory get fixed by autoimport."""
test_file = tmpdir / "source.py"
test_file.write("os.getcwd()")
result = runner.invoke(cli, [str(test_dir), str(test_file)])
assert result.exit_code == 0
fixed_source = "import os\n\nos.getcwd()"
assert (test_dir / "test_file1.py").read_text() == fixed_source
assert (test_dir / "subdir/test_file2.py").read_text() == fixed_source
assert test_file.read() == fixed_source
def test_corrects_code_from_stdin(runner: CliRunner) -> None:
"""Correct the source code passed as stdin."""
source = "os.getcwd()"
fixed_source = dedent(
"""\
import os
os.getcwd()"""
)
result = runner.invoke(cli, ["-"], input=source)
assert result.exit_code == 0
assert result.stdout == fixed_source
PYPROJECT_CONFIG = """
[tool.autoimport]
common_statements = { "FooBar" = "from baz.qux import FooBar" }
"""
PYPROJECT_CONFIG_TEST_SOURCE = "FooBar\n"
PYPROJECT_CONFIG_FIXED_SOURCE = """\
from baz.qux import FooBar
FooBar
"""
def test_pyproject_common_statements(runner: CliRunner, tmpdir: LocalPath) -> None:
"""Allow common_statements to be defined in pyproject.toml"""
pyproject_toml = tmpdir / "pyproject.toml"
pyproject_toml.write(PYPROJECT_CONFIG)
test_file = tmpdir / "source.py"
test_file.write(PYPROJECT_CONFIG_TEST_SOURCE)
with tmpdir.as_cwd():
result = runner.invoke(cli, [str(test_file)])
assert result.exit_code == 0
assert test_file.read() == PYPROJECT_CONFIG_FIXED_SOURCE
def test_config_path_argument(runner: CliRunner, tmpdir: LocalPath) -> None:
"""Allow common_statements to be defined in pyproject.toml"""
cfg_dir = tmpdir / "cfg"
cfg_dir.mkdir()
pyproject_toml = cfg_dir / "pyproject.toml"
pyproject_toml.write(PYPROJECT_CONFIG)
code_dir = tmpdir / "code"
code_dir.mkdir()
test_file = code_dir / "source.py"
test_file.write(PYPROJECT_CONFIG_TEST_SOURCE)
result = runner.invoke(cli, ["--config-file", str(pyproject_toml), str(test_file)])
assert result.exit_code == 0
assert test_file.read() == PYPROJECT_CONFIG_FIXED_SOURCE
def test_fix_files_doesnt_touch_the_file_if_its_not_going_to_change_it(
runner: CliRunner, tmpdir: LocalPath
) -> None:
"""
Given: A file that doesn't need any change
When: fix files is run
Then: The file is untouched
"""
test_file = tmpdir / "source.py"
test_file.write("a = 1")
modified_time = os.path.getmtime(test_file)
result = runner.invoke(cli, [str(test_file)])
assert result.exit_code == 0
assert os.path.getmtime(test_file) == modified_time