From 6dd71c6d050630fe3ee29728f906884ab627987a Mon Sep 17 00:00:00 2001 From: camc314 <18101008+camc314@users.noreply.github.com> Date: Tue, 3 Dec 2024 13:15:49 +0000 Subject: [PATCH] test(linter): port eslint tests to no-unused-expressions (#7611) --- .../rules/typescript/no_unused_expressions.rs | 103 +++++++ .../typescript_no_unused_expressions.snap | 256 ++++++++++++++++++ 2 files changed, 359 insertions(+) diff --git a/crates/oxc_linter/src/rules/typescript/no_unused_expressions.rs b/crates/oxc_linter/src/rules/typescript/no_unused_expressions.rs index 374b4e30e4185..9b3ccec059a53 100644 --- a/crates/oxc_linter/src/rules/typescript/no_unused_expressions.rs +++ b/crates/oxc_linter/src/rules/typescript/no_unused_expressions.rs @@ -191,6 +191,57 @@ fn test() { use crate::tester::Tester; let pass = vec![ + // https://github.com/eslint/eslint/blob/946ae00457265eb298eb169d6d48ca7ec71b9eef/tests/lib/rules/no-unused-expressions.js#L21 + ("function f(){}", None), + ("a = b", None), + ("new a", None), + ("{}", None), + ("f(); g()", None), + ("i++", None), + ("a()", None), + ("a && a()", Some(serde_json::json!([{ "allowShortCircuit": true }]))), + ("a() || (b = c)", Some(serde_json::json!([{ "allowShortCircuit": true }]))), + ("a ? b() : c()", Some(serde_json::json!([{ "allowTernary": true }]))), + ( + "a ? b() || (c = d) : e()", + Some(serde_json::json!([{ "allowShortCircuit": true, "allowTernary": true }])), + ), + ("delete foo.bar", None), + ("void new C", None), + (r#""use strict";"#, None), + (r#""directive one"; "directive two"; f();"#, None), + (r#"function foo() {"use strict"; return true; }"#, None), + (r#"var foo = () => {"use strict"; return true; }"#, None), // { "ecmaVersion": 6 }, + (r#"function foo() {"directive one"; "directive two"; f(); }"#, None), + (r#"function foo() { var foo = "use strict"; return true; }"#, None), + ("function* foo(){ yield 0; }", None), // { "ecmaVersion": 6 }, + ("async function foo() { await 5; }", None), // { "ecmaVersion": 8 }, + ("async function foo() { await foo.bar; }", None), // { "ecmaVersion": 8 }, + ( + "async function foo() { bar && await baz; }", + Some(serde_json::json!([{ "allowShortCircuit": true }])), + ), // { "ecmaVersion": 8 }, + ( + "async function foo() { foo ? await bar : await baz; }", + Some(serde_json::json!([{ "allowTernary": true }])), + ), // { "ecmaVersion": 8 }, + ( + "tag`tagged template literal`", + Some(serde_json::json!([{ "allowTaggedTemplates": true }])), + ), // { "ecmaVersion": 6 }, + ( + "shouldNotBeAffectedByAllowTemplateTagsOption()", + Some(serde_json::json!([{ "allowTaggedTemplates": true }])), + ), // { "ecmaVersion": 6 }, + (r#"import("foo")"#, None), // { "ecmaVersion": 11 }, + (r#"func?.("foo")"#, None), // { "ecmaVersion": 11 }, + (r#"obj?.foo("bar")"#, None), // { "ecmaVersion": 11 }, + ("
", None), // { "parserOptions": { "ecmaFeatures": { "jsx": true } } }, + ("<>>", None), // { "parserOptions": { "ecmaFeatures": { "jsx": true } } }, + ("var partial = ", None), // { "parserOptions": { "ecmaFeatures": { "jsx": true } } }, + ("var partial = ", Some(serde_json::json!([{ "enforceForJSX": true }]))), // { "parserOptions": { "ecmaFeatures": { "jsx": true } } }, + ("var partial = <>>", Some(serde_json::json!([{ "enforceForJSX": true }]))), // { "parserOptions": { "ecmaFeatures": { "jsx": true } } } + // https://github.com/typescript-eslint/typescript-eslint/blob/32a7a7061abba5bbf1403230526514768d3e2760/packages/eslint-plugin/tests/rules/no-unused-expressions.test.ts#L29 ( " test.age?.toLocaleString(); @@ -285,6 +336,58 @@ fn test() { ]; let fail = vec![ + // https://github.com/eslint/eslint/blob/946ae00457265eb298eb169d6d48ca7ec71b9eef/tests/lib/rules/no-unused-expressions.js#L111 + ("0", None), + ("a", None), + ("f(), 0", None), + ("{0}", None), + ("[]", None), + ("a && b();", None), + ("a() || false", None), + ("a || (b = c)", None), + ("a ? b() || (c = d) : e", None), + ("`untagged template literal`", None), // { "ecmaVersion": 6 }, + ("tag`tagged template literal`", None), // { "ecmaVersion": 6 }, + ("a && b()", Some(serde_json::json!([{ "allowTernary": true }]))), + ("a ? b() : c()", Some(serde_json::json!([{ "allowShortCircuit": true }]))), + ("a || b", Some(serde_json::json!([{ "allowShortCircuit": true }]))), + ("a() && b", Some(serde_json::json!([{ "allowShortCircuit": true }]))), + ("a ? b : 0", Some(serde_json::json!([{ "allowTernary": true }]))), + ("a ? b : c()", Some(serde_json::json!([{ "allowTernary": true }]))), + ("foo.bar;", None), + ("!a", None), + ("+a", None), + (r#""directive one"; f(); "directive two";"#, None), + (r#"function foo() {"directive one"; f(); "directive two"; }"#, None), + (r#"if (0) { "not a directive"; f(); }"#, None), + (r#"function foo() { var foo = true; "use strict"; }"#, None), + (r#"var foo = () => { var foo = true; "use strict"; }"#, None), // { "ecmaVersion": 6 }, + ( + "`untagged template literal`", + Some(serde_json::json!([{ "allowTaggedTemplates": true }])), + ), // { "ecmaVersion": 6 }, + ( + "`untagged template literal`", + Some(serde_json::json!([{ "allowTaggedTemplates": false }])), + ), // { "ecmaVersion": 6 }, + ( + "tag`tagged template literal`", + Some(serde_json::json!([{ "allowTaggedTemplates": false }])), + ), // { "ecmaVersion": 6 }, + ("obj?.foo", None), // { "ecmaVersion": 2020 }, + ("obj?.foo.bar", None), // { "ecmaVersion": 2020 }, + ("obj?.foo().bar", None), // { "ecmaVersion": 2020 }, + ("", Some(serde_json::json!([{ "enforceForJSX": true }]))), // { "parserOptions": { "ecmaFeatures": { "jsx": true } } }, + ("<>>", Some(serde_json::json!([{ "enforceForJSX": true }]))), // { "parserOptions": { "ecmaFeatures": { "jsx": true } } }, + ("class C { static { 'use strict'; } }", None), // { "ecmaVersion": 2022 }, + ( + "class C { static { + 'foo' + 'bar' + } }", + None, + ), // { "ecmaVersion": 2022 } + // https://github.com/typescript-eslint/typescript-eslint/blob/32a7a7061abba5bbf1403230526514768d3e2760/packages/eslint-plugin/tests/rules/no-unused-expressions.test.ts#L91 ( " if (0) 0; diff --git a/crates/oxc_linter/src/snapshots/typescript_no_unused_expressions.snap b/crates/oxc_linter/src/snapshots/typescript_no_unused_expressions.snap index d06ee11f31264..39fda8439bca9 100644 --- a/crates/oxc_linter/src/snapshots/typescript_no_unused_expressions.snap +++ b/crates/oxc_linter/src/snapshots/typescript_no_unused_expressions.snap @@ -1,6 +1,262 @@ --- source: crates/oxc_linter/src/tester.rs --- + ⚠ typescript-eslint(no-unused-expressions): Disallow unused expressions + ╭─[no_unused_expressions.tsx:1:1] + 1 │ 0 + · ─ + ╰──── + help: Consider removing this expression + + ⚠ typescript-eslint(no-unused-expressions): Disallow unused expressions + ╭─[no_unused_expressions.tsx:1:1] + 1 │ a + · ─ + ╰──── + help: Consider removing this expression + + ⚠ typescript-eslint(no-unused-expressions): Disallow unused expressions + ╭─[no_unused_expressions.tsx:1:1] + 1 │ f(), 0 + · ────── + ╰──── + help: Consider removing this expression + + ⚠ typescript-eslint(no-unused-expressions): Disallow unused expressions + ╭─[no_unused_expressions.tsx:1:2] + 1 │ {0} + · ─ + ╰──── + help: Consider removing this expression + + ⚠ typescript-eslint(no-unused-expressions): Disallow unused expressions + ╭─[no_unused_expressions.tsx:1:1] + 1 │ [] + · ── + ╰──── + help: Consider removing this expression + + ⚠ typescript-eslint(no-unused-expressions): Disallow unused expressions + ╭─[no_unused_expressions.tsx:1:1] + 1 │ a && b(); + · ───────── + ╰──── + help: Consider removing this expression + + ⚠ typescript-eslint(no-unused-expressions): Disallow unused expressions + ╭─[no_unused_expressions.tsx:1:1] + 1 │ a() || false + · ──────────── + ╰──── + help: Consider removing this expression + + ⚠ typescript-eslint(no-unused-expressions): Disallow unused expressions + ╭─[no_unused_expressions.tsx:1:1] + 1 │ a || (b = c) + · ──────────── + ╰──── + help: Consider removing this expression + + ⚠ typescript-eslint(no-unused-expressions): Disallow unused expressions + ╭─[no_unused_expressions.tsx:1:1] + 1 │ a ? b() || (c = d) : e + · ────────────────────── + ╰──── + help: Consider removing this expression + + ⚠ typescript-eslint(no-unused-expressions): Disallow unused expressions + ╭─[no_unused_expressions.tsx:1:1] + 1 │ `untagged template literal` + · ─────────────────────────── + ╰──── + help: Consider removing this expression + + ⚠ typescript-eslint(no-unused-expressions): Disallow unused expressions + ╭─[no_unused_expressions.tsx:1:1] + 1 │ tag`tagged template literal` + · ──────────────────────────── + ╰──── + help: Consider removing this expression + + ⚠ typescript-eslint(no-unused-expressions): Disallow unused expressions + ╭─[no_unused_expressions.tsx:1:1] + 1 │ a && b() + · ──────── + ╰──── + help: Consider removing this expression + + ⚠ typescript-eslint(no-unused-expressions): Disallow unused expressions + ╭─[no_unused_expressions.tsx:1:1] + 1 │ a ? b() : c() + · ───────────── + ╰──── + help: Consider removing this expression + + ⚠ typescript-eslint(no-unused-expressions): Disallow unused expressions + ╭─[no_unused_expressions.tsx:1:1] + 1 │ a || b + · ────── + ╰──── + help: Consider removing this expression + + ⚠ typescript-eslint(no-unused-expressions): Disallow unused expressions + ╭─[no_unused_expressions.tsx:1:1] + 1 │ a() && b + · ──────── + ╰──── + help: Consider removing this expression + + ⚠ typescript-eslint(no-unused-expressions): Disallow unused expressions + ╭─[no_unused_expressions.tsx:1:1] + 1 │ a ? b : 0 + · ───────── + ╰──── + help: Consider removing this expression + + ⚠ typescript-eslint(no-unused-expressions): Disallow unused expressions + ╭─[no_unused_expressions.tsx:1:1] + 1 │ a ? b : c() + · ─────────── + ╰──── + help: Consider removing this expression + + ⚠ typescript-eslint(no-unused-expressions): Disallow unused expressions + ╭─[no_unused_expressions.tsx:1:1] + 1 │ foo.bar; + · ──────── + ╰──── + help: Consider removing this expression + + ⚠ typescript-eslint(no-unused-expressions): Disallow unused expressions + ╭─[no_unused_expressions.tsx:1:1] + 1 │ !a + · ── + ╰──── + help: Consider removing this expression + + ⚠ typescript-eslint(no-unused-expressions): Disallow unused expressions + ╭─[no_unused_expressions.tsx:1:1] + 1 │ +a + · ── + ╰──── + help: Consider removing this expression + + ⚠ typescript-eslint(no-unused-expressions): Disallow unused expressions + ╭─[no_unused_expressions.tsx:1:23] + 1 │ "directive one"; f(); "directive two"; + · ──────────────── + ╰──── + help: Consider removing this expression + + ⚠ typescript-eslint(no-unused-expressions): Disallow unused expressions + ╭─[no_unused_expressions.tsx:1:39] + 1 │ function foo() {"directive one"; f(); "directive two"; } + · ──────────────── + ╰──── + help: Consider removing this expression + + ⚠ typescript-eslint(no-unused-expressions): Disallow unused expressions + ╭─[no_unused_expressions.tsx:1:10] + 1 │ if (0) { "not a directive"; f(); } + · ────────────────── + ╰──── + help: Consider removing this expression + + ⚠ typescript-eslint(no-unused-expressions): Disallow unused expressions + ╭─[no_unused_expressions.tsx:1:34] + 1 │ function foo() { var foo = true; "use strict"; } + · ───────────── + ╰──── + help: Consider removing this expression + + ⚠ typescript-eslint(no-unused-expressions): Disallow unused expressions + ╭─[no_unused_expressions.tsx:1:35] + 1 │ var foo = () => { var foo = true; "use strict"; } + · ───────────── + ╰──── + help: Consider removing this expression + + ⚠ typescript-eslint(no-unused-expressions): Disallow unused expressions + ╭─[no_unused_expressions.tsx:1:1] + 1 │ `untagged template literal` + · ─────────────────────────── + ╰──── + help: Consider removing this expression + + ⚠ typescript-eslint(no-unused-expressions): Disallow unused expressions + ╭─[no_unused_expressions.tsx:1:1] + 1 │ `untagged template literal` + · ─────────────────────────── + ╰──── + help: Consider removing this expression + + ⚠ typescript-eslint(no-unused-expressions): Disallow unused expressions + ╭─[no_unused_expressions.tsx:1:1] + 1 │ tag`tagged template literal` + · ──────────────────────────── + ╰──── + help: Consider removing this expression + + ⚠ typescript-eslint(no-unused-expressions): Disallow unused expressions + ╭─[no_unused_expressions.tsx:1:1] + 1 │ obj?.foo + · ──────── + ╰──── + help: Consider removing this expression + + ⚠ typescript-eslint(no-unused-expressions): Disallow unused expressions + ╭─[no_unused_expressions.tsx:1:1] + 1 │ obj?.foo.bar + · ──────────── + ╰──── + help: Consider removing this expression + + ⚠ typescript-eslint(no-unused-expressions): Disallow unused expressions + ╭─[no_unused_expressions.tsx:1:1] + 1 │ obj?.foo().bar + · ────────────── + ╰──── + help: Consider removing this expression + + ⚠ typescript-eslint(no-unused-expressions): Disallow unused expressions + ╭─[no_unused_expressions.tsx:1:1] + 1 │ + · ─────── + ╰──── + help: Consider removing this expression + + ⚠ typescript-eslint(no-unused-expressions): Disallow unused expressions + ╭─[no_unused_expressions.tsx:1:1] + 1 │ <>> + · ───── + ╰──── + help: Consider removing this expression + + ⚠ typescript-eslint(no-unused-expressions): Disallow unused expressions + ╭─[no_unused_expressions.tsx:1:20] + 1 │ class C { static { 'use strict'; } } + · ───────────── + ╰──── + help: Consider removing this expression + + ⚠ typescript-eslint(no-unused-expressions): Disallow unused expressions + ╭─[no_unused_expressions.tsx:2:4] + 1 │ class C { static { + 2 │ 'foo' + · ───── + 3 │ 'bar' + ╰──── + help: Consider removing this expression + + ⚠ typescript-eslint(no-unused-expressions): Disallow unused expressions + ╭─[no_unused_expressions.tsx:3:4] + 2 │ 'foo' + 3 │ 'bar' + · ───── + 4 │ } } + ╰──── + help: Consider removing this expression + ⚠ typescript-eslint(no-unused-expressions): Disallow unused expressions ╭─[no_unused_expressions.tsx:2:11] 1 │