Coverage for tests / unit / tools / oxlint / test_check_method.py: 100%
77 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 OxlintPlugin.check method."""
3from __future__ import annotations
5import pathlib
6import subprocess
7from pathlib import Path
8from typing import TYPE_CHECKING, cast
9from unittest.mock import MagicMock, patch
11from assertpy import assert_that
13from lintro.parsers.oxlint.oxlint_issue import OxlintIssue
15if TYPE_CHECKING:
16 from lintro.tools.definitions.oxlint import OxlintPlugin
19def test_check_with_issues(oxlint_plugin: OxlintPlugin, tmp_path: Path) -> None:
20 """Check returns issues when found.
22 Args:
23 oxlint_plugin: The OxlintPlugin instance to test.
24 tmp_path: Temporary directory path for test files.
25 """
26 test_file = pathlib.Path(tmp_path) / "test.js"
27 test_file.write_text("var unused = 1;\n")
29 mock_output = """{
30 "diagnostics": [
31 {
32 "message": "Variable 'unused' is declared but never used.",
33 "code": "eslint(no-unused-vars)",
34 "severity": "warning",
35 "filename": "test.js",
36 "labels": [{"span": {"line": 1, "column": 5}}]
37 }
38 ]
39 }"""
40 mock_result = (False, mock_output)
42 with (
43 patch.object(oxlint_plugin, "_prepare_execution") as mock_prepare,
44 patch.object(oxlint_plugin, "_run_subprocess", return_value=mock_result),
45 patch.object(oxlint_plugin, "_get_executable_command", return_value=["oxlint"]),
46 patch.object(oxlint_plugin, "_build_config_args", return_value=[]),
47 ):
48 mock_ctx = MagicMock()
49 mock_ctx.should_skip = False
50 mock_ctx.early_result = None
51 mock_ctx.timeout = 30
52 mock_ctx.cwd = str(tmp_path)
53 mock_ctx.rel_files = ["test.js"]
54 mock_ctx.files = [str(test_file)]
55 mock_prepare.return_value = mock_ctx
57 result = oxlint_plugin.check([str(test_file)], {})
59 assert_that(result.name).is_equal_to("oxlint")
60 assert_that(result.success).is_false()
61 assert_that(result.issues_count).is_equal_to(1)
62 assert_that(result.issues).is_not_none()
63 issue = cast(OxlintIssue, result.issues[0]) # type: ignore[index] # validated via is_not_none
64 assert_that(issue.code).is_equal_to("eslint(no-unused-vars)")
67def test_check_without_issues(oxlint_plugin: OxlintPlugin, tmp_path: Path) -> None:
68 """Check returns success when no issues found.
70 Args:
71 oxlint_plugin: The OxlintPlugin instance to test.
72 tmp_path: Temporary directory path for test files.
73 """
74 test_file = pathlib.Path(tmp_path) / "test.js"
75 test_file.write_text("const x = 1;\nconsole.log(x);\n")
77 mock_output = '{"diagnostics": []}'
78 mock_result = (True, mock_output)
80 with (
81 patch.object(oxlint_plugin, "_prepare_execution") as mock_prepare,
82 patch.object(oxlint_plugin, "_run_subprocess", return_value=mock_result),
83 patch.object(oxlint_plugin, "_get_executable_command", return_value=["oxlint"]),
84 patch.object(oxlint_plugin, "_build_config_args", return_value=[]),
85 ):
86 mock_ctx = MagicMock()
87 mock_ctx.should_skip = False
88 mock_ctx.early_result = None
89 mock_ctx.timeout = 30
90 mock_ctx.cwd = str(tmp_path)
91 mock_ctx.rel_files = ["test.js"]
92 mock_ctx.files = [str(test_file)]
93 mock_prepare.return_value = mock_ctx
95 result = oxlint_plugin.check([str(test_file)], {})
97 assert_that(result.name).is_equal_to("oxlint")
98 assert_that(result.success).is_true()
99 assert_that(result.issues_count).is_equal_to(0)
100 assert_that(result.output).is_none()
103def test_check_timeout_handling(oxlint_plugin: OxlintPlugin, tmp_path: Path) -> None:
104 """Check handles timeout correctly.
106 Args:
107 oxlint_plugin: The OxlintPlugin instance to test.
108 tmp_path: Temporary directory path for test files.
109 """
110 test_file = pathlib.Path(tmp_path) / "test.js"
111 test_file.write_text("const x = 1;\n")
113 with (
114 patch.object(oxlint_plugin, "_prepare_execution") as mock_prepare,
115 patch.object(
116 oxlint_plugin,
117 "_run_subprocess",
118 side_effect=subprocess.TimeoutExpired(cmd=["oxlint"], timeout=30),
119 ),
120 patch.object(oxlint_plugin, "_get_executable_command", return_value=["oxlint"]),
121 patch.object(oxlint_plugin, "_build_config_args", return_value=[]),
122 ):
123 mock_ctx = MagicMock()
124 mock_ctx.should_skip = False
125 mock_ctx.early_result = None
126 mock_ctx.timeout = 30
127 mock_ctx.cwd = str(tmp_path)
128 mock_ctx.rel_files = ["test.js"]
129 mock_ctx.files = [str(test_file)]
130 mock_prepare.return_value = mock_ctx
132 result = oxlint_plugin.check([str(test_file)], {})
134 assert_that(result.success).is_false()
135 assert_that(result.output).contains("timed out")
136 assert_that(result.output).contains("30s")
137 assert_that(result.issues_count).is_equal_to(1)
138 issue = cast(OxlintIssue, result.issues[0]) # type: ignore[index] # validated via is_not_none
139 assert_that(issue.code).is_equal_to("TIMEOUT")
142def test_check_early_skip(oxlint_plugin: OxlintPlugin, tmp_path: Path) -> None:
143 """Check returns early when should_skip is True.
145 Args:
146 oxlint_plugin: The OxlintPlugin instance to test.
147 tmp_path: Temporary directory path for test files.
148 """
149 from lintro.models.core.tool_result import ToolResult
151 early_result = ToolResult(
152 name="oxlint",
153 success=True,
154 output=None,
155 issues_count=0,
156 issues=[],
157 )
159 with patch.object(oxlint_plugin, "_prepare_execution") as mock_prepare:
160 mock_ctx = MagicMock()
161 mock_ctx.should_skip = True
162 mock_ctx.early_result = early_result
163 mock_prepare.return_value = mock_ctx
165 result = oxlint_plugin.check([str(tmp_path)], {})
167 assert_that(result).is_same_as(early_result)