Coverage for tests / unit / cli / test_check_command.py: 100%
118 statements
« prev ^ index » next coverage.py v7.13.0, created at 2026-04-03 18:53 +0000
« prev ^ index » next coverage.py v7.13.0, created at 2026-04-03 18:53 +0000
1"""Unit tests for lintro/cli_utils/commands/check.py."""
3from __future__ import annotations
5from pathlib import Path
6from unittest.mock import MagicMock, patch
8import pytest
9from assertpy import assert_that
10from click.testing import CliRunner
12from lintro.cli_utils.commands.check import check, check_command
14# =============================================================================
15# Check Command Basic Tests
16# =============================================================================
19def test_check_command_help(cli_runner: CliRunner) -> None:
20 """Verify check command shows help.
22 Args:
23 cli_runner: The Click CLI test runner.
24 """
25 result = cli_runner.invoke(check_command, ["--help"])
27 assert_that(result.exit_code).is_equal_to(0)
28 assert_that(result.output).contains("Check files")
31def test_check_command_default_paths(
32 cli_runner: CliRunner,
33 mock_run_lint_tools_check: MagicMock,
34) -> None:
35 """Verify check command uses default paths when none provided.
37 Args:
38 cli_runner: The Click CLI test runner.
39 mock_run_lint_tools_check: Mock for the run_lint_tools_check function.
40 """
41 with cli_runner.isolated_filesystem():
42 cli_runner.invoke(check_command, [])
44 mock_run_lint_tools_check.assert_called_once()
45 call_kwargs = mock_run_lint_tools_check.call_args.kwargs
46 assert_that(call_kwargs["paths"]).is_equal_to(["."])
49def test_check_command_with_paths(
50 cli_runner: CliRunner,
51 mock_run_lint_tools_check: MagicMock,
52 tmp_path: Path,
53) -> None:
54 """Verify check command passes provided paths.
56 Args:
57 cli_runner: The Click CLI test runner.
58 mock_run_lint_tools_check: Mock for the run_lint_tools_check function.
59 tmp_path: Temporary directory path for testing.
60 """
61 test_file = tmp_path / "test.py"
62 test_file.write_text("# test")
64 cli_runner.invoke(check_command, [str(test_file)])
66 mock_run_lint_tools_check.assert_called_once()
67 call_kwargs = mock_run_lint_tools_check.call_args.kwargs
68 assert_that(call_kwargs["paths"]).contains(str(test_file))
71def test_check_command_exit_code_zero_on_success(
72 cli_runner: CliRunner,
73 mock_run_lint_tools_check: MagicMock,
74) -> None:
75 """Verify check command exits with 0 on success.
77 Args:
78 cli_runner: The Click CLI test runner.
79 mock_run_lint_tools_check: Mock for the run_lint_tools_check function.
80 """
81 mock_run_lint_tools_check.return_value = 0
82 with cli_runner.isolated_filesystem():
83 result = cli_runner.invoke(check_command, [])
85 assert_that(result.exit_code).is_equal_to(0)
88def test_check_command_exit_code_nonzero_on_issues(
89 cli_runner: CliRunner,
90 mock_run_lint_tools_check: MagicMock,
91) -> None:
92 """Verify check command exits with non-zero when issues found.
94 Args:
95 cli_runner: The Click CLI test runner.
96 mock_run_lint_tools_check: Mock for the run_lint_tools_check function.
97 """
98 mock_run_lint_tools_check.return_value = 1
99 with cli_runner.isolated_filesystem():
100 result = cli_runner.invoke(check_command, [])
102 assert_that(result.exit_code).is_equal_to(1)
105# =============================================================================
106# Check Command Options Tests
107# =============================================================================
110def test_check_command_tools_option(
111 cli_runner: CliRunner,
112 mock_run_lint_tools_check: MagicMock,
113) -> None:
114 """Verify --tools option is passed correctly.
116 Args:
117 cli_runner: The Click CLI test runner.
118 mock_run_lint_tools_check: Mock for the run_lint_tools_check function.
119 """
120 with cli_runner.isolated_filesystem():
121 cli_runner.invoke(check_command, ["--tools", "ruff,mypy"])
123 mock_run_lint_tools_check.assert_called_once()
124 call_kwargs = mock_run_lint_tools_check.call_args.kwargs
125 assert_that(call_kwargs["tools"]).is_equal_to("ruff,mypy")
128def test_check_command_exclude_option(
129 cli_runner: CliRunner,
130 mock_run_lint_tools_check: MagicMock,
131) -> None:
132 """Verify --exclude option is passed correctly.
134 Args:
135 cli_runner: The Click CLI test runner.
136 mock_run_lint_tools_check: Mock for the run_lint_tools_check function.
137 """
138 with cli_runner.isolated_filesystem():
139 cli_runner.invoke(check_command, ["--exclude", "*.pyc,__pycache__"])
141 mock_run_lint_tools_check.assert_called_once()
142 call_kwargs = mock_run_lint_tools_check.call_args.kwargs
143 assert_that(call_kwargs["exclude"]).is_equal_to("*.pyc,__pycache__")
146def test_check_command_include_venv_flag(
147 cli_runner: CliRunner,
148 mock_run_lint_tools_check: MagicMock,
149) -> None:
150 """Verify --include-venv flag is passed correctly.
152 Args:
153 cli_runner: The Click CLI test runner.
154 mock_run_lint_tools_check: Mock for the run_lint_tools_check function.
155 """
156 with cli_runner.isolated_filesystem():
157 cli_runner.invoke(check_command, ["--include-venv"])
159 mock_run_lint_tools_check.assert_called_once()
160 call_kwargs = mock_run_lint_tools_check.call_args.kwargs
161 assert_that(call_kwargs["include_venv"]).is_true()
164def test_check_command_output_format_option(
165 cli_runner: CliRunner,
166 mock_run_lint_tools_check: MagicMock,
167) -> None:
168 """Verify --output-format option is passed correctly.
170 Args:
171 cli_runner: The Click CLI test runner.
172 mock_run_lint_tools_check: Mock for the run_lint_tools_check function.
173 """
174 with cli_runner.isolated_filesystem():
175 cli_runner.invoke(check_command, ["--output-format", "json"])
177 mock_run_lint_tools_check.assert_called_once()
178 call_kwargs = mock_run_lint_tools_check.call_args.kwargs
179 assert_that(call_kwargs["output_format"]).is_equal_to("json")
182@pytest.mark.parametrize(
183 "format_option",
184 ["plain", "grid", "markdown", "html", "json", "csv"],
185 ids=["plain", "grid", "markdown", "html", "json", "csv"],
186)
187def test_check_command_output_format_valid_choices(
188 cli_runner: CliRunner,
189 mock_run_lint_tools_check: MagicMock,
190 format_option: str,
191) -> None:
192 """Verify all valid output format choices are accepted.
194 Args:
195 cli_runner: The Click CLI test runner.
196 mock_run_lint_tools_check: Mock for the run_lint_tools_check function.
197 format_option: The output format option value to test.
198 """
199 with cli_runner.isolated_filesystem():
200 result = cli_runner.invoke(check_command, ["--output-format", format_option])
202 assert_that(result.exit_code).is_equal_to(0)
205def test_check_command_group_by_option(
206 cli_runner: CliRunner,
207 mock_run_lint_tools_check: MagicMock,
208) -> None:
209 """Verify --group-by option is passed correctly.
211 Args:
212 cli_runner: The Click CLI test runner.
213 mock_run_lint_tools_check: Mock for the run_lint_tools_check function.
214 """
215 with cli_runner.isolated_filesystem():
216 cli_runner.invoke(check_command, ["--group-by", "code"])
218 mock_run_lint_tools_check.assert_called_once()
219 call_kwargs = mock_run_lint_tools_check.call_args.kwargs
220 assert_that(call_kwargs["group_by"]).is_equal_to("code")
223@pytest.mark.parametrize(
224 "group_by_option",
225 ["file", "code", "none", "auto"],
226 ids=["file", "code", "none", "auto"],
227)
228def test_check_command_group_by_valid_choices(
229 cli_runner: CliRunner,
230 mock_run_lint_tools_check: MagicMock,
231 group_by_option: str,
232) -> None:
233 """Verify all valid group-by choices are accepted.
235 Args:
236 cli_runner: The Click CLI test runner.
237 mock_run_lint_tools_check: Mock for the run_lint_tools_check function.
238 group_by_option: The group-by option value to test.
239 """
240 with cli_runner.isolated_filesystem():
241 result = cli_runner.invoke(check_command, ["--group-by", group_by_option])
243 assert_that(result.exit_code).is_equal_to(0)
246def test_check_command_verbose_flag(
247 cli_runner: CliRunner,
248 mock_run_lint_tools_check: MagicMock,
249) -> None:
250 """Verify --verbose flag is passed correctly.
252 Args:
253 cli_runner: The Click CLI test runner.
254 mock_run_lint_tools_check: Mock for the run_lint_tools_check function.
255 """
256 with cli_runner.isolated_filesystem():
257 cli_runner.invoke(check_command, ["--verbose"])
259 mock_run_lint_tools_check.assert_called_once()
260 call_kwargs = mock_run_lint_tools_check.call_args.kwargs
261 assert_that(call_kwargs["verbose"]).is_true()
264def test_check_command_raw_output_flag(
265 cli_runner: CliRunner,
266 mock_run_lint_tools_check: MagicMock,
267) -> None:
268 """Verify --raw-output flag is passed correctly.
270 Args:
271 cli_runner: The Click CLI test runner.
272 mock_run_lint_tools_check: Mock for the run_lint_tools_check function.
273 """
274 with cli_runner.isolated_filesystem():
275 cli_runner.invoke(check_command, ["--raw-output"])
277 mock_run_lint_tools_check.assert_called_once()
278 call_kwargs = mock_run_lint_tools_check.call_args.kwargs
279 assert_that(call_kwargs["raw_output"]).is_true()
282def test_check_command_tool_options(
283 cli_runner: CliRunner,
284 mock_run_lint_tools_check: MagicMock,
285) -> None:
286 """Verify --tool-options is passed correctly.
288 Args:
289 cli_runner: The Click CLI test runner.
290 mock_run_lint_tools_check: Mock for the run_lint_tools_check function.
291 """
292 with cli_runner.isolated_filesystem():
293 cli_runner.invoke(
294 check_command,
295 ["--tool-options", "ruff:line-length=120"],
296 )
298 mock_run_lint_tools_check.assert_called_once()
299 call_kwargs = mock_run_lint_tools_check.call_args.kwargs
300 assert_that(call_kwargs["tool_options"]).is_equal_to("ruff:line-length=120")
303def test_check_command_output_file(
304 cli_runner: CliRunner,
305 mock_run_lint_tools_check: MagicMock,
306 tmp_path: Path,
307) -> None:
308 """Verify --output option is passed correctly.
310 Args:
311 cli_runner: The Click CLI test runner.
312 mock_run_lint_tools_check: Mock for the run_lint_tools_check function.
313 tmp_path: Temporary directory path for testing.
314 """
315 output_file = str(tmp_path / "results.json")
316 with cli_runner.isolated_filesystem():
317 cli_runner.invoke(check_command, ["--output", output_file])
319 mock_run_lint_tools_check.assert_called_once()
320 call_kwargs = mock_run_lint_tools_check.call_args.kwargs
321 assert_that(call_kwargs["output_file"]).is_equal_to(output_file)
324# =============================================================================
325# Programmatic check() Function Tests
326# =============================================================================
329def test_check_function_calls_command(mock_run_lint_tools_check: MagicMock) -> None:
330 """Verify check() function invokes the check_command.
332 Args:
333 mock_run_lint_tools_check: Mock for the run_lint_tools_check function.
334 """
335 with patch("lintro.cli_utils.commands.check.CliRunner") as mock_runner_cls:
336 mock_runner = MagicMock()
337 mock_result = MagicMock()
338 mock_result.exit_code = 0
339 mock_runner.invoke.return_value = mock_result
340 mock_runner_cls.return_value = mock_runner
342 check(
343 paths=("src",),
344 tools="ruff",
345 tool_options=None,
346 exclude=None,
347 include_venv=False,
348 output=None,
349 output_format="grid",
350 group_by="file",
351 ignore_conflicts=False,
352 verbose=False,
353 no_log=False,
354 )
356 mock_runner.invoke.assert_called_once()
359def test_check_function_exits_on_failure() -> None:
360 """Verify check() function exits with non-zero code on failure."""
361 with patch("lintro.cli_utils.commands.check.CliRunner") as mock_runner_cls:
362 mock_runner = MagicMock()
363 mock_result = MagicMock()
364 mock_result.exit_code = 1
365 mock_runner.invoke.return_value = mock_result
366 mock_runner_cls.return_value = mock_runner
368 with pytest.raises(SystemExit) as exc_info:
369 check(
370 paths=("src",),
371 tools="ruff",
372 tool_options=None,
373 exclude=None,
374 include_venv=False,
375 output=None,
376 output_format="grid",
377 group_by="file",
378 ignore_conflicts=False,
379 verbose=False,
380 no_log=False,
381 )
383 assert_that(exc_info.value.code).is_equal_to(1)