Coverage for tests / unit / parsers / test_oxlint_parser.py: 100%

107 statements  

« prev     ^ index     » next       coverage.py v7.13.0, created at 2026-04-03 18:53 +0000

1"""Unit tests for Oxlint parser functionality.""" 

2 

3from __future__ import annotations 

4 

5from assertpy import assert_that 

6 

7from lintro.parsers.oxlint.oxlint_parser import parse_oxlint_output 

8 

9 

10def test_parse_oxlint_output_empty() -> None: 

11 """Test parsing empty Oxlint output.""" 

12 issues = parse_oxlint_output("") 

13 assert_that(issues).is_empty() 

14 

15 

16def test_parse_oxlint_output_none_string() -> None: 

17 """Test parsing None-like empty Oxlint output.""" 

18 issues = parse_oxlint_output("") 

19 assert_that(issues).is_empty() 

20 

21 issues = parse_oxlint_output(" ") 

22 assert_that(issues).is_empty() 

23 

24 

25def test_parse_oxlint_output_malformed_json() -> None: 

26 """Test parsing malformed JSON Oxlint output.""" 

27 issues = parse_oxlint_output("{invalid json") 

28 assert_that(issues).is_empty() 

29 

30 

31def test_parse_oxlint_output_not_dict() -> None: 

32 """Test parsing Oxlint output that is not a dictionary.""" 

33 issues = parse_oxlint_output("[]") 

34 assert_that(issues).is_empty() 

35 

36 

37def test_parse_oxlint_output_no_json_braces() -> None: 

38 """Test parsing output without JSON object.""" 

39 issues = parse_oxlint_output("some non-json text without braces") 

40 assert_that(issues).is_empty() 

41 

42 

43def test_parse_oxlint_output_single_diagnostic() -> None: 

44 """Test parsing Oxlint output with a single diagnostic.""" 

45 json_output = """{ 

46 "diagnostics": [{ 

47 "message": "Variable 'unused' is declared but never used.", 

48 "code": "eslint(no-unused-vars)", 

49 "severity": "warning", 

50 "filename": "src/test.js", 

51 "labels": [{"span": {"line": 4, "column": 5}}], 

52 "help": "Consider removing or using the variable." 

53 }] 

54 }""" 

55 

56 issues = parse_oxlint_output(json_output) 

57 assert_that(issues).is_length(1) 

58 

59 issue = issues[0] 

60 assert_that(issue.file).is_equal_to("src/test.js") 

61 assert_that(issue.line).is_equal_to(4) 

62 assert_that(issue.column).is_equal_to(5) 

63 assert_that(issue.message).is_equal_to( 

64 "Variable 'unused' is declared but never used.", 

65 ) 

66 assert_that(issue.code).is_equal_to("eslint(no-unused-vars)") 

67 assert_that(issue.severity).is_equal_to("warning") 

68 assert_that(issue.fixable).is_false() 

69 assert_that(issue.help).is_equal_to("Consider removing or using the variable.") 

70 

71 

72def test_parse_oxlint_output_multiple_diagnostics() -> None: 

73 """Test parsing Oxlint output with multiple diagnostics.""" 

74 json_output = """{ 

75 "diagnostics": [ 

76 { 

77 "message": "Variable 'unused' is declared but never used.", 

78 "code": "eslint(no-unused-vars)", 

79 "severity": "warning", 

80 "filename": "src/test.js", 

81 "labels": [{"span": {"line": 4, "column": 5}}] 

82 }, 

83 { 

84 "message": "Using == may be unsafe.", 

85 "code": "eslint(eqeqeq)", 

86 "severity": "error", 

87 "filename": "src/test.js", 

88 "labels": [{"span": {"line": 10, "column": 12}}] 

89 } 

90 ] 

91 }""" 

92 

93 issues = parse_oxlint_output(json_output) 

94 assert_that(issues).is_length(2) 

95 

96 # First issue (warning) 

97 assert_that(issues[0].severity).is_equal_to("warning") 

98 assert_that(issues[0].code).is_equal_to("eslint(no-unused-vars)") 

99 assert_that(issues[0].line).is_equal_to(4) 

100 

101 # Second issue (error) 

102 assert_that(issues[1].severity).is_equal_to("error") 

103 assert_that(issues[1].code).is_equal_to("eslint(eqeqeq)") 

104 assert_that(issues[1].line).is_equal_to(10) 

105 

106 

107def test_parse_oxlint_output_missing_filename() -> None: 

108 """Test parsing Oxlint output with missing filename.""" 

109 json_output = """{ 

110 "diagnostics": [{ 

111 "message": "Test error", 

112 "code": "test-rule", 

113 "severity": "error", 

114 "labels": [{"span": {"line": 1, "column": 1}}] 

115 }] 

116 }""" 

117 

118 issues = parse_oxlint_output(json_output) 

119 assert_that(issues).is_empty() 

120 

121 

122def test_parse_oxlint_output_missing_labels() -> None: 

123 """Test parsing Oxlint output with missing labels. 

124 

125 When labels are missing, parser defaults to line=1, column=1 

126 (1-based numbering, defaults to start of file). 

127 """ 

128 json_output = """{ 

129 "diagnostics": [{ 

130 "message": "Test error", 

131 "code": "test-rule", 

132 "severity": "error", 

133 "filename": "test.js" 

134 }] 

135 }""" 

136 

137 issues = parse_oxlint_output(json_output) 

138 assert_that(issues).is_length(1) 

139 issue = issues[0] 

140 assert_that(issue.line).is_equal_to(1) 

141 assert_that(issue.column).is_equal_to(1) 

142 

143 

144def test_parse_oxlint_output_empty_labels() -> None: 

145 """Test parsing Oxlint output with empty labels array. 

146 

147 When labels array is empty, parser defaults to line=1, column=1 

148 (1-based numbering, defaults to start of file). 

149 """ 

150 json_output = """{ 

151 "diagnostics": [{ 

152 "message": "Test error", 

153 "code": "test-rule", 

154 "severity": "error", 

155 "filename": "test.js", 

156 "labels": [] 

157 }] 

158 }""" 

159 

160 issues = parse_oxlint_output(json_output) 

161 assert_that(issues).is_length(1) 

162 issue = issues[0] 

163 assert_that(issue.line).is_equal_to(1) 

164 assert_that(issue.column).is_equal_to(1) 

165 

166 

167def test_parse_oxlint_output_missing_span() -> None: 

168 """Test parsing Oxlint output with labels but missing span. 

169 

170 When span is missing from label, parser defaults to line=1, column=1 

171 (1-based numbering, defaults to start of file). 

172 """ 

173 json_output = """{ 

174 "diagnostics": [{ 

175 "message": "Test error", 

176 "code": "test-rule", 

177 "severity": "error", 

178 "filename": "test.js", 

179 "labels": [{}] 

180 }] 

181 }""" 

182 

183 issues = parse_oxlint_output(json_output) 

184 assert_that(issues).is_length(1) 

185 issue = issues[0] 

186 assert_that(issue.line).is_equal_to(1) 

187 assert_that(issue.column).is_equal_to(1) 

188 

189 

190def test_parse_oxlint_output_with_extra_text() -> None: 

191 """Test parsing Oxlint output with extra text after JSON.""" 

192 json_content = ( 

193 '{"diagnostics": [{"message": "Test error", "code": "test-rule", ' 

194 '"severity": "error", "filename": "test.js", ' 

195 '"labels": [{"span": {"line": 1, "column": 1}}]}]}' 

196 ) 

197 extra_text = "\nSome extra output from oxlint...\n" 

198 

199 issues = parse_oxlint_output(json_content + extra_text) 

200 assert_that(issues).is_length(1) 

201 assert_that(issues[0].file).is_equal_to("test.js") 

202 

203 

204def test_parse_oxlint_output_with_prefix_text() -> None: 

205 """Test parsing Oxlint output with prefix text before JSON.""" 

206 json_content = ( 

207 '{"diagnostics": [{"message": "Test error", "code": "test-rule", ' 

208 '"severity": "error", "filename": "test.js", ' 

209 '"labels": [{"span": {"line": 1, "column": 1}}]}]}' 

210 ) 

211 prefix_text = "Running oxlint...\n" 

212 

213 issues = parse_oxlint_output(prefix_text + json_content) 

214 assert_that(issues).is_length(1) 

215 assert_that(issues[0].file).is_equal_to("test.js") 

216 

217 

218def test_parse_oxlint_output_missing_optional_fields() -> None: 

219 """Test parsing Oxlint output with missing optional fields.""" 

220 json_output = """{ 

221 "diagnostics": [{ 

222 "filename": "test.js", 

223 "labels": [{"span": {"line": 1, "column": 1}}] 

224 }] 

225 }""" 

226 

227 issues = parse_oxlint_output(json_output) 

228 assert_that(issues).is_length(1) 

229 

230 issue = issues[0] 

231 assert_that(issue.file).is_equal_to("test.js") 

232 assert_that(issue.message).is_equal_to("") 

233 assert_that(issue.code).is_equal_to("") 

234 assert_that(issue.severity).is_equal_to("warning") # Default 

235 assert_that(issue.help).is_none() 

236 

237 

238def test_parse_oxlint_output_diagnostics_not_list() -> None: 

239 """Test parsing Oxlint output where diagnostics is not a list.""" 

240 json_output = '{"diagnostics": "not a list"}' 

241 

242 issues = parse_oxlint_output(json_output) 

243 assert_that(issues).is_empty() 

244 

245 

246def test_parse_oxlint_output_diagnostic_not_dict() -> None: 

247 """Test parsing Oxlint output where diagnostic is not a dict.""" 

248 json_output = '{"diagnostics": ["not a dict"]}' 

249 

250 issues = parse_oxlint_output(json_output) 

251 assert_that(issues).is_empty() 

252 

253 

254def test_parse_oxlint_output_empty_filename() -> None: 

255 """Test parsing Oxlint output with empty filename.""" 

256 json_output = """{ 

257 "diagnostics": [{ 

258 "message": "Test error", 

259 "code": "test-rule", 

260 "severity": "error", 

261 "filename": "", 

262 "labels": [{"span": {"line": 1, "column": 1}}] 

263 }] 

264 }""" 

265 

266 issues = parse_oxlint_output(json_output) 

267 assert_that(issues).is_empty() 

268 

269 

270def test_parse_oxlint_output_no_help_field() -> None: 

271 """Test parsing Oxlint output without help field.""" 

272 json_output = """{ 

273 "diagnostics": [{ 

274 "message": "Test error", 

275 "code": "test-rule", 

276 "severity": "error", 

277 "filename": "test.js", 

278 "labels": [{"span": {"line": 1, "column": 1}}] 

279 }] 

280 }""" 

281 

282 issues = parse_oxlint_output(json_output) 

283 assert_that(issues).is_length(1) 

284 assert_that(issues[0].help).is_none()