Coverage for tests / unit / tools / executor / test_tool_executor_pytest.py: 100%

116 statements  

« prev     ^ index     » next       coverage.py v7.13.0, created at 2026-04-03 18:53 +0000

1"""Tests for pytest-specific tool executor functionality.""" 

2 

3import tempfile 

4from pathlib import Path 

5from unittest.mock import Mock, patch 

6 

7import pytest 

8from assertpy import assert_that 

9 

10from lintro.models.core.tool_result import ToolResult 

11from lintro.utils.execution.tool_configuration import get_tools_to_run 

12from lintro.utils.tool_executor import run_lint_tools_simple 

13 

14 

15def test_get_tools_to_run_test_action_with_pytest() -> None: 

16 """Test get_tools_to_run with test action returns pytest.""" 

17 result = get_tools_to_run(tools="pytest", action="test") 

18 assert_that(result.to_run).is_length(1) 

19 assert_that(result.to_run[0]).is_equal_to("pytest") 

20 

21 

22def test_get_tools_to_run_test_action_with_pytest_full_name() -> None: 

23 """Test get_tools_to_run with test action using full pytest name.""" 

24 result = get_tools_to_run(tools="pytest", action="test") 

25 assert_that(result.to_run).is_length(1) 

26 assert_that(result.to_run[0]).is_equal_to("pytest") 

27 

28 

29def test_get_tools_to_run_test_action_with_none_tools() -> None: 

30 """Test get_tools_to_run with test action and None tools.""" 

31 result = get_tools_to_run(tools=None, action="test") 

32 assert_that(result.to_run).is_length(1) 

33 assert_that(result.to_run[0]).is_equal_to("pytest") 

34 

35 

36def test_get_tools_to_run_test_action_with_invalid_tool() -> None: 

37 """Test get_tools_to_run raises error with invalid tool for test action.""" 

38 with pytest.raises(ValueError, match="(?i)only.*pytest.*supported"): 

39 get_tools_to_run(tools="ruff", action="test") 

40 

41 

42def test_get_tools_to_run_test_action_with_multiple_tools() -> None: 

43 """Test get_tools_to_run raises error with multiple tools for test action.""" 

44 with pytest.raises(ValueError, match="(?i)only.*pytest.*supported"): 

45 get_tools_to_run(tools="pytest,ruff", action="test") 

46 

47 

48def test_get_tools_to_run_check_action_rejects_pytest() -> None: 

49 """Test get_tools_to_run rejects pytest for check action.""" 

50 with pytest.raises(ValueError, match="not available for check"): 

51 get_tools_to_run(tools="pytest", action="check") 

52 

53 

54def test_get_tools_to_run_format_action_rejects_pytest() -> None: 

55 """Test get_tools_to_run rejects pytest for format action.""" 

56 with pytest.raises(ValueError, match="not available for check/fmt"): 

57 get_tools_to_run(tools="pytest", action="fmt") 

58 

59 

60def test_get_tools_to_run_test_action_unavailable() -> None: 

61 """Test get_tools_to_run with test action ensures pytest is available.""" 

62 # Verify that pytest is available in the registry 

63 result = get_tools_to_run(tools=None, action="test") 

64 assert_that(result.to_run).is_not_empty() 

65 assert_that(result.to_run[0]).is_equal_to("pytest") 

66 

67 

68def test_get_tools_to_run_check_action_filters_out_pytest() -> None: 

69 """Test get_tools_to_run filters pytest out for check action.""" 

70 result = get_tools_to_run(tools="all", action="check") 

71 # Should not contain pytest 

72 assert_that(result.to_run).does_not_contain("pytest") 

73 

74 

75def test_get_tools_to_run_format_action_filters_out_pytest() -> None: 

76 """Test get_tools_to_run filters pytest out for format action.""" 

77 result = get_tools_to_run(tools="all", action="fmt") 

78 # Should not contain pytest 

79 assert_that(result.to_run).does_not_contain("pytest") 

80 

81 

82def test_run_lint_tools_simple_test_action_basic() -> None: 

83 """Test run_lint_tools_simple with test action.""" 

