Coverage for tests / unit / tools / ruff / check / test_json_parsing.py: 100%
35 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 JSON output parsing in execute_ruff_check."""
3from __future__ import annotations
5from typing import cast
6from unittest.mock import MagicMock, patch
8from assertpy import assert_that
10from lintro.parsers.ruff.ruff_issue import RuffIssue
11from lintro.tools.implementations.ruff.check import execute_ruff_check
14def test_execute_ruff_check_parses_json_output_correctly(
15 mock_ruff_tool: MagicMock,
16 sample_ruff_json_output: str,
17) -> None:
18 """Parse JSON output and create correct issue objects.
20 Args:
21 mock_ruff_tool: Mock RuffTool instance for testing.
22 sample_ruff_json_output: Sample JSON output from ruff.
23 """
24 from lintro.parsers.ruff.ruff_parser import parse_ruff_output
26 with (
27 patch(
28 "lintro.tools.implementations.ruff.check.walk_files_with_excludes",
29 return_value=["test.py"],
30 ),
31 patch(
32 "lintro.tools.implementations.ruff.check.run_subprocess_with_timeout",
33 return_value=(False, sample_ruff_json_output),
34 ),
35 patch(
36 "lintro.tools.implementations.ruff.check.parse_ruff_output",
37 side_effect=parse_ruff_output,
38 ),
39 ):
40 result = execute_ruff_check(mock_ruff_tool, ["/test/project"])
42 # Verify overall result reflects subprocess failure and issues found
43 assert_that(result.success).is_false()
44 assert_that(result.issues_count).is_equal_to(2)
45 assert_that(result.issues).is_not_none()
46 assert_that(result.issues).is_length(2)
48 # Verify first issue
49 first_issue = cast(RuffIssue, result.issues[0]) # type: ignore[index] # validated via is_not_none
50 assert_that(first_issue.code).is_equal_to("F401")
51 assert_that(first_issue.file).is_equal_to("test.py")
52 assert_that(first_issue.line).is_equal_to(1)
53 assert_that(first_issue.column).is_equal_to(1)
55 # Verify second issue
56 second_issue = cast(RuffIssue, result.issues[1]) # type: ignore[index] # validated via is_not_none
57 assert_that(second_issue.code).is_equal_to("E501")
60def test_execute_ruff_check_empty_json_output(
61 mock_ruff_tool: MagicMock,
62 sample_ruff_json_empty_output: str,
63) -> None:
64 """Handle empty JSON output correctly.
66 Args:
67 mock_ruff_tool: Mock RuffTool instance for testing.
68 sample_ruff_json_empty_output: Sample empty JSON output from ruff.
69 """
70 with (
71 patch(
72 "lintro.tools.implementations.ruff.check.walk_files_with_excludes",
73 return_value=["test.py"],
74 ),
75 patch(
76 "lintro.tools.implementations.ruff.check.run_subprocess_with_timeout",
77 return_value=(True, sample_ruff_json_empty_output),
78 ),
79 patch(
80 "lintro.tools.implementations.ruff.check.parse_ruff_output",
81 return_value=[],
82 ),
83 ):
84 result = execute_ruff_check(mock_ruff_tool, ["/test/project"])
86 assert_that(result.success).is_true()
87 assert_that(result.issues_count).is_equal_to(0)
90def test_execute_ruff_check_parses_format_check_output(
91 mock_ruff_tool: MagicMock,
92 sample_ruff_format_check_output: str,
93) -> None:
94 """Parse format check output and create correct format issues.
96 Args:
97 mock_ruff_tool: Mock RuffTool instance for testing.
98 sample_ruff_format_check_output: Sample format check output from ruff.
99 """
100 mock_ruff_tool.options["format_check"] = True
102 from lintro.parsers.ruff.ruff_parser import parse_ruff_format_check_output
104 with (
105 patch(
106 "lintro.tools.implementations.ruff.check.walk_files_with_excludes",
107 return_value=["test.py", "src/module.py"],
108 ),
109 patch(
110 "lintro.tools.implementations.ruff.check.run_subprocess_with_timeout",
111 return_value=(True, ""),
112 ),
113 patch(
114 "lintro.tools.implementations.ruff.check.parse_ruff_output",
115 return_value=[],
116 ),
117 patch(
118 "lintro.tools.implementations.ruff.check.parse_ruff_format_check_output",
119 side_effect=parse_ruff_format_check_output,
120 ),
121 ):
122 # Need a separate mock for the format check subprocess call
123 with patch(
124 "lintro.tools.implementations.ruff.check.run_subprocess_with_timeout",
125 ) as mock_subprocess:
126 # First call: lint check, Second call: format check
127 mock_subprocess.side_effect = [
128 (True, "[]"),
129 (False, sample_ruff_format_check_output),
130 ]
132 result = execute_ruff_check(mock_ruff_tool, ["/test/project"])
134 # Format check subprocess failed, so overall result should be failure
135 assert_that(result.success).is_false()
136 assert_that(result.issues_count).is_equal_to(2)