Coverage for tests / unit / parsers / test_ruff_parser_additional.py: 100%
53 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"""Additional tests for Ruff parser coverage gaps."""
3from __future__ import annotations
5from assertpy import assert_that
7from lintro.parsers.ruff.ruff_parser import parse_ruff_output
10def test_parse_ruff_output_plain_json_array() -> None:
11 """Parse a simple JSON array output into issues list."""
12 output = (
13 "[\n"
14 ' {"filename": "a.py", "location": {"row": 1, "column": 2},'
15 ' "code": "E1", "message": "x"}\n'
16 "]"
17 )
18 issues = parse_ruff_output(output)
19 assert_that(len(issues)).is_equal_to(1)
20 assert_that(issues[0].file.endswith("a.py")).is_true()
23def test_parse_ruff_output_empty_and_malformed_line_skipped() -> None:
24 """Skip empty and malformed lines in JSONL output gracefully."""
25 jl = (
26 "\n\n" # empties ignored
27 '{"filename":"b.py","location":{"row":2,"column":1},"code":"F","message":"m"}\n'
28 "not-json\n" # malformed line skipped
29 )
30 issues = parse_ruff_output(jl)
31 files = [i.file for i in issues]
32 assert_that(files).contains("b.py")
35# =============================================================================
36# Edge case tests
37# =============================================================================
40def test_parse_ruff_output_unicode_file_path() -> None:
41 """Handle Unicode characters in file paths."""
42 output = (
43 '{"filename": "src/código/módulo.py", "location": {"row": 1, "column": 1}, '
44 '"code": "E501", "message": "line too long"}'
45 )
46 issues = parse_ruff_output(output)
47 assert_that(issues).is_length(1)
48 assert_that(issues[0].file).contains("módulo.py")
51def test_parse_ruff_output_file_path_with_spaces() -> None:
52 """Handle file paths with spaces."""
53 output = (
54 '{"filename": "my project/source files/main.py", '
55 '"location": {"row": 5, "column": 10}, "code": "F401", "message": "unused"}'
56 )
57 issues = parse_ruff_output(output)
58 assert_that(issues).is_length(1)
59 assert_that(issues[0].file).contains("my project")
62def test_parse_ruff_output_special_chars_in_message() -> None:
63 """Handle special characters in error messages."""
64 output = (
65 '{"filename": "test.py", "location": {"row": 1, "column": 1}, '
66 '"code": "E501", "message": "Line contains \\"quotes\\" and <brackets>"}'
67 )
68 issues = parse_ruff_output(output)
69 assert_that(issues).is_length(1)
70 assert_that(issues[0].message).contains("quotes")
73def test_parse_ruff_output_null_values_handled() -> None:
74 """Handle null values in JSON output gracefully."""
75 output = (
76 '{"filename": "test.py", "location": {"row": 1, "column": null}, '
77 '"code": "E501", "message": "error"}'
78 )
79 issues = parse_ruff_output(output)
80 # Should either parse with default column or handle gracefully
81 assert_that(issues).is_length(1)
84def test_parse_ruff_output_very_long_file_path() -> None:
85 """Handle very long file paths."""
86 long_path = "src/" + "nested/" * 50 + "deep_file.py"
87 output = (
88 f'{{"filename": "{long_path}", "location": {{"row": 1, "column": 1}}, '
89 '"code": "E501", "message": "error"}'
90 )
91 issues = parse_ruff_output(output)
92 assert_that(issues).is_length(1)
93 assert_that(issues[0].file).contains("deep_file.py")
96def test_parse_ruff_output_extremely_long_message() -> None:
97 """Handle extremely long error messages."""
98 long_message = "x" * 10000
99 output = (
100 f'{{"filename": "test.py", "location": {{"row": 1, "column": 1}}, '
101 f'"code": "E501", "message": "{long_message}"}}'
102 )
103 issues = parse_ruff_output(output)
104 assert_that(issues).is_length(1)
105 assert_that(len(issues[0].message)).is_equal_to(10000)
108def test_parse_ruff_output_zero_line_number() -> None:
109 """Handle zero line number (edge case)."""
110 output = (
111 '{"filename": "test.py", "location": {"row": 0, "column": 1}, '
112 '"code": "E501", "message": "error"}'
113 )
114 issues = parse_ruff_output(output)
115 assert_that(issues).is_length(1)
116 assert_that(issues[0].line).is_equal_to(0)
119def test_parse_ruff_output_negative_column() -> None:
120 """Handle negative column number gracefully."""
121 output = (
122 '{"filename": "test.py", "location": {"row": 1, "column": -1}, '
123 '"code": "E501", "message": "error"}'
124 )
125 issues = parse_ruff_output(output)
126 # Should handle gracefully without crashing
127 assert_that(issues).is_length(1)