From 14e5ddb3ae8d9536a1f350e4246897bc33413b6d Mon Sep 17 00:00:00 2001 From: connorshea <2977353+connorshea@users.noreply.github.com> Date: Sun, 1 Mar 2026 11:33:04 +0000 Subject: [PATCH] test(linter/unicorn): regenerate tests (#19861) I can break this into smaller PRs if desired, basically just cleaning up the unicorn tests in a variety of ways and/or regenerating them: - Remove unnecessary raw string usage. - Regenerate tests that used old escaping, so we can more easily detect updates/new tests/changes in the future. - Indentation fixes - Removal of tab usage in a few files. - Regeneration of all of the unicorn rules' tests where new rules were added, some are commented out due to failure for now. - Updates to the snapshots accordingly. --- .../rules/unicorn/consistent_date_clone.rs | 30 +-- .../src/rules/unicorn/error_message.rs | 142 ++++++++++---- .../src/rules/unicorn/no_array_for_each.rs | 34 ++-- .../unicorn/no_array_method_this_argument.rs | 1 + .../rules/unicorn/no_invalid_fetch_options.rs | 40 ++-- .../no_invalid_remove_event_listener.rs | 8 +- .../unicorn/no_negation_in_equality_check.rs | 46 ++--- .../src/rules/unicorn/no_nested_ternary.rs | 1 + .../src/rules/unicorn/no_new_buffer.rs | 42 +++++ .../oxc_linter/src/rules/unicorn/no_null.rs | 1 + .../unicorn/no_object_as_default_parameter.rs | 39 +++- .../src/rules/unicorn/no_process_exit.rs | 114 ++++++------ .../src/rules/unicorn/no_static_only_class.rs | 50 +++++ .../src/rules/unicorn/no_this_assignment.rs | 6 + .../src/rules/unicorn/no_unreadable_iife.rs | 42 ++--- .../unicorn/no_useless_collection_argument.rs | 1 + .../unicorn/no_useless_fallback_in_spread.rs | 1 + .../rules/unicorn/no_useless_switch_case.rs | 32 ++-- .../src/rules/unicorn/no_useless_undefined.rs | 132 ++++++------- .../src/rules/unicorn/no_zero_fractions.rs | 74 ++++---- .../src/rules/unicorn/prefer_array_flat.rs | 47 ++++- .../rules/unicorn/prefer_array_flat_map.rs | 27 +++ .../src/rules/unicorn/prefer_array_some.rs | 176 +++++++++--------- .../src/rules/unicorn/prefer_code_point.rs | 50 ++--- .../rules/unicorn/prefer_dom_node_dataset.rs | 8 +- .../rules/unicorn/prefer_dom_node_remove.rs | 2 + .../unicorn/prefer_dom_node_text_content.rs | 8 +- .../src/rules/unicorn/prefer_global_this.rs | 4 + .../src/rules/unicorn/prefer_math_trunc.rs | 4 + .../rules/unicorn/prefer_modern_dom_apis.rs | 58 +++--- .../prefer_native_coercion_functions.rs | 104 +++++++++++ .../src/rules/unicorn/prefer_node_protocol.rs | 49 ++++- .../unicorn/prefer_optional_catch_binding.rs | 95 +++++++--- .../rules/unicorn/prefer_query_selector.rs | 43 +++-- .../src/rules/unicorn/prefer_regexp_test.rs | 31 +++ .../src/rules/unicorn/prefer_string_slice.rs | 74 ++++++++ .../unicorn/prefer_string_trim_start_end.rs | 5 + .../rules/unicorn/prefer_top_level_await.rs | 21 +++ .../unicorn/require_array_join_separator.rs | 26 +++ .../require_post_message_target_origin.rs | 2 + .../src/snapshots/unicorn_error_message.snap | 28 +++ ...unicorn_no_negation_in_equality_check.snap | 66 +++---- .../snapshots/unicorn_no_nested_ternary.snap | 14 ++ .../src/snapshots/unicorn_no_new_buffer.snap | 102 ++++++++++ ...nicorn_no_object_as_default_parameter.snap | 78 +++++++- .../unicorn_no_static_only_class.snap | 98 ++++++++++ .../snapshots/unicorn_no_unreadable_iife.snap | 62 +++--- ...nicorn_no_useless_collection_argument.snap | 7 + ...unicorn_no_useless_fallback_in_spread.snap | 7 + .../snapshots/unicorn_no_zero_fractions.snap | 32 ++++ .../snapshots/unicorn_prefer_array_flat.snap | 46 ++++- .../unicorn_prefer_array_flat_map.snap | 57 ++++++ .../snapshots/unicorn_prefer_global_this.snap | 14 ++ .../unicorn_prefer_modern_dom_apis.snap | 44 +++++ ...corn_prefer_native_coercion_functions.snap | 63 +++++++ .../unicorn_prefer_node_protocol.snap | 27 +++ ...unicorn_prefer_optional_catch_binding.snap | 72 ++++++- .../unicorn_prefer_query_selector.snap | 25 +++ .../snapshots/unicorn_prefer_regexp_test.snap | 84 +++++++++ .../unicorn_prefer_string_slice.snap | 51 +++++ .../unicorn_prefer_string_trim_start_end.snap | 9 + .../unicorn_require_array_join_separator.snap | 20 ++ 62 files changed, 2083 insertions(+), 593 deletions(-) diff --git a/crates/oxc_linter/src/rules/unicorn/consistent_date_clone.rs b/crates/oxc_linter/src/rules/unicorn/consistent_date_clone.rs index bf90f08400b06..3f72bdcf90c4c 100644 --- a/crates/oxc_linter/src/rules/unicorn/consistent_date_clone.rs +++ b/crates/oxc_linter/src/rules/unicorn/consistent_date_clone.rs @@ -95,22 +95,22 @@ fn test() { "Date(date.getTime())", // TODO: We may support these cases in future "new Date( - date.getFullYear(), - date.getMonth(), - date.getDate(), - date.getHours(), - date.getMinutes(), - date.getSeconds(), - date.getMilliseconds(), - );", + date.getFullYear(), + date.getMonth(), + date.getDate(), + date.getHours(), + date.getMinutes(), + date.getSeconds(), + date.getMilliseconds(), + );", "new Date( - date.getFullYear(), - date.getMonth(), - date.getDate(), - date.getHours(), - date.getMinutes(), - date.getSeconds(), - );", + date.getFullYear(), + date.getMonth(), + date.getDate(), + date.getHours(), + date.getMinutes(), + date.getSeconds(), + );", ]; let fail = vec![ diff --git a/crates/oxc_linter/src/rules/unicorn/error_message.rs b/crates/oxc_linter/src/rules/unicorn/error_message.rs index 16295aa516392..eec7101f9e4ed 100644 --- a/crates/oxc_linter/src/rules/unicorn/error_message.rs +++ b/crates/oxc_linter/src/rules/unicorn/error_message.rs @@ -110,48 +110,112 @@ fn test() { use crate::tester::Tester; let pass = vec![ - ("throw new Error('error')", None), - ("throw new TypeError('error')", None), - ("throw new MyCustomError('error')", None), - ("throw new MyCustomError()", None), - ("throw generateError()", None), - ("throw foo()", None), - ("throw err", None), - ("throw 1", None), - ("new Error(\"message\", 0, 0)", None), - ("new Error(foo)", None), - ("new Error(...foo)", None), - ("new AggregateError(errors, \"message\")", None), - ("new NotAggregateError(errors)", None), - ("new AggregateError(...foo)", None), - ("new AggregateError(...foo, \"\")", None), - ("new AggregateError(errors, ...foo)", None), - ("new AggregateError(errors, message, \"\")", None), - ("new AggregateError(\"\", message, \"\")", None), + "throw new Error('error')", + "throw new TypeError('error')", + "throw new MyCustomError('error')", + "throw new MyCustomError()", + "throw generateError()", + "throw foo()", + "throw err", + "throw 1", + "const err = TypeError('error'); + throw err;", + r#"new Error("message", 0, 0)"#, + "new Error(foo)", + r"const errors = []; + if (condition) { + errors.push('hello'); + } + if (errors.length) { + throw new Error(errors.join('\\\\n')); + }", + "new Error(...foo)", + "/* global x */ + const a = x; + throw x;", + // TODO: Get this passing. + // "const Error = function () {}; + // const err = new Error({ + // name: 'Unauthorized', + // });", + r#"new AggregateError(errors, "message")"#, + "new NotAggregateError(errors)", + "new AggregateError(...foo)", + r#"new AggregateError(...foo, "")"#, + "new AggregateError(errors, ...foo)", + r#"new AggregateError(errors, message, "")"#, + r#"new AggregateError("", message, "")"#, + r#"new SuppressedError(error, suppressed, "message")"#, + "new NotSuppressedError(error, suppressed)", + "new SuppressedError(...foo)", + r#"new SuppressedError(...foo, "")"#, + "new SuppressedError(error, suppressed, ...foo)", + r#"new SuppressedError(error, suppressed, message, "")"#, + r#"new SuppressedError("", "", message, "")"#, ]; let fail = vec![ - ("throw new Error()", None), - ("throw Error()", None), - ("throw new Error('')", None), - ("throw new Error(``)", None), - ("const foo = new TypeError()", None), - ("const foo = new SyntaxError()", None), - ("throw new Error([])", None), - ("throw new Error([foo])", None), - ("throw new Error({})", None), - ("throw new Error({foo})", None), - ("const error = new RangeError;", None), - ("new AggregateError(errors)", None), - ("AggregateError(errors)", None), - ("new AggregateError(errors, \"\")", None), - ("new AggregateError(errors, ``)", None), - ("new AggregateError(errors, \"\", extraArgument)", None), - ("new AggregateError(errors, [])", None), - ("new AggregateError(errors, [foo])", None), - ("new AggregateError(errors, {})", None), - ("new AggregateError(errors, {foo})", None), - ("const error = new AggregateError;", None), + "throw new Error()", + "throw Error()", + "throw new Error('')", + "throw new Error(``)", + "const err = new Error(); + throw err;", + "let err = 1; + err = new Error(); + throw err;", + "let err = new Error(); + err = 1; + throw err;", + "const foo = new TypeError()", + "const foo = new SyntaxError()", + // TODO: Get all of the comments tests here passing. + // "const errorMessage = Object.freeze({errorMessage: 1}).errorMessage; + // throw new Error(errorMessage)", + "throw new Error([])", + "throw new Error([foo])", + // "throw new Error([0][0])", + "throw new Error({})", + "throw new Error({foo})", + // "throw new Error({foo: 0}.foo)", + // "throw new Error(lineNumber=2)", + "const error = new RangeError;", + "throw Object.assign(new Error(), {foo})", + "new AggregateError(errors)", + "AggregateError(errors)", + r#"new AggregateError(errors, "")"#, + "new AggregateError(errors, ``)", + r#"new AggregateError(errors, "", extraArgument)"#, + // "const errorMessage = Object.freeze({errorMessage: 1}).errorMessage; + // throw new AggregateError(errors, errorMessage)", + "new AggregateError(errors, [])", + "new AggregateError(errors, [foo])", + // "new AggregateError(errors, [0][0])", + "new AggregateError(errors, {})", + "new AggregateError(errors, {foo})", + // "new AggregateError(errors, {foo: 0}.foo)", + // "new AggregateError(errors, lineNumber=2)", + "const error = new AggregateError;", + // TODO: Update the rule to get these tests working. + // "new SuppressedError(error, suppressed,)", + // "new SuppressedError(error,)", + // "new SuppressedError()", + // "SuppressedError(error, suppressed,)", + // "SuppressedError(error,)", + // "SuppressedError()", + // r#"new SuppressedError(error, suppressed, "")"#, + // "new SuppressedError(error, suppressed, ``)", + // r#"new SuppressedError(error, suppressed, "", options)"#, + // "const errorMessage = Object.freeze({errorMessage: 1}).errorMessage; + // throw new SuppressedError(error, suppressed, errorMessage)", + // "new SuppressedError(error, suppressed, [])", + // "new SuppressedError(error, suppressed, [foo])", + // "new SuppressedError(error, suppressed, [0][0])", + // "new SuppressedError(error, suppressed, {})", + // "new SuppressedError(error, suppressed, {foo})", + // "new SuppressedError(error, suppressed, {foo: 0}.foo)", + // "new SuppressedError(error, suppressed, lineNumber=2)", + // "const error = new SuppressedError;", ]; Tester::new(ErrorMessage::NAME, ErrorMessage::PLUGIN, pass, fail).test_and_snapshot(); diff --git a/crates/oxc_linter/src/rules/unicorn/no_array_for_each.rs b/crates/oxc_linter/src/rules/unicorn/no_array_for_each.rs index 090629291f56c..7eada64ec2cae 100644 --- a/crates/oxc_linter/src/rules/unicorn/no_array_for_each.rs +++ b/crates/oxc_linter/src/rules/unicorn/no_array_for_each.rs @@ -114,28 +114,28 @@ fn test() { use crate::tester::Tester; let pass = vec![ - r"new foo.forEach(element => bar())", - r"forEach(element => bar())", - r"foo.notForEach(element => bar())", - r"React.Children.forEach(children, (child) => {});", - r"Children.forEach(children, (child) => {});", + "new foo.forEach(element => bar())", + "forEach(element => bar())", + "foo.notForEach(element => bar())", + "React.Children.forEach(children, (child) => {});", + "Children.forEach(children, (child) => {});", r#"import { Effect } from "effect"; Effect.forEach([], () => {})"#, r#"import { Effect as E } from "effect"; E.forEach([], () => {})"#, ]; let fail = vec![ - r"foo.forEach?.(element => bar(element))", - r"1?.forEach((a, b) => call(a, b))", - r"array.forEach((arrayInArray) => arrayInArray.forEach(element => bar(element)));", - r"array.forEach((arrayInArray) => arrayInArray?.forEach(element => bar(element)));", - r"array.forEach((element, index = element) => {})", - r"array.forEach(({foo}, index = foo) => {})", - r"array.forEach((element, {bar = element}) => {})", - r"array.forEach(({foo}, {bar = foo}) => {})", - r"foo.forEach(function(element, element1) {})", - r"foo.forEach(function element(element, element1) {})", - r"this._listeners.forEach((listener: () => void) => listener());", - r"return foo.forEach(element => {bar(element)});", + "foo.forEach?.(element => bar(element))", + "1?.forEach((a, b) => call(a, b))", + "array.forEach((arrayInArray) => arrayInArray.forEach(element => bar(element)));", + "array.forEach((arrayInArray) => arrayInArray?.forEach(element => bar(element)));", + "array.forEach((element, index = element) => {})", + "array.forEach(({foo}, index = foo) => {})", + "array.forEach((element, {bar = element}) => {})", + "array.forEach(({foo}, {bar = foo}) => {})", + "foo.forEach(function(element, element1) {})", + "foo.forEach(function element(element, element1) {})", + "this._listeners.forEach((listener: () => void) => listener());", + "return foo.forEach(element => {bar(element)});", ]; // TODO: Implement a fixer. diff --git a/crates/oxc_linter/src/rules/unicorn/no_array_method_this_argument.rs b/crates/oxc_linter/src/rules/unicorn/no_array_method_this_argument.rs index 497c898bfdee4..d710800bbc886 100644 --- a/crates/oxc_linter/src/rules/unicorn/no_array_method_this_argument.rs +++ b/crates/oxc_linter/src/rules/unicorn/no_array_method_this_argument.rs @@ -229,6 +229,7 @@ fn test() { "Array.fromAsync(iterableOrArrayLike, ...() => {}, thisArgument)", "Array.fromAsync(...iterableOrArrayLike, () => {}, thisArgument)", "Array.fromAsync(iterableOrArrayLike, () => {}, thisArgument, extraArgument)", + "Array?.fromAsync(iterableOrArrayLike, () => {}, thisArgument)", "lodash.every(array, () => {})", "lodash.find(array, () => {})", "jQuery.map(array, () => {})", diff --git a/crates/oxc_linter/src/rules/unicorn/no_invalid_fetch_options.rs b/crates/oxc_linter/src/rules/unicorn/no_invalid_fetch_options.rs index d6f7b197daa89..fe36805481eb0 100644 --- a/crates/oxc_linter/src/rules/unicorn/no_invalid_fetch_options.rs +++ b/crates/oxc_linter/src/rules/unicorn/no_invalid_fetch_options.rs @@ -257,24 +257,24 @@ fn test() { let pass = vec![ r#"fetch(url, {method: "POST", body})"#, r#"new Request(url, {method: "POST", body})"#, - r"fetch(url, {})", - r"new Request(url, {})", - r"fetch(url)", - r"new Request(url)", + "fetch(url, {})", + "new Request(url, {})", + "fetch(url)", + "new Request(url)", r#"fetch(url, {method: "UNKNOWN", body})"#, r#"new Request(url, {method: "UNKNOWN", body})"#, - r"fetch(url, {body: undefined})", - r"new Request(url, {body: undefined})", - r"fetch(url, {body: null})", - r"new Request(url, {body: null})", - r"fetch(url, {...options, body})", - r"new Request(url, {...options, body})", - r"new fetch(url, {body})", - r"Request(url, {body})", - r"not_fetch(url, {body})", - r"new not_Request(url, {body})", - r"fetch({body}, url)", - r"new Request({body}, url)", + "fetch(url, {body: undefined})", + "new Request(url, {body: undefined})", + "fetch(url, {body: null})", + "new Request(url, {body: null})", + "fetch(url, {...options, body})", + "new Request(url, {...options, body})", + "new fetch(url, {body})", + "Request(url, {body})", + "not_fetch(url, {body})", + "new not_Request(url, {body})", + "fetch({body}, url)", + "new Request({body}, url)", r#"fetch(url, {[body]: "foo=bar"})"#, r#"new Request(url, {[body]: "foo=bar"})"#, r#"fetch(url, {body: "foo=bar", body: undefined});"#, @@ -314,8 +314,8 @@ fn test() { ]; let fail = vec![ - r"fetch(url, {body})", - r"new Request(url, {body})", + "fetch(url, {body})", + "new Request(url, {body})", r#"fetch(url, {method: "GET", body})"#, r#"new Request(url, {method: "GET", body})"#, r#"fetch(url, {method: "HEAD", body})"#, @@ -326,8 +326,8 @@ fn test() { r#"const method = "head"; new Request(url, {method, body: "foo=bar"})"#, r#"const method = "head"; fetch(url, {method, body: "foo=bar"})"#, r#"const method = `head`; fetch(url, {method, body: "foo=bar"})"#, - r"fetch(url, {body}, extraArgument)", - r"new Request(url, {body}, extraArgument)", + "fetch(url, {body}, extraArgument)", + "new Request(url, {body}, extraArgument)", r#"fetch(url, {body: undefined, body: "foo=bar"});"#, r#"new Request(url, {body: undefined, body: "foo=bar"});"#, r#"fetch(url, {method: "post", body: "foo=bar", method: "HEAD"});"#, diff --git a/crates/oxc_linter/src/rules/unicorn/no_invalid_remove_event_listener.rs b/crates/oxc_linter/src/rules/unicorn/no_invalid_remove_event_listener.rs index eabb37d151c13..137e7466761b9 100644 --- a/crates/oxc_linter/src/rules/unicorn/no_invalid_remove_event_listener.rs +++ b/crates/oxc_linter/src/rules/unicorn/no_invalid_remove_event_listener.rs @@ -137,8 +137,8 @@ fn test() { r#"el.notRemoveEventListener("click", () => {})"#, r#"el[removeEventListener]("click", () => {})"#, r#"el.removeEventListener("click")"#, - r"el.removeEventListener()", - r"el.removeEventListener(() => {})", + "el.removeEventListener()", + "el.removeEventListener(() => {})", r#"el.removeEventListener(...["click", () => {}], () => {})"#, r#"el.removeEventListener(() => {}, "click")"#, r#"window.removeEventListener("click", bind())"#, @@ -146,7 +146,7 @@ fn test() { r#"window.removeEventListener("click", handler[bind]())"#, r#"window.removeEventListener("click", handler.bind?.())"#, r#"window.removeEventListener("click", handler?.bind())"#, - r"window.removeEventListener(handler)", + "window.removeEventListener(handler)", r#"this.removeEventListener("click", getListener())"#, r#"el.removeEventListener("scroll", handler)"#, r#"el.removeEventListener("keydown", obj.listener)"#, @@ -168,7 +168,7 @@ fn test() { // r#"el?.removeEventListener("mouseout", function (e) {})"#, r#"el.removeEventListener("mouseout", function (e) {}, true)"#, r#"el.removeEventListener("click", function (e) {}, ...moreArguments)"#, - r"el.removeEventListener(() => {}, () => {}, () => {})", + "el.removeEventListener(() => {}, () => {}, () => {})", "document.removeEventListener('keydown', () => foo())", "document.removeEventListener('keydown', function () {})", // make sure that if the listener is a big one, we shorten the span. diff --git a/crates/oxc_linter/src/rules/unicorn/no_negation_in_equality_check.rs b/crates/oxc_linter/src/rules/unicorn/no_negation_in_equality_check.rs index bf64b58d559b2..d1d568a7c13c1 100644 --- a/crates/oxc_linter/src/rules/unicorn/no_negation_in_equality_check.rs +++ b/crates/oxc_linter/src/rules/unicorn/no_negation_in_equality_check.rs @@ -139,35 +139,23 @@ fn test() { "!foo !== bar", "!foo == bar", "!foo != bar", - " - function x() { - return!foo === bar; - } - ", - " - function x() { - return! - foo === bar; - throw! - foo === bar; - } - ", - " - foo - !(a) === b - ", - " - foo - ![a, b].join('') === c - ", - " - foo - ! [a, b].join('') === c - ", - " - foo - !/* comment */[a, b].join('') === c - ", + "function x() { + return!foo === bar; + }", + "function x() { + return! + foo === bar; + throw! + foo === bar; + }", + "foo + !(a) === b", + "foo + ![a, b].join('') === c", + "foo + ! [a, b].join('') === c", + "foo + !/* comment */[a, b].join('') === c", ]; let fix = vec![ diff --git a/crates/oxc_linter/src/rules/unicorn/no_nested_ternary.rs b/crates/oxc_linter/src/rules/unicorn/no_nested_ternary.rs index 87469c7fda8c7..80af533807a15 100644 --- a/crates/oxc_linter/src/rules/unicorn/no_nested_ternary.rs +++ b/crates/oxc_linter/src/rules/unicorn/no_nested_ternary.rs @@ -132,6 +132,7 @@ fn test() { "const foo = i > 5 ? true : i < 100 ? true : false;", "foo ? bar : baz === qux ? quxx : foobar;", "foo ? baz === qux ? quxx : foobar : bar;", + "const foo = i > 5 ? i < 100 ? true : false : i < 100 ? true : false;", "const foo = i > 5 ? true : (i < 100 ? true : (i < 1000 ? true : false));", "const foo = a ? b : diff --git a/crates/oxc_linter/src/rules/unicorn/no_new_buffer.rs b/crates/oxc_linter/src/rules/unicorn/no_new_buffer.rs index c9de83e4f6532..159927dbfd909 100644 --- a/crates/oxc_linter/src/rules/unicorn/no_new_buffer.rs +++ b/crates/oxc_linter/src/rules/unicorn/no_new_buffer.rs @@ -121,15 +121,57 @@ fn test() { let fail = vec![ "const buffer = new Buffer([0x62, 0x75, 0x66, 0x66, 0x65, 0x72])", "const buffer = new Buffer([0x62, bar])", + "const array = [0x62]; + const buffer = new Buffer(array);", + "const arrayBuffer = new ArrayBuffer(10); + const buffer = new Buffer(arrayBuffer);", + "const arrayBuffer = new ArrayBuffer(10); + const buffer = new Buffer(arrayBuffer, 0, );", + "const arrayBuffer = new ArrayBuffer(10); + const buffer = new Buffer(arrayBuffer, 0, 2);", "const buffer = new Buffer(10);", + "const size = 10; + const buffer = new Buffer(size);", "new Buffer(foo.length)", "new Buffer(Math.min(foo, bar))", r#"const buffer = new Buffer("string");"#, r#"const buffer = new Buffer("7468697320697320612074c3a97374", "hex")"#, + r#"const string = "string"; + const buffer = new Buffer(string);"#, "const buffer = new Buffer(`${unknown}`)", "const buffer = new (Buffer)(unknown)", "const buffer = new Buffer(unknown, 2)", "const buffer = new Buffer(...unknown)", + "() => { + return new // 1 + Buffer(); + }", + "() => { + return ( + new // 2 + Buffer() + ); + }", + "() => { + return new // 3 + (Buffer); + }", + "() => { + return new // 4 + Buffer; + }", + "() => { + return ( + new // 5 + Buffer + ); + }", + "() => { + return ( + new // 6 + (Buffer) + ); + }", "const buffer = new /* comment */ Buffer()", "const buffer = new /* comment */ Buffer", "new Buffer(input, encoding);", diff --git a/crates/oxc_linter/src/rules/unicorn/no_null.rs b/crates/oxc_linter/src/rules/unicorn/no_null.rs index 4021fbfa6e812..bd4e37dcd76de 100644 --- a/crates/oxc_linter/src/rules/unicorn/no_null.rs +++ b/crates/oxc_linter/src/rules/unicorn/no_null.rs @@ -270,6 +270,7 @@ fn test() { ("Object.create(null as any)", None), ("Object.create(null, {foo: {value:1}})", None), ("let insertedNode = parentNode.insertBefore(newNode, null)", None), + ("let insertedNode = parentNode?.insertBefore(newNode, null)", None), ("const foo = \"null\";", None), ("Object.create()", None), ("Object.create(bar)", None), diff --git a/crates/oxc_linter/src/rules/unicorn/no_object_as_default_parameter.rs b/crates/oxc_linter/src/rules/unicorn/no_object_as_default_parameter.rs index b03b3e54f52cc..396fb4316706d 100644 --- a/crates/oxc_linter/src/rules/unicorn/no_object_as_default_parameter.rs +++ b/crates/oxc_linter/src/rules/unicorn/no_object_as_default_parameter.rs @@ -110,6 +110,12 @@ fn test() { "const abc = ([foo = {a: 123}]) => {};", "const abc = ({foo: bar = {a: 123}}) => {};", "const abc = () => (foo = {a: 123});", + "class A { + [foo = {a: 123}]() {} + }", + "class A extends (foo = {a: 123}) { + a() {} + }", ]; let fail = vec![ @@ -123,7 +129,38 @@ fn test() { "const abc = (foo = {a: 123, b: false}) => {};", r#"const abc = (foo = {a: false, b: 1, c: "test", d: null}) => {};"#, "const abc = function(foo = {a: 123}) {}", - "function abc(foo = {a: 123}) {}", + "class A { + abc(foo = {a: 123}) {} + }", + "class A { + constructor(foo = {a: 123}) {} + }", + // This one is a syntax error and so should be excluded from the failure cases. + // "class A { + // set abc(foo = {a: 123}) {} + // }", + "class A { + static abc(foo = {a: 123}) {} + }", + "class A { + * abc(foo = {a: 123}) {} + }", + "class A { + static async * abc(foo = {a: 123}) {} + }", + "class A { + [foo = {a: 123}](foo = {a: 123}) {} + }", + "const A = class { + abc(foo = {a: 123}) {} + }", + "object = { + abc(foo = {a: 123}) {} + };", + "const A = class { + abc({a} = {a: 123}) {} + }", + "/**/function abc(foo = {a: 123}) {}", "const abc = (foo = {a: false}) => {};", "function abc({a} = {a: 123}) {}", "function abc([a] = {a: 123}) {}", diff --git a/crates/oxc_linter/src/rules/unicorn/no_process_exit.rs b/crates/oxc_linter/src/rules/unicorn/no_process_exit.rs index a3adb12493ba5..8d74356cabba6 100644 --- a/crates/oxc_linter/src/rules/unicorn/no_process_exit.rs +++ b/crates/oxc_linter/src/rules/unicorn/no_process_exit.rs @@ -89,100 +89,100 @@ fn test() { use crate::tester::Tester; let pass = vec![ - ("#!/usr/bin/env node\n\nprocess.exit();"), - ("Process.exit()"), - ("const x = process.exit;"), - ("x(process.exit)"), - (r#"process.on("SIGINT", function() { process.exit(1); })"#), - (r#"process.on("SIGKILL", function() { process.exit(1); })"#), - (r#"process.on("SIGINT", () => { process.exit(1); })"#), - (r#"process.on("SIGINT", () => process.exit(1))"#), - (r#"process.on("SIGINT", () => { if (true) { process.exit(1); } })"#), - (r#"process.once("SIGINT", function() { process.exit(1); })"#), - (r#"process.once("SIGKILL", function() { process.exit(1); })"#), - (r#"process.once("SIGINT", () => { process.exit(1); })"#), - (r#"process.once("SIGINT", () => process.exit(1))"#), - (r#"process.once("SIGINT", () => { if (true) { process.exit(1); } })"#), - // (r" + "#!/usr/bin/env node\n\nprocess.exit();", + "Process.exit()", + "const x = process.exit;", + "x(process.exit)", + r#"process.on("SIGINT", function() { process.exit(1); })"#, + r#"process.on("SIGKILL", function() { process.exit(1); })"#, + r#"process.on("SIGINT", () => { process.exit(1); })"#, + r#"process.on("SIGINT", () => process.exit(1))"#, + r#"process.on("SIGINT", () => { if (true) { process.exit(1); } })"#, + r#"process.once("SIGINT", function() { process.exit(1); })"#, + r#"process.once("SIGKILL", function() { process.exit(1); })"#, + r#"process.once("SIGINT", () => { process.exit(1); })"#, + r#"process.once("SIGINT", () => process.exit(1))"#, + r#"process.once("SIGINT", () => { if (true) { process.exit(1); } })"#, + // r" // const {workerData, parentPort} = require('worker_threads'); // process.exit(1); - // "), - // (r" + // ", + // r" // const {workerData, parentPort} = require('node:worker_threads'); // process.exit(1); - // "), - // (r" + // ", + // r" // import {workerData, parentPort} from 'worker_threads'; // process.exit(1); - // "), - // (r" + // ", + // r" // import foo from 'worker_threads'; // process.exit(1); - // "), - // (r" + // ", + // r" // import foo from 'node:worker_threads'; // process.exit(1); - // "), + // ", // Not `CallExpression` - ("new process.exit(1);"), + "new process.exit(1);", // Not `MemberExpression` - ("exit(1);"), + "exit(1);", // `callee.property` is not a `Identifier` - // (r#"process["exit"](1);"#), + // r#"process["exit"](1);"#, // Computed - ("process[exit](1);"), + "process[exit](1);", // Not exit - ("process.foo(1);"), + "process.foo(1);", // Not `process` - ("foo.exit(1);"), + "foo.exit(1);", // `callee.object.type` is not a `Identifier` - ("lib.process.exit(1);"), + "lib.process.exit(1);", ]; let fail = vec![ - ("process.exit();"), - ("process.exit(1);"), - ("x(process.exit(1));"), - (r#"process.on("SIGINT", function() {});process.exit();"#), - (r#"process.once("SIGINT", function() {}); process.exit(0)"#), - (r" + "process.exit();", + "process.exit(1);", + "x(process.exit(1));", + r#"process.on("SIGINT", function() {});process.exit();"#, + r#"process.once("SIGINT", function() {}); process.exit(0)"#, + r" const mod = require('not_worker_threads'); process.exit(1); - "), - (r" + ", + r" import mod from 'not_worker_threads'; process.exit(1); - "), + ", // Not `CallExpression` - (r" + r" const mod = new require('worker_threads'); process.exit(1); - "), + ", // Not `Literal` worker_threads - (r" + r" const mod = require(worker_threads); process.exit(1); - "), + ", // Not `CallExpression` - (r#"new process.on("SIGINT", function() { process.exit(1); })"#), - (r#"new process.once("SIGINT", function() { process.exit(1); })"#), + r#"new process.on("SIGINT", function() { process.exit(1); })"#, + r#"new process.once("SIGINT", function() { process.exit(1); })"#, // Not `MemberExpression` - (r#"on("SIGINT", function() { process.exit(1); })"#), - (r#"once("SIGINT", function() { process.exit(1); })"#), + r#"on("SIGINT", function() { process.exit(1); })"#, + r#"once("SIGINT", function() { process.exit(1); })"#, // `callee.property` is not a `Identifier` - // (r#"process["on"]("SIGINT", function() { process.exit(1); })"#), - // (r#"process["once"]("SIGINT", function() { process.exit(1); })"#), + // r#"process["on"]("SIGINT", function() { process.exit(1); })"#, + // r#"process["once"]("SIGINT", function() { process.exit(1); })"#, // Computed - (r#"process[on]("SIGINT", function() { process.exit(1); })"#), - (r#"process[once]("SIGINT", function() { process.exit(1); })"#), + r#"process[on]("SIGINT", function() { process.exit(1); })"#, + r#"process[once]("SIGINT", function() { process.exit(1); })"#, // Not `on` / `once` - (r#"process.foo("SIGINT", function() { process.exit(1); })"#), + r#"process.foo("SIGINT", function() { process.exit(1); })"#, // Not `process` - (r#"foo.on("SIGINT", function() { process.exit(1); })"#), - (r#"foo.once("SIGINT", function() { process.exit(1); })"#), + r#"foo.on("SIGINT", function() { process.exit(1); })"#, + r#"foo.once("SIGINT", function() { process.exit(1); })"#, // `callee.object.type` is not a `Identifier` - (r#"lib.process.on("SIGINT", function() { process.exit(1); })"#), - (r#"lib.process.once("SIGINT", function() { process.exit(1); })"#), + r#"lib.process.on("SIGINT", function() { process.exit(1); })"#, + r#"lib.process.once("SIGINT", function() { process.exit(1); })"#, ]; Tester::new(NoProcessExit::NAME, NoProcessExit::PLUGIN, pass, fail).test_and_snapshot(); diff --git a/crates/oxc_linter/src/rules/unicorn/no_static_only_class.rs b/crates/oxc_linter/src/rules/unicorn/no_static_only_class.rs index 750db1c9ccf22..4e54d70ba45e6 100644 --- a/crates/oxc_linter/src/rules/unicorn/no_static_only_class.rs +++ b/crates/oxc_linter/src/rules/unicorn/no_static_only_class.rs @@ -266,6 +266,56 @@ fn test() { "export default class A { static a() {}; }", "export default class { static a() {}; }", "export class A { static a() {}; }", + "function a() { + return class + { + static a() {} + } + }", + "function a() { + return class /* comment */ + { + static a() {} + } + }", + "function a() { + return class // comment + { + static a() {} + } + }", + "class A {static a(){}} + class B extends A {}", + "class A {static a(){}} + console.log(typeof A)", + "class A {static a(){}} + const a = new A;", + "class A { + static a + static b = 1 + static [c] = 2 + static [d] + static e() {} + static [f]() {} + }", + "class A { + static a; + static b = 1; + static [((c))] = ((2)); + static [d]; + static e() {}; + static [f]() {}; + }", + "/* */ + class /* */ A /* */ { + /* */ static /* */ a /* */; /* */ + /* */ static /* */ b /* */ = /* */ 1 /* */; /* */ + /* */ static /* */ [ /* */ c /* */ ] /* */ = /* */ 2 /* */; /* */ + /* */ static /* */ [/* */ d /* */] /* */; /* */ + /* */ static /* */ /* */ e /* */ ( /* */ ) {/* */}/* */; /* */ + /* */ static /* */ [/* */ f /* */ ] /* */ ( /* */ ) {/* */ }/* */ ; /* */ + } + /* */", "class A {static [this.a] = 1}", "class A { static a() {} }", ]; diff --git a/crates/oxc_linter/src/rules/unicorn/no_this_assignment.rs b/crates/oxc_linter/src/rules/unicorn/no_this_assignment.rs index 272ed28b2e396..cbea9f8f2b38b 100644 --- a/crates/oxc_linter/src/rules/unicorn/no_this_assignment.rs +++ b/crates/oxc_linter/src/rules/unicorn/no_this_assignment.rs @@ -125,6 +125,12 @@ fn test() { "function foo(a = this) {}", "function foo({a = this}) {}", "function foo([a = this]) {}", + "class A { + foo = this; + }", + "class A { + static foo = this; + }", ]; let fail = vec![ diff --git a/crates/oxc_linter/src/rules/unicorn/no_unreadable_iife.rs b/crates/oxc_linter/src/rules/unicorn/no_unreadable_iife.rs index f2501a7002d1e..03892c973aeb4 100644 --- a/crates/oxc_linter/src/rules/unicorn/no_unreadable_iife.rs +++ b/crates/oxc_linter/src/rules/unicorn/no_unreadable_iife.rs @@ -82,48 +82,34 @@ fn test() { let pass = vec![ "const foo = (bar => bar)();", - " - const foo = (() => { + "const foo = (() => { return a ? b : c - })(); - ", + })();", ]; let fail = vec![ "const foo = (() => (a ? b : c))();", - " - const foo = (() => ( + "const foo = (() => ( a ? b : c - ))(); - ", - " - const foo = ( + ))();", + "const foo = ( () => ( a ? b : c ) - )(); - ", - " - const foo = (() => ( + )();", + "const foo = (() => ( a, b - ))(); - ", - " - const foo = (() => ({ + ))();", + "const foo = (() => ({ a: b, - }))(); - ", + }))();", "const foo = (bar => (bar))();", - " - (async () => ({ + "(async () => ({ bar, - }))(); - ", - " - const foo = (async (bar) => ({ + }))();", + "const foo = (async (bar) => ({ bar: await baz(), - }))(); - ", + }))();", "(async () => (( {bar} )))();", ]; diff --git a/crates/oxc_linter/src/rules/unicorn/no_useless_collection_argument.rs b/crates/oxc_linter/src/rules/unicorn/no_useless_collection_argument.rs index fd2eabe42f828..a04454a0eaa2b 100644 --- a/crates/oxc_linter/src/rules/unicorn/no_useless_collection_argument.rs +++ b/crates/oxc_linter/src/rules/unicorn/no_useless_collection_argument.rs @@ -247,6 +247,7 @@ fn test() { r#"new Set([] ?? "")"#, r#"new Set( (( (( "" )) ?? (( [] )) )) )"#, "new Set(foo ?? bar ?? [])", + "new Set([/**/])", ]; let fix = vec![ diff --git a/crates/oxc_linter/src/rules/unicorn/no_useless_fallback_in_spread.rs b/crates/oxc_linter/src/rules/unicorn/no_useless_fallback_in_spread.rs index 5abf32946d582..b735efb47b9c5 100644 --- a/crates/oxc_linter/src/rules/unicorn/no_useless_fallback_in_spread.rs +++ b/crates/oxc_linter/src/rules/unicorn/no_useless_fallback_in_spread.rs @@ -153,6 +153,7 @@ fn test() { "const object = {...((foo && {}) || {})}", "const object = {...(foo && {} || {})}", "const object = {...({...(foo || {})})}", + "const object = {...({...((0, foo) || {})})}", "function foo(a = {...(bar || {})}){}", "const object = {...(document.all || {})}", ]; diff --git a/crates/oxc_linter/src/rules/unicorn/no_useless_switch_case.rs b/crates/oxc_linter/src/rules/unicorn/no_useless_switch_case.rs index 94f65e7ffff12..4bc048fedcb7d 100644 --- a/crates/oxc_linter/src/rules/unicorn/no_useless_switch_case.rs +++ b/crates/oxc_linter/src/rules/unicorn/no_useless_switch_case.rs @@ -97,7 +97,7 @@ fn test() { use crate::tester::Tester; let pass = vec![ - r" + " switch (foo) { case a: case b: @@ -105,7 +105,7 @@ fn test() { break; } ", - r" + " switch (foo) { case a: handleCaseA(); @@ -115,7 +115,7 @@ fn test() { break; } ", - r" + " switch (foo) { case a: handleCaseA(); @@ -124,7 +124,7 @@ fn test() { break; } ", - r" + " switch (foo) { case a: break; @@ -133,7 +133,7 @@ fn test() { break; } ", - r" + " switch (foo) { case a: handleCaseA(); @@ -143,7 +143,7 @@ fn test() { break; } ", - r" + " switch (foo) { case a: default: @@ -154,7 +154,7 @@ fn test() { break; } ", - r" + " switch (1) { // This is not useless case 1: @@ -164,7 +164,7 @@ fn test() { console.log('2') } ", - r" + " switch (1) { default: handleDefaultCase1(); @@ -178,7 +178,7 @@ fn test() { ]; let fail = vec![ - r" + " switch (foo) { case a: default: @@ -186,7 +186,7 @@ fn test() { break; } ", - r" + " switch (foo) { case a: { } @@ -195,7 +195,7 @@ fn test() { break; } ", - r" + " switch (foo) { case a: { ;; @@ -211,7 +211,7 @@ fn test() { break; } ", - r" + " switch (foo) { case a: case (( b )) : @@ -220,7 +220,7 @@ fn test() { break; } ", - r" + " switch (foo) { case a: case b: @@ -233,7 +233,7 @@ fn test() { break; } ", - r" + " switch (foo) { case a: case b: @@ -242,7 +242,7 @@ fn test() { break; } ", - r" + " switch (foo) { // eslint-disable-next-line case a: @@ -252,7 +252,7 @@ fn test() { break; } ", - r" + " switch (foo) { case a: // eslint-disable-next-line diff --git a/crates/oxc_linter/src/rules/unicorn/no_useless_undefined.rs b/crates/oxc_linter/src/rules/unicorn/no_useless_undefined.rs index 589af2f4bfca3..d2bc1f60a03f4 100644 --- a/crates/oxc_linter/src/rules/unicorn/no_useless_undefined.rs +++ b/crates/oxc_linter/src/rules/unicorn/no_useless_undefined.rs @@ -353,72 +353,72 @@ fn test() { let options_ignore_arrow_function_body = || Some(serde_json::json!([{ "checkArrowFunctionBody": false }])); let pass = vec![ - (r"function foo() {return;}", None), - (r"const foo = () => {};", None), - (r"let foo;", None), - (r"var foo;", None), - (r"const foo = undefined;", None), - (r"foo();", None), - (r"foo(bar,);", None), - (r"foo(undefined, bar);", None), - (r"const {foo} = {};", None), - (r"function foo({bar} = {}) {}", None), - (r"function foo(bar) {}", None), + ("function foo() {return;}", None), + ("const foo = () => {};", None), + ("let foo;", None), + ("var foo;", None), + ("const foo = undefined;", None), + ("foo();", None), + ("foo(bar,);", None), + ("foo(undefined, bar);", None), + ("const {foo} = {};", None), + ("function foo({bar} = {}) {}", None), + ("function foo(bar) {}", None), // I guess nobody uses this, but `yield* undefined;` is valid code, and `yield*;` is not (r"function* foo() {yield* undefined;}", None), // Ignored - (r"if (Object.is(foo, undefined)){}", None), - (r"t.is(foo, undefined)", None), - (r"assert.equal(foo, undefined, message)", None), - (r"assert.notEqual(foo, undefined, message)", None), - (r"assert.strictEqual(foo, undefined, message)", None), - (r"assert.notStrictEqual(foo, undefined, message)", None), - (r"assert.propertyVal(foo, 'bar', undefined, message)", None), - (r"assert.notPropertyVal(foo, 'bar', undefined, message)", None), - (r"expect(foo).not(undefined)", None), - (r"expect(foo).to.have.property('bar', undefined)", None), - (r"expect(foo).toBe(undefined)", None), - (r"expect(foo).toContain(undefined)", None), - (r"expect(foo).toContainEqual(undefined)", None), - (r"expect(foo).toEqual(undefined)", None), - (r"t.same(foo, undefined)", None), - (r"t.notSame(foo, undefined)", None), - (r"t.strictSame(foo, undefined)", None), - (r"t.strictNotSame(foo, undefined)", None), - (r"expect(someFunction).toHaveBeenCalledWith(1, 2, undefined);", None), - (r"set.add(undefined);", None), - (r"map.set(foo, undefined);", None), - (r"array.push(foo, undefined);", None), - (r"array.push(undefined);", None), - (r"array.unshift(foo, undefined);", None), - (r"array.unshift(undefined);", None), - (r"createContext(undefined);", None), - (r"React.createContext(undefined);", None), - (r"setState(undefined)", None), - (r"setState?.(undefined)", None), - (r"props.setState(undefined)", None), - (r"props.setState?.(undefined)", None), - (r"array.includes(undefined)", None), - (r"set.has(undefined)", None), + ("if (Object.is(foo, undefined)){}", None), + ("t.is(foo, undefined)", None), + ("assert.equal(foo, undefined, message)", None), + ("assert.notEqual(foo, undefined, message)", None), + ("assert.strictEqual(foo, undefined, message)", None), + ("assert.notStrictEqual(foo, undefined, message)", None), + ("assert.propertyVal(foo, 'bar', undefined, message)", None), + ("assert.notPropertyVal(foo, 'bar', undefined, message)", None), + ("expect(foo).not(undefined)", None), + ("expect(foo).to.have.property('bar', undefined)", None), + ("expect(foo).toBe(undefined)", None), + ("expect(foo).toContain(undefined)", None), + ("expect(foo).toContainEqual(undefined)", None), + ("expect(foo).toEqual(undefined)", None), + ("t.same(foo, undefined)", None), + ("t.notSame(foo, undefined)", None), + ("t.strictSame(foo, undefined)", None), + ("t.strictNotSame(foo, undefined)", None), + ("expect(someFunction).toHaveBeenCalledWith(1, 2, undefined);", None), + ("set.add(undefined);", None), + ("map.set(foo, undefined);", None), + ("array.push(foo, undefined);", None), + ("array.push(undefined);", None), + ("array.unshift(foo, undefined);", None), + ("array.unshift(undefined);", None), + ("createContext(undefined);", None), + ("React.createContext(undefined);", None), + ("setState(undefined)", None), + ("setState?.(undefined)", None), + ("props.setState(undefined)", None), + ("props.setState?.(undefined)", None), + ("array.includes(undefined)", None), + ("set.has(undefined)", None), // `Function#bind()` - (r"foo.bind(bar, undefined);", None), - (r"foo.bind(...bar, undefined);", None), - (r"foo.bind(...[], undefined);", None), - (r"foo.bind(...[undefined], undefined);", None), - (r"foo.bind(bar, baz, undefined);", None), - (r"foo?.bind(bar, undefined);", None), + ("foo.bind(bar, undefined);", None), + ("foo.bind(...bar, undefined);", None), + ("foo.bind(...[], undefined);", None), + ("foo.bind(...[undefined], undefined);", None), + ("foo.bind(bar, baz, undefined);", None), + ("foo?.bind(bar, undefined);", None), // `checkArguments: false` - (r"foo(undefined, undefined);", options_ignore_arguments()), - (r"foo.bind(undefined);", options_ignore_arguments()), + ("foo(undefined, undefined);", options_ignore_arguments()), + ("foo.bind(undefined);", options_ignore_arguments()), ( - r"function run(name?: string) { return name; } run(undefined);", + "function run(name?: string) { return name; } run(undefined);", options_ignore_arguments(), ), // `checkArrowFunctionBody: false` - (r"const foo = () => undefined", options_ignore_arrow_function_body()), - (r"const x = { a: undefined }", None), + ("const foo = () => undefined", options_ignore_arrow_function_body()), + ("const x = { a: undefined }", None), // https://github.com/zeit/next.js/blob/3af0fe5cf2542237f34d106872d104c3606b1858/packages/next/build/utils.ts#L620 - (r"prerenderPaths?.add(entry)", None), + ("prerenderPaths?.add(entry)", None), ( r#" function getThing(): string | undefined { @@ -445,11 +445,11 @@ fn test() { "#, None, ), - (r"const foo = (): undefined => {return undefined;}", None), - (r"const foo = (): undefined => undefined;", None), - (r"const foo = (): string => undefined;", None), - (r"const foo = function (): undefined {return undefined}", None), - (r"export function foo(): undefined {return undefined}", None), + ("const foo = (): undefined => {return undefined;}", None), + ("const foo = (): undefined => undefined;", None), + ("const foo = (): string => undefined;", None), + ("const foo = function (): undefined {return undefined}", None), + ("export function foo(): undefined {return undefined}", None), ( r" const object = { @@ -530,18 +530,18 @@ fn test() { ", None, ), - (r"createContext(undefined);", None), - (r"React.createContext(undefined);", None), - (r"const x = { a: undefined }", None), + ("createContext(undefined);", None), + ("React.createContext(undefined);", None), + ("const x = { a: undefined }", None), ( - r" + " const y: any = {} y.foo = undefined ", None, ), ( - r" + " class Foo { public x: number | undefined = undefined } diff --git a/crates/oxc_linter/src/rules/unicorn/no_zero_fractions.rs b/crates/oxc_linter/src/rules/unicorn/no_zero_fractions.rs index b54f6a5e18cbb..c017576649352 100644 --- a/crates/oxc_linter/src/rules/unicorn/no_zero_fractions.rs +++ b/crates/oxc_linter/src/rules/unicorn/no_zero_fractions.rs @@ -136,42 +136,50 @@ fn test() { let pass = vec![ r#"const foo = "123.1000""#, r#"foo("123.1000")"#, - r"const foo = 1", - r"const foo = 1 + 2", - r"const foo = -1", - r"const foo = 123123123", - r"const foo = 1.1", - r"const foo = -1.1", - r"const foo = 123123123.4", - r"const foo = 1e3", - r"1 .toString()", + "const foo = 1", + "const foo = 1 + 2", + "const foo = -1", + "const foo = 123123123", + "const foo = 1.1", + "const foo = -1.1", + "const foo = 123123123.4", + "const foo = 1e3", + "1 .toString()", ]; let fail = vec![ - r"const foo = 1.0", - r"const foo = 1.0 + 1", - r"foo(1.0 + 1)", - r"const foo = 1.00", - r"const foo = 1.00000", - r"const foo = -1.0", - r"const foo = 123123123.0", - r"const foo = 123.11100000000", - r"const foo = 1.", - r"const foo = +1.", - r"const foo = -1.", - r"const foo = 1.e10", - r"const foo = +1.e-10", - r"const foo = -1.e+10", - r"const foo = (1.).toString()", - r"1.00.toFixed(2)", - r"1.00 .toFixed(2)", - r"(1.00).toFixed(2)", - r"1.00?.toFixed(2)", - r"a = .0;", - r"a = .0.toString()", - r"function foo(){return.0}", - r"function foo(){return.0.toString()}", - r"function foo(){return.0+.1}", + "const foo = 1.0", + "const foo = 1.0 + 1", + "foo(1.0 + 1)", + "const foo = 1.00", + "const foo = 1.00000", + "const foo = -1.0", + "const foo = 123123123.0", + "const foo = 123.11100000000", + "const foo = 1.", + "const foo = +1.", + "const foo = -1.", + "const foo = 1.e10", + "const foo = +1.e-10", + "const foo = -1.e+10", + "const foo = (1.).toString()", + "1.00.toFixed(2)", + "1.00 .toFixed(2)", + "(1.00).toFixed(2)", + "1.00?.toFixed(2)", + "console.log() + 1..toString()", + "console.log() + a[1.].toString()", + "console.log() + 1.00e10.toString()", + "console.log() + a[1.00e10].toString()", + "a = .0;", + "a = .0.toString()", + "function foo(){return.0}", + "function foo(){return.0.toString()}", + "function foo(){return.0+.1}", "Γ΄Test(0.)", ]; diff --git a/crates/oxc_linter/src/rules/unicorn/prefer_array_flat.rs b/crates/oxc_linter/src/rules/unicorn/prefer_array_flat.rs index ae5135c21b850..66ce05b3b55af 100644 --- a/crates/oxc_linter/src/rules/unicorn/prefer_array_flat.rs +++ b/crates/oxc_linter/src/rules/unicorn/prefer_array_flat.rs @@ -298,6 +298,25 @@ fn test() { "array.flatMap((x, y) => x)", // "array.flatMap((x) => { return x; })", "array.flatMap(x => y)", + // TODO: Get this passing. + // "const randomObject = { + // flatMap(function_) { + // function_(); + // }, + // }; + // randomObject.flatMap(x => x);", + // "Effects.flatMap(x => x)", + // "const effects = { + // flatMap(function_) { + // function_(); + // }, + // }; + // effects.flatMap(x => x);", + // "const effects = new Set(); effects.flatMap(x => x);", + // "const mapping = new Map(); mapping.flatMap(x => x);", + // r#"const text = ""; text.flatMap(x => x);"#, + // "const handler = () => {}; handler.flatMap(x => x);", + // "const collection = new Foo(); collection.flatMap(x => x);", "new array.reduce((a, b) => a.concat(b), [])", "array.reduce", "reduce((a, b) => a.concat(b), [])", @@ -408,7 +427,15 @@ fn test() { "array.flatMap(x => x)", "array?.flatMap(x => x)", "function foo(){return[].flatMap(x => x)}", - "foo.flatMap(x => x) instanceof Array", + "foo.flatMap(x => x)instanceof Array", + "array.flatMap((x) => x)", + "Foo.bar.flatMap(x => x)", + "const values = getValues(); values.flatMap(x => x);", + "const values = []; values.flatMap(x => x);", + "const Items = []; Items.flatMap(x => x);", + "for (const value of values) { + value.flatMap(x => x); + }", "array.reduce((a, b) => a.concat(b), [])", "array?.reduce((a, b) => a.concat(b), [])", "function foo(){return[].reduce((a, b) => a.concat(b), [])}", @@ -502,6 +529,24 @@ fn test() { ("array.flatMap(x => x)", "array.flat()"), ("array.reduce((a, b) => a.concat(b), [])", "array.flat()"), ("array.reduce((a, b) => [...a, ...b], [])", "array.flat()"), + ("Foo.bar.flatMap(x => x)", "Foo.bar.flat()"), + ( + "const values = getValues(); values.flatMap(x => x);", + "const values = getValues(); values.flat();", + ), + ("const values = []; values.flatMap(x => x);", "const values = []; values.flat();"), + ("const Items = []; Items.flatMap(x => x);", "const Items = []; Items.flat();"), + ( + "for (const value of values) { + value.flatMap(x => x); + }", + "for (const value of values) { + value.flat(); + }", + ), + // TODO: Get these passing. + // ("/**/[].concat.apply([], array)", "/**/array.flat()"), + // ("Array.prototype.concat.apply([], array)", "array.flat()"), ]; Tester::new(PreferArrayFlat::NAME, PreferArrayFlat::PLUGIN, pass, fail) diff --git a/crates/oxc_linter/src/rules/unicorn/prefer_array_flat_map.rs b/crates/oxc_linter/src/rules/unicorn/prefer_array_flat_map.rs index 4655c4163947e..0dd9d7db71317 100644 --- a/crates/oxc_linter/src/rules/unicorn/prefer_array_flat_map.rs +++ b/crates/oxc_linter/src/rules/unicorn/prefer_array_flat_map.rs @@ -128,8 +128,14 @@ fn test() { "const bar = [1,2,3].map((i) => i)", "const bar = [1,2,3].map((i) => { return i; })", "const bar = foo.map(i => i)", + // TODO: Fix the rule so these tests pass. + // "const bar = foo.map?.(i => [i]).flat()", + // "const bar = foo.map(i => [i])?.flat()", + // "const bar = foo.map(i => [i]).flat?.()", "const bar = [[1],[2],[3]].flat()", "const bar = [1,2,3].map(i => [i]).sort().flat()", + "let bar = [1,2,3].map(i => [i]); + bar = bar.flat();", "const bar = [[1],[2],[3]].map(i => [i]).flat(2)", "const bar = [[1],[2],[3]].map(i => [i]).flat(2.0)", // Parsed as 0.9999999999999999. Rounds down to 0. @@ -167,10 +173,31 @@ fn test() { "const bar = [1,2,3].map((i) => { return [i]; }).flat()", "const bar = [1,2,3].map(foo).flat()", "const bar = foo.map(i => [i]).flat()", + "const bar = foo?.map(i => [i]).flat()", "const bar = { map: () => {} }.map(i => [i]).flat()", "const bar = [1,2,3].map(i => i).map(i => [i]).flat()", "const bar = [1,2,3].sort().map(i => [i]).flat()", "const bar = (([1,2,3].map(i => [i]))).flat()", + "let bar = [1,2,3].map(i => { + return [i]; + }).flat();", + "let bar = [1,2,3].map(i => { + return [i]; + }) + .flat();", + "let bar = [1,2,3].map(i => { + return [i]; + }) // comment + .flat();", + "let bar = [1,2,3].map(i => { + return [i]; + }) // comment + .flat(); // other", + "let bar = [1,2,3] + .map(i => { return [i]; }) + .flat();", + "let bar = [1,2,3].map(i => { return [i]; }) + .flat();", "let bar = [1,2,3] . map( x => y ) . flat () // πŸ€ͺ", "const bar = [1,2,3].map(i => [i]).flat(1);", ]; diff --git a/crates/oxc_linter/src/rules/unicorn/prefer_array_some.rs b/crates/oxc_linter/src/rules/unicorn/prefer_array_some.rs index 0191781703191..7bfe520abb281 100644 --- a/crates/oxc_linter/src/rules/unicorn/prefer_array_some.rs +++ b/crates/oxc_linter/src/rules/unicorn/prefer_array_some.rs @@ -353,103 +353,103 @@ fn test() { use crate::tester::Tester; let pass = vec![ - r"const bar = foo.find(fn)", - r"const bar = foo.find(fn) || baz", - r"if (foo.find(fn) ?? bar) {}", - r"array.filter(fn).length > 0.", - r"array.filter(fn).length > .0", - r"array.filter(fn).length > 0.0", - r"array.filter(fn).length > 0x00", - r"array.filter(fn).length < 0", - r"array.filter(fn).length >= 0", - r"0 > array.filter(fn).length", - r"array.filter(fn).length !== 0.", - r"array.filter(fn).length !== .0", - r"array.filter(fn).length !== 0.0", - r"array.filter(fn).length !== 0x00", - r"array.filter(fn).length != 0", - r"array.filter(fn).length === 0", - r"array.filter(fn).length == 0", - r"array.filter(fn).length = 0", - r"0 !== array.filter(fn).length", - r"array.filter(fn).length >= 1", - r"array.filter(fn).length >= 1.", - r"array.filter(fn).length >= 1.0", - r"array.filter(fn).length >= 0x1", - r"array.filter(fn).length > 1", - r"array.filter(fn).length < 1", - r"array.filter(fn).length = 1", - r"array.filter(fn).length += 1", - r"1 >= array.filter(fn).length", - r"array.filter(fn)?.length > 0", - r"array.filter(fn)[length] > 0", - r"array.filter(fn).notLength > 0", - r"array.filter(fn).length() > 0", - r"+array.filter(fn).length >= 1", - r"array.filter?.(fn).length > 0", - r"array?.filter(fn).length > 0", - r"array.notFilter(fn).length > 0", - r"array.filter.length > 0", + "const bar = foo.find(fn)", + "const bar = foo.find(fn) || baz", + "if (foo.find(fn) ?? bar) {}", + "array.filter(fn).length > 0.", + "array.filter(fn).length > .0", + "array.filter(fn).length > 0.0", + "array.filter(fn).length > 0x00", + "array.filter(fn).length < 0", + "array.filter(fn).length >= 0", + "0 > array.filter(fn).length", + "array.filter(fn).length !== 0.", + "array.filter(fn).length !== .0", + "array.filter(fn).length !== 0.0", + "array.filter(fn).length !== 0x00", + "array.filter(fn).length != 0", + "array.filter(fn).length === 0", + "array.filter(fn).length == 0", + "array.filter(fn).length = 0", + "0 !== array.filter(fn).length", + "array.filter(fn).length >= 1", + "array.filter(fn).length >= 1.", + "array.filter(fn).length >= 1.0", + "array.filter(fn).length >= 0x1", + "array.filter(fn).length > 1", + "array.filter(fn).length < 1", + "array.filter(fn).length = 1", + "array.filter(fn).length += 1", + "1 >= array.filter(fn).length", + "array.filter(fn)?.length > 0", + "array.filter(fn)[length] > 0", + "array.filter(fn).notLength > 0", + "array.filter(fn).length() > 0", + "+array.filter(fn).length >= 1", + "array.filter?.(fn).length > 0", + "array?.filter(fn).length > 0", + "array.notFilter(fn).length > 0", + "array.filter.length > 0", r#"$element.filter(":visible").length > 0"#, - r"foo.find(fn) == 0", + "foo.find(fn) == 0", r#"foo.find(fn) != """#, - r"foo.find(fn) === null", + "foo.find(fn) === null", r#"foo.find(fn) !== "null""#, - r"foo.find(fn) >= undefined", - r"foo.find(fn) instanceof undefined", + "foo.find(fn) >= undefined", + "foo.find(fn) instanceof undefined", r#"typeof foo.find(fn) === "undefined""#, // findIndex: negative one - r"foo.notMatchedMethod(bar) !== -1", - r"new foo.findIndex(bar) !== -1", - r"foo.findIndex(bar, extraArgument) !== -1", - r"foo.findIndex(bar) instanceof -1", - r"foo.findIndex(...bar) !== -1", + "foo.notMatchedMethod(bar) !== -1", + "new foo.findIndex(bar) !== -1", + "foo.findIndex(bar, extraArgument) !== -1", + "foo.findIndex(bar) instanceof -1", + "foo.findIndex(...bar) !== -1", // findLastIndex: negative one - r"new foo.findLastIndex(bar) !== -1", - r"foo.findLastIndex(bar, extraArgument) !== -1", - r"foo.findLastIndex(bar) instanceof -1", - r"foo.findLastIndex(...bar) !== -1", + "new foo.findLastIndex(bar) !== -1", + "foo.findLastIndex(bar, extraArgument) !== -1", + "foo.findLastIndex(bar) instanceof -1", + "foo.findLastIndex(...bar) !== -1", ]; let fail = vec![ - r"if (foo.find(fn)) {}", - r"if (foo.findLast(fn)) {}", + "if (foo.find(fn)) {}", + "if (foo.findLast(fn)) {}", r#"if (array.find(element => element === "πŸ¦„")) {}"#, r#"const foo = array.find(element => element === "πŸ¦„") ? bar : baz;"#, - r"array.filter(fn).length > 0", - r"array.filter(fn).length !== 0", - r"foo.find(fn) == null", - r"foo.find(fn) == undefined", - r"foo.find(fn) === undefined", - r"foo.find(fn) != null", - r"foo.find(fn) != undefined", - r"foo.find(fn) !== undefined", + "array.filter(fn).length > 0", + "array.filter(fn).length !== 0", + "foo.find(fn) == null", + "foo.find(fn) == undefined", + "foo.find(fn) === undefined", + "foo.find(fn) != null", + "foo.find(fn) != undefined", + "foo.find(fn) !== undefined", r#"a = (( ((foo.find(fn))) == ((null)) )) ? "no" : "yes";"#, // findIndex: negative one || ( >= || < ) 0 - r"foo.findIndex(bar) !== -1", - r"foo.findIndex(bar) != -1", - r"foo.findIndex(bar) > - 1", - r"foo.findIndex(bar) === -1", - r"foo.findIndex(bar) == - 1", - r"foo.findIndex(bar) >= 0", - r"foo.findIndex(bar) < 0", - r"foo.findIndex(bar) !== (( - 1 ))", - r"foo.findIndex(element => element.bar === 1) !== (( - 1 ))", + "foo.findIndex(bar) !== -1", + "foo.findIndex(bar) != -1", + "foo.findIndex(bar) > - 1", + "foo.findIndex(bar) === -1", + "foo.findIndex(bar) == - 1", + "foo.findIndex(bar) >= 0", + "foo.findIndex(bar) < 0", + "foo.findIndex(bar) !== (( - 1 ))", + "foo.findIndex(element => element.bar === 1) !== (( - 1 ))", // findLastIndex: negative one || ( >= || < ) 0 - r"foo.findLastIndex(bar) !== -1", - r"foo.findLastIndex(bar) != -1", - r"foo.findLastIndex(bar) > - 1", - r"foo.findLastIndex(bar) === -1", - r"foo.findLastIndex(bar) == - 1", - r"foo.findLastIndex(bar) >= 0", - r"foo.findLastIndex(bar) < 0", - r"foo.findLastIndex(bar) !== (( - 1 ))", - r"foo.findLastIndex(element => element.bar === 1) !== (( - 1 ))", + "foo.findLastIndex(bar) !== -1", + "foo.findLastIndex(bar) != -1", + "foo.findLastIndex(bar) > - 1", + "foo.findLastIndex(bar) === -1", + "foo.findLastIndex(bar) == - 1", + "foo.findLastIndex(bar) >= 0", + "foo.findLastIndex(bar) < 0", + "foo.findLastIndex(bar) !== (( - 1 ))", + "foo.findLastIndex(element => element.bar === 1) !== (( - 1 ))", ]; let fix = vec![ - (r"if (foo.find(fn)) {}", r"if (foo.some(fn)) {}"), - (r"if (foo.findLast(fn)) {}", r"if (foo.some(fn)) {}"), + ("if (foo.find(fn)) {}", "if (foo.some(fn)) {}"), + ("if (foo.findLast(fn)) {}", "if (foo.some(fn)) {}"), ( r#"if (array.find(element => element === "πŸ¦„")) {}"#, r#"if (array.some(element => element === "πŸ¦„")) {}"#, @@ -458,14 +458,14 @@ fn test() { r#"const foo = array.find(element => element === "πŸ¦„") ? bar : baz;"#, r#"const foo = array.some(element => element === "πŸ¦„") ? bar : baz;"#, ), - (r"array.filter(fn).length > 0", r"array.some(fn)"), - (r"array.filter(fn).length !== 0", r"array.some(fn)"), - (r"foo.find(fn) == null", r"foo.some(fn) == null"), - (r"foo.find(fn) == undefined", r"foo.some(fn) == undefined"), - (r"foo.find(fn) === undefined", r"foo.some(fn) === undefined"), - (r"foo.find(fn) != null", r"foo.some(fn) != null"), - (r"foo.find(fn) != undefined", r"foo.some(fn) != undefined"), - (r"foo.find(fn) !== undefined", r"foo.some(fn) !== undefined"), + ("array.filter(fn).length > 0", "array.some(fn)"), + ("array.filter(fn).length !== 0", "array.some(fn)"), + ("foo.find(fn) == null", "foo.some(fn) == null"), + ("foo.find(fn) == undefined", "foo.some(fn) == undefined"), + ("foo.find(fn) === undefined", "foo.some(fn) === undefined"), + ("foo.find(fn) != null", "foo.some(fn) != null"), + ("foo.find(fn) != undefined", "foo.some(fn) != undefined"), + ("foo.find(fn) !== undefined", "foo.some(fn) !== undefined"), ( r#"a = (( ((foo.find(fn))) == ((null)) )) ? "no" : "yes";"#, r#"a = (( ((foo.some(fn))) == ((null)) )) ? "no" : "yes";"#, diff --git a/crates/oxc_linter/src/rules/unicorn/prefer_code_point.rs b/crates/oxc_linter/src/rules/unicorn/prefer_code_point.rs index 06c2c1b5a767e..b67af752f662c 100644 --- a/crates/oxc_linter/src/rules/unicorn/prefer_code_point.rs +++ b/crates/oxc_linter/src/rules/unicorn/prefer_code_point.rs @@ -78,42 +78,42 @@ fn test() { let pass = vec![ r#""πŸ¦„".codePointAt(0)"#, - r"foo.charCodeAt", - r"new foo.charCodeAt", - r"charCodeAt(0)", - r"foo.charCodeAt?.(0)", - r"foo?.charCodeAt(0)", - r"foo[charCodeAt](0)", + "foo.charCodeAt", + "new foo.charCodeAt", + "charCodeAt(0)", + "foo.charCodeAt?.(0)", + "foo?.charCodeAt(0)", + "foo[charCodeAt](0)", r#"foo["charCodeAt"](0)"#, - r"foo.notCharCodeAt(0)", - r"String.fromCodePoint(0x1f984)", - r"String.fromCodePoint", - r"new String.fromCodePoint", - r"fromCodePoint(foo)", - r"String.fromCodePoint?.(foo)", - r"String?.fromCodePoint(foo)", - r"window.String.fromCodePoint(foo)", - r"String[fromCodePoint](foo)", + "foo.notCharCodeAt(0)", + "String.fromCodePoint(0x1f984)", + "String.fromCodePoint", + "new String.fromCodePoint", + "fromCodePoint(foo)", + "String.fromCodePoint?.(foo)", + "String?.fromCodePoint(foo)", + "window.String.fromCodePoint(foo)", + "String[fromCodePoint](foo)", r#"String["fromCodePoint"](foo)"#, - r"String.notFromCodePoint(foo)", - r"NotString.fromCodePoint(foo)", + "String.notFromCodePoint(foo)", + "NotString.fromCodePoint(foo)", ]; let fail = vec![ - r"string.charCodeAt(index)", - r"(( (( string )).charCodeAt( ((index)), )))", - r"String.fromCharCode( code )", - r"(( (( String )).fromCharCode( ((code)), ) ))", + "string.charCodeAt(index)", + "(( (( string )).charCodeAt( ((index)), )))", + "String.fromCharCode( code )", + "(( (( String )).fromCharCode( ((code)), ) ))", ]; let fix = vec![ - (r"string.charCodeAt(index)", r"string.codePointAt(index)"), + ("string.charCodeAt(index)", "string.codePointAt(index)"), ( - r"(( (( String )).fromCharCode( ((code)), ) ))", - r"(( (( String )).fromCodePoint( ((code)), ) ))", + "(( (( String )).fromCharCode( ((code)), ) ))", + "(( (( String )).fromCodePoint( ((code)), ) ))", ), (r#""πŸ¦„".charCodeAt(0)"#, r#""πŸ¦„".codePointAt(0)"#), - (r"String.fromCharCode(0x1f984);", r"String.fromCodePoint(0x1f984);"), + ("String.fromCharCode(0x1f984);", "String.fromCodePoint(0x1f984);"), ]; Tester::new(PreferCodePoint::NAME, PreferCodePoint::PLUGIN, pass, fail) diff --git a/crates/oxc_linter/src/rules/unicorn/prefer_dom_node_dataset.rs b/crates/oxc_linter/src/rules/unicorn/prefer_dom_node_dataset.rs index ea68e443ac813..b77742106a76c 100644 --- a/crates/oxc_linter/src/rules/unicorn/prefer_dom_node_dataset.rs +++ b/crates/oxc_linter/src/rules/unicorn/prefer_dom_node_dataset.rs @@ -398,10 +398,10 @@ fn test() { "element.setAttribute('data-foo2', 'πŸ¦„');", "element.setAttribute('data-foo:bar', 'zaz');", r#"element.setAttribute("data-foo:bar", "zaz");"#, - r"element.setAttribute('data-foo.bar', 'zaz');", - r"element.setAttribute('data-foo-bar', 'zaz');", - r"element.setAttribute('data-foo', /* comment */ 'bar');", - r"element.querySelector('#selector').setAttribute('data-AllowAccess', true);", + "element.setAttribute('data-foo.bar', 'zaz');", + "element.setAttribute('data-foo-bar', 'zaz');", + "element.setAttribute('data-foo', /* comment */ 'bar');", + "element.querySelector('#selector').setAttribute('data-AllowAccess', true);", r#"element.setAttribute("data-", "πŸ¦„");"#, r#"element.setAttribute("data--foo", "πŸ¦„");"#, r#"element.setAttribute("DATA--FOO", "πŸ¦„");"#, diff --git a/crates/oxc_linter/src/rules/unicorn/prefer_dom_node_remove.rs b/crates/oxc_linter/src/rules/unicorn/prefer_dom_node_remove.rs index 9642fa02b1624..86092d7315e81 100644 --- a/crates/oxc_linter/src/rules/unicorn/prefer_dom_node_remove.rs +++ b/crates/oxc_linter/src/rules/unicorn/prefer_dom_node_remove.rs @@ -96,6 +96,8 @@ fn test() { "parentNode.removeChild(undefined)", "new parentNode.removeChild(bar);", "removeChild(foo);", + // TODO: Get this passing. + // "parentNode['removeChild'](bar);", "parentNode[removeChild](bar);", "parentNode.foo(bar);", "parentNode.removeChild(bar, extra);", diff --git a/crates/oxc_linter/src/rules/unicorn/prefer_dom_node_text_content.rs b/crates/oxc_linter/src/rules/unicorn/prefer_dom_node_text_content.rs index 12d1b51051d0c..2224421b54ab0 100644 --- a/crates/oxc_linter/src/rules/unicorn/prefer_dom_node_text_content.rs +++ b/crates/oxc_linter/src/rules/unicorn/prefer_dom_node_text_content.rs @@ -140,12 +140,12 @@ fn test() { "const {innerText} = node;", "const {innerText,} = node;", "const {innerText: text} = node;", - "const {innerText = \"default text\"} = node;", - "const {innerText: text = \"default text\"} = node;", + r#"const {innerText = "default text"} = node;"#, + r#"const {innerText: text = "default text"} = node;"#, "({innerText} = node);", "({innerText: text} = node);", - "({innerText = \"default text\"} = node);", - "({innerText: text = \"default text\"} = node);", + r#"({innerText = "default text"} = node);"#, + r#"({innerText: text = "default text"} = node);"#, "function foo({innerText}) {return innerText}", "for (const [{innerText}] of elements);", ]; diff --git a/crates/oxc_linter/src/rules/unicorn/prefer_global_this.rs b/crates/oxc_linter/src/rules/unicorn/prefer_global_this.rs index ae4d23767afa9..ce5660d2e08f8 100644 --- a/crates/oxc_linter/src/rules/unicorn/prefer_global_this.rs +++ b/crates/oxc_linter/src/rules/unicorn/prefer_global_this.rs @@ -289,6 +289,8 @@ fn test() { "self.navigator", r#"window.addEventListener("resize", () => {})"#, "window.onresize = function () {}", + // TODO: Get this passing. + // r#"'open' in window; window.open("https://example.com")"#, "const {window} = jsdom() window.jQuery = jQuery;", "({ foo: window.name } = {})", @@ -375,6 +377,8 @@ fn test() { "[window.foo] = []", "foo[window]", "foo[window.foo]", + "'foo' in window", + "'foo' in global", r#"typeof window !== "undefined""#, r#"typeof self !== "undefined""#, r#"typeof global !== "undefined""#, diff --git a/crates/oxc_linter/src/rules/unicorn/prefer_math_trunc.rs b/crates/oxc_linter/src/rules/unicorn/prefer_math_trunc.rs index 3908b80ab5f14..8e8d8dbde3575 100644 --- a/crates/oxc_linter/src/rules/unicorn/prefer_math_trunc.rs +++ b/crates/oxc_linter/src/rules/unicorn/prefer_math_trunc.rs @@ -153,6 +153,10 @@ fn test() { "const foo = ~3.9;", "const foo = 1.1 >> 1", "const foo = 0 << 1", + "let foo = 0; + foo |= 1;", + "let foo = 1.2; // comment 1 + foo |= 1; // comment 2 and 1.2 | 0", ]; let fail = vec![ diff --git a/crates/oxc_linter/src/rules/unicorn/prefer_modern_dom_apis.rs b/crates/oxc_linter/src/rules/unicorn/prefer_modern_dom_apis.rs index 5f5ac19bd240f..0cf9b1de52021 100644 --- a/crates/oxc_linter/src/rules/unicorn/prefer_modern_dom_apis.rs +++ b/crates/oxc_linter/src/rules/unicorn/prefer_modern_dom_apis.rs @@ -168,13 +168,13 @@ fn test() { let pass = vec![ "oldChildNode.replaceWith(newChildNode);", "referenceNode.before(newNode);", - "referenceNode.before(\"text\");", + r#"referenceNode.before("text");"#, "referenceNode.prepend(newNode);", - "referenceNode.prepend(\"text\");", + r#"referenceNode.prepend("text");"#, "referenceNode.append(newNode);", - "referenceNode.append(\"text\");", + r#"referenceNode.append("text");"#, "referenceNode.after(newNode);", - "referenceNode.after(\"text\");", + r#"referenceNode.after("text");"#, "oldChildNode.replaceWith(undefined, oldNode);", "oldChildNode.replaceWith(newNode, undefined);", "new parentNode.replaceChild(newNode, oldNode);", @@ -212,6 +212,14 @@ fn test() { let fail = vec![ "parentNode.replaceChild(newChildNode, oldChildNode);", + "parentNode.replaceChild( + newChildNode, + oldChildNode + );", + "parentNode.replaceChild( // inline comments + newChildNode, // inline comments + oldChildNode // inline comments + );", "const foo = parentNode.replaceChild(newChildNode, oldChildNode);", "foo = parentNode.replaceChild(newChildNode, oldChildNode);", "parentNode.insertBefore(newNode, referenceNode);", @@ -220,23 +228,31 @@ fn test() { "foo = parentNode.insertBefore(alfa, beta);", "new Dom(parentNode.insertBefore(alfa, beta))", "`${parentNode.insertBefore(alfa, beta)}`", - "referenceNode.insertAdjacentText(\"beforebegin\", \"text\");", - "referenceNode.insertAdjacentText(\"afterbegin\", \"text\");", - "referenceNode.insertAdjacentText(\"beforeend\", \"text\");", - "referenceNode.insertAdjacentText(\"afterend\", \"text\");", - "const foo = referenceNode.insertAdjacentText(\"beforebegin\", \"text\");", - "foo = referenceNode.insertAdjacentText(\"beforebegin\", \"text\");", - "referenceNode.insertAdjacentElement(\"beforebegin\", newNode);", - "referenceNode.insertAdjacentElement(\"afterbegin\", \"text\");", - "referenceNode.insertAdjacentElement(\"beforeend\", \"text\");", - "referenceNode.insertAdjacentElement(\"afterend\", newNode);", - "const foo = referenceNode.insertAdjacentElement(\"beforebegin\", newNode);", - "foo = referenceNode.insertAdjacentElement(\"beforebegin\", newNode);", - "const foo = [referenceNode.insertAdjacentElement(\"beforebegin\", newNode)]", - "foo(bar = referenceNode.insertAdjacentElement(\"beforebegin\", newNode))", - "const foo = () => { return referenceNode.insertAdjacentElement(\"beforebegin\", newNode); }", - "if (referenceNode.insertAdjacentElement(\"beforebegin\", newNode)) {}", - "const foo = { bar: referenceNode.insertAdjacentElement(\"beforebegin\", newNode) }", + r#"referenceNode.insertAdjacentText("beforebegin", "text");"#, + r#"referenceNode.insertAdjacentText("afterbegin", "text");"#, + r#"referenceNode.insertAdjacentText("beforeend", "text");"#, + r#"referenceNode.insertAdjacentText("afterend", "text");"#, + r#"const foo = referenceNode.insertAdjacentText("beforebegin", "text");"#, + r#"foo = referenceNode.insertAdjacentText("beforebegin", "text");"#, + r#"referenceNode.insertAdjacentElement("beforebegin", newNode);"#, + r#"referenceNode.insertAdjacentElement("afterbegin", "text");"#, + r#"referenceNode.insertAdjacentElement("beforeend", "text");"#, + r#"referenceNode.insertAdjacentElement("afterend", newNode);"#, + r#"referenceNode.insertAdjacentElement( + "afterend", + newNode + );"#, + r#"referenceNode.insertAdjacentElement( // inline comments + "afterend", // inline comments + newNode // inline comments + ); // inline comments"#, + r#"const foo = referenceNode.insertAdjacentElement("beforebegin", newNode);"#, + r#"foo = referenceNode.insertAdjacentElement("beforebegin", newNode);"#, + r#"const foo = [referenceNode.insertAdjacentElement("beforebegin", newNode)]"#, + r#"foo(bar = referenceNode.insertAdjacentElement("beforebegin", newNode))"#, + r#"const foo = () => { return referenceNode.insertAdjacentElement("beforebegin", newNode); }"#, + r#"if (referenceNode.insertAdjacentElement("beforebegin", newNode)) {}"#, + r#"const foo = { bar: referenceNode.insertAdjacentElement("beforebegin", newNode) }"#, ]; let fix = vec![ diff --git a/crates/oxc_linter/src/rules/unicorn/prefer_native_coercion_functions.rs b/crates/oxc_linter/src/rules/unicorn/prefer_native_coercion_functions.rs index a67479139d09d..8c0126ffd06ab 100644 --- a/crates/oxc_linter/src/rules/unicorn/prefer_native_coercion_functions.rs +++ b/crates/oxc_linter/src/rules/unicorn/prefer_native_coercion_functions.rs @@ -260,6 +260,44 @@ fn test() { "const foo = function * (v) {yield String(v);}", "const foo = async function (v) {await String(v);}", "const foo = function (v) {return;}", + // TODO: Get this passing. + // "function foo(v) { + // 'use strict'; + // return String(v); + // }", + "function foo(v) { + return String(v); + function x() {} + }", + "function foo({v}) { + return String(v); + }", + "function foo(v) { + return String({v}); + }", + "function foo(...v) { + return String(v); + }", + "function foo(...v) { + return String(...v); + }", + // TODO: Get this passing. + // "class A { + // constructor(v) { + // return String(v); + // } + // }", + "class A { + get foo() { + return String(v); + } + }", + // TODO: Get this passing. + // "class A { + // set foo(v) { + // return String(v); + // } + // }", "({get foo() {return String(v)}})", "({set foo(v) {return String(v)}})", "array.some?.(v => v)", @@ -272,6 +310,18 @@ fn test() { "array.some(function(v) {return;})", "array.some(function(v) {return v.v;})", "cells.every((cellRowIdx, cellColIdx, tableLoop, cellLoop) => {});", + "const identity = v => v; + array.some(identity)", + r#"array.some(function(v) { + "use strict"; + return v; + })"#, + // TODO: Get these passing. + // "array.filter((value): value is string => value)", // {"parser": parsers.typescript}, + // "array.filter((value): value is string => { + // return value; + // })", // {"parser": parsers.typescript}, + // "array.some((value): value is string => value)", // {"parser": parsers.typescript} ]; let fail = vec![ @@ -280,9 +330,55 @@ fn test() { "const foo = v => BigInt(v)", "const foo = v => Boolean(v)", "const foo = v => Symbol(v)", + "const foo = v => { + return String(v); + }", + "const foo = function (v) { + return String(v); + }", "function foo(v) { return String(v); }", "export default function foo(v) { return String(v); }", "export default function (v) { return String(v); }", + "class A { + foo(v) { + return String(v); + } + bar() {} + }", + "class A { + static foo(v) { + return String(v); + } + bar() {} + }", + "class A { + #foo(v) { + return String(v); + } + bar() {} + }", + "class A { + static #foo(v) { + return String(v); + } + bar() {} + }", + // TODO: Get these passing. + // "object = { + // foo(v) { + // return String(v); + // }, + // bar + // }", + // "object = { + // foo: function(v) { + // return String(v); + // }, + // bar + // }", + // "object = { + // [function(v) {return String(v);}]: 1, + // }", "const foo = (v, extra) => String(v)", "const foo = (v, ) => String(v, extra)", "const foo = (v, ) => /* comment */ String(v)", @@ -294,8 +390,16 @@ fn test() { "array.findIndex(v => v)", "array.findLastIndex(v => v)", "array.some(v => v)", + "array.some(v => { + return v; + })", + // TODO: Get this working. + // "array.some(function (v) { + // return v; + // })", "array.some((v, extra) => v)", "array.some((v, ) => /* comment */ v)", + "array.filter((value): boolean => value)", // {"parser": parsers.typescript} ]; Tester::new( diff --git a/crates/oxc_linter/src/rules/unicorn/prefer_node_protocol.rs b/crates/oxc_linter/src/rules/unicorn/prefer_node_protocol.rs index aa77b467d7840..c61e4d996ab28 100644 --- a/crates/oxc_linter/src/rules/unicorn/prefer_node_protocol.rs +++ b/crates/oxc_linter/src/rules/unicorn/prefer_node_protocol.rs @@ -110,16 +110,33 @@ fn test() { r#"import type fs = require("node:fs");"#, r#"const fs = require("node:fs");"#, r#"const fs = require("node:fs/promises");"#, - r"const fs = require(fs);", + "const fs = require(fs);", r#"const fs = notRequire("fs");"#, r#"const fs = foo.require("fs");"#, r#"const fs = require.resolve("fs");"#, - r"const fs = require(`fs`);", + "const fs = require(`fs`);", r#"const fs = require?.("fs");"#, r#"const fs = require("fs", extra);"#, - r"const fs = require();", + "const fs = require();", r#"const fs = require(...["fs"]);"#, r#"const fs = require("unicorn");"#, + r#"const fs = process.getBuiltinModule("node:fs")"#, + r#"const fs = process.getBuiltinModule?.("fs")"#, + r#"const fs = process?.getBuiltinModule("fs")"#, + r#"const fs = process.notGetBuiltinModule("fs")"#, + r#"const fs = notProcess.getBuiltinModule("fs")"#, + r#"const fs = process.getBuiltinModule("fs", extra)"#, + r#"const fs = process.getBuiltinModule(...["fs"])"#, + "const fs = process.getBuiltinModule()", + r#"const fs = process.getBuiltinModule("unicorn")"#, + r#"import {getBuiltinModule} from 'node:process'; + const fs = getBuiltinModule("fs");"#, + // This is a syntax error, can be ignored. + // r#"export fs from "node:fs";"#, + r#"const fs = require("node:fs") as "fs";"#, + r#"type fs = typeof import("node:fs");"#, + r#"type fs = typeof SomeType<"fs">;"#, + "type fs = typeof fs;", ]; let fail = vec![ @@ -127,26 +144,40 @@ fn test() { r#"import * as fs from "fs";"#, r#"import fs = require("fs");"#, r#"export {promises} from "fs";"#, + "async function foo() { + const fs = await import('fs'); + }", r#"import fs from "fs/promises";"#, r#"export {default} from "fs/promises";"#, + "async function foo() { + const fs = await import('fs/promises'); + }", r#"import {promises} from "fs";"#, r#"export {default as promises} from "fs";"#, - r"import {promises} from 'fs';", + "import {promises} from 'fs';", + r#"async function foo() { + const fs = await import("fs/promises"); + }"#, + // Don't bother fixing this + // r#"async function foo() { + // const fs = await import(/* escaped */"\\\\u{66}s/promises"); + // }"#, r#"import "buffer";"#, r#"import "child_process";"#, r#"import "timers/promises";"#, r#"const {promises} = require("fs")"#, - r"const fs = require('fs/promises')", + "const fs = require('fs/promises')", + // r#"const fs = process.getBuiltinModule("fs")"#, r#"export fs from "fs";"#, - r"await import('assert/strict')", + "await import('assert/strict')", ]; let fix = vec![ (r#"import fs from "fs";"#, r#"import fs from "node:fs";"#), (r#"import * as fs from "fs";"#, r#"import * as fs from "node:fs";"#), - (r"import fs from 'fs';", r"import fs from 'node:fs';"), - (r"const fs = require('fs');", r"const fs = require('node:fs');"), - (r"import fs = require('fs');", r"import fs = require('node:fs');"), + ("import fs from 'fs';", "import fs from 'node:fs';"), + ("const fs = require('fs');", "const fs = require('node:fs');"), + ("import fs = require('fs');", "import fs = require('node:fs');"), (r#"import "child_process";"#, r#"import "node:child_process";"#), (r#"import fs from "fs/promises";"#, r#"import fs from "node:fs/promises";"#), ]; diff --git a/crates/oxc_linter/src/rules/unicorn/prefer_optional_catch_binding.rs b/crates/oxc_linter/src/rules/unicorn/prefer_optional_catch_binding.rs index 8af93a0a65c12..13620a7211990 100644 --- a/crates/oxc_linter/src/rules/unicorn/prefer_optional_catch_binding.rs +++ b/crates/oxc_linter/src/rules/unicorn/prefer_optional_catch_binding.rs @@ -113,39 +113,84 @@ fn test() { use crate::tester::Tester; let pass = vec![ - r"try {} catch {}", - r"try {} catch ({message}) {alert(message)}", - r"try {} catch ({cause: {message}}) {alert(message)}", - r"try {} catch({nonExistsProperty = thisWillExecute()}) {}", + "try {} catch {}", + "try {} catch { + error + }", + "try {} catch(used) { + console.error(used); + }", + "try {} catch(usedInADeeperScope) { + function foo() { + function bar() { + console.error(usedInADeeperScope); + } + } + }", + "try {} catch ({message}) {alert(message)}", + "try {} catch ({cause: {message}}) {alert(message)}", + "try {} catch({nonExistsProperty = thisWillExecute()}) {}", ]; let fail = vec![ - r"try {} catch (_) {}", - r"try {} catch (theRealErrorName) {}", - r"try { } catch (e) - { }", - r"try {} catch(e) {}", - r"try {} catch (e){}", - r"try {} catch ({}) {}", - r"try {} catch ({message}) {}", - r"try {} catch ({message: notUsedMessage}) {}", - r"try {} catch ({cause: {message}}) {}", + "try {} catch (_) {}", + "try {} catch (foo) { + function bar(foo) {} + }", + "try {} catch (outer) { + try {} catch (inner) { + } + } + try { + try {} catch (inTry) { + } + } catch (another) { + try {} catch (inCatch) { + } + } finally { + try {} catch (inFinally) { + } + }", + "try {} catch (theRealErrorName) {}", + "/* comment */ + try { + /* comment */ + // comment + } catch ( + /* comment */ + // comment + unused + /* comment */ + // comment + ) { + /* comment */ + // comment + } + /* comment */", + "try { } catch (e) + { }", + "try {} catch(e) {}", + "try {} catch (e){}", + "try {} catch ({}) {}", + "try {} catch ({message}) {}", + "try {} catch ({message: notUsedMessage}) {}", + "try {} catch ({cause: {message}}) {}", ]; let fix = vec![ - (r"try {} catch (_) {}", r"try {} catch {}"), - (r"try {} catch (theRealErrorName) {}", r"try {} catch {}"), + ("try {} catch (_) {}", "try {} catch {}"), + ("try {} catch (theRealErrorName) {}", "try {} catch {}"), ( - r"try { } catch (e) - { }", - r"try { } catch { }", + "try { } catch (e) + { }", + "try { } catch { }", ), - (r"try {} catch(e) {}", r"try {} catch{}"), - (r"try {} catch (e){}", r"try {} catch {}"), - (r"try {} catch ({}) {}", r"try {} catch {}"), - (r"try {} catch ({message}) {}", r"try {} catch {}"), - (r"try {} catch ({message: notUsedMessage}) {}", r"try {} catch {}"), - (r"try {} catch ({cause: {message}}) {}", r"try {} catch {}"), + ("try {} catch(e) {}", "try {} catch{}"), + ("try {} catch (e){}", "try {} catch {}"), + ("try {} catch ({}) {}", "try {} catch {}"), + ("try {} catch ({message}) {}", "try {} catch {}"), + ("try {} catch ({message: notUsedMessage}) {}", "try {} catch {}"), + ("try {} catch ({cause: {message}}) {}", "try {} catch {}"), ]; Tester::new(PreferOptionalCatchBinding::NAME, PreferOptionalCatchBinding::PLUGIN, pass, fail) diff --git a/crates/oxc_linter/src/rules/unicorn/prefer_query_selector.rs b/crates/oxc_linter/src/rules/unicorn/prefer_query_selector.rs index 488e3fb3f88ef..52d13b68950af 100644 --- a/crates/oxc_linter/src/rules/unicorn/prefer_query_selector.rs +++ b/crates/oxc_linter/src/rules/unicorn/prefer_query_selector.rs @@ -169,22 +169,23 @@ fn test() { "document.getElementById();", "document?.getElementById('foo');", "document.getElementById?.('foo');", - "document.getElementsByClassName(\"foo\", \"bar\");", - "document.getElementById(...[\"id\"]);", - "document.querySelector(\"#foo\");", - "document.querySelector(\".bar\");", - "document.querySelector(\"main #foo .bar\");", - "document.querySelectorAll(\".foo .bar\");", - "document.querySelectorAll(\"li a\");", - "document.querySelector(\"li\").querySelectorAll(\"a\");", + r#"document.getElementsByClassName("foo", "bar");"#, + r#"document.getElementById(...["id"]);"#, + r##"document.querySelector("#foo");"##, + r#"document.querySelector(".bar");"#, + r#"document.querySelector("main #foo .bar");"#, + r#"document.querySelectorAll(".foo .bar");"#, + r#"document.querySelectorAll("li a");"#, + r#"document.querySelector("li").querySelectorAll("a");"#, + "document.getElementsByName();", ]; let fail = vec![ - "document.getElementById(\"foo\");", - "document.getElementsByClassName(\"foo\");", - "document.getElementsByClassName(\"foo bar\");", - "document.getElementsByTagName(\"foo\");", - "document.getElementById(\"\");", + r#"document.getElementById("foo");"#, + r#"document.getElementsByClassName("foo");"#, + r#"document.getElementsByClassName("foo bar");"#, + r#"document.getElementsByTagName("foo");"#, + r#"document.getElementById("");"#, "document.getElementById('foo');", "document.getElementsByClassName('foo');", "document.getElementsByClassName('foo bar');", @@ -200,9 +201,21 @@ fn test() { "document.getElementsByClassName(null);", "document.getElementsByTagName(null);", "document.getElementsByClassName(fn());", - "document.getElementsByClassName(\"foo\" + fn());", - "document.getElementsByClassName(foo + \"bar\");", + r#"document.getElementsByClassName("foo" + fn());"#, + r#"document.getElementsByClassName(foo + "bar");"#, + r#"for (const div of document.body.getElementById("id").getElementsByClassName("class")) { + console.log(div.getElementsByTagName("div")); + }"#, "e.getElementById(3)", + // TODO: Get these cases passing. + // r#"document.getElementsByName("foo");"#, + // "document.getElementsByName('foo');", + // "document.getElementsByName(`foo`);", + // "document.getElementsByName(`${'foo'}`);", + // "document.getElementsByName(null);", + // r#"document.getElementsByName("");"#, + // r#"document.getElementsByName(foo + "bar");"#, + // r#"document.getElementsByName("multiple name should be fixable");"#, ]; let fix = vec![ diff --git a/crates/oxc_linter/src/rules/unicorn/prefer_regexp_test.rs b/crates/oxc_linter/src/rules/unicorn/prefer_regexp_test.rs index e71ea17fa5664..0ed2d806974c1 100644 --- a/crates/oxc_linter/src/rules/unicorn/prefer_regexp_test.rs +++ b/crates/oxc_linter/src/rules/unicorn/prefer_regexp_test.rs @@ -224,12 +224,33 @@ fn test() { "if (foo.match(bar?.baz)) {}", "if (foo.match(bar?.baz())) {}", "if (foo.match(bar || baz)) {}", + "async function a() { + if (foo.match(await bar())) {} + }", "if ((foo).match(/re/)) {}", "if ((foo).match(new SomeRegExp)) {}", "if ((foo).match(bar?.baz)) {}", "if ((foo).match(bar?.baz())) {}", "const bar = false; const baz = /a/; if ((foo).match(bar || baz)) {}", + "async function a() { + if ((foo).match(await bar())) {} + }", "const re = [/a/]; if (foo.match([re][0])) {}", + "async function a() { + if ( + /* 1 */ foo() /* 2 */ + ./* 3 */ match /* 4 */ ( + /* 5 */ await /* 6 */ bar() /* 7 */ + , + /* 8 */ + ) + ) {} + }", + r"const string = '[.!?]\\\\s*$'; + if (foo.match(string)) { + }", + r"const regex = new RegExp('[.!?]\\\\s*$'); + if (foo.match(regex)) {}", "if (foo.match(unknown)) {}", "if (foo.match(/a/g));", "if (foo.match(/a/y));", @@ -242,6 +263,16 @@ fn test() { "if (/a/yi.exec(foo));", r#"if (new RegExp("a", "g").exec(foo));"#, r#"if (new RegExp("a", "y").exec(foo));"#, + "const regex = /weird/g; + if (foo.match(regex));", + "const regex = /weird/g; + if (regex.exec(foo));", + "const regex = /weird/y; + if (regex.exec(foo));", + "const regex = /weird/gyi; + if (regex.exec(foo));", + "let re = new RegExp('foo', 'g'); + if(str.match(re));", "!/a/u.exec(foo)", "!/a/v.exec(foo)", ]; diff --git a/crates/oxc_linter/src/rules/unicorn/prefer_string_slice.rs b/crates/oxc_linter/src/rules/unicorn/prefer_string_slice.rs index 89383982ca230..20aace2afc958 100644 --- a/crates/oxc_linter/src/rules/unicorn/prefer_string_slice.rs +++ b/crates/oxc_linter/src/rules/unicorn/prefer_string_slice.rs @@ -96,7 +96,11 @@ fn test() { r#""foo".substr("1", 2)"#, r#""foo".substr(0, -1)"#, r#""foo".substr(0, "foo".length)"#, + r#"const length = 123; + "foo".substr(1, length - 4)"#, r#""foo".substr(1, length)"#, + "const uri = 'foo'; + ((uri || '')).substr(1)", "foo.substr(start)", r#""foo".substr(1)"#, "foo.substr(start, length)", @@ -119,6 +123,19 @@ fn test() { "foo.substring(start, end)", r#""foo".substring(1, 3)"#, "foo.substring(1, 2, 3)", + "function foo() { + return (bar as string).substr(3); + }", + "function foo() { + return ((bar as string)).substring(3); + }", + "/* 1 */ (( /* 2 */ 0 /* 3 */, /* 4 */ foo /* 5 */ )) /* 6 */ + . /* 7 */ substring /* 8 */ ( + /* 9 */ (( /* 10 */ bar /* 11 */ )) /* 12 */, + /* 13 */ (( /* 14 */ 0 /* 15 */ )) /* 16 */, + /* 17 */ + ) + /* 18 */", "foo.substr(0, ...bar)", "foo.substr(...bar)", "foo.substr(0, (100, 1))", @@ -128,6 +145,8 @@ fn test() { "foo.substring(0, (10, 1))", "foo.substring(0, await 1)", "foo.substring((10, bar))", + r#"const string = "::"; + const output = string.substr(-2, 2);"#, ]; let fix = vec![ @@ -140,6 +159,61 @@ fn test() { ("foo.bar?.baz?.substr()", "foo.bar?.baz?.slice()"), ("foo.bar?.baz.substring()", "foo.bar?.baz.slice()"), ("foo.bar.baz?.substr()", "foo.bar.baz?.slice()"), + (r#""foo".substr()"#, r#""foo".slice()"#), + // TODO: Get this passing. + // ( + // r#"const length = 123; + // "foo".substr(0, length)"#, + // r#"const length = 123; + // "foo".slice(0, Math.max(0, length))"#, + // ), + // (r#""foo".substr(0, -1)"#, r#""foo".slice(0, 0)"#), + (r#""foo".substr(0, "foo".length)"#, r#""foo".slice(0, "foo".length)"#), + ( + "const uri = 'foo'; + ((uri || '')).substr(1)", + "const uri = 'foo'; + ((uri || '')).slice(1)", + ), + ("foo.substr(start)", "foo.slice(start)"), + (r#""foo".substr(1)"#, r#""foo".slice(1)"#), + // TODO: Get this passing. + // (r#""foo".substr(1, 2)"#, r#""foo".slice(1, 3)"#), + // ( + // r#""Sample".substr(0, "Sample".lastIndexOf("/"))"#, + // r#""Sample".slice(0, Math.max(0, "Sample".lastIndexOf("/")))"#, + // ), + ("foo.substring()", "foo.slice()"), + (r#""foo".substring()"#, r#""foo".slice()"#), + (r#""foo".substring(1)"#, r#""foo".slice(1)"#), + (r#""foo".substring(1, 2)"#, r#""foo".slice(1, 2)"#), + // TODO: Get this passing. + // (r#""foo".substring(2, 1)"#, r#""foo".slice(1, 2)"#), + // (r#""foo".substring(-1, -5)"#, r#""foo".slice(0, 0)"#), + // (r#""foo".substring(-1, 2)"#, r#""foo".slice(0, 2)"#), + // (r#""foo".substring(length)"#, r#""foo".slice(Math.max(0, length))"#), + (r#""foo".substring("fo".length)"#, r#""foo".slice("fo".length)"#), // spellchecker:disable-line + // TODO: Get this passing. + // (r#""foo".substring(0, length)"#, r#""foo".slice(0, Math.max(0, length))"#), + // (r#""foo".substring(length, 0)"#, r#""foo".slice(0, Math.max(0, length))"#), + // ("foo.substring(start)", "foo.slice(Math.max(0, start))"), + (r#""foo".substring(1, 3)"#, r#""foo".slice(1, 3)"#), + ( + "function foo() { + return (bar as string).substr(3); + }", + "function foo() { + return (bar as string).slice(3); + }", + ), + ( + "function foo() { + return ((bar as string)).substring(3); + }", + "function foo() { + return ((bar as string)).slice(3); + }", + ), ]; Tester::new(PreferStringSlice::NAME, PreferStringSlice::PLUGIN, pass, fail) diff --git a/crates/oxc_linter/src/rules/unicorn/prefer_string_trim_start_end.rs b/crates/oxc_linter/src/rules/unicorn/prefer_string_trim_start_end.rs index c3b3cc153fb30..41141fcac8244 100644 --- a/crates/oxc_linter/src/rules/unicorn/prefer_string_trim_start_end.rs +++ b/crates/oxc_linter/src/rules/unicorn/prefer_string_trim_start_end.rs @@ -120,6 +120,11 @@ fn test() { "trimLeft.trimRight()", "foo.trimLeft.trimRight()", r#""foo".trimLeft()"#, + "foo + // comment + .trimRight/* comment */( + /* comment */ + )", "foo?.trimLeft()", ]; diff --git a/crates/oxc_linter/src/rules/unicorn/prefer_top_level_await.rs b/crates/oxc_linter/src/rules/unicorn/prefer_top_level_await.rs index d238ce15a6bf7..6c1633cbb82e0 100644 --- a/crates/oxc_linter/src/rules/unicorn/prefer_top_level_await.rs +++ b/crates/oxc_linter/src/rules/unicorn/prefer_top_level_await.rs @@ -334,6 +334,7 @@ fn test() { (async () => {})(), /* hole */, foo(), + foo?.(), foo.then(bar), foo.catch(bar), ]); @@ -344,6 +345,26 @@ fn test() { None, None, ), + ( + "async function getStat() {} + const [core, pure, bundle] = await Promise.all([ + getStat('core-js'), + ALL && getStat('core-js-pure'), + ALL && getStat('core-js-bundle'), + ]);", + None, + None, + None, + ), + ( + "async function getStat() {} + const [core] = await Promise.all([ + ALL ? getStat('core-js') : getStat('core-js-pure'), + ]);", + None, + None, + None, + ), ( "const foo = async () => {}; const promise = Promise.all([ diff --git a/crates/oxc_linter/src/rules/unicorn/require_array_join_separator.rs b/crates/oxc_linter/src/rules/unicorn/require_array_join_separator.rs index e56b650709b5e..3dadbaa14bb4f 100644 --- a/crates/oxc_linter/src/rules/unicorn/require_array_join_separator.rs +++ b/crates/oxc_linter/src/rules/unicorn/require_array_join_separator.rs @@ -166,6 +166,32 @@ fn test() { "[].join.call(foo , );", "Array.prototype.join.call(foo)", "Array.prototype.join.call(foo, )", + "( + /**/ + [ + /**/ + ] + /**/ + . + /**/ + join + /**/ + . + /**/ + call + /**/ + ( + /**/ + ( + /**/ + foo + /**/ + ) + /**/ + , + /**/ + )/**/ + )", "foo?.join()", ]; diff --git a/crates/oxc_linter/src/rules/unicorn/require_post_message_target_origin.rs b/crates/oxc_linter/src/rules/unicorn/require_post_message_target_origin.rs index 3f45c9bc7e2ca..d94ee50886233 100644 --- a/crates/oxc_linter/src/rules/unicorn/require_post_message_target_origin.rs +++ b/crates/oxc_linter/src/rules/unicorn/require_post_message_target_origin.rs @@ -147,6 +147,8 @@ fn test() { "self.postMessage(message)", "globalThis.postMessage(message)", "foo.postMessage(message )", + // TODO: Get this passing. + // "foo?.postMessage(message )", "foo.postMessage( ((message)) )", "foo.postMessage(message,)", "foo.postMessage(message , )", diff --git a/crates/oxc_linter/src/snapshots/unicorn_error_message.snap b/crates/oxc_linter/src/snapshots/unicorn_error_message.snap index a36e9849cdf07..b6b0dacb995e9 100644 --- a/crates/oxc_linter/src/snapshots/unicorn_error_message.snap +++ b/crates/oxc_linter/src/snapshots/unicorn_error_message.snap @@ -26,6 +26,28 @@ source: crates/oxc_linter/src/tester.rs Β· ── ╰──── + ⚠ eslint-plugin-unicorn(error-message): Pass a message to the Error constructor. + ╭─[error_message.tsx:1:13] + 1 β”‚ const err = new Error(); + Β· ─────────── + 2 β”‚ throw err; + ╰──── + + ⚠ eslint-plugin-unicorn(error-message): Pass a message to the Error constructor. + ╭─[error_message.tsx:2:19] + 1 β”‚ let err = 1; + 2 β”‚ err = new Error(); + Β· ─────────── + 3 β”‚ throw err; + ╰──── + + ⚠ eslint-plugin-unicorn(error-message): Pass a message to the Error constructor. + ╭─[error_message.tsx:1:11] + 1 β”‚ let err = new Error(); + Β· ─────────── + 2 β”‚ err = 1; + ╰──── + ⚠ eslint-plugin-unicorn(error-message): Pass a message to the TypeError constructor. ╭─[error_message.tsx:1:13] 1 β”‚ const foo = new TypeError() @@ -68,6 +90,12 @@ source: crates/oxc_linter/src/tester.rs Β· ────────────── ╰──── + ⚠ eslint-plugin-unicorn(error-message): Pass a message to the Error constructor. + ╭─[error_message.tsx:1:21] + 1 β”‚ throw Object.assign(new Error(), {foo}) + Β· ─────────── + ╰──── + ⚠ eslint-plugin-unicorn(error-message): Pass a message to the AggregateError constructor. ╭─[error_message.tsx:1:1] 1 β”‚ new AggregateError(errors) diff --git a/crates/oxc_linter/src/snapshots/unicorn_no_negation_in_equality_check.snap b/crates/oxc_linter/src/snapshots/unicorn_no_negation_in_equality_check.snap index 634942b0d2e22..2e56a7edfa1a3 100644 --- a/crates/oxc_linter/src/snapshots/unicorn_no_negation_in_equality_check.snap +++ b/crates/oxc_linter/src/snapshots/unicorn_no_negation_in_equality_check.snap @@ -31,64 +31,60 @@ source: crates/oxc_linter/src/tester.rs help: Remove the negation operator and use '==' instead of '!='. ⚠ eslint-plugin-unicorn(no-negation-in-equality-check): Negated expression is not allowed in equality check. - ╭─[no_negation_in_equality_check.tsx:3:35] - 2 β”‚ function x() { - 3 β”‚ return!foo === bar; - Β· ──── - 4 β”‚ } + ╭─[no_negation_in_equality_check.tsx:2:23] + 1 β”‚ function x() { + 2 β”‚ return!foo === bar; + Β· ──── + 3 β”‚ } ╰──── help: Remove the negation operator and use '!==' instead of '==='. ⚠ eslint-plugin-unicorn(no-negation-in-equality-check): Negated expression is not allowed in equality check. - ╭─[no_negation_in_equality_check.tsx:3:35] - 2 β”‚ function x() { - 3 β”‚ ╭─▢ return! - 4 β”‚ ╰─▢ foo === bar; - 5 β”‚ throw! + ╭─[no_negation_in_equality_check.tsx:2:23] + 1 β”‚ function x() { + 2 β”‚ ╭─▢ return! + 3 β”‚ ╰─▢ foo === bar; + 4 β”‚ throw! ╰──── help: Remove the negation operator and use '!==' instead of '==='. ⚠ eslint-plugin-unicorn(no-negation-in-equality-check): Negated expression is not allowed in equality check. - ╭─[no_negation_in_equality_check.tsx:5:34] - 4 β”‚ foo === bar; - 5 β”‚ ╭─▢ throw! - 6 β”‚ ╰─▢ foo === bar; - 7 β”‚ } + ╭─[no_negation_in_equality_check.tsx:4:22] + 3 β”‚ foo === bar; + 4 β”‚ ╭─▢ throw! + 5 β”‚ ╰─▢ foo === bar; + 6 β”‚ } ╰──── help: Remove the negation operator and use '!==' instead of '==='. ⚠ eslint-plugin-unicorn(no-negation-in-equality-check): Negated expression is not allowed in equality check. - ╭─[no_negation_in_equality_check.tsx:3:25] - 2 β”‚ foo - 3 β”‚ !(a) === b - Β· ──── - 4 β”‚ + ╭─[no_negation_in_equality_check.tsx:2:13] + 1 β”‚ foo + 2 β”‚ !(a) === b + Β· ──── ╰──── help: Remove the negation operator and use '!==' instead of '==='. ⚠ eslint-plugin-unicorn(no-negation-in-equality-check): Negated expression is not allowed in equality check. - ╭─[no_negation_in_equality_check.tsx:3:25] - 2 β”‚ foo - 3 β”‚ ![a, b].join('') === c - Β· ──────────────── - 4 β”‚ + ╭─[no_negation_in_equality_check.tsx:2:13] + 1 β”‚ foo + 2 β”‚ ![a, b].join('') === c + Β· ──────────────── ╰──── help: Remove the negation operator and use '!==' instead of '==='. ⚠ eslint-plugin-unicorn(no-negation-in-equality-check): Negated expression is not allowed in equality check. - ╭─[no_negation_in_equality_check.tsx:3:25] - 2 β”‚ foo - 3 β”‚ ! [a, b].join('') === c - Β· ───────────────── - 4 β”‚ + ╭─[no_negation_in_equality_check.tsx:2:13] + 1 β”‚ foo + 2 β”‚ ! [a, b].join('') === c + Β· ───────────────── ╰──── help: Remove the negation operator and use '!==' instead of '==='. ⚠ eslint-plugin-unicorn(no-negation-in-equality-check): Negated expression is not allowed in equality check. - ╭─[no_negation_in_equality_check.tsx:3:25] - 2 β”‚ foo - 3 β”‚ !/* comment */[a, b].join('') === c - Β· ───────────────────────────── - 4 β”‚ + ╭─[no_negation_in_equality_check.tsx:2:13] + 1 β”‚ foo + 2 β”‚ !/* comment */[a, b].join('') === c + Β· ───────────────────────────── ╰──── help: Remove the negation operator and use '!==' instead of '==='. diff --git a/crates/oxc_linter/src/snapshots/unicorn_no_nested_ternary.snap b/crates/oxc_linter/src/snapshots/unicorn_no_nested_ternary.snap index 09a80009beba4..a185a6977ba53 100644 --- a/crates/oxc_linter/src/snapshots/unicorn_no_nested_ternary.snap +++ b/crates/oxc_linter/src/snapshots/unicorn_no_nested_ternary.snap @@ -58,6 +58,20 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Add parentheses around the nested ternary expression. + ⚠ eslint-plugin-unicorn(no-nested-ternary): Unexpected nested ternary expression without parentheses. + ╭─[no_nested_ternary.tsx:1:21] + 1 β”‚ const foo = i > 5 ? i < 100 ? true : false : i < 100 ? true : false; + Β· ────────────────────── + ╰──── + help: Add parentheses around the nested ternary expression. + + ⚠ eslint-plugin-unicorn(no-nested-ternary): Unexpected nested ternary expression without parentheses. + ╭─[no_nested_ternary.tsx:1:46] + 1 β”‚ const foo = i > 5 ? i < 100 ? true : false : i < 100 ? true : false; + Β· ────────────────────── + ╰──── + help: Add parentheses around the nested ternary expression. + ⚠ eslint-plugin-unicorn(no-nested-ternary): Unexpected deeply nested ternary expression. ╭─[no_nested_ternary.tsx:1:47] 1 β”‚ const foo = i > 5 ? true : (i < 100 ? true : (i < 1000 ? true : false)); diff --git a/crates/oxc_linter/src/snapshots/unicorn_no_new_buffer.snap b/crates/oxc_linter/src/snapshots/unicorn_no_new_buffer.snap index 8a73576cab5b7..97dcbc0777b17 100644 --- a/crates/oxc_linter/src/snapshots/unicorn_no_new_buffer.snap +++ b/crates/oxc_linter/src/snapshots/unicorn_no_new_buffer.snap @@ -16,6 +16,38 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: `new Buffer()` is deprecated, use `Buffer.alloc()` or `Buffer.from()` instead. + ⚠ eslint-plugin-unicorn(no-new-buffer): Use `Buffer.alloc()` or `Buffer.from()` instead of the deprecated `new Buffer()` constructor. + ╭─[no_new_buffer.tsx:2:32] + 1 β”‚ const array = [0x62]; + 2 β”‚ const buffer = new Buffer(array); + Β· ────── + ╰──── + help: `new Buffer()` is deprecated, use `Buffer.alloc()` or `Buffer.from()` instead. + + ⚠ eslint-plugin-unicorn(no-new-buffer): Use `Buffer.alloc()` or `Buffer.from()` instead of the deprecated `new Buffer()` constructor. + ╭─[no_new_buffer.tsx:2:32] + 1 β”‚ const arrayBuffer = new ArrayBuffer(10); + 2 β”‚ const buffer = new Buffer(arrayBuffer); + Β· ────── + ╰──── + help: `new Buffer()` is deprecated, use `Buffer.alloc()` or `Buffer.from()` instead. + + ⚠ eslint-plugin-unicorn(no-new-buffer): Use `Buffer.alloc()` or `Buffer.from()` instead of the deprecated `new Buffer()` constructor. + ╭─[no_new_buffer.tsx:2:32] + 1 β”‚ const arrayBuffer = new ArrayBuffer(10); + 2 β”‚ const buffer = new Buffer(arrayBuffer, 0, ); + Β· ────── + ╰──── + help: `new Buffer()` is deprecated, use `Buffer.alloc()` or `Buffer.from()` instead. + + ⚠ eslint-plugin-unicorn(no-new-buffer): Use `Buffer.alloc()` or `Buffer.from()` instead of the deprecated `new Buffer()` constructor. + ╭─[no_new_buffer.tsx:2:32] + 1 β”‚ const arrayBuffer = new ArrayBuffer(10); + 2 β”‚ const buffer = new Buffer(arrayBuffer, 0, 2); + Β· ────── + ╰──── + help: `new Buffer()` is deprecated, use `Buffer.alloc()` or `Buffer.from()` instead. + ⚠ eslint-plugin-unicorn(no-new-buffer): Use `Buffer.alloc()` or `Buffer.from()` instead of the deprecated `new Buffer()` constructor. ╭─[no_new_buffer.tsx:1:20] 1 β”‚ const buffer = new Buffer(10); @@ -23,6 +55,14 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: `new Buffer()` is deprecated, use `Buffer.alloc()` or `Buffer.from()` instead. + ⚠ eslint-plugin-unicorn(no-new-buffer): Use `Buffer.alloc()` or `Buffer.from()` instead of the deprecated `new Buffer()` constructor. + ╭─[no_new_buffer.tsx:2:32] + 1 β”‚ const size = 10; + 2 β”‚ const buffer = new Buffer(size); + Β· ────── + ╰──── + help: `new Buffer()` is deprecated, use `Buffer.alloc()` or `Buffer.from()` instead. + ⚠ eslint-plugin-unicorn(no-new-buffer): Use `Buffer.alloc()` or `Buffer.from()` instead of the deprecated `new Buffer()` constructor. ╭─[no_new_buffer.tsx:1:5] 1 β”‚ new Buffer(foo.length) @@ -51,6 +91,14 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: `new Buffer()` is deprecated, use `Buffer.alloc()` or `Buffer.from()` instead. + ⚠ eslint-plugin-unicorn(no-new-buffer): Use `Buffer.alloc()` or `Buffer.from()` instead of the deprecated `new Buffer()` constructor. + ╭─[no_new_buffer.tsx:2:32] + 1 β”‚ const string = "string"; + 2 β”‚ const buffer = new Buffer(string); + Β· ────── + ╰──── + help: `new Buffer()` is deprecated, use `Buffer.alloc()` or `Buffer.from()` instead. + ⚠ eslint-plugin-unicorn(no-new-buffer): Use `Buffer.alloc()` or `Buffer.from()` instead of the deprecated `new Buffer()` constructor. ╭─[no_new_buffer.tsx:1:20] 1 β”‚ const buffer = new Buffer(`${unknown}`) @@ -79,6 +127,60 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: `new Buffer()` is deprecated, use `Buffer.alloc()` or `Buffer.from()` instead. + ⚠ eslint-plugin-unicorn(no-new-buffer): Use `Buffer.alloc()` or `Buffer.from()` instead of the deprecated `new Buffer()` constructor. + ╭─[no_new_buffer.tsx:3:21] + 2 β”‚ return new // 1 + 3 β”‚ Buffer(); + Β· ────── + 4 β”‚ } + ╰──── + help: `new Buffer()` is deprecated, use `Buffer.alloc()` or `Buffer.from()` instead. + + ⚠ eslint-plugin-unicorn(no-new-buffer): Use `Buffer.alloc()` or `Buffer.from()` instead of the deprecated `new Buffer()` constructor. + ╭─[no_new_buffer.tsx:4:25] + 3 β”‚ new // 2 + 4 β”‚ Buffer() + Β· ────── + 5 β”‚ ); + ╰──── + help: `new Buffer()` is deprecated, use `Buffer.alloc()` or `Buffer.from()` instead. + + ⚠ eslint-plugin-unicorn(no-new-buffer): Use `Buffer.alloc()` or `Buffer.from()` instead of the deprecated `new Buffer()` constructor. + ╭─[no_new_buffer.tsx:3:22] + 2 β”‚ return new // 3 + 3 β”‚ (Buffer); + Β· ────── + 4 β”‚ } + ╰──── + help: `new Buffer()` is deprecated, use `Buffer.alloc()` or `Buffer.from()` instead. + + ⚠ eslint-plugin-unicorn(no-new-buffer): Use `Buffer.alloc()` or `Buffer.from()` instead of the deprecated `new Buffer()` constructor. + ╭─[no_new_buffer.tsx:3:21] + 2 β”‚ return new // 4 + 3 β”‚ Buffer; + Β· ────── + 4 β”‚ } + ╰──── + help: `new Buffer()` is deprecated, use `Buffer.alloc()` or `Buffer.from()` instead. + + ⚠ eslint-plugin-unicorn(no-new-buffer): Use `Buffer.alloc()` or `Buffer.from()` instead of the deprecated `new Buffer()` constructor. + ╭─[no_new_buffer.tsx:4:25] + 3 β”‚ new // 5 + 4 β”‚ Buffer + Β· ────── + 5 β”‚ ); + ╰──── + help: `new Buffer()` is deprecated, use `Buffer.alloc()` or `Buffer.from()` instead. + + ⚠ eslint-plugin-unicorn(no-new-buffer): Use `Buffer.alloc()` or `Buffer.from()` instead of the deprecated `new Buffer()` constructor. + ╭─[no_new_buffer.tsx:4:26] + 3 β”‚ new // 6 + 4 β”‚ (Buffer) + Β· ────── + 5 β”‚ ); + ╰──── + help: `new Buffer()` is deprecated, use `Buffer.alloc()` or `Buffer.from()` instead. + ⚠ eslint-plugin-unicorn(no-new-buffer): Use `Buffer.alloc()` or `Buffer.from()` instead of the deprecated `new Buffer()` constructor. ╭─[no_new_buffer.tsx:1:34] 1 β”‚ const buffer = new /* comment */ Buffer() diff --git a/crates/oxc_linter/src/snapshots/unicorn_no_object_as_default_parameter.snap b/crates/oxc_linter/src/snapshots/unicorn_no_object_as_default_parameter.snap index 8487d99d61eb6..9762b950eff47 100644 --- a/crates/oxc_linter/src/snapshots/unicorn_no_object_as_default_parameter.snap +++ b/crates/oxc_linter/src/snapshots/unicorn_no_object_as_default_parameter.snap @@ -63,9 +63,81 @@ source: crates/oxc_linter/src/tester.rs ╰──── ⚠ eslint-plugin-unicorn(no-object-as-default-parameter): Do not use an object literal as default for parameter `foo`. - ╭─[no_object_as_default_parameter.tsx:1:20] - 1 β”‚ function abc(foo = {a: 123}) {} - Β· ──────── + ╭─[no_object_as_default_parameter.tsx:2:27] + 1 β”‚ class A { + 2 β”‚ abc(foo = {a: 123}) {} + Β· ──────── + 3 β”‚ } + ╰──── + + ⚠ eslint-plugin-unicorn(no-object-as-default-parameter): Do not use an object literal as default for parameter `foo`. + ╭─[no_object_as_default_parameter.tsx:2:35] + 1 β”‚ class A { + 2 β”‚ constructor(foo = {a: 123}) {} + Β· ──────── + 3 β”‚ } + ╰──── + + ⚠ eslint-plugin-unicorn(no-object-as-default-parameter): Do not use an object literal as default for parameter `foo`. + ╭─[no_object_as_default_parameter.tsx:2:34] + 1 β”‚ class A { + 2 β”‚ static abc(foo = {a: 123}) {} + Β· ──────── + 3 β”‚ } + ╰──── + + ⚠ eslint-plugin-unicorn(no-object-as-default-parameter): Do not use an object literal as default for parameter `foo`. + ╭─[no_object_as_default_parameter.tsx:2:29] + 1 β”‚ class A { + 2 β”‚ * abc(foo = {a: 123}) {} + Β· ──────── + 3 β”‚ } + ╰──── + + ⚠ eslint-plugin-unicorn(no-object-as-default-parameter): Do not use an object literal as default for parameter `foo`. + ╭─[no_object_as_default_parameter.tsx:2:42] + 1 β”‚ class A { + 2 β”‚ static async * abc(foo = {a: 123}) {} + Β· ──────── + 3 β”‚ } + ╰──── + + ⚠ eslint-plugin-unicorn(no-object-as-default-parameter): Do not use an object literal as default for parameter `foo`. + ╭─[no_object_as_default_parameter.tsx:2:40] + 1 β”‚ class A { + 2 β”‚ [foo = {a: 123}](foo = {a: 123}) {} + Β· ──────── + 3 β”‚ } + ╰──── + + ⚠ eslint-plugin-unicorn(no-object-as-default-parameter): Do not use an object literal as default for parameter `foo`. + ╭─[no_object_as_default_parameter.tsx:2:27] + 1 β”‚ const A = class { + 2 β”‚ abc(foo = {a: 123}) {} + Β· ──────── + 3 β”‚ } + ╰──── + + ⚠ eslint-plugin-unicorn(no-object-as-default-parameter): Do not use an object literal as default for parameter `foo`. + ╭─[no_object_as_default_parameter.tsx:2:27] + 1 β”‚ object = { + 2 β”‚ abc(foo = {a: 123}) {} + Β· ──────── + 3 β”‚ }; + ╰──── + + ⚠ eslint-plugin-unicorn(no-object-as-default-parameter): Do not use an object literal as default + ╭─[no_object_as_default_parameter.tsx:2:27] + 1 β”‚ const A = class { + 2 β”‚ abc({a} = {a: 123}) {} + Β· ──────── + 3 β”‚ } + ╰──── + + ⚠ eslint-plugin-unicorn(no-object-as-default-parameter): Do not use an object literal as default for parameter `foo`. + ╭─[no_object_as_default_parameter.tsx:1:24] + 1 β”‚ /**/function abc(foo = {a: 123}) {} + Β· ──────── ╰──── ⚠ eslint-plugin-unicorn(no-object-as-default-parameter): Do not use an object literal as default for parameter `foo`. diff --git a/crates/oxc_linter/src/snapshots/unicorn_no_static_only_class.snap b/crates/oxc_linter/src/snapshots/unicorn_no_static_only_class.snap index 0d0367905b364..8d4244f9ccaa1 100644 --- a/crates/oxc_linter/src/snapshots/unicorn_no_static_only_class.snap +++ b/crates/oxc_linter/src/snapshots/unicorn_no_static_only_class.snap @@ -56,6 +56,104 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Convert to an object instead of a class with only static members. + ⚠ eslint-plugin-unicorn(no-static-only-class): Use an object instead of a class with only static members. + ╭─[no_static_only_class.tsx:2:24] + 1 β”‚ function a() { + 2 β”‚ ╭─▢ return class + 3 β”‚ β”‚ { + 4 β”‚ β”‚ static a() {} + 5 β”‚ ╰─▢ } + 6 β”‚ } + ╰──── + help: Convert to an object instead of a class with only static members. + + ⚠ eslint-plugin-unicorn(no-static-only-class): Use an object instead of a class with only static members. + ╭─[no_static_only_class.tsx:2:24] + 1 β”‚ function a() { + 2 β”‚ ╭─▢ return class /* comment */ + 3 β”‚ β”‚ { + 4 β”‚ β”‚ static a() {} + 5 β”‚ ╰─▢ } + 6 β”‚ } + ╰──── + help: Convert to an object instead of a class with only static members. + + ⚠ eslint-plugin-unicorn(no-static-only-class): Use an object instead of a class with only static members. + ╭─[no_static_only_class.tsx:2:24] + 1 β”‚ function a() { + 2 β”‚ ╭─▢ return class // comment + 3 β”‚ β”‚ { + 4 β”‚ β”‚ static a() {} + 5 β”‚ ╰─▢ } + 6 β”‚ } + ╰──── + help: Convert to an object instead of a class with only static members. + + ⚠ eslint-plugin-unicorn(no-static-only-class): Use an object instead of a class with only static members. + ╭─[no_static_only_class.tsx:1:1] + 1 β”‚ class A {static a(){}} + Β· ────────────────────── + 2 β”‚ class B extends A {} + ╰──── + help: Convert to an object instead of a class with only static members. + + ⚠ eslint-plugin-unicorn(no-static-only-class): Use an object instead of a class with only static members. + ╭─[no_static_only_class.tsx:1:1] + 1 β”‚ class A {static a(){}} + Β· ────────────────────── + 2 β”‚ console.log(typeof A) + ╰──── + help: Convert to an object instead of a class with only static members. + + ⚠ eslint-plugin-unicorn(no-static-only-class): Use an object instead of a class with only static members. + ╭─[no_static_only_class.tsx:1:1] + 1 β”‚ class A {static a(){}} + Β· ────────────────────── + 2 β”‚ const a = new A; + ╰──── + help: Convert to an object instead of a class with only static members. + + ⚠ eslint-plugin-unicorn(no-static-only-class): Use an object instead of a class with only static members. + ╭─[no_static_only_class.tsx:1:1] + 1 β”‚ ╭─▢ class A { + 2 β”‚ β”‚ static a + 3 β”‚ β”‚ static b = 1 + 4 β”‚ β”‚ static [c] = 2 + 5 β”‚ β”‚ static [d] + 6 β”‚ β”‚ static e() {} + 7 β”‚ β”‚ static [f]() {} + 8 β”‚ ╰─▢ } + ╰──── + help: Convert to an object instead of a class with only static members. + + ⚠ eslint-plugin-unicorn(no-static-only-class): Use an object instead of a class with only static members. + ╭─[no_static_only_class.tsx:1:1] + 1 β”‚ ╭─▢ class A { + 2 β”‚ β”‚ static a; + 3 β”‚ β”‚ static b = 1; + 4 β”‚ β”‚ static [((c))] = ((2)); + 5 β”‚ β”‚ static [d]; + 6 β”‚ β”‚ static e() {}; + 7 β”‚ β”‚ static [f]() {}; + 8 β”‚ ╰─▢ } + ╰──── + help: Convert to an object instead of a class with only static members. + + ⚠ eslint-plugin-unicorn(no-static-only-class): Use an object instead of a class with only static members. + ╭─[no_static_only_class.tsx:2:13] + 1 β”‚ /* */ + 2 β”‚ ╭─▢ class /* */ A /* */ { + 3 β”‚ β”‚ /* */ static /* */ a /* */; /* */ + 4 β”‚ β”‚ /* */ static /* */ b /* */ = /* */ 1 /* */; /* */ + 5 β”‚ β”‚ /* */ static /* */ [ /* */ c /* */ ] /* */ = /* */ 2 /* */; /* */ + 6 β”‚ β”‚ /* */ static /* */ [/* */ d /* */] /* */; /* */ + 7 β”‚ β”‚ /* */ static /* */ /* */ e /* */ ( /* */ ) {/* */}/* */; /* */ + 8 β”‚ β”‚ /* */ static /* */ [/* */ f /* */ ] /* */ ( /* */ ) {/* */ }/* */ ; /* */ + 9 β”‚ ╰─▢ } + 10 β”‚ /* */ + ╰──── + help: Convert to an object instead of a class with only static members. + ⚠ eslint-plugin-unicorn(no-static-only-class): Use an object instead of a class with only static members. ╭─[no_static_only_class.tsx:1:1] 1 β”‚ class A {static [this.a] = 1} diff --git a/crates/oxc_linter/src/snapshots/unicorn_no_unreadable_iife.snap b/crates/oxc_linter/src/snapshots/unicorn_no_unreadable_iife.snap index b18ea214a26a1..285081ee83975 100644 --- a/crates/oxc_linter/src/snapshots/unicorn_no_unreadable_iife.snap +++ b/crates/oxc_linter/src/snapshots/unicorn_no_unreadable_iife.snap @@ -10,42 +10,36 @@ source: crates/oxc_linter/src/tester.rs help: Rewrite the IIFE to avoid having a parenthesized arrow function body. ⚠ eslint-plugin-unicorn(no-unreadable-iife): IIFE with parenthesized arrow function body is considered unreadable. - ╭─[no_unreadable_iife.tsx:2:32] - 1 β”‚ - 2 β”‚ ╭─▢ const foo = (() => ( - 3 β”‚ β”‚ a ? b : c - 4 β”‚ ╰─▢ ))(); - 5 β”‚ + ╭─[no_unreadable_iife.tsx:1:20] + 1 β”‚ ╭─▢ const foo = (() => ( + 2 β”‚ β”‚ a ? b : c + 3 β”‚ ╰─▢ ))(); ╰──── help: Rewrite the IIFE to avoid having a parenthesized arrow function body. ⚠ eslint-plugin-unicorn(no-unreadable-iife): IIFE with parenthesized arrow function body is considered unreadable. - ╭─[no_unreadable_iife.tsx:3:23] - 2 β”‚ const foo = ( - 3 β”‚ ╭─▢ () => ( - 4 β”‚ β”‚ a ? b : c - 5 β”‚ ╰─▢ ) - 6 β”‚ )(); + ╭─[no_unreadable_iife.tsx:2:23] + 1 β”‚ const foo = ( + 2 β”‚ ╭─▢ () => ( + 3 β”‚ β”‚ a ? b : c + 4 β”‚ ╰─▢ ) + 5 β”‚ )(); ╰──── help: Rewrite the IIFE to avoid having a parenthesized arrow function body. ⚠ eslint-plugin-unicorn(no-unreadable-iife): IIFE with parenthesized arrow function body is considered unreadable. - ╭─[no_unreadable_iife.tsx:2:32] - 1 β”‚ - 2 β”‚ ╭─▢ const foo = (() => ( - 3 β”‚ β”‚ a, b - 4 β”‚ ╰─▢ ))(); - 5 β”‚ + ╭─[no_unreadable_iife.tsx:1:20] + 1 β”‚ ╭─▢ const foo = (() => ( + 2 β”‚ β”‚ a, b + 3 β”‚ ╰─▢ ))(); ╰──── help: Rewrite the IIFE to avoid having a parenthesized arrow function body. ⚠ eslint-plugin-unicorn(no-unreadable-iife): IIFE with parenthesized arrow function body is considered unreadable. - ╭─[no_unreadable_iife.tsx:2:32] - 1 β”‚ - 2 β”‚ ╭─▢ const foo = (() => ({ - 3 β”‚ β”‚ a: b, - 4 β”‚ ╰─▢ }))(); - 5 β”‚ + ╭─[no_unreadable_iife.tsx:1:20] + 1 β”‚ ╭─▢ const foo = (() => ({ + 2 β”‚ β”‚ a: b, + 3 β”‚ ╰─▢ }))(); ╰──── help: Rewrite the IIFE to avoid having a parenthesized arrow function body. @@ -57,22 +51,18 @@ source: crates/oxc_linter/src/tester.rs help: Rewrite the IIFE to avoid having a parenthesized arrow function body. ⚠ eslint-plugin-unicorn(no-unreadable-iife): IIFE with parenthesized arrow function body is considered unreadable. - ╭─[no_unreadable_iife.tsx:2:26] - 1 β”‚ - 2 β”‚ ╭─▢ (async () => ({ - 3 β”‚ β”‚ bar, - 4 β”‚ ╰─▢ }))(); - 5 β”‚ + ╭─[no_unreadable_iife.tsx:1:14] + 1 β”‚ ╭─▢ (async () => ({ + 2 β”‚ β”‚ bar, + 3 β”‚ ╰─▢ }))(); ╰──── help: Rewrite the IIFE to avoid having a parenthesized arrow function body. ⚠ eslint-plugin-unicorn(no-unreadable-iife): IIFE with parenthesized arrow function body is considered unreadable. - ╭─[no_unreadable_iife.tsx:2:41] - 1 β”‚ - 2 β”‚ ╭─▢ const foo = (async (bar) => ({ - 3 β”‚ β”‚ bar: await baz(), - 4 β”‚ ╰─▢ }))(); - 5 β”‚ + ╭─[no_unreadable_iife.tsx:1:29] + 1 β”‚ ╭─▢ const foo = (async (bar) => ({ + 2 β”‚ β”‚ bar: await baz(), + 3 β”‚ ╰─▢ }))(); ╰──── help: Rewrite the IIFE to avoid having a parenthesized arrow function body. diff --git a/crates/oxc_linter/src/snapshots/unicorn_no_useless_collection_argument.snap b/crates/oxc_linter/src/snapshots/unicorn_no_useless_collection_argument.snap index 32ec217eae7d5..4c55fb9455468 100644 --- a/crates/oxc_linter/src/snapshots/unicorn_no_useless_collection_argument.snap +++ b/crates/oxc_linter/src/snapshots/unicorn_no_useless_collection_argument.snap @@ -190,3 +190,10 @@ source: crates/oxc_linter/src/tester.rs Β· ── ╰──── help: Delete this code. + + ⚠ eslint-plugin-unicorn(no-useless-collection-argument): The empty array is useless + ╭─[no_useless_collection_argument.mjs:1:9] + 1 β”‚ new Set([/**/]) + Β· ────── + ╰──── + help: Delete this code. diff --git a/crates/oxc_linter/src/snapshots/unicorn_no_useless_fallback_in_spread.snap b/crates/oxc_linter/src/snapshots/unicorn_no_useless_fallback_in_spread.snap index 50e81d1c59ef1..2871fc3562266 100644 --- a/crates/oxc_linter/src/snapshots/unicorn_no_useless_fallback_in_spread.snap +++ b/crates/oxc_linter/src/snapshots/unicorn_no_useless_fallback_in_spread.snap @@ -163,6 +163,13 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Spreading falsy values in object literals won't add any unexpected properties, so it's unnecessary to add an empty object as fallback. + ⚠ eslint-plugin-unicorn(no-useless-fallback-in-spread): Empty fallbacks in spreads are unnecessary + ╭─[no_useless_fallback_in_spread.tsx:1:22] + 1 β”‚ const object = {...({...((0, foo) || {})})} + Β· ─────────────────── + ╰──── + help: Spreading falsy values in object literals won't add any unexpected properties, so it's unnecessary to add an empty object as fallback. + ⚠ eslint-plugin-unicorn(no-useless-fallback-in-spread): Empty fallbacks in spreads are unnecessary ╭─[no_useless_fallback_in_spread.tsx:1:19] 1 β”‚ function foo(a = {...(bar || {})}){} diff --git a/crates/oxc_linter/src/snapshots/unicorn_no_zero_fractions.snap b/crates/oxc_linter/src/snapshots/unicorn_no_zero_fractions.snap index 01e49e59a3cd1..ef5ee1363559e 100644 --- a/crates/oxc_linter/src/snapshots/unicorn_no_zero_fractions.snap +++ b/crates/oxc_linter/src/snapshots/unicorn_no_zero_fractions.snap @@ -135,6 +135,38 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Replace the number literal with `1` + ⚠ eslint-plugin-unicorn(no-zero-fractions): Don't use a dangling dot in the number. + ╭─[no_zero_fractions.tsx:2:13] + 1 β”‚ console.log() + 2 β”‚ 1..toString() + Β· ── + ╰──── + help: Replace the number literal with `1` + + ⚠ eslint-plugin-unicorn(no-zero-fractions): Don't use a dangling dot in the number. + ╭─[no_zero_fractions.tsx:2:15] + 1 β”‚ console.log() + 2 β”‚ a[1.].toString() + Β· ── + ╰──── + help: Replace the number literal with `1` + + ⚠ eslint-plugin-unicorn(no-zero-fractions): Don't use a zero fraction in the number. + ╭─[no_zero_fractions.tsx:2:13] + 1 β”‚ console.log() + 2 β”‚ 1.00e10.toString() + Β· ─────── + ╰──── + help: Replace the number literal with `1e10` + + ⚠ eslint-plugin-unicorn(no-zero-fractions): Don't use a zero fraction in the number. + ╭─[no_zero_fractions.tsx:2:15] + 1 β”‚ console.log() + 2 β”‚ a[1.00e10].toString() + Β· ─────── + ╰──── + help: Replace the number literal with `1e10` + ⚠ eslint-plugin-unicorn(no-zero-fractions): Don't use a zero fraction in the number. ╭─[no_zero_fractions.tsx:1:5] 1 β”‚ a = .0; diff --git a/crates/oxc_linter/src/snapshots/unicorn_prefer_array_flat.snap b/crates/oxc_linter/src/snapshots/unicorn_prefer_array_flat.snap index 893606964177a..f192c92da10ab 100644 --- a/crates/oxc_linter/src/snapshots/unicorn_prefer_array_flat.snap +++ b/crates/oxc_linter/src/snapshots/unicorn_prefer_array_flat.snap @@ -25,11 +25,55 @@ source: crates/oxc_linter/src/tester.rs ⚠ eslint-plugin-unicorn(prefer-array-flat): Prefer Array#flat() over legacy techniques to flatten arrays. ╭─[prefer_array_flat.tsx:1:1] - 1 β”‚ foo.flatMap(x => x) instanceof Array + 1 β”‚ foo.flatMap(x => x)instanceof Array Β· ─────────────────── ╰──── help: Call `.flat()` on the array instead. + ⚠ eslint-plugin-unicorn(prefer-array-flat): Prefer Array#flat() over legacy techniques to flatten arrays. + ╭─[prefer_array_flat.tsx:1:1] + 1 β”‚ array.flatMap((x) => x) + Β· ─────────────────────── + ╰──── + help: Call `.flat()` on the array instead. + + ⚠ eslint-plugin-unicorn(prefer-array-flat): Prefer Array#flat() over legacy techniques to flatten arrays. + ╭─[prefer_array_flat.tsx:1:1] + 1 β”‚ Foo.bar.flatMap(x => x) + Β· ─────────────────────── + ╰──── + help: Call `.flat()` on the array instead. + + ⚠ eslint-plugin-unicorn(prefer-array-flat): Prefer Array#flat() over legacy techniques to flatten arrays. + ╭─[prefer_array_flat.tsx:1:29] + 1 β”‚ const values = getValues(); values.flatMap(x => x); + Β· ────────────────────── + ╰──── + help: Call `.flat()` on the array instead. + + ⚠ eslint-plugin-unicorn(prefer-array-flat): Prefer Array#flat() over legacy techniques to flatten arrays. + ╭─[prefer_array_flat.tsx:1:20] + 1 β”‚ const values = []; values.flatMap(x => x); + Β· ────────────────────── + ╰──── + help: Call `.flat()` on the array instead. + + ⚠ eslint-plugin-unicorn(prefer-array-flat): Prefer Array#flat() over legacy techniques to flatten arrays. + ╭─[prefer_array_flat.tsx:1:19] + 1 β”‚ const Items = []; Items.flatMap(x => x); + Β· ───────────────────── + ╰──── + help: Call `.flat()` on the array instead. + + ⚠ eslint-plugin-unicorn(prefer-array-flat): Prefer Array#flat() over legacy techniques to flatten arrays. + ╭─[prefer_array_flat.tsx:2:17] + 1 β”‚ for (const value of values) { + 2 β”‚ value.flatMap(x => x); + Β· ───────────────────── + 3 β”‚ } + ╰──── + help: Call `.flat()` on the array instead. + ⚠ eslint-plugin-unicorn(prefer-array-flat): Prefer Array#flat() over legacy techniques to flatten arrays. ╭─[prefer_array_flat.tsx:1:1] 1 β”‚ array.reduce((a, b) => a.concat(b), []) diff --git a/crates/oxc_linter/src/snapshots/unicorn_prefer_array_flat_map.snap b/crates/oxc_linter/src/snapshots/unicorn_prefer_array_flat_map.snap index ca2609711e100..ba8c50bc2cb0d 100644 --- a/crates/oxc_linter/src/snapshots/unicorn_prefer_array_flat_map.snap +++ b/crates/oxc_linter/src/snapshots/unicorn_prefer_array_flat_map.snap @@ -86,6 +86,13 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Prefer `.flatMap(…)` over `.map(…).flat()`. + ⚠ eslint-plugin-unicorn(prefer-array-flat-map): `Array.flatMap` performs `Array.map` and `Array.flat` in one step. + ╭─[prefer_array_flat_map.tsx:1:13] + 1 β”‚ const bar = foo?.map(i => [i]).flat() + Β· ───────────────────────── + ╰──── + help: Prefer `.flatMap(…)` over `.map(…).flat()`. + ⚠ eslint-plugin-unicorn(prefer-array-flat-map): `Array.flatMap` performs `Array.map` and `Array.flat` in one step. ╭─[prefer_array_flat_map.tsx:1:13] 1 β”‚ const bar = { map: () => {} }.map(i => [i]).flat() @@ -114,6 +121,56 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Prefer `.flatMap(…)` over `.map(…).flat()`. + ⚠ eslint-plugin-unicorn(prefer-array-flat-map): `Array.flatMap` performs `Array.map` and `Array.flat` in one step. + ╭─[prefer_array_flat_map.tsx:1:11] + 1 β”‚ ╭─▢ let bar = [1,2,3].map(i => { + 2 β”‚ β”‚ return [i]; + 3 β”‚ ╰─▢ }).flat(); + ╰──── + help: Prefer `.flatMap(…)` over `.map(…).flat()`. + + ⚠ eslint-plugin-unicorn(prefer-array-flat-map): `Array.flatMap` performs `Array.map` and `Array.flat` in one step. + ╭─[prefer_array_flat_map.tsx:1:11] + 1 β”‚ ╭─▢ let bar = [1,2,3].map(i => { + 2 β”‚ β”‚ return [i]; + 3 β”‚ β”‚ }) + 4 β”‚ ╰─▢ .flat(); + ╰──── + help: Prefer `.flatMap(…)` over `.map(…).flat()`. + + ⚠ eslint-plugin-unicorn(prefer-array-flat-map): `Array.flatMap` performs `Array.map` and `Array.flat` in one step. + ╭─[prefer_array_flat_map.tsx:1:11] + 1 β”‚ ╭─▢ let bar = [1,2,3].map(i => { + 2 β”‚ β”‚ return [i]; + 3 β”‚ β”‚ }) // comment + 4 β”‚ ╰─▢ .flat(); + ╰──── + help: Prefer `.flatMap(…)` over `.map(…).flat()`. + + ⚠ eslint-plugin-unicorn(prefer-array-flat-map): `Array.flatMap` performs `Array.map` and `Array.flat` in one step. + ╭─[prefer_array_flat_map.tsx:1:11] + 1 β”‚ ╭─▢ let bar = [1,2,3].map(i => { + 2 β”‚ β”‚ return [i]; + 3 β”‚ β”‚ }) // comment + 4 β”‚ ╰─▢ .flat(); // other + ╰──── + help: Prefer `.flatMap(…)` over `.map(…).flat()`. + + ⚠ eslint-plugin-unicorn(prefer-array-flat-map): `Array.flatMap` performs `Array.map` and `Array.flat` in one step. + ╭─[prefer_array_flat_map.tsx:1:11] + 1 β”‚ ╭─▢ let bar = [1,2,3] + 2 β”‚ β”‚ .map(i => { return [i]; }) + 3 β”‚ ╰─▢ .flat(); + ╰──── + help: Prefer `.flatMap(…)` over `.map(…).flat()`. + + ⚠ eslint-plugin-unicorn(prefer-array-flat-map): `Array.flatMap` performs `Array.map` and `Array.flat` in one step. + ╭─[prefer_array_flat_map.tsx:1:11] + 1 β”‚ ╭─▢ let bar = [1,2,3].map(i => { return [i]; }) + 2 β”‚ ╰─▢ .flat(); + ╰──── + help: Prefer `.flatMap(…)` over `.map(…).flat()`. + ⚠ eslint-plugin-unicorn(prefer-array-flat-map): `Array.flatMap` performs `Array.map` and `Array.flat` in one step. ╭─[prefer_array_flat_map.tsx:1:11] 1 β”‚ let bar = [1,2,3] . map( x => y ) . flat () // πŸ€ͺ diff --git a/crates/oxc_linter/src/snapshots/unicorn_prefer_global_this.snap b/crates/oxc_linter/src/snapshots/unicorn_prefer_global_this.snap index a001da9ffdc3a..f4203910d9336 100644 --- a/crates/oxc_linter/src/snapshots/unicorn_prefer_global_this.snap +++ b/crates/oxc_linter/src/snapshots/unicorn_prefer_global_this.snap @@ -398,6 +398,20 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Replace the alias with `globalThis`. + ⚠ eslint-plugin-unicorn(prefer-global-this): Prefer `globalThis` over environment-specific global aliases like `window`, `self`, and `global`. + ╭─[prefer_global_this.tsx:1:10] + 1 β”‚ 'foo' in window + Β· ────── + ╰──── + help: Replace the alias with `globalThis`. + + ⚠ eslint-plugin-unicorn(prefer-global-this): Prefer `globalThis` over environment-specific global aliases like `window`, `self`, and `global`. + ╭─[prefer_global_this.tsx:1:10] + 1 β”‚ 'foo' in global + Β· ────── + ╰──── + help: Replace the alias with `globalThis`. + ⚠ eslint-plugin-unicorn(prefer-global-this): Prefer `globalThis` over environment-specific global aliases like `window`, `self`, and `global`. ╭─[prefer_global_this.tsx:1:8] 1 β”‚ typeof window !== "undefined" diff --git a/crates/oxc_linter/src/snapshots/unicorn_prefer_modern_dom_apis.snap b/crates/oxc_linter/src/snapshots/unicorn_prefer_modern_dom_apis.snap index 295e503876302..004eb17c79901 100644 --- a/crates/oxc_linter/src/snapshots/unicorn_prefer_modern_dom_apis.snap +++ b/crates/oxc_linter/src/snapshots/unicorn_prefer_modern_dom_apis.snap @@ -9,6 +9,28 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Replace `parentNode.replaceChild(newChildNode, oldChildNode)` with `oldChildNode.replaceWith(newChildNode)`. + ⚠ eslint-plugin-unicorn(prefer-modern-dom-apis): Prefer using `replaceWith` over `replaceChild`. + ╭─[prefer_modern_dom_apis.tsx:1:12] + 1 β”‚ parentNode.replaceChild( + Β· ──────────── + 2 β”‚ newChildNode, + ╰──── + help: Replace `parentNode.replaceChild( + newChildNode, + oldChildNode + )` with `oldChildNode.replaceWith(newChildNode)`. + + ⚠ eslint-plugin-unicorn(prefer-modern-dom-apis): Prefer using `replaceWith` over `replaceChild`. + ╭─[prefer_modern_dom_apis.tsx:1:12] + 1 β”‚ parentNode.replaceChild( // inline comments + Β· ──────────── + 2 β”‚ newChildNode, // inline comments + ╰──── + help: Replace `parentNode.replaceChild( // inline comments + newChildNode, // inline comments + oldChildNode // inline comments + )` with `oldChildNode.replaceWith(newChildNode)`. + ⚠ eslint-plugin-unicorn(prefer-modern-dom-apis): Prefer using `replaceWith` over `replaceChild`. ╭─[prefer_modern_dom_apis.tsx:1:24] 1 β”‚ const foo = parentNode.replaceChild(newChildNode, oldChildNode); @@ -128,6 +150,28 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Replace `referenceNode.insertAdjacentElement("afterend", newNode)` with `referenceNode.after(newNode)`. + ⚠ eslint-plugin-unicorn(prefer-modern-dom-apis): Prefer using `after` over `insertAdjacentElement`. + ╭─[prefer_modern_dom_apis.tsx:1:15] + 1 β”‚ referenceNode.insertAdjacentElement( + Β· ───────────────────── + 2 β”‚ "afterend", + ╰──── + help: Replace `referenceNode.insertAdjacentElement( + "afterend", + newNode + )` with `referenceNode.after(newNode)`. + + ⚠ eslint-plugin-unicorn(prefer-modern-dom-apis): Prefer using `after` over `insertAdjacentElement`. + ╭─[prefer_modern_dom_apis.tsx:1:15] + 1 β”‚ referenceNode.insertAdjacentElement( // inline comments + Β· ───────────────────── + 2 β”‚ "afterend", // inline comments + ╰──── + help: Replace `referenceNode.insertAdjacentElement( // inline comments + "afterend", // inline comments + newNode // inline comments + )` with `referenceNode.after(newNode)`. + ⚠ eslint-plugin-unicorn(prefer-modern-dom-apis): Prefer using `before` over `insertAdjacentElement`. ╭─[prefer_modern_dom_apis.tsx:1:27] 1 β”‚ const foo = referenceNode.insertAdjacentElement("beforebegin", newNode); diff --git a/crates/oxc_linter/src/snapshots/unicorn_prefer_native_coercion_functions.snap b/crates/oxc_linter/src/snapshots/unicorn_prefer_native_coercion_functions.snap index 507cef90bda85..95a0fba2c906a 100644 --- a/crates/oxc_linter/src/snapshots/unicorn_prefer_native_coercion_functions.snap +++ b/crates/oxc_linter/src/snapshots/unicorn_prefer_native_coercion_functions.snap @@ -32,6 +32,20 @@ source: crates/oxc_linter/src/tester.rs Β· ────────────── ╰──── + ⚠ eslint-plugin-unicorn(prefer-native-coercion-functions): The function is equivalent to `String`. Call `String` directly. + ╭─[prefer_native_coercion_functions.tsx:1:13] + 1 β”‚ ╭─▢ const foo = v => { + 2 β”‚ β”‚ return String(v); + 3 β”‚ ╰─▢ } + ╰──── + + ⚠ eslint-plugin-unicorn(prefer-native-coercion-functions): The function is equivalent to `String`. Call `String` directly. + ╭─[prefer_native_coercion_functions.tsx:1:13] + 1 β”‚ ╭─▢ const foo = function (v) { + 2 β”‚ β”‚ return String(v); + 3 β”‚ ╰─▢ } + ╰──── + ⚠ eslint-plugin-unicorn(prefer-native-coercion-functions): The function is equivalent to `String`. Call `String` directly. ╭─[prefer_native_coercion_functions.tsx:1:1] 1 β”‚ function foo(v) { return String(v); } @@ -50,6 +64,42 @@ source: crates/oxc_linter/src/tester.rs Β· ────────────────────────────────── ╰──── + ⚠ eslint-plugin-unicorn(prefer-native-coercion-functions): The function is equivalent to `String`. Call `String` directly. + ╭─[prefer_native_coercion_functions.tsx:2:20] + 1 β”‚ class A { + 2 β”‚ ╭─▢ foo(v) { + 3 β”‚ β”‚ return String(v); + 4 β”‚ ╰─▢ } + 5 β”‚ bar() {} + ╰──── + + ⚠ eslint-plugin-unicorn(prefer-native-coercion-functions): The function is equivalent to `String`. Call `String` directly. + ╭─[prefer_native_coercion_functions.tsx:2:27] + 1 β”‚ class A { + 2 β”‚ ╭─▢ static foo(v) { + 3 β”‚ β”‚ return String(v); + 4 β”‚ ╰─▢ } + 5 β”‚ bar() {} + ╰──── + + ⚠ eslint-plugin-unicorn(prefer-native-coercion-functions): The function is equivalent to `String`. Call `String` directly. + ╭─[prefer_native_coercion_functions.tsx:2:21] + 1 β”‚ class A { + 2 β”‚ ╭─▢ #foo(v) { + 3 β”‚ β”‚ return String(v); + 4 β”‚ ╰─▢ } + 5 β”‚ bar() {} + ╰──── + + ⚠ eslint-plugin-unicorn(prefer-native-coercion-functions): The function is equivalent to `String`. Call `String` directly. + ╭─[prefer_native_coercion_functions.tsx:2:28] + 1 β”‚ class A { + 2 β”‚ ╭─▢ static #foo(v) { + 3 β”‚ β”‚ return String(v); + 4 β”‚ ╰─▢ } + 5 β”‚ bar() {} + ╰──── + ⚠ eslint-plugin-unicorn(prefer-native-coercion-functions): The function is equivalent to `String`. Call `String` directly. ╭─[prefer_native_coercion_functions.tsx:1:13] 1 β”‚ const foo = (v, extra) => String(v) @@ -116,6 +166,13 @@ source: crates/oxc_linter/src/tester.rs Β· ────── ╰──── + ⚠ eslint-plugin-unicorn(prefer-native-coercion-functions): The arrow function in the callback of the array is equivalent to `Boolean`. Replace the callback with `Boolean`. + ╭─[prefer_native_coercion_functions.tsx:1:12] + 1 β”‚ ╭─▢ array.some(v => { + 2 β”‚ β”‚ return v; + 3 β”‚ ╰─▢ }) + ╰──── + ⚠ eslint-plugin-unicorn(prefer-native-coercion-functions): The arrow function in the callback of the array is equivalent to `Boolean`. Replace the callback with `Boolean`. ╭─[prefer_native_coercion_functions.tsx:1:12] 1 β”‚ array.some((v, extra) => v) @@ -127,3 +184,9 @@ source: crates/oxc_linter/src/tester.rs 1 β”‚ array.some((v, ) => /* comment */ v) Β· ──────────────────────── ╰──── + + ⚠ eslint-plugin-unicorn(prefer-native-coercion-functions): The arrow function in the callback of the array is equivalent to `Boolean`. Replace the callback with `Boolean`. + ╭─[prefer_native_coercion_functions.tsx:1:14] + 1 β”‚ array.filter((value): boolean => value) + Β· ───────────────────────── + ╰──── diff --git a/crates/oxc_linter/src/snapshots/unicorn_prefer_node_protocol.snap b/crates/oxc_linter/src/snapshots/unicorn_prefer_node_protocol.snap index 8ed0dec478ba5..eb9c5ba4727ff 100644 --- a/crates/oxc_linter/src/snapshots/unicorn_prefer_node_protocol.snap +++ b/crates/oxc_linter/src/snapshots/unicorn_prefer_node_protocol.snap @@ -30,6 +30,15 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Prefer `node:fs` over `fs`. + ⚠ eslint-plugin-unicorn(prefer-node-protocol): Prefer using the `node:` protocol when importing Node.js builtin modules. + ╭─[prefer_node_protocol.tsx:2:41] + 1 β”‚ async function foo() { + 2 β”‚ const fs = await import('fs'); + Β· ──── + 3 β”‚ } + ╰──── + help: Prefer `node:fs` over `fs`. + ⚠ eslint-plugin-unicorn(prefer-node-protocol): Prefer using the `node:` protocol when importing Node.js builtin modules. ╭─[prefer_node_protocol.tsx:1:16] 1 β”‚ import fs from "fs/promises"; @@ -44,6 +53,15 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Prefer `node:fs/promises` over `fs/promises`. + ⚠ eslint-plugin-unicorn(prefer-node-protocol): Prefer using the `node:` protocol when importing Node.js builtin modules. + ╭─[prefer_node_protocol.tsx:2:41] + 1 β”‚ async function foo() { + 2 β”‚ const fs = await import('fs/promises'); + Β· ───────────── + 3 β”‚ } + ╰──── + help: Prefer `node:fs/promises` over `fs/promises`. + ⚠ eslint-plugin-unicorn(prefer-node-protocol): Prefer using the `node:` protocol when importing Node.js builtin modules. ╭─[prefer_node_protocol.tsx:1:24] 1 β”‚ import {promises} from "fs"; @@ -65,6 +83,15 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Prefer `node:fs` over `fs`. + ⚠ eslint-plugin-unicorn(prefer-node-protocol): Prefer using the `node:` protocol when importing Node.js builtin modules. + ╭─[prefer_node_protocol.tsx:2:41] + 1 β”‚ async function foo() { + 2 β”‚ const fs = await import("fs/promises"); + Β· ───────────── + 3 β”‚ } + ╰──── + help: Prefer `node:fs/promises` over `fs/promises`. + ⚠ eslint-plugin-unicorn(prefer-node-protocol): Prefer using the `node:` protocol when importing Node.js builtin modules. ╭─[prefer_node_protocol.tsx:1:8] 1 β”‚ import "buffer"; diff --git a/crates/oxc_linter/src/snapshots/unicorn_prefer_optional_catch_binding.snap b/crates/oxc_linter/src/snapshots/unicorn_prefer_optional_catch_binding.snap index ebbe3c3f35633..a077efb7b1d9d 100644 --- a/crates/oxc_linter/src/snapshots/unicorn_prefer_optional_catch_binding.snap +++ b/crates/oxc_linter/src/snapshots/unicorn_prefer_optional_catch_binding.snap @@ -9,6 +9,67 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Delete this code. + ⚠ eslint-plugin-unicorn(prefer-optional-catch-binding): Prefer omitting the catch binding parameter if it is unused + ╭─[prefer_optional_catch_binding.tsx:1:15] + 1 β”‚ try {} catch (foo) { + Β· ─── + 2 β”‚ function bar(foo) {} + ╰──── + help: Delete this code. + + ⚠ eslint-plugin-unicorn(prefer-optional-catch-binding): Prefer omitting the catch binding parameter if it is unused + ╭─[prefer_optional_catch_binding.tsx:1:15] + 1 β”‚ try {} catch (outer) { + Β· ───── + 2 β”‚ try {} catch (inner) { + ╰──── + help: Delete this code. + + ⚠ eslint-plugin-unicorn(prefer-optional-catch-binding): Prefer omitting the catch binding parameter if it is unused + ╭─[prefer_optional_catch_binding.tsx:2:31] + 1 β”‚ try {} catch (outer) { + 2 β”‚ try {} catch (inner) { + Β· ───── + 3 β”‚ } + ╰──── + help: Delete this code. + + ⚠ eslint-plugin-unicorn(prefer-optional-catch-binding): Prefer omitting the catch binding parameter if it is unused + ╭─[prefer_optional_catch_binding.tsx:6:31] + 5 β”‚ try { + 6 β”‚ try {} catch (inTry) { + Β· ───── + 7 β”‚ } + ╰──── + help: Delete this code. + + ⚠ eslint-plugin-unicorn(prefer-optional-catch-binding): Prefer omitting the catch binding parameter if it is unused + ╭─[prefer_optional_catch_binding.tsx:8:22] + 7 β”‚ } + 8 β”‚ } catch (another) { + Β· ─────── + 9 β”‚ try {} catch (inCatch) { + ╰──── + help: Delete this code. + + ⚠ eslint-plugin-unicorn(prefer-optional-catch-binding): Prefer omitting the catch binding parameter if it is unused + ╭─[prefer_optional_catch_binding.tsx:9:31] + 8 β”‚ } catch (another) { + 9 β”‚ try {} catch (inCatch) { + Β· ─────── + 10 β”‚ } + ╰──── + help: Delete this code. + + ⚠ eslint-plugin-unicorn(prefer-optional-catch-binding): Prefer omitting the catch binding parameter if it is unused + ╭─[prefer_optional_catch_binding.tsx:12:31] + 11 β”‚ } finally { + 12 β”‚ try {} catch (inFinally) { + Β· ───────── + 13 β”‚ } + ╰──── + help: Delete this code. + ⚠ eslint-plugin-unicorn(prefer-optional-catch-binding): Prefer omitting the catch binding parameter if it is unused ╭─[prefer_optional_catch_binding.tsx:1:15] 1 β”‚ try {} catch (theRealErrorName) {} @@ -16,11 +77,20 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Delete this code. + ⚠ eslint-plugin-unicorn(prefer-optional-catch-binding): Prefer omitting the catch binding parameter if it is unused + ╭─[prefer_optional_catch_binding.tsx:8:17] + 7 β”‚ // comment + 8 β”‚ unused + Β· ────── + 9 β”‚ /* comment */ + ╰──── + help: Delete this code. + ⚠ eslint-plugin-unicorn(prefer-optional-catch-binding): Prefer omitting the catch binding parameter if it is unused ╭─[prefer_optional_catch_binding.tsx:1:25] 1 β”‚ try { } catch (e) Β· ─ - 2 β”‚ { } + 2 β”‚ { } ╰──── help: Delete this code. diff --git a/crates/oxc_linter/src/snapshots/unicorn_prefer_query_selector.snap b/crates/oxc_linter/src/snapshots/unicorn_prefer_query_selector.snap index e2071279ed325..bd495f5d7ed9a 100644 --- a/crates/oxc_linter/src/snapshots/unicorn_prefer_query_selector.snap +++ b/crates/oxc_linter/src/snapshots/unicorn_prefer_query_selector.snap @@ -156,6 +156,31 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: It's better to use the same method to query DOM elements. This helps keep consistency and it lends itself to future improvements (e.g. more specific selectors). + ⚠ eslint-plugin-unicorn(prefer-query-selector): Prefer `.querySelectorAll()` over `.getElementsByClassName()`. + ╭─[prefer_query_selector.tsx:1:54] + 1 β”‚ for (const div of document.body.getElementById("id").getElementsByClassName("class")) { + Β· ────────────────────── + 2 β”‚ console.log(div.getElementsByTagName("div")); + ╰──── + help: It's better to use the same method to query DOM elements. This helps keep consistency and it lends itself to future improvements (e.g. more specific selectors). + + ⚠ eslint-plugin-unicorn(prefer-query-selector): Prefer `.querySelector()` over `.getElementById()`. + ╭─[prefer_query_selector.tsx:1:33] + 1 β”‚ for (const div of document.body.getElementById("id").getElementsByClassName("class")) { + Β· ────────────── + 2 β”‚ console.log(div.getElementsByTagName("div")); + ╰──── + help: It's better to use the same method to query DOM elements. This helps keep consistency and it lends itself to future improvements (e.g. more specific selectors). + + ⚠ eslint-plugin-unicorn(prefer-query-selector): Prefer `.querySelectorAll()` over `.getElementsByTagName()`. + ╭─[prefer_query_selector.tsx:2:33] + 1 β”‚ for (const div of document.body.getElementById("id").getElementsByClassName("class")) { + 2 β”‚ console.log(div.getElementsByTagName("div")); + Β· ──────────────────── + 3 β”‚ } + ╰──── + help: It's better to use the same method to query DOM elements. This helps keep consistency and it lends itself to future improvements (e.g. more specific selectors). + ⚠ eslint-plugin-unicorn(prefer-query-selector): Prefer `.querySelector()` over `.getElementById()`. ╭─[prefer_query_selector.tsx:1:3] 1 β”‚ e.getElementById(3) diff --git a/crates/oxc_linter/src/snapshots/unicorn_prefer_regexp_test.snap b/crates/oxc_linter/src/snapshots/unicorn_prefer_regexp_test.snap index 4b17eaa63e7a2..b91d5f625818b 100644 --- a/crates/oxc_linter/src/snapshots/unicorn_prefer_regexp_test.snap +++ b/crates/oxc_linter/src/snapshots/unicorn_prefer_regexp_test.snap @@ -198,6 +198,15 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: `RegExp#test()` exclusively returns a boolean and therefore is more efficient. + ⚠ eslint-plugin-unicorn(prefer-regexp-test): Prefer `RegExp#test()` over `String#match()` and `RegExp#exec()`. + ╭─[prefer_regexp_test.tsx:2:25] + 1 β”‚ async function a() { + 2 β”‚ if (foo.match(await bar())) {} + Β· ───── + 3 β”‚ } + ╰──── + help: `RegExp#test()` exclusively returns a boolean and therefore is more efficient. + ⚠ eslint-plugin-unicorn(prefer-regexp-test): Prefer `RegExp#test()` over `String#match()` and `RegExp#exec()`. ╭─[prefer_regexp_test.tsx:1:11] 1 β”‚ if ((foo).match(/re/)) {} @@ -233,6 +242,15 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: `RegExp#test()` exclusively returns a boolean and therefore is more efficient. + ⚠ eslint-plugin-unicorn(prefer-regexp-test): Prefer `RegExp#test()` over `String#match()` and `RegExp#exec()`. + ╭─[prefer_regexp_test.tsx:2:27] + 1 β”‚ async function a() { + 2 β”‚ if ((foo).match(await bar())) {} + Β· ───── + 3 β”‚ } + ╰──── + help: `RegExp#test()` exclusively returns a boolean and therefore is more efficient. + ⚠ eslint-plugin-unicorn(prefer-regexp-test): Prefer `RegExp#test()` over `String#match()` and `RegExp#exec()`. ╭─[prefer_regexp_test.tsx:1:27] 1 β”‚ const re = [/a/]; if (foo.match([re][0])) {} @@ -240,6 +258,32 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: `RegExp#test()` exclusively returns a boolean and therefore is more efficient. + ⚠ eslint-plugin-unicorn(prefer-regexp-test): Prefer `RegExp#test()` over `String#match()` and `RegExp#exec()`. + ╭─[prefer_regexp_test.tsx:4:34] + 3 β”‚ /* 1 */ foo() /* 2 */ + 4 β”‚ ./* 3 */ match /* 4 */ ( + Β· ───── + 5 β”‚ /* 5 */ await /* 6 */ bar() /* 7 */ + ╰──── + help: `RegExp#test()` exclusively returns a boolean and therefore is more efficient. + + ⚠ eslint-plugin-unicorn(prefer-regexp-test): Prefer `RegExp#test()` over `String#match()` and `RegExp#exec()`. + ╭─[prefer_regexp_test.tsx:2:21] + 1 β”‚ const string = '[.!?]\\\\s*$'; + 2 β”‚ if (foo.match(string)) { + Β· ───── + 3 β”‚ } + ╰──── + help: `RegExp#test()` exclusively returns a boolean and therefore is more efficient. + + ⚠ eslint-plugin-unicorn(prefer-regexp-test): Prefer `RegExp#test()` over `String#match()` and `RegExp#exec()`. + ╭─[prefer_regexp_test.tsx:2:21] + 1 β”‚ const regex = new RegExp('[.!?]\\\\s*$'); + 2 β”‚ if (foo.match(regex)) {} + Β· ───── + ╰──── + help: `RegExp#test()` exclusively returns a boolean and therefore is more efficient. + ⚠ eslint-plugin-unicorn(prefer-regexp-test): Prefer `RegExp#test()` over `String#match()` and `RegExp#exec()`. ╭─[prefer_regexp_test.tsx:1:9] 1 β”‚ if (foo.match(unknown)) {} @@ -324,6 +368,46 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: `RegExp#test()` exclusively returns a boolean and therefore is more efficient. + ⚠ eslint-plugin-unicorn(prefer-regexp-test): Prefer `RegExp#test()` over `String#match()` and `RegExp#exec()`. + ╭─[prefer_regexp_test.tsx:2:21] + 1 β”‚ const regex = /weird/g; + 2 β”‚ if (foo.match(regex)); + Β· ───── + ╰──── + help: `RegExp#test()` exclusively returns a boolean and therefore is more efficient. + + ⚠ eslint-plugin-unicorn(prefer-regexp-test): Prefer `RegExp#test()` over `String#match()` and `RegExp#exec()`. + ╭─[prefer_regexp_test.tsx:2:23] + 1 β”‚ const regex = /weird/g; + 2 β”‚ if (regex.exec(foo)); + Β· ──── + ╰──── + help: `RegExp#test()` exclusively returns a boolean and therefore is more efficient. + + ⚠ eslint-plugin-unicorn(prefer-regexp-test): Prefer `RegExp#test()` over `String#match()` and `RegExp#exec()`. + ╭─[prefer_regexp_test.tsx:2:23] + 1 β”‚ const regex = /weird/y; + 2 β”‚ if (regex.exec(foo)); + Β· ──── + ╰──── + help: `RegExp#test()` exclusively returns a boolean and therefore is more efficient. + + ⚠ eslint-plugin-unicorn(prefer-regexp-test): Prefer `RegExp#test()` over `String#match()` and `RegExp#exec()`. + ╭─[prefer_regexp_test.tsx:2:23] + 1 β”‚ const regex = /weird/gyi; + 2 β”‚ if (regex.exec(foo)); + Β· ──── + ╰──── + help: `RegExp#test()` exclusively returns a boolean and therefore is more efficient. + + ⚠ eslint-plugin-unicorn(prefer-regexp-test): Prefer `RegExp#test()` over `String#match()` and `RegExp#exec()`. + ╭─[prefer_regexp_test.tsx:2:20] + 1 β”‚ let re = new RegExp('foo', 'g'); + 2 β”‚ if(str.match(re)); + Β· ───── + ╰──── + help: `RegExp#test()` exclusively returns a boolean and therefore is more efficient. + ⚠ eslint-plugin-unicorn(prefer-regexp-test): Prefer `RegExp#test()` over `String#match()` and `RegExp#exec()`. ╭─[prefer_regexp_test.tsx:1:7] 1 β”‚ !/a/u.exec(foo) diff --git a/crates/oxc_linter/src/snapshots/unicorn_prefer_string_slice.snap b/crates/oxc_linter/src/snapshots/unicorn_prefer_string_slice.snap index 8b5c61c0eb146..ec5fc10f468fd 100644 --- a/crates/oxc_linter/src/snapshots/unicorn_prefer_string_slice.snap +++ b/crates/oxc_linter/src/snapshots/unicorn_prefer_string_slice.snap @@ -128,6 +128,14 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Replace `substr` with `slice`. + ⚠ eslint-plugin-unicorn(prefer-string-slice): Prefer String#slice() over String#substr() + ╭─[prefer_string_slice.tsx:2:19] + 1 β”‚ const length = 123; + 2 β”‚ "foo".substr(1, length - 4) + Β· ────── + ╰──── + help: Replace `substr` with `slice`. + ⚠ eslint-plugin-unicorn(prefer-string-slice): Prefer String#slice() over String#substr() ╭─[prefer_string_slice.tsx:1:7] 1 β”‚ "foo".substr(1, length) @@ -135,6 +143,14 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Replace `substr` with `slice`. + ⚠ eslint-plugin-unicorn(prefer-string-slice): Prefer String#slice() over String#substr() + ╭─[prefer_string_slice.tsx:2:27] + 1 β”‚ const uri = 'foo'; + 2 β”‚ ((uri || '')).substr(1) + Β· ────── + ╰──── + help: Replace `substr` with `slice`. + ⚠ eslint-plugin-unicorn(prefer-string-slice): Prefer String#slice() over String#substr() ╭─[prefer_string_slice.tsx:1:5] 1 β”‚ foo.substr(start) @@ -289,6 +305,33 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Replace `substring` with `slice`. + ⚠ eslint-plugin-unicorn(prefer-string-slice): Prefer String#slice() over String#substr() + ╭─[prefer_string_slice.tsx:2:40] + 1 β”‚ function foo() { + 2 β”‚ return (bar as string).substr(3); + Β· ────── + 3 β”‚ } + ╰──── + help: Replace `substr` with `slice`. + + ⚠ eslint-plugin-unicorn(prefer-string-slice): Prefer String#slice() over String#substring() + ╭─[prefer_string_slice.tsx:2:42] + 1 β”‚ function foo() { + 2 β”‚ return ((bar as string)).substring(3); + Β· ───────── + 3 β”‚ } + ╰──── + help: Replace `substring` with `slice`. + + ⚠ eslint-plugin-unicorn(prefer-string-slice): Prefer String#slice() over String#substring() + ╭─[prefer_string_slice.tsx:2:27] + 1 β”‚ /* 1 */ (( /* 2 */ 0 /* 3 */, /* 4 */ foo /* 5 */ )) /* 6 */ + 2 β”‚ . /* 7 */ substring /* 8 */ ( + Β· ───────── + 3 β”‚ /* 9 */ (( /* 10 */ bar /* 11 */ )) /* 12 */, + ╰──── + help: Replace `substring` with `slice`. + ⚠ eslint-plugin-unicorn(prefer-string-slice): Prefer String#slice() over String#substr() ╭─[prefer_string_slice.tsx:1:5] 1 β”‚ foo.substr(0, ...bar) @@ -351,3 +394,11 @@ source: crates/oxc_linter/src/tester.rs Β· ───────── ╰──── help: Replace `substring` with `slice`. + + ⚠ eslint-plugin-unicorn(prefer-string-slice): Prefer String#slice() over String#substr() + ╭─[prefer_string_slice.tsx:2:35] + 1 β”‚ const string = "::"; + 2 β”‚ const output = string.substr(-2, 2); + Β· ────── + ╰──── + help: Replace `substr` with `slice`. diff --git a/crates/oxc_linter/src/snapshots/unicorn_prefer_string_trim_start_end.snap b/crates/oxc_linter/src/snapshots/unicorn_prefer_string_trim_start_end.snap index d9edc68637f52..374758d79e5b8 100644 --- a/crates/oxc_linter/src/snapshots/unicorn_prefer_string_trim_start_end.snap +++ b/crates/oxc_linter/src/snapshots/unicorn_prefer_string_trim_start_end.snap @@ -37,6 +37,15 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Replace with `trimStart` + ⚠ eslint-plugin-unicorn(prefer-string-trim-start-end): Prefer `trimEnd` over `trimRight` + ╭─[prefer_string_trim_start_end.tsx:3:18] + 2 β”‚ // comment + 3 β”‚ .trimRight/* comment */( + Β· ───────── + 4 β”‚ /* comment */ + ╰──── + help: Replace with `trimEnd` + ⚠ eslint-plugin-unicorn(prefer-string-trim-start-end): Prefer `trimStart` over `trimLeft` ╭─[prefer_string_trim_start_end.tsx:1:6] 1 β”‚ foo?.trimLeft() diff --git a/crates/oxc_linter/src/snapshots/unicorn_require_array_join_separator.snap b/crates/oxc_linter/src/snapshots/unicorn_require_array_join_separator.snap index 4c8c323f557ca..15b778ebe2b3a 100644 --- a/crates/oxc_linter/src/snapshots/unicorn_require_array_join_separator.snap +++ b/crates/oxc_linter/src/snapshots/unicorn_require_array_join_separator.snap @@ -44,6 +44,26 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: Missing the separator argument. + ⚠ eslint-plugin-unicorn(require-array-join-separator): Enforce using the separator argument with Array#join() + ╭─[require_array_join_separator.tsx:13:25] + 12 β”‚ /**/ + 13 β”‚ ╭─▢ call + 14 β”‚ β”‚ /**/ + 15 β”‚ β”‚ ( + 16 β”‚ β”‚ /**/ + 17 β”‚ β”‚ ( + 18 β”‚ β”‚ /**/ + 19 β”‚ β”‚ foo + 20 β”‚ β”‚ /**/ + 21 β”‚ β”‚ ) + 22 β”‚ β”‚ /**/ + 23 β”‚ β”‚ , + 24 β”‚ β”‚ /**/ + 25 β”‚ ╰─▢ )/**/ + 26 β”‚ ) + ╰──── + help: Missing the separator argument. + ⚠ eslint-plugin-unicorn(require-array-join-separator): Enforce using the separator argument with Array#join() ╭─[require_array_join_separator.tsx:1:10] 1 β”‚ foo?.join()