84 with ( 

85 tempfile.TemporaryDirectory() as tmpdir, 

86 patch("lintro.utils.tool_executor.tool_manager") as mock_manager, 

87 patch("lintro.utils.tool_executor.OutputManager") as mock_output, 

88 patch("lintro.utils.console.create_logger") as mock_logger, 

89 ): 

90 mock_logger_inst = Mock() 

91 mock_logger.return_value = mock_logger_inst 

92 mock_output_inst = Mock() 

93 mock_output_inst.run_dir = Path(tmpdir) 

94 mock_output.return_value = mock_output_inst 

95 

96 mock_pytest_tool = Mock() 

97 mock_pytest_tool.name = "pytest" 

98 mock_pytest_tool.check.return_value = ToolResult( 

99 name="pytest", 

100 success=True, 

101 issues=[], 

102 issues_count=0, 

103 output="All tests passed", 

104 ) 

105 mock_manager.get_tool.return_value = mock_pytest_tool 

106 

107 result = run_lint_tools_simple( 

108 action="test", 

109 paths=["."], 

110 tools="pytest", 

111 tool_options=None, 

112 exclude=None, 

113 include_venv=False, 

114 group_by="file", 

115 output_format="plain", 

116 verbose=False, 

117 raw_output=False, 

118 ) 

119 

120 assert_that(result).is_equal_to(0) 

121 

122 

123def test_run_lint_tools_simple_test_action_with_failures() -> None: 

124 """Test run_lint_tools_simple with test failures.""" 

125 with ( 

126 tempfile.TemporaryDirectory() as tmpdir, 

127 patch("lintro.utils.tool_executor.tool_manager") as mock_manager, 

128 patch("lintro.utils.tool_executor.OutputManager") as mock_output, 

129 patch("lintro.utils.console.create_logger") as mock_logger, 

130 ): 

131 mock_logger_inst = Mock() 

132 mock_logger.return_value = mock_logger_inst 

133 mock_output_inst = Mock() 

134 mock_output_inst.run_dir = Path(tmpdir) 

135 mock_output.return_value = mock_output_inst 

136 

137 mock_pytest_tool = Mock() 

138 mock_pytest_tool.name = "pytest" 

139 mock_pytest_tool.check.return_value = ToolResult( 

140 name="pytest", 

141 success=False, 

142 issues_count=2, 

143 issues=[], 

144 output="2 test failures", 

145 ) 

146 mock_manager.get_tool.return_value = mock_pytest_tool 

147 

148 result = run_lint_tools_simple( 

149 action="test", 

150 paths=["."], 

151 tools="pytest", 

152 tool_options=None, 

153 exclude=None, 

154 include_venv=False, 

155 group_by="file", 

156 output_format="plain", 

157 verbose=False, 

158 raw_output=False, 

159 ) 

160 

161 assert_that(result).is_equal_to(1) 

162 

163 

164def test_run_lint_tools_simple_test_action_invalid_tool() -> None: 

165 """Test run_lint_tools_simple with invalid tool for test action.""" 

166 with ( 

167 tempfile.TemporaryDirectory() as tmpdir, 

168 patch("lintro.utils.tool_executor.OutputManager") as mock_output, 

169 patch("lintro.utils.console.create_logger") as mock_logger, 

170 ): 

171 mock_logger_inst = Mock() 

172 mock_logger.return_value = mock_logger_inst 

173 mock_output_inst = Mock() 

174 mock_output_inst.run_dir = Path(tmpdir) 

175 mock_output.return_value = mock_output_inst 

176 

177 result = run_lint_tools_simple( 

178 action="test", 

179 paths=["."], 

180 tools="ruff", 

181 tool_options=None, 

182 exclude=None, 

183 include_venv=False, 

184 group_by="file", 

185 output_format="plain", 

186 verbose=False, 

187 raw_output=False, 

188 ) 

189 

190 # Should return failure when tool is not available 

191 assert_that(result).is_equal_to(1) 

192 

193 

194def test_run_lint_tools_simple_test_action_with_tool_options() -> None: 

195 """Test run_lint_tools_simple with pytest tool options.""" 

196 with ( 

197 tempfile.TemporaryDirectory() as tmpdir, 

198 patch("lintro.utils.tool_executor.tool_manager") as mock_manager, 

199 patch("lintro.utils.tool_executor.OutputManager") as mock_output, 

200 patch("lintro.utils.console.create_logger") as mock_logger, 

201 ): 

