diff --git a/apps/oxlint/src/output_formatter/junit.rs b/apps/oxlint/src/output_formatter/junit.rs index 89f800497a63a..f780aa6b7cc8a 100644 --- a/apps/oxlint/src/output_formatter/junit.rs +++ b/apps/oxlint/src/output_formatter/junit.rs @@ -33,18 +33,21 @@ impl DiagnosticReporter for JUnitReporter { fn format_junit(diagnostics: &[Error]) -> String { let mut grouped: FxHashMap> = FxHashMap::default(); - let mut total_errors = 0; - let mut total_warnings = 0; for diagnostic in diagnostics { let info = Info::new(diagnostic); grouped.entry(info.filename).or_default().push(diagnostic); } - let mut test_suite = String::new(); - for diagnostics in grouped.values() { - let diagnostic = diagnostics[0]; - let filename = Info::new(diagnostic).filename; + let mut filenames: Vec<_> = grouped.keys().cloned().collect(); + filenames.sort(); + + let mut total_errors = 0; + let mut total_warnings = 0; + let mut test_suites = Vec::new(); + + for filename in filenames { + let diagnostics = grouped.get(&filename).expect("filename collected from map"); let mut test_cases = String::new(); let mut error = 0; let mut warning = 0; @@ -74,23 +77,23 @@ fn format_junit(diagnostics: &[Error]) -> String { ); let test_case = format!("\n \n{status}\n "); - test_cases = format!("{test_cases}{test_case}"); + test_cases.push_str(&test_case); } - test_suite = format!( + test_suites.push(format!( " {}\n ", filename, diagnostics.len(), error, warning, test_cases - ); + )); } let test_suites = format!( "\n{}\n\n", total_errors + total_warnings, total_warnings, total_errors, - test_suite + test_suites.join("\n") ); format!("\n{test_suites}") @@ -132,4 +135,38 @@ mod test { let output = reporter.finish(&DiagnosticResult::default()).unwrap(); assert_eq!(output, EXPECTED_REPORT); } + + #[test] + fn test_junit_reporter_multiple_files() { + const EXPECTED_REPORT: &str = r#" + + + + line 1, column 1, error message a + + + + + line 1, column 1, warning message b + + + +"#; + + let mut reporter = JUnitReporter::default(); + + let error = OxcDiagnostic::error("error message a") + .with_label(Span::new(0, 8)) + .with_source_code(NamedSource::new("a.js", "let a = ;")); + + let warning = OxcDiagnostic::warn("warning message b") + .with_label(Span::new(0, 9)) + .with_source_code(NamedSource::new("b.js", "debugger;")); + + reporter.render_error(error); + reporter.render_error(warning); + + let output = reporter.finish(&DiagnosticResult::default()).unwrap(); + assert_eq!(output, EXPECTED_REPORT); + } }