diff --git a/Cargo.lock b/Cargo.lock index a6756661b6ce8a..36d8e1388be839 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2227,6 +2227,7 @@ dependencies = [ "oxc_linter", "oxc_span", "rayon", + "regex", "rustc-hash", "serde", "serde_json", diff --git a/apps/oxlint/Cargo.toml b/apps/oxlint/Cargo.toml index 1c1bec5e2bd371..f525bc37f15db6 100644 --- a/apps/oxlint/Cargo.toml +++ b/apps/oxlint/Cargo.toml @@ -40,6 +40,7 @@ ignore = { workspace = true, features = ["simd-accel"] } insta = { workspace = true } miette = { workspace = true } rayon = { workspace = true } +regex = { workspace = true } rustc-hash = { workspace = true } serde = { workspace = true } serde_json = { workspace = true } diff --git a/apps/oxlint/fixtures/output_formatter_diagnostic/.oxlintrc.json b/apps/oxlint/fixtures/output_formatter_diagnostic/.oxlintrc.json new file mode 100644 index 00000000000000..1f40dc74759bb6 --- /dev/null +++ b/apps/oxlint/fixtures/output_formatter_diagnostic/.oxlintrc.json @@ -0,0 +1,6 @@ +{ + "rules": { + "no-debugger": "error", + "no-unused-vars": "warn" + } +} \ No newline at end of file diff --git a/apps/oxlint/fixtures/output_formatter_diagnostic/test.js b/apps/oxlint/fixtures/output_formatter_diagnostic/test.js new file mode 100644 index 00000000000000..b21b0b3376cc26 --- /dev/null +++ b/apps/oxlint/fixtures/output_formatter_diagnostic/test.js @@ -0,0 +1,5 @@ +function foo(a, b) { + return a; +} + +debugger; diff --git a/apps/oxlint/src/output_formatter/default.rs b/apps/oxlint/src/output_formatter/default.rs index 8c2a8b032823f2..6de7da6d35d3b1 100644 --- a/apps/oxlint/src/output_formatter/default.rs +++ b/apps/oxlint/src/output_formatter/default.rs @@ -1,13 +1,12 @@ use std::time::Duration; +use crate::output_formatter::InternalFormatter; use oxc_diagnostics::{ reporter::{DiagnosticReporter, DiagnosticResult}, Error, GraphicalReportHandler, }; use oxc_linter::table::RuleTable; -use crate::output_formatter::InternalFormatter; - #[derive(Debug)] pub struct DefaultOutputFormatter; @@ -59,12 +58,25 @@ struct GraphicalReporter { handler: GraphicalReportHandler, } +#[cfg(not(test))] impl Default for GraphicalReporter { fn default() -> Self { Self { handler: GraphicalReportHandler::new() } } } +#[cfg(test)] +use oxc_diagnostics::GraphicalTheme; + +/// we need to override the GraphicalReport for the tests +/// because our CI can not handle colors output and [`GraphicalReportHandler`] will auto detect the environment +#[cfg(test)] +impl Default for GraphicalReporter { + fn default() -> Self { + Self { handler: GraphicalReportHandler::new_themed(GraphicalTheme::none()) } + } +} + impl DiagnosticReporter for GraphicalReporter { fn finish(&mut self, result: &DiagnosticResult) -> Option { let mut output = String::new(); @@ -103,13 +115,6 @@ impl DiagnosticReporter for GraphicalReporter { Some(output) } } -impl GraphicalReporter { - #[cfg(test)] - pub fn with_handler(mut self, handler: GraphicalReportHandler) -> Self { - self.handler = handler; - self - } -} #[cfg(test)] mod test { @@ -119,7 +124,7 @@ mod test { default::{DefaultOutputFormatter, GraphicalReporter}, InternalFormatter, LintCommandInfo, }; - use miette::{GraphicalReportHandler, GraphicalTheme, NamedSource}; + use miette::NamedSource; use oxc_diagnostics::{ reporter::{DiagnosticReporter, DiagnosticResult}, OxcDiagnostic, @@ -196,9 +201,7 @@ mod test { #[test] fn reporter_error() { - let mut reporter = GraphicalReporter::default().with_handler( - GraphicalReportHandler::new_themed(GraphicalTheme::none()).with_links(false), - ); + let mut reporter = GraphicalReporter::default(); let error = OxcDiagnostic::warn("error message") .with_label(Span::new(0, 8)) diff --git a/apps/oxlint/src/output_formatter/mod.rs b/apps/oxlint/src/output_formatter/mod.rs index 1cfd083f38f1e0..16c6bcdfd3fc80 100644 --- a/apps/oxlint/src/output_formatter/mod.rs +++ b/apps/oxlint/src/output_formatter/mod.rs @@ -111,3 +111,58 @@ impl OutputFormatter { self.internal.get_diagnostic_reporter() } } + +#[cfg(test)] +mod test { + use std::path::PathBuf; + + use crate::tester::Tester; + + #[test] + fn test_output_formatter_diagnostic_default() { + let cwd: PathBuf = "fixtures/output_formatter_diagnostic".into(); + let args = &["--format=default", "test.js"]; + + Tester::new().with_cwd(cwd.clone()).test_and_snapshot(args); + } + + /// disabled for windows + /// json will output the offset which will be different for windows + /// when there are multiple lines (`\r\n` vs `\n`) + #[cfg(all(test, not(target_os = "windows")))] + #[test] + fn test_output_formatter_diagnostic_json() { + let cwd: PathBuf = "fixtures/output_formatter_diagnostic".into(); + let args = &["--format=json", "test.js"]; + + Tester::new().with_cwd(cwd.clone()).test_and_snapshot(args); + } + + #[test] + fn test_output_formatter_diagnostic_checkstyle() { + let cwd: PathBuf = "fixtures/output_formatter_diagnostic".into(); + let args = &["--format=checkstyle", "test.js"]; + + Tester::new().with_cwd(cwd.clone()).test_and_snapshot(args); + } + + #[test] + fn test_output_formatter_diagnostic_github() { + let cwd: PathBuf = "fixtures/output_formatter_diagnostic".into(); + let args = &["--format=github", "test.js"]; + + Tester::new().with_cwd(cwd.clone()).test_and_snapshot(args); + } + + /// disabled for windows + /// stylish will output the offset which will be different for windows + /// when there are multiple lines (`\r\n` vs `\n`) + #[cfg(all(test, not(target_os = "windows")))] + #[test] + fn test_output_formatter_diagnostic_stylish() { + let cwd: PathBuf = "fixtures/output_formatter_diagnostic".into(); + let args = &["--format=stylish", "test.js"]; + + Tester::new().with_cwd(cwd.clone()).test_and_snapshot(args); + } +} diff --git a/apps/oxlint/src/snapshots/--format=checkstyle test.js@oxlint.snap b/apps/oxlint/src/snapshots/--format=checkstyle test.js@oxlint.snap new file mode 100644 index 00000000000000..53cd97c1ff64c3 --- /dev/null +++ b/apps/oxlint/src/snapshots/--format=checkstyle test.js@oxlint.snap @@ -0,0 +1,7 @@ +--- +source: apps/oxlint/src/tester.rs +--- +########## +--format=checkstyle test.js +---------- + diff --git a/apps/oxlint/src/snapshots/--format=default test.js@oxlint.snap b/apps/oxlint/src/snapshots/--format=default test.js@oxlint.snap new file mode 100644 index 00000000000000..34516fdf0481ec --- /dev/null +++ b/apps/oxlint/src/snapshots/--format=default test.js@oxlint.snap @@ -0,0 +1,35 @@ +--- +source: apps/oxlint/src/tester.rs +--- +########## +--format=default test.js +---------- + + x ]8;;https://oxc.rs/docs/guide/usage/linter/rules/eslint/no-debugger.html\eslint(no-debugger)]8;;\: `debugger` statement is not allowed + ,-[test.js:5:1] + 4 | + 5 | debugger; + : ^^^^^^^^^ + `---- + help: Delete this code. + + ! ]8;;https://oxc.rs/docs/guide/usage/linter/rules/eslint/no-unused-vars.html\eslint(no-unused-vars)]8;;\: Function 'foo' is declared but never used. + ,-[test.js:1:10] + 1 | function foo(a, b) { + : ^|^ + : `-- 'foo' is declared here + 2 | return a; + `---- + help: Consider removing this declaration. + + ! ]8;;https://oxc.rs/docs/guide/usage/linter/rules/eslint/no-unused-vars.html\eslint(no-unused-vars)]8;;\: Parameter 'b' is declared but never used. Unused parameters should start with a '_'. + ,-[test.js:1:17] + 1 | function foo(a, b) { + : | + : `-- 'b' is declared here + 2 | return a; + `---- + help: Consider removing this parameter. + +Found 2 warnings and 1 error. +Finished in on 1 file with 97 rules using . diff --git a/apps/oxlint/src/snapshots/--format=github test.js@oxlint.snap b/apps/oxlint/src/snapshots/--format=github test.js@oxlint.snap new file mode 100644 index 00000000000000..57d10d20772026 --- /dev/null +++ b/apps/oxlint/src/snapshots/--format=github test.js@oxlint.snap @@ -0,0 +1,9 @@ +--- +source: apps/oxlint/src/tester.rs +--- +########## +--format=github test.js +---------- +::error file=test.js,line=5,endLine=5,col=1,endColumn=10,title=oxlint::`debugger` statement is not allowed +::warning file=test.js,line=1,endLine=1,col=10,endColumn=13,title=oxlint::Function 'foo' is declared but never used. +::warning file=test.js,line=1,endLine=1,col=17,endColumn=18,title=oxlint::Parameter 'b' is declared but never used. Unused parameters should start with a '_'. diff --git a/apps/oxlint/src/snapshots/--format=json test.js@oxlint.snap b/apps/oxlint/src/snapshots/--format=json test.js@oxlint.snap new file mode 100644 index 00000000000000..ed80afd1fec6a2 --- /dev/null +++ b/apps/oxlint/src/snapshots/--format=json test.js@oxlint.snap @@ -0,0 +1,11 @@ +--- +source: apps/oxlint/src/tester.rs +--- +########## +--format=json test.js +---------- +[ + {"message": "`debugger` statement is not allowed","code": "eslint(no-debugger)","severity": "error","causes": [],"url": "https://oxc.rs/docs/guide/usage/linter/rules/eslint/no-debugger.html","help": "Delete this code.","filename": "test.js","labels": [{"span": {"offset": 38,"length": 9}}],"related": []}, + {"message": "Function 'foo' is declared but never used.","code": "eslint(no-unused-vars)","severity": "warning","causes": [],"url": "https://oxc.rs/docs/guide/usage/linter/rules/eslint/no-unused-vars.html","help": "Consider removing this declaration.","filename": "test.js","labels": [{"label": "'foo' is declared here","span": {"offset": 9,"length": 3}}],"related": []}, + {"message": "Parameter 'b' is declared but never used. Unused parameters should start with a '_'.","code": "eslint(no-unused-vars)","severity": "warning","causes": [],"url": "https://oxc.rs/docs/guide/usage/linter/rules/eslint/no-unused-vars.html","help": "Consider removing this parameter.","filename": "test.js","labels": [{"label": "'b' is declared here","span": {"offset": 16,"length": 1}}],"related": []} +] diff --git a/apps/oxlint/src/snapshots/--format=stylish test.js@oxlint.snap b/apps/oxlint/src/snapshots/--format=stylish test.js@oxlint.snap new file mode 100644 index 00000000000000..fb00d12c7ef5b2 --- /dev/null +++ b/apps/oxlint/src/snapshots/--format=stylish test.js@oxlint.snap @@ -0,0 +1,13 @@ +--- +source: apps/oxlint/src/tester.rs +--- +########## +--format=stylish test.js +---------- + +test.js + 9:3  warning Function 'foo' is declared but never used. eslint(no-unused-vars) + 16:1 warning Parameter 'b' is declared but never used. Unused parameters should start with a '_'. eslint(no-unused-vars) + 38:9 error `debugger` statement is not allowed eslint(no-debugger) + +✖ 3 problems (1 error, 2 warnings) diff --git a/apps/oxlint/src/tester.rs b/apps/oxlint/src/tester.rs index 848437737f8c81..acc0681daa1002 100644 --- a/apps/oxlint/src/tester.rs +++ b/apps/oxlint/src/tester.rs @@ -3,8 +3,9 @@ use crate::cli::{lint_command, CliRunResult, LintResult, LintRunner}; #[cfg(test)] use crate::runner::Runner; #[cfg(test)] +use regex::Regex; +#[cfg(test)] use std::{env, path::PathBuf}; - #[cfg(test)] pub struct Tester { cwd: PathBuf, @@ -64,8 +65,13 @@ impl Tester { settings.set_omit_expression(true); settings.set_snapshot_suffix("oxlint"); + let regex = Regex::new(r"\d+ms|\d+ threads?").unwrap(); + + let output_string = &String::from_utf8(output).unwrap(); + let output_string = regex.replace_all(output_string, ""); + settings.bind(|| { - insta::assert_snapshot!(format!("{}", args_string), String::from_utf8(output).unwrap()); + insta::assert_snapshot!(format!("{}", args_string), output_string); }); } }