202 mock_logger_inst = Mock() 

203 mock_logger.return_value = mock_logger_inst 

204 mock_output_inst = Mock() 

205 mock_output_inst.run_dir = Path(tmpdir) 

206 mock_output.return_value = mock_output_inst 

207 

208 mock_pytest_tool = Mock() 

209 mock_pytest_tool.name = "pytest" 

210 mock_pytest_tool.check.return_value = ToolResult( 

211 name="pytest", 

212 success=True, 

213 issues=[], 

214 issues_count=0, 

215 output="All tests passed", 

216 ) 

217 mock_manager.get_tool.return_value = mock_pytest_tool 

218 

219 run_lint_tools_simple( 

220 action="test", 

221 paths=["."], 

222 tools="pytest", 

223 tool_options="pytest:maxfail=5,pytest:tb=long", 

224 exclude=None, 

225 include_venv=False, 

226 group_by="file", 

227 output_format="plain", 

228 verbose=False, 

229 raw_output=False, 

230 ) 

231 

232 # Should call set_options on the tool 

233 mock_pytest_tool.set_options.assert_called() 

234 

235 

236def test_run_lint_tools_simple_test_action_exclude_patterns() -> None: 

237 """Test run_lint_tools_simple with exclude patterns.""" 

238 with ( 

239 tempfile.TemporaryDirectory() as tmpdir, 

240 patch("lintro.utils.tool_executor.tool_manager") as mock_manager, 

241 patch("lintro.utils.tool_executor.OutputManager") as mock_output, 

242 patch("lintro.utils.console.create_logger") as mock_logger, 

243 ): 

244 mock_logger_inst = Mock() 

245 mock_logger.return_value = mock_logger_inst 

246 mock_output_inst = Mock() 

247 mock_output_inst.run_dir = Path(tmpdir) 

248 mock_output.return_value = mock_output_inst 

249 

250 mock_pytest_tool = Mock() 

251 mock_pytest_tool.name = "pytest" 

252 mock_pytest_tool.check.return_value = ToolResult( 

253 name="pytest", 

254 success=True, 

255 issues=[], 

256 issues_count=0, 

257 output="All tests passed", 

258 ) 

259 mock_manager.get_tool.return_value = mock_pytest_tool 

260 

261 run_lint_tools_simple( 

262 action="test", 

263 paths=["."], 

264 tools="pytest", 

265 tool_options=None, 

266 exclude="*.venv", 

267 include_venv=False, 

268 group_by="file", 

269 output_format="plain", 

270 verbose=False, 

271 raw_output=False, 

272 ) 

273 

274 # Should set exclude patterns on tool 

275 mock_pytest_tool.check.assert_called_once() 

276 

277 

278def test_run_lint_tools_simple_test_action_verbose() -> None: 

279 """Test run_lint_tools_simple with verbose flag.""" 

280 with ( 

281 tempfile.TemporaryDirectory() as tmpdir, 

282 patch("lintro.utils.tool_executor.tool_manager") as mock_manager, 

283 patch("lintro.utils.tool_executor.OutputManager") as mock_output, 

284 patch("lintro.utils.console.create_logger") as mock_logger, 

285 ): 

286 mock_logger_inst = Mock() 

287 mock_logger.return_value = mock_logger_inst 

288 mock_output_inst = Mock() 

289 mock_output_inst.run_dir = Path(tmpdir) 

290 mock_output.return_value = mock_output_inst 

291 

292 mock_pytest_tool = Mock() 

293 mock_pytest_tool.name = "pytest" 

294 mock_pytest_tool.check.return_value = ToolResult( 

295 name="pytest", 

296 success=True, 

297 issues=[], 

298 issues_count=0, 

299 output="All tests passed", 

300 ) 

301 mock_manager.get_tool.return_value = mock_pytest_tool 

302 

303 run_lint_tools_simple( 

304 action="test", 

305 paths=["."], 

306 tools="pytest", 

307 tool_options=None, 

308 exclude=None, 

309 include_venv=False, 

310 group_by="file", 

311 output_format="plain", 

312 verbose=True, 

313 raw_output=False, 

314 ) 

315 

316 # Logger factory should be called 

317 mock_logger.assert_called_once()