diff --git a/crates/oxc_linter/src/rules/jest/no_standalone_expect.rs b/crates/oxc_linter/src/rules/jest/no_standalone_expect/mod.rs similarity index 56% rename from crates/oxc_linter/src/rules/jest/no_standalone_expect.rs rename to crates/oxc_linter/src/rules/jest/no_standalone_expect/mod.rs index a66e00a324538..ce71466eec39f 100644 --- a/crates/oxc_linter/src/rules/jest/no_standalone_expect.rs +++ b/crates/oxc_linter/src/rules/jest/no_standalone_expect/mod.rs @@ -231,163 +231,3 @@ fn is_var_declarator_or_test_block<'a>( false } - -#[test] -fn test() { - use crate::tester::Tester; - - let pass = vec![ - ("expect.any(String)", None), - ("expect.extend({})", None), - ("describe('a test', () => { it('an it', () => {expect(1).toBe(1); }); });", None), - ( - "describe('a test', () => { it('an it', () => { const func = () => { expect(1).toBe(1); }; }); });", - None, - ), - ("describe('a test', () => { const func = () => { expect(1).toBe(1); }; });", None), - ("describe('a test', () => { function func() { expect(1).toBe(1); }; });", None), - ("describe('a test', () => { const func = function(){ expect(1).toBe(1); }; });", None), - ("it('an it', () => expect(1).toBe(1))", None), - ("const func = function(){ expect(1).toBe(1); };", None), - ("const func = () => expect(1).toBe(1);", None), - ("{}", None), - ("it.each([1, true])('trues', value => { expect(value).toBe(true); });", None), - ( - "it.each([1, true])('trues', value => { expect(value).toBe(true); }); it('an it', () => { expect(1).toBe(1) });", - None, - ), - ( - " - it.each` - num | value - ${1} | ${true} - `('trues', ({ value }) => { - expect(value).toBe(true); - }); - ", - None, - ), - ("it.only('an only', value => { expect(value).toBe(true); });", None), - ("it.concurrent('an concurrent', value => { expect(value).toBe(true); });", None), - ( - "describe.each([1, true])('trues', value => { it('an it', () => expect(value).toBe(true) ); });", - None, - ), - ( - " - describe('scenario', () => { - const t = Math.random() ? it.only : it; - t('testing', () => expect(true)); - }); - ", - Some(serde_json::json!([{ "additionalTestBlockFunctions": ['t'] }])), - ), - ( - r" - each([ - [1, 1, 2], - [1, 2, 3], - [2, 1, 3], - ]).test('returns the result of adding %d to %d', (a, b, expected) => { - expect(a + b).toBe(expected); - }); - ", - Some(serde_json::json!([{ "additionalTestBlockFunctions": ["each.test"] }])), - ), - ]; - - let fail = vec![ - ("(() => {})('testing', () => expect(true).toBe(false))", None), - ("expect.hasAssertions()", None), - ("expect().hasAssertions()", None), - ( - " - describe('scenario', () => { - const t = Math.random() ? it.only : it; - t('testing', () => expect(true).toBe(false)); - }); - ", - None, - ), - ( - " - describe('scenario', () => { - const t = Math.random() ? it.only : it; - t('testing', () => expect(true).toBe(false)); - }); - ", - None, - ), - ( - " - each([ - [1, 1, 2], - [1, 2, 3], - [2, 1, 3], - ]).test('returns the result of adding %d to %d', (a, b, expected) => { - expect(a + b).toBe(expected); - }); - ", - None, - ), - ( - " - each([ - [1, 1, 2], - [1, 2, 3], - [2, 1, 3], - ]).test('returns the result of adding %d to %d', (a, b, expected) => { - expect(a + b).toBe(expected); - }); - ", - Some(serde_json::json!([{ "additionalTestBlockFunctions": ["each"] }])), - ), - ( - " - each([ - [1, 1, 2], - [1, 2, 3], - [2, 1, 3], - ]).test('returns the result of adding %d to %d', (a, b, expected) => { - expect(a + b).toBe(expected); - }); - ", - Some(serde_json::json!([{ "additionalTestBlockFunctions": ["test"] }])), - ), - ("describe('a test', () => { expect(1).toBe(1); });", None), - ("describe('a test', () => expect(1).toBe(1));", None), - ( - "describe('a test', () => { const func = () => { expect(1).toBe(1); }; expect(1).toBe(1); });", - None, - ), - ( - "describe('a test', () => { it(() => { expect(1).toBe(1); }); expect(1).toBe(1); });", - None, - ), - ("expect(1).toBe(1);", None), - ("{expect(1).toBe(1)}", None), - ( - "it.each([1, true])('trues', value => { expect(value).toBe(true); }); expect(1).toBe(1);", - None, - ), - ("describe.each([1, true])('trues', value => { expect(value).toBe(true); });", None), - ( - " - import { expect as pleaseExpect } from '@jest/globals'; - describe('a test', () => { pleaseExpect(1).toBe(1); }); - ", - None, - ), - ( - " - import { expect as pleaseExpect } from '@jest/globals'; - beforeEach(() => pleaseExpect.hasAssertions()); - ", - None, - ), - ]; - - Tester::new(NoStandaloneExpect::NAME, NoStandaloneExpect::PLUGIN, pass, fail) - .with_jest_plugin(true) - .test_and_snapshot(); -} diff --git a/crates/oxc_linter/src/rules/jest/no_standalone_expect/tests/jest.rs b/crates/oxc_linter/src/rules/jest/no_standalone_expect/tests/jest.rs new file mode 100644 index 0000000000000..06e9a16135f58 --- /dev/null +++ b/crates/oxc_linter/src/rules/jest/no_standalone_expect/tests/jest.rs @@ -0,0 +1,161 @@ +#[test] +fn test() { + use super::PreferLowercaseTitle; + use crate::rule::RuleMeta; + use crate::tester::Tester; + + let pass = vec![ + ("expect.any(String)", None), + ("expect.extend({})", None), + ("describe('a test', () => { it('an it', () => {expect(1).toBe(1); }); });", None), + ( + "describe('a test', () => { it('an it', () => { const func = () => { expect(1).toBe(1); }; }); });", + None, + ), + ("describe('a test', () => { const func = () => { expect(1).toBe(1); }; });", None), + ("describe('a test', () => { function func() { expect(1).toBe(1); }; });", None), + ("describe('a test', () => { const func = function(){ expect(1).toBe(1); }; });", None), + ("it('an it', () => expect(1).toBe(1))", None), + ("const func = function(){ expect(1).toBe(1); };", None), + ("const func = () => expect(1).toBe(1);", None), + ("{}", None), + ("it.each([1, true])('trues', value => { expect(value).toBe(true); });", None), + ( + "it.each([1, true])('trues', value => { expect(value).toBe(true); }); it('an it', () => { expect(1).toBe(1) });", + None, + ), + ( + " + it.each` + num | value + ${1} | ${true} + `('trues', ({ value }) => { + expect(value).toBe(true); + }); + ", + None, + ), + ("it.only('an only', value => { expect(value).toBe(true); });", None), + ("it.concurrent('an concurrent', value => { expect(value).toBe(true); });", None), + ( + "describe.each([1, true])('trues', value => { it('an it', () => expect(value).toBe(true) ); });", + None, + ), + ( + " + describe('scenario', () => { + const t = Math.random() ? it.only : it; + t('testing', () => expect(true)); + }); + ", + Some(serde_json::json!([{ "additionalTestBlockFunctions": ['t'] }])), + ), + ( + r" + each([ + [1, 1, 2], + [1, 2, 3], + [2, 1, 3], + ]).test('returns the result of adding %d to %d', (a, b, expected) => { + expect(a + b).toBe(expected); + }); + ", + Some(serde_json::json!([{ "additionalTestBlockFunctions": ["each.test"] }])), + ), + ]; + + let fail = vec![ + ("(() => {})('testing', () => expect(true).toBe(false))", None), + ("expect.hasAssertions()", None), + ("expect().hasAssertions()", None), + ( + " + describe('scenario', () => { + const t = Math.random() ? it.only : it; + t('testing', () => expect(true).toBe(false)); + }); + ", + None, + ), + ( + " + describe('scenario', () => { + const t = Math.random() ? it.only : it; + t('testing', () => expect(true).toBe(false)); + }); + ", + None, + ), + ( + " + each([ + [1, 1, 2], + [1, 2, 3], + [2, 1, 3], + ]).test('returns the result of adding %d to %d', (a, b, expected) => { + expect(a + b).toBe(expected); + }); + ", + None, + ), + ( + " + each([ + [1, 1, 2], + [1, 2, 3], + [2, 1, 3], + ]).test('returns the result of adding %d to %d', (a, b, expected) => { + expect(a + b).toBe(expected); + }); + ", + Some(serde_json::json!([{ "additionalTestBlockFunctions": ["each"] }])), + ), + ( + " + each([ + [1, 1, 2], + [1, 2, 3], + [2, 1, 3], + ]).test('returns the result of adding %d to %d', (a, b, expected) => { + expect(a + b).toBe(expected); + }); + ", + Some(serde_json::json!([{ "additionalTestBlockFunctions": ["test"] }])), + ), + ("describe('a test', () => { expect(1).toBe(1); });", None), + ("describe('a test', () => expect(1).toBe(1));", None), + ( + "describe('a test', () => { const func = () => { expect(1).toBe(1); }; expect(1).toBe(1); });", + None, + ), + ( + "describe('a test', () => { it(() => { expect(1).toBe(1); }); expect(1).toBe(1); });", + None, + ), + ("expect(1).toBe(1);", None), + ("{expect(1).toBe(1)}", None), + ( + "it.each([1, true])('trues', value => { expect(value).toBe(true); }); expect(1).toBe(1);", + None, + ), + ("describe.each([1, true])('trues', value => { expect(value).toBe(true); });", None), + ( + " + import { expect as pleaseExpect } from '@jest/globals'; + describe('a test', () => { pleaseExpect(1).toBe(1); }); + ", + None, + ), + ( + " + import { expect as pleaseExpect } from '@jest/globals'; + beforeEach(() => pleaseExpect.hasAssertions()); + ", + None, + ), + ]; + + Tester::new(NoStandaloneExpect::NAME, NoStandaloneExpect::PLUGIN, pass, fail) + .with_jest_plugin(true) + .test_and_snapshot(); +} diff --git a/crates/oxc_linter/src/rules/jest/no_standalone_expect/tests/mod.rs b/crates/oxc_linter/src/rules/jest/no_standalone_expect/tests/mod.rs new file mode 100644 index 0000000000000..0ec040ad1dbec --- /dev/null +++ b/crates/oxc_linter/src/rules/jest/no_standalone_expect/tests/mod.rs @@ -0,0 +1,4 @@ +mod jest; +mod vitest; + +use super::NoStandaloneExpect; diff --git a/crates/oxc_linter/src/rules/jest/no_standalone_expect/tests/vitest.rs b/crates/oxc_linter/src/rules/jest/no_standalone_expect/tests/vitest.rs new file mode 100644 index 0000000000000..88f0e4e58cdd2 --- /dev/null +++ b/crates/oxc_linter/src/rules/jest/no_standalone_expect/tests/vitest.rs @@ -0,0 +1,89 @@ +#[test] +fn test() { + use super::PreferLowercaseTitle; + use crate::rule::RuleMeta; + use crate::tester::Tester; + + let pass = vec![ + ("beforeEach(() => { doSomething(); });", None), + ("expect.any(String)", None), + ("expect.extend({})", None), + (r#"bench("a bench", () => {})"#, None), + (r#"describe("a test", () => { it("an it", () => {expect(1).toBe(1); }); });"#, None), + ( + r#"describe("a test", () => { it("an it", () => { const func = () => { expect(1).toBe(1); }; }); });"#, + None, + ), + (r#"describe("a test", () => { const func = () => { expect(1).toBe(1); }; });"#, None), + (r#"describe("a test", () => { function func() { expect(1).toBe(1); }; });"#, None), + (r#"describe("a test", () => { const func = function(){ expect(1).toBe(1); }; });"#, None), + ( + r#"describe.only.concurrent.todo("a test", () => { const func = function(){ expect(1).toBe(1); }; });"#, + None, + ), + (r#"it("an it", () => expect(1).toBe(1))"#, None), + (r#"it.only("an it", () => expect(1).toBe(1))"#, None), + (r#"it.concurrent("an it", () => expect(1).toBe(1))"#, None), + (r#"it.extend.skip("an it", () => expect(1).toBe(1))"#, None), + (r#"test("a test", () => expect(1).toBe(1))"#, None), + (r#"test.skip("a skipped test", () => expect(1).toBe(1))"#, None), + (r#"test.fails("a failing test", () => expect(1).toBe(1))"#, None), + ("const func = function(){ expect(1).toBe(1); };", None), + ("const func = () => expect(1).toBe(1);", None), + ("{}", None), + (r#"it.each([1, true])("trues", value => { expect(value).toBe(true); });"#, None), + ( + r#"it.each([1, true])("trues", value => { expect(value).toBe(true); }); it("an it", () => { expect(1).toBe(1) });"#, + None, + ), + ]; + + let fail = vec![ + ("(() => {})('testing', () => expect(true).toBe(false))", None), + ("expect.hasAssertions()", None), + ( + " + describe('scenario', () => { + const t = Math.random() ? it.only : it; + t('testing', () => expect(true).toBe(false)); + }); + ", + None, + ), + ( + "describe('scenario', () => { + const t = Math.random() ? it.only : it; + t('testing', () => expect(true).toBe(false)); + });", + None, + ), + (r#"describe("a test", () => { expect(1).toBe(1); });"#, None), + (r#"describe("a test", () => expect(1).toBe(1));"#, None), + ( + r#"describe("a test", () => { const func = () => { expect(1).toBe(1); }; expect(1).toBe(1); });"#, + None, + ), + ( + r#"describe("a test", () => { it(() => { expect(1).toBe(1); }); expect(1).toBe(1); });"#, + None, + ), + ("expect(1).toBe(1);", None), + ("{expect(1).toBe(1)}", None), + ( + " + each([ + [1, 1, 2], + [1, 2, 3], + [2, 1, 3], + ]).test('returns the result of adding %d to %d', (a, b, expected) => { + expect(a + b).toBe(expected); + });", + Some(serde_json::json!([{ "additionalTestBlockFunctions": ["test"] }])), + ), + ]; + + Tester::new(NoStandaloneExpect::NAME, NoStandaloneExpect::PLUGIN, pass, fail) + .with_vitest_plugin(true) + .with_snapshot_suffix("vitest") + .test_and_snapshot(); +} diff --git a/crates/oxc_linter/src/utils/mod.rs b/crates/oxc_linter/src/utils/mod.rs index c520ca4173377..f36272f9e53db 100644 --- a/crates/oxc_linter/src/utils/mod.rs +++ b/crates/oxc_linter/src/utils/mod.rs @@ -34,6 +34,7 @@ const VITEST_COMPATIBLE_JEST_RULES: phf::Set<&'static str> = phf::phf_set! { "no-interpolation-in-snapshots", "no-restricted-jest-methods", "no-restricted-matchers", + "no-standalone-expect", "no-test-prefixes", "no-test-return-statement", "prefer-comparison-matcher",