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

1"""Unit tests for lintro/cli_utils/commands/check.py.""" 

2 

3from __future__ import annotations 

4 

5from pathlib import Path 

6from unittest.mock import MagicMock, patch 

7 

8import pytest 

9from assertpy import assert_that 

10from click.testing import CliRunner 

11 

12from lintro.cli_utils.commands.check import check, check_command 

13 

14# ============================================================================= 

15# Check Command Basic Tests 

16# ============================================================================= 

17 

18 

19def test_check_command_help(cli_runner: CliRunner) -> None: 

20 """Verify check command shows help. 

21 

22 Args: 

23 cli_runner: The Click CLI test runner. 

24 """ 

25 result = cli_runner.invoke(check_command, ["--help"]) 

26 

27 assert_that(result.exit_code).is_equal_to(0) 

28 assert_that(result.output).contains("Check files") 

29 

30 

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. 

36 

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, []) 

43 

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(["."]) 

47 

48 

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. 

55 

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") 

63 

64 cli_runner.invoke(check_command, [str(test_file)]) 

65 

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)) 

69 

70 

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. 

76 

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, []) 

84 

85 assert_that(result.exit_code).is_equal_to(0) 

86 

87 

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. 

93 

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, []) 

101 

102 assert_that(result.exit_code).is_equal_to(1) 

103 

104 

105# ============================================================================= 

106# Check Command Options Tests 

107# ============================================================================= 

108 

109 

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. 

115 

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"]) 

122 

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") 

126 

127 

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. 

133 

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__"]) 

140 

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__") 

144 

145 

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. 

151 

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"]) 

158 

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() 

162 

163 

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. 

169 

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"]) 

176 

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") 

180 

181 

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. 

193 

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]) 

201 

202 assert_that(result.exit_code).is_equal_to(0) 

203 

204 

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. 

210 

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"]) 

217 

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") 

221 

222 

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. 

234 

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]) 

242 

243 assert_that(result.exit_code).is_equal_to(0) 

244 

245 

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. 

251 

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"]) 

258 

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() 

262 

263 

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. 

269 

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"]) 

276 

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() 

280 

281 

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. 

287 

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 ) 

297 

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") 

301 

302 

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. 

309 

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]) 

318 

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) 

322 

323 

324# ============================================================================= 

325# Programmatic check() Function Tests 

326# ============================================================================= 

327 

328 

329def test_check_function_calls_command(mock_run_lint_tools_check: MagicMock) -> None: 

330 """Verify check() function invokes the check_command. 

331 

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 

341 

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 ) 

355 

356 mock_runner.invoke.assert_called_once() 

357 

358 

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 

367 

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 ) 

382 

383 assert_that(exc_info.value.code).is_equal_to(1)