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
« prev ^ index » next coverage.py v7.13.0, created at 2026-04-03 18:53 +0000
1"""Tests for pytest-specific tool executor functionality."""
3import tempfile
4from pathlib import Path
5from unittest.mock import Mock, patch
7import pytest
8from assertpy import assert_that
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
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")
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")
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")
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")
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")
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")
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")
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")
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")
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")
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
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
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 )
120 assert_that(result).is_equal_to(0)
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
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
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 )
161 assert_that(result).is_equal_to(1)
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
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 )
190 # Should return failure when tool is not available
191 assert_that(result).is_equal_to(1)
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
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
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 )
232 # Should call set_options on the tool
233 mock_pytest_tool.set_options.assert_called()
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
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
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 )
274 # Should set exclude patterns on tool
275 mock_pytest_tool.check.assert_called_once()
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
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
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 )
316 # Logger factory should be called
317 mock_logger.assert_called_once()