From bf895eb90d69cabbdbe2d26acaf43a688f88d4ed Mon Sep 17 00:00:00 2001 From: "Alexander S." Date: Sat, 25 Jan 2025 11:51:00 +0100 Subject: [PATCH] test(linter): add diagnostic format test snapshots (#8696) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit windows will fail, looks like the offset missmatch is because of `\r\n` vs `\n`. ``` Snapshot file: apps\oxlint\src\snapshots\--format=json test.js@oxlint.snap Snapshot: --format=json test.js@oxlint Source: C:\dev\oxc:74 ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────-old snapshot +new results ────────────┬───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── 0 0 │ ########## 1 1 │ --format=json test.js 2 2 │ ---------- 3 3 │ [ 4 │- {"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": []}, 4 │+ {"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": 42,"length": 9}}],"related": []}, 5 5 │ {"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": []}, 6 6 │ {"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": []} 7 7 │ ] ────────────┴─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────To update snapshots run `cargo insta review` Stopped on the first failure. Run `cargo insta test` to run all snapshots. thread 'output_formatter::test::test_output_formatter_diagnostic_json' panicked at C:\Users\sysix\.cargo\registry\src\index.crates.io-6f17d22bba15001f\insta-1.42.0\src\runtime.rs:679:13: snapshot assertion for '--format=json test.js@oxlint' failed in line 74 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace ---- output_formatter::test::test_output_formatter_diagnostic_stylish stdout ---- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Snapshot Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━Snapshot file: apps\oxlint\src\snapshots\--format=stylish test.js@oxlint.snap Snapshot: --format=stylish test.js@oxlint Source: C:\dev\oxc:74 ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────-old snapshot +new results ────────────┬───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── 3 3 │ 4 4 │ ␛[4mtest.js␛[0m␊ 5 5 │ ␛[2m9:3 ␛[0m ␛[33mwarning␛[0m Function 'foo' is declared but never used. ␛[2meslint(no-unused-vars)␛[0m␊ 6 6 │ ␛[2m16:1␛[0m ␛[33mwarning␛[0m Parameter 'b' is declared but never used. Unused parameters should start with a '_'. ␛[2meslint(no-unused-vars)␛[0m␊ 7 │- ␛[2m38:9␛[0m ␛[31merror␛[0m `debugger` statement is not allowed ␛[2meslint(no-debugger)␛[0m␊ 7 │+ ␛[2m42:9␛[0m ␛[31merror␛[0m `debugger` statement is not allowed ␛[2meslint(no-debugger)␛[0m␊ 8 8 │ 9 9 │ ␛[31m✖ 3 problems (1 error, 2 warnings)␛[0m ────────────┴─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────To update snapshots run `cargo insta review` Stopped on the first failure. Run `cargo insta test` to run all snapshots. thread 'output_formatter::test::test_output_formatter_diagnostic_stylish' panicked at C:\Users\sysix\.cargo\registry\src\index.crates.io-6f17d22bba15001f\insta-1.42.0\src\runtime.rs:679:13: snapshot assertion for '--format=stylish test.js@oxlint' failed in line 74 failures: output_formatter::test::test_output_formatter_diagnostic_json output_formatter::test::test_output_formatter_diagnostic_stylish test result: FAILED. 85 passed; 2 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.12s ``` --- Cargo.lock | 1 + apps/oxlint/Cargo.toml | 5 +- .../.oxlintrc.json | 6 +++ .../output_formatter_diagnostic/test.js | 5 ++ apps/oxlint/src/output_formatter/default.rs | 29 ++++++----- apps/oxlint/src/output_formatter/mod.rs | 50 +++++++++++++++++++ .../--format=checkstyle test.js@oxlint.snap | 7 +++ .../--format=default test.js@oxlint.snap | 35 +++++++++++++ .../--format=github test.js@oxlint.snap | 9 ++++ .../--format=json test.js@oxlint.snap | 11 ++++ .../--format=stylish test.js@oxlint.snap | 13 +++++ apps/oxlint/src/tester.rs | 10 +++- 12 files changed, 165 insertions(+), 16 deletions(-) create mode 100644 apps/oxlint/fixtures/output_formatter_diagnostic/.oxlintrc.json create mode 100644 apps/oxlint/fixtures/output_formatter_diagnostic/test.js create mode 100644 apps/oxlint/src/snapshots/--format=checkstyle test.js@oxlint.snap create mode 100644 apps/oxlint/src/snapshots/--format=default test.js@oxlint.snap create mode 100644 apps/oxlint/src/snapshots/--format=github test.js@oxlint.snap create mode 100644 apps/oxlint/src/snapshots/--format=json test.js@oxlint.snap create mode 100644 apps/oxlint/src/snapshots/--format=stylish test.js@oxlint.snap diff --git a/Cargo.lock b/Cargo.lock index 32e2183f0..bd3d63e2e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2228,6 +2228,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 1c1bec5e2..19bc43ea2 100644 --- a/apps/oxlint/Cargo.toml +++ b/apps/oxlint/Cargo.toml @@ -37,7 +37,6 @@ oxc_span = { workspace = true } bpaf = { workspace = true, features = ["autocomplete", "bright-color", "derive"] } ignore = { workspace = true, features = ["simd-accel"] } -insta = { workspace = true } miette = { workspace = true } rayon = { workspace = true } rustc-hash = { workspace = true } @@ -46,6 +45,10 @@ serde_json = { workspace = true } tempfile = { workspace = true } tracing-subscriber = { workspace = true, features = [] } # Omit the `regex` feature +[dev-dependencies] +insta = { workspace = true } +regex = { workspace = true } + [features] default = [] allocator = ["dep:jemallocator", "dep:mimalloc"] 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 000000000..1f40dc747 --- /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 000000000..b21b0b337 --- /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 8c2a8b032..6de7da6d3 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 1cfd083f3..061e2eb05 100644 --- a/apps/oxlint/src/output_formatter/mod.rs +++ b/apps/oxlint/src/output_formatter/mod.rs @@ -111,3 +111,53 @@ impl OutputFormatter { self.internal.get_diagnostic_reporter() } } + +#[cfg(test)] +mod test { + use crate::tester::Tester; + + const TEST_CWD: &str = "fixtures/output_formatter_diagnostic"; + + #[test] + fn test_output_formatter_diagnostic_default() { + let args = &["--format=default", "test.js"]; + + Tester::new().with_cwd(TEST_CWD.into()).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 args = &["--format=json", "test.js"]; + + Tester::new().with_cwd(TEST_CWD.into()).test_and_snapshot(args); + } + + #[test] + fn test_output_formatter_diagnostic_checkstyle() { + let args = &["--format=checkstyle", "test.js"]; + + Tester::new().with_cwd(TEST_CWD.into()).test_and_snapshot(args); + } + + #[test] + fn test_output_formatter_diagnostic_github() { + let args = &["--format=github", "test.js"]; + + Tester::new().with_cwd(TEST_CWD.into()).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 args = &["--format=stylish", "test.js"]; + + Tester::new().with_cwd(TEST_CWD.into()).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 000000000..53cd97c1f --- /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 000000000..34516fdf0 --- /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 000000000..57d10d207 --- /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 000000000..ed80afd1f --- /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 000000000..fb00d12c7 --- /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 848437737..acc0681da 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); }); } }