Coverage for tests / unit / tools / oxfmt / test_fix_method.py: 100%
72 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 OxfmtPlugin.fix method."""
3from __future__ import annotations
5import subprocess
6from typing import TYPE_CHECKING, Any
7from unittest.mock import MagicMock, patch
9from assertpy import assert_that
11from lintro.models.core.tool_result import ToolResult
12from lintro.parsers.oxfmt.oxfmt_issue import OxfmtIssue
14if TYPE_CHECKING:
15 from lintro.tools.definitions.oxfmt import OxfmtPlugin
18def test_fix_success_no_issues(
19 oxfmt_plugin: OxfmtPlugin,
20 mock_execution_context_for_tool: Any,
21) -> None:
22 """Fix returns success when no issues to fix.
24 Args:
25 oxfmt_plugin: The OxfmtPlugin instance to test.
26 mock_execution_context_for_tool: Mock execution context factory.
27 """
28 with (
29 patch.object(oxfmt_plugin, "_prepare_execution") as mock_prepare,
30 patch.object(oxfmt_plugin, "_run_subprocess") as mock_run,
31 patch.object(oxfmt_plugin, "_get_executable_command") as mock_exec,
32 patch.object(oxfmt_plugin, "_build_config_args") as mock_config,
33 ):
34 mock_prepare.return_value = mock_execution_context_for_tool(
35 files=["test.js"],
36 rel_files=["test.js"],
37 cwd="/tmp",
38 )
40 mock_exec.return_value = ["oxfmt"]
41 mock_config.return_value = []
42 # Initial check - no issues, fix - success, final check - no issues
43 mock_run.side_effect = [
44 (True, ""),
45 (True, ""),
46 (True, ""),
47 ]
49 result = oxfmt_plugin.fix(["/tmp/test.js"], {})
51 assert_that(result.success).is_true()
52 assert_that(result.remaining_issues_count).is_equal_to(0)
55def test_fix_success_with_fixes_applied(
56 oxfmt_plugin: OxfmtPlugin,
57 mock_execution_context_for_tool: Any,
58) -> None:
59 """Fix returns success when fixes are applied.
61 Args:
62 oxfmt_plugin: The OxfmtPlugin instance to test.
63 mock_execution_context_for_tool: Mock execution context factory.
64 """
65 with (
66 patch.object(oxfmt_plugin, "_prepare_execution") as mock_prepare,
67 patch.object(oxfmt_plugin, "_run_subprocess") as mock_run,
68 patch.object(oxfmt_plugin, "_get_executable_command") as mock_exec,
69 patch.object(oxfmt_plugin, "_build_config_args") as mock_config,
70 ):
71 mock_prepare.return_value = mock_execution_context_for_tool(
72 files=["test.js"],
73 rel_files=["test.js"],
74 cwd="/tmp",
75 )
77 mock_exec.return_value = ["oxfmt"]
78 mock_config.return_value = []
79 mock_run.side_effect = [
80 (False, "test.js"), # Initial check - issue found
81 (True, ""), # Fix command
82 (True, ""), # Final check - no issues
83 ]
85 result = oxfmt_plugin.fix(["/tmp/test.js"], {})
87 assert_that(result.success).is_true()
88 assert_that(result.fixed_issues_count).is_equal_to(1)
89 assert_that(result.remaining_issues_count).is_equal_to(0)
92def test_fix_timeout_during_initial_check(
93 oxfmt_plugin: OxfmtPlugin,
94 mock_execution_context_for_tool: Any,
95) -> None:
96 """Fix handles timeout during initial check.
98 Args:
99 oxfmt_plugin: The OxfmtPlugin instance to test.
100 mock_execution_context_for_tool: Mock execution context factory.
101 """
102 timeout_result = ToolResult(
103 name="oxfmt",
104 success=False,
105 output="Oxfmt execution timed out (30s limit exceeded).",
106 issues_count=1,
107 issues=[
108 OxfmtIssue(
109 file="execution",
110 line=1,
111 column=1,
112 code="TIMEOUT",
113 message="Oxfmt execution timed out",
114 ),
115 ],
116 initial_issues_count=1,
117 fixed_issues_count=0,
118 remaining_issues_count=1,
119 )
121 with (
122 patch.object(oxfmt_plugin, "_prepare_execution") as mock_prepare,
123 patch.object(oxfmt_plugin, "_run_subprocess") as mock_run,
124 patch.object(oxfmt_plugin, "_get_executable_command") as mock_exec,
125 patch.object(oxfmt_plugin, "_build_config_args") as mock_config,
126 patch.object(
127 oxfmt_plugin,
128 "_create_timeout_result",
129 return_value=timeout_result,
130 ),
131 ):
132 mock_prepare.return_value = mock_execution_context_for_tool(
133 files=["test.js"],
134 rel_files=["test.js"],
135 cwd="/tmp",
136 )
138 mock_exec.return_value = ["oxfmt"]
139 mock_config.return_value = []
140 mock_run.side_effect = subprocess.TimeoutExpired(cmd="oxfmt", timeout=30)
142 result = oxfmt_plugin.fix(["/tmp/test.js"], {})
144 assert_that(result.success).is_false()
145 assert_that(result.output).contains("timed out")
148def test_fix_timeout_during_fix_command(
149 oxfmt_plugin: OxfmtPlugin,
150 mock_execution_context_for_tool: Any,
151) -> None:
152 """Fix handles timeout during fix command.
154 Args:
155 oxfmt_plugin: The OxfmtPlugin instance to test.
156 mock_execution_context_for_tool: Mock execution context factory.
157 """
158 timeout_result = ToolResult(
159 name="oxfmt",
160 success=False,
161 output="Oxfmt execution timed out (30s limit exceeded).",
162 issues_count=2,
163 issues=[
164 OxfmtIssue(
165 file="test.js",
166 line=1,
167 column=1,
168 code="FORMAT",
169 message="File is not formatted",
170 ),
171 OxfmtIssue(
172 file="execution",
173 line=1,
174 column=1,
175 code="TIMEOUT",
176 message="Oxfmt execution timed out",
177 ),
178 ],
179 initial_issues_count=2,
180 fixed_issues_count=0,
181 remaining_issues_count=2,
182 )
184 with (
185 patch.object(oxfmt_plugin, "_prepare_execution") as mock_prepare,
186 patch.object(oxfmt_plugin, "_run_subprocess") as mock_run,
187 patch.object(oxfmt_plugin, "_get_executable_command") as mock_exec,
188 patch.object(oxfmt_plugin, "_build_config_args") as mock_config,
189 patch.object(
190 oxfmt_plugin,
191 "_create_timeout_result",
192 return_value=timeout_result,
193 ),
194 ):
195 mock_prepare.return_value = mock_execution_context_for_tool(
196 files=["test.js"],
197 rel_files=["test.js"],
198 cwd="/tmp",
199 )
201 mock_exec.return_value = ["oxfmt"]
202 mock_config.return_value = []
203 mock_run.side_effect = [
204 (False, "test.js"), # Initial check - issue found
205 subprocess.TimeoutExpired(cmd="oxfmt", timeout=30), # Fix times out
206 ]
208 result = oxfmt_plugin.fix(["/tmp/test.js"], {})
210 assert_that(result.success).is_false()
211 assert_that(result.output).contains("timed out")
214def test_fix_early_return_when_should_skip(
215 oxfmt_plugin: OxfmtPlugin,
216 mock_execution_context_for_tool: Any,
217) -> None:
218 """Fix returns early result when should_skip is True.
220 Args:
221 oxfmt_plugin: The OxfmtPlugin instance to test.
222 mock_execution_context_for_tool: Mock execution context factory.
223 """
224 with patch.object(oxfmt_plugin, "_prepare_execution") as mock_prepare:
225 ctx = mock_execution_context_for_tool(should_skip=True)
226 ctx.early_result = MagicMock(success=True, issues_count=0)
227 mock_prepare.return_value = ctx
229 result = oxfmt_plugin.fix(["/tmp"], {})
231 assert_that(result.success).is_true()
234def test_fix_multiple_files_with_issues(
235 oxfmt_plugin: OxfmtPlugin,
236 mock_execution_context_for_tool: Any,
237) -> None:
238 """Fix handles multiple files with formatting issues.
240 Args:
241 oxfmt_plugin: The OxfmtPlugin instance to test.
242 mock_execution_context_for_tool: Mock execution context factory.
243 """
244 with (
245 patch.object(oxfmt_plugin, "_prepare_execution") as mock_prepare,
246 patch.object(oxfmt_plugin, "_run_subprocess") as mock_run,
247 patch.object(oxfmt_plugin, "_get_executable_command") as mock_exec,
248 patch.object(oxfmt_plugin, "_build_config_args") as mock_config,
249 ):
250 mock_prepare.return_value = mock_execution_context_for_tool(
251 files=["test1.js", "test2.ts", "test3.tsx"],
252 rel_files=["test1.js", "test2.ts", "test3.tsx"],
253 cwd="/tmp",
254 )
256 mock_exec.return_value = ["oxfmt"]
257 mock_config.return_value = []
258 mock_run.side_effect = [
259 (False, "test1.js\ntest2.ts\ntest3.tsx"), # Initial check - 3 issues
260 (True, ""), # Fix command
261 (True, ""), # Final check - no issues
262 ]
264 result = oxfmt_plugin.fix(["/tmp"], {})
266 assert_that(result.success).is_true()
267 assert_that(result.initial_issues_count).is_equal_to(3)
268 assert_that(result.fixed_issues_count).is_equal_to(3)
269 assert_that(result.remaining_issues_count).is_equal_to(0)
272def test_fix_output_includes_fix_count(
273 oxfmt_plugin: OxfmtPlugin,
274 mock_execution_context_for_tool: Any,
275) -> None:
276 """Fix output includes count of fixed issues.
278 Args:
279 oxfmt_plugin: The OxfmtPlugin instance to test.
280 mock_execution_context_for_tool: Mock execution context factory.
281 """
282 with (
283 patch.object(oxfmt_plugin, "_prepare_execution") as mock_prepare,
284 patch.object(oxfmt_plugin, "_run_subprocess") as mock_run,
285 patch.object(oxfmt_plugin, "_get_executable_command") as mock_exec,
286 patch.object(oxfmt_plugin, "_build_config_args") as mock_config,
287 ):
288 mock_prepare.return_value = mock_execution_context_for_tool(
289 files=["test.js"],
290 rel_files=["test.js"],
291 cwd="/tmp",
292 )
294 mock_exec.return_value = ["oxfmt"]
295 mock_config.return_value = []
296 mock_run.side_effect = [
297 (False, "test.js"), # Initial check - issue found
298 (True, ""), # Fix command
299 (True, ""), # Final check - no issues
300 ]
302 result = oxfmt_plugin.fix(["/tmp/test.js"], {})
304 assert_that(result.output).contains("Fixed 1 formatting issue")