diff --git a/crates/oxc_linter/src/rules/jest/max_expects.rs b/crates/oxc_linter/src/rules/jest/max_expects.rs index 4f7aed21868cf..acf96758724b8 100644 --- a/crates/oxc_linter/src/rules/jest/max_expects.rs +++ b/crates/oxc_linter/src/rules/jest/max_expects.rs @@ -121,7 +121,7 @@ impl MaxExpects { fn test() { use crate::tester::Tester; - let pass = vec![ + let mut pass = vec![ ("test('should pass')", None), ("test('should pass', () => {})", None), ("test.skip('should pass', () => {})", None), @@ -358,7 +358,7 @@ fn test() { ), ]; - let fail = vec![ + let mut fail = vec![ ( " test('should not pass', function () { @@ -471,6 +471,88 @@ fn test() { ), ]; + let pass_vitest = vec![ + ("test('should pass')", None), + ("test('should pass', () => {})", None), + ("test.skip('should pass', () => {})", None), + ( + "test('should pass', () => { + expect(true).toBeDefined(); + expect(true).toBeDefined(); + expect(true).toBeDefined(); + expect(true).toBeDefined(); + expect(true).toBeDefined(); + });", + None, + ), + ( + "test('should pass', () => { + expect(true).toBeDefined(); + expect(true).toBeDefined(); + expect(true).toBeDefined(); + expect(true).toBeDefined(); + expect(true).toBeDefined(); + });", + None, + ), + ( + " test('should pass', async () => { + expect.hasAssertions(); + + expect(true).toBeDefined(); + expect(true).toBeDefined(); + expect(true).toBeDefined(); + expect(true).toBeDefined(); + expect(true).toEqual(expect.any(Boolean)); + });", + None, + ), + ]; + + let fail_vitest = vec![ + ( + "test('should not pass', function () { + expect(true).toBeDefined(); + expect(true).toBeDefined(); + expect(true).toBeDefined(); + expect(true).toBeDefined(); + expect(true).toBeDefined(); + expect(true).toBeDefined(); + }); + ", + None, + ), + ( + "test('should not pass', () => { + expect(true).toBeDefined(); + expect(true).toBeDefined(); + expect(true).toBeDefined(); + expect(true).toBeDefined(); + expect(true).toBeDefined(); + expect(true).toBeDefined(); + }); + test('should not pass', () => { + expect(true).toBeDefined(); + expect(true).toBeDefined(); + expect(true).toBeDefined(); + expect(true).toBeDefined(); + expect(true).toBeDefined(); + expect(true).toBeDefined(); + });", + None, + ), + ( + "test('should not pass', () => { + expect(true).toBeDefined(); + expect(true).toBeDefined(); + });", + Some(serde_json::json!([{ "max": 1 }])), + ), + ]; + + pass.extend(pass_vitest); + fail.extend(fail_vitest); + Tester::new(MaxExpects::NAME, MaxExpects::PLUGIN, pass, fail) .with_jest_plugin(true) .test_and_snapshot(); diff --git a/crates/oxc_linter/src/rules/jest/max_nested_describe.rs b/crates/oxc_linter/src/rules/jest/max_nested_describe.rs index 6f181bd1f5d69..09addf14e6083 100644 --- a/crates/oxc_linter/src/rules/jest/max_nested_describe.rs +++ b/crates/oxc_linter/src/rules/jest/max_nested_describe.rs @@ -181,7 +181,7 @@ impl MaxNestedDescribe { fn test() { use crate::tester::Tester; - let pass = vec![ + let mut pass = vec![ ( " describe('foo', function() { @@ -287,7 +287,7 @@ fn test() { ), ]; - let fail = vec![ + let mut fail = vec![ ( " describe('foo', function() { @@ -397,6 +397,91 @@ fn test() { ), ]; + let pass_vitest = vec![ + ( + " + describe('another suite', () => { + describe('another suite', () => { + it('skipped test', () => { + // Test skipped, as tests are running in Only mode + assert.equal(Math.sqrt(4), 3) + }) + + it.only('test', () => { + // Only this test (and others marked with only) are run + assert.equal(Math.sqrt(4), 2) + }) + }) + }) + ", + None, + ), + ( + " + describe('another suite', () => { + describe('another suite', () => { + describe('another suite', () => { + describe('another suite', () => { + + }) + }) + }) + }) + ", + None, + ), + ]; + + let fail_vitest = vec![ + ( + " + describe('another suite', () => { + describe('another suite', () => { + describe('another suite', () => { + describe('another suite', () => { + describe('another suite', () => { + describe('another suite', () => { + + }) + }) + }) + }) + }) + }) + ", + None, + ), + ( + " + describe('another suite', () => { + describe('another suite', () => { + describe('another suite', () => { + describe('another suite', () => { + describe('another suite', () => { + describe('another suite', () => { + it('skipped test', () => { + // Test skipped, as tests are running in Only mode + assert.equal(Math.sqrt(4), 3) + }) + + it.only('test', () => { + // Only this test (and others marked with only) are run + assert.equal(Math.sqrt(4), 2) + }) + }) + }) + }) + }) + }) + }) + ", + None, + ), + ]; + + pass.extend(pass_vitest); + fail.extend(fail_vitest); + Tester::new(MaxNestedDescribe::NAME, MaxNestedDescribe::PLUGIN, pass, fail) .with_jest_plugin(true) .test_and_snapshot(); diff --git a/crates/oxc_linter/src/rules/jest/no_duplicate_hooks.rs b/crates/oxc_linter/src/rules/jest/no_duplicate_hooks.rs index 6e083842b407e..5b67ce0407d17 100644 --- a/crates/oxc_linter/src/rules/jest/no_duplicate_hooks.rs +++ b/crates/oxc_linter/src/rules/jest/no_duplicate_hooks.rs @@ -189,7 +189,7 @@ impl NoDuplicateHooks { fn test() { use crate::tester::Tester; - let pass = vec![ + let mut pass = vec![ ( " describe(\"foo\", () => { @@ -319,7 +319,7 @@ fn test() { ), ]; - let fail = vec![ + let mut fail = vec![ ( " describe(\"foo\", () => { @@ -555,6 +555,189 @@ fn test() { ), ]; + let pass_vitest = vec![ + ( + r#" + describe("foo", () => { + beforeEach(() => {}) + test("bar", () => { + someFn(); + }) + }) + "#, + None, + ), + ( + r#" + beforeEach(() => {}) + test("bar", () => { + someFn(); + }) + "#, + None, + ), + ( + r#" + describe("foo", () => { + beforeAll(() => {}), + beforeEach(() => {}) + afterEach(() => {}) + afterAll(() => {}) + + test("bar", () => { + someFn(); + }) + }) + "#, + None, + ), + ( + r#" + describe.skip("foo", () => { + beforeEach(() => {}), + beforeAll(() => {}), + test("bar", () => { + someFn(); + }) + }) + describe("foo", () => { + beforeEach(() => {}), + beforeAll(() => {}), + test("bar", () => { + someFn(); + }) + }) + "#, + None, + ), + ( + r#" + describe("foo", () => { + beforeEach(() => {}), + test("bar", () => { + someFn(); + }) + describe("inner_foo", () => { + beforeEach(() => {}) + test("inner bar", () => { + someFn(); + }) + }) + }) + "#, + None, + ), + ( + " + describe.each(['hello'])('%s', () => { + beforeEach(() => {}); + it('is fine', () => {}); + }); + ", + None, + ), + ]; + + let fail_vitest = vec![ + ( + r#" + describe("foo", () => { + beforeEach(() => {}), + beforeEach(() => {}), + test("bar", () => { + someFn(); + }) + }) + "#, + None, + ), + ( + r#" + describe.skip("foo", () => { + afterEach(() => {}), + afterEach(() => {}), + test("bar", () => { + someFn(); + }) + }) + "#, + None, + ), + ( + r#" + describe.skip("foo", () => { + beforeEach(() => {}), + beforeAll(() => {}), + test("bar", () => { + someFn(); + }) + }) + describe("foo", () => { + beforeEach(() => {}), + beforeEach(() => {}), + beforeAll(() => {}), + test("bar", () => { + someFn(); + }) + }) + "#, + None, + ), + ( + r#" + describe.skip("foo", () => { + beforeEach(() => {}), + beforeAll(() => {}), + test("bar", () => { + someFn(); + }) + }) + describe("foo", () => { + beforeEach(() => {}), + beforeEach(() => {}), + beforeAll(() => {}), + test("bar", () => { + someFn(); + }) + }) + "#, + None, + ), + ( + " + describe.each(['hello'])('%s', () => { + beforeEach(() => {}); + beforeEach(() => {}); + + it('is not fine', () => {}); + }); + ", + None, + ), + ( + " + describe('something', () => { + describe.each(['hello'])('%s', () => { + beforeEach(() => {}); + + it('is fine', () => {}); + }); + + describe.each(['world'])('%s', () => { + beforeEach(() => {}); + beforeEach(() => {}); + + it('is not fine', () => {}); + }); + }); + ", + None, + ), + ]; + + pass.extend(pass_vitest); + fail.extend(fail_vitest); + Tester::new(NoDuplicateHooks::NAME, NoDuplicateHooks::PLUGIN, pass, fail) .with_jest_plugin(true) .test_and_snapshot(); diff --git a/crates/oxc_linter/src/rules/jest/no_hooks.rs b/crates/oxc_linter/src/rules/jest/no_hooks.rs index 28aa6e23e56c3..46adcac92817d 100644 --- a/crates/oxc_linter/src/rules/jest/no_hooks.rs +++ b/crates/oxc_linter/src/rules/jest/no_hooks.rs @@ -131,7 +131,7 @@ impl NoHooks { fn test() { use crate::tester::Tester; - let pass = vec![ + let mut pass = vec![ ("test(\"foo\")", None), ("describe(\"foo\", () => { it(\"bar\") })", None), ("test(\"foo\", () => { expect(subject.beforeEach()).toBe(true) })", None), @@ -142,7 +142,7 @@ fn test() { ("test(\"foo\")", Some(serde_json::json!([{ "allow": "undefined" }]))), ]; - let fail = vec![ + let mut fail = vec![ ("beforeAll(() => {})", None), ("beforeEach(() => {})", None), ("afterAll(() => {})", None), @@ -162,6 +162,39 @@ fn test() { ), ]; + let pass_vitest = vec![ + (r#"test("foo")"#, None), + (r#"describe("foo", () => { it("bar") })"#, None), + (r#"test("foo", () => { expect(subject.beforeEach()).toBe(true) })"#, None), + ( + "afterEach(() => {}); afterAll(() => {});", + Some(serde_json::json!([{ "allow": ["afterEach", "afterAll"] }])), + ), + (r#"test("foo")"#, Some(serde_json::json!([{ "allow": null }]))), + ]; + + let fail_vitest = vec![ + ("beforeAll(() => {})", None), + ("beforeEach(() => {})", None), + ("afterAll(() => {})", None), + ("afterEach(() => {})", None), + ( + "beforeEach(() => {}); afterEach(() => { vi.resetModules() });", + Some(serde_json::json!([{ "allow": ["afterEach"] }])), + ), + ( + " + import { beforeEach as afterEach, afterEach as beforeEach, vi } from 'vitest'; + afterEach(() => {}); + beforeEach(() => { vi.resetModules() }); + ", + Some(serde_json::json!([{ "allow": ["afterEach"] }])), + ), // { "parserOptions": { "sourceType": "module" } } + ]; + + pass.extend(pass_vitest); + fail.extend(fail_vitest); + Tester::new(NoHooks::NAME, NoHooks::PLUGIN, pass, fail) .with_jest_plugin(true) .test_and_snapshot(); diff --git a/crates/oxc_linter/src/rules/jest/no_interpolation_in_snapshots.rs b/crates/oxc_linter/src/rules/jest/no_interpolation_in_snapshots.rs index 5320efe267738..8a991c6f51bf9 100644 --- a/crates/oxc_linter/src/rules/jest/no_interpolation_in_snapshots.rs +++ b/crates/oxc_linter/src/rules/jest/no_interpolation_in_snapshots.rs @@ -98,6 +98,8 @@ fn run<'a>(possible_jest_node: &PossibleJestNode<'a, '_>, ctx: &LintContext<'a>) fn test() { use crate::tester::Tester; + // Note: Both Jest and Vitest share the same unit tests + let pass = vec![ ("expect('something').toEqual('else');", None), ("expect(something).toMatchInlineSnapshot();", None), diff --git a/crates/oxc_linter/src/rules/jest/no_restricted_matchers.rs b/crates/oxc_linter/src/rules/jest/no_restricted_matchers.rs index 31bb51c18be44..cb2f3cb44f508 100644 --- a/crates/oxc_linter/src/rules/jest/no_restricted_matchers.rs +++ b/crates/oxc_linter/src/rules/jest/no_restricted_matchers.rs @@ -170,6 +170,8 @@ impl NoRestrictedMatchers { fn test() { use crate::tester::Tester; + // Note: Both Jest and Vitest share the same unit tests + let pass = vec![ ("expect(a).toHaveBeenCalled()", None), ("expect(a).not.toHaveBeenCalled()", None), diff --git a/crates/oxc_linter/src/rules/jest/no_test_return_statement.rs b/crates/oxc_linter/src/rules/jest/no_test_return_statement.rs index 3a91b4dcfd225..12058129c8831 100644 --- a/crates/oxc_linter/src/rules/jest/no_test_return_statement.rs +++ b/crates/oxc_linter/src/rules/jest/no_test_return_statement.rs @@ -130,7 +130,10 @@ fn check_test_return_statement<'a>(func_body: &OBox<'_, FunctionBody<'a>>, ctx: fn test() { use crate::tester::Tester; + // Note: Both Jest and Vitest share the same unit tests + let pass = vec![ + ("it('noop', () => {});", None), ("test('noop', () => {});", None), ("test('one', () => expect(1).toBe(1));", None), ("test('empty')", None), diff --git a/crates/oxc_linter/src/rules/jest/prefer_comparison_matcher.rs b/crates/oxc_linter/src/rules/jest/prefer_comparison_matcher.rs index ef89db166c18b..03dfaa54b91be 100644 --- a/crates/oxc_linter/src/rules/jest/prefer_comparison_matcher.rs +++ b/crates/oxc_linter/src/rules/jest/prefer_comparison_matcher.rs @@ -469,6 +469,47 @@ fn test() { fix.push((case.as_str(), fixer.as_str(), None)); } + let pass_vitest = vec![ + ("expect.hasAssertions", None), + ("expect.hasAssertions()", None), + ("expect.assertions(1)", None), + ("expect(true).toBe(...true)", None), + ("expect()", None), + ("expect({}).toStrictEqual({})", None), + ("expect(a === b).toBe(true)", None), + ("expect(a !== 2).toStrictEqual(true)", None), + ("expect(a === b).not.toEqual(true)", None), + (r#"expect(a !== "string").toStrictEqual(true)"#, None), + ("expect(5 != a).toBe(true)", None), + (r#"expect(a == "string").toBe(true)"#, None), + (r#"expect(a == "string").not.toBe(true)"#, None), + ("expect().fail('Should not succeed a HTTPS proxy request.');", None), + ]; + + let fail_vitest = vec![ + ("expect(a > b).toBe(true)", None), + ("expect(a < b).toBe(true)", None), + ("expect(a >= b).toBe(true)", None), + ("expect(a <= b).toBe(true)", None), + ("expect(a > b).not.toBe(true)", None), + ("expect(a < b).not.toBe(true)", None), + ("expect(a >= b).not.toBe(true)", None), + ]; + + let fix_vitest = vec![ + ("expect(a > b).toBe(true)", "expect(a).toBeGreaterThan(b)", None), + ("expect(a < b).toBe(true)", "expect(a).toBeLessThan(b)", None), + ("expect(a >= b).toBe(true)", "expect(a).toBeGreaterThanOrEqual(b)", None), + ("expect(a <= b).toBe(true)", "expect(a).toBeLessThanOrEqual(b)", None), + ("expect(a > b).not.toBe(true)", "expect(a).toBeLessThanOrEqual(b)", None), + ("expect(a < b).not.toBe(true)", "expect(a).toBeGreaterThanOrEqual(b)", None), + ("expect(a >= b).not.toBe(true)", "expect(a).toBeLessThan(b)", None), + ]; + + pass.extend(pass_vitest); + fail.extend(fail_vitest); + fix.extend(fix_vitest); + Tester::new(PreferComparisonMatcher::NAME, PreferComparisonMatcher::PLUGIN, pass, fail) .with_jest_plugin(true) .expect_fix(fix) diff --git a/crates/oxc_linter/src/rules/jest/prefer_equality_matcher.rs b/crates/oxc_linter/src/rules/jest/prefer_equality_matcher.rs index 3fee8decaa7fa..75d62c6f01d07 100644 --- a/crates/oxc_linter/src/rules/jest/prefer_equality_matcher.rs +++ b/crates/oxc_linter/src/rules/jest/prefer_equality_matcher.rs @@ -99,7 +99,7 @@ impl PreferEqualityMatcher { fn test() { use crate::tester::Tester; - let pass = vec![ + let mut pass = vec![ ("expect.hasAssertions", None), ("expect.hasAssertions()", None), ("expect.assertions(1)", None), @@ -109,7 +109,7 @@ fn test() { ("expect(a == b).toBe(true)", None), ]; - let fail = vec![ + let mut fail = vec![ ("expect(a !== b).toBe(true)", None), ("expect(a !== b).toBe(false)", None), ("expect(a !== b).resolves.toBe(true)", None), @@ -120,6 +120,48 @@ fn test() { ("expect(a !== b).resolves.not.toBe(false)", None), ]; + let pass_vitest = vec![ + ("expect.hasAssertions", None), + ("expect.hasAssertions()", None), + ("expect.assertions(1)", None), + ("expect(true).toBe(...true)", None), + ("expect(a == 1).toBe(true)", None), + ("expect(1 == a).toBe(true)", None), + ("expect(a == b).toBe(true)", None), + ("expect.hasAssertions", None), + ("expect.hasAssertions()", None), + ("expect.assertions(1)", None), + ("expect(true).toBe(...true)", None), + ("expect(a != 1).toBe(true)", None), + ("expect(1 != a).toBe(true)", None), + ("expect(a != b).toBe(true)", None), + ]; + + let fail_vitest = vec![ + ("expect(a === b).toBe(true);", None), + ("expect(a === b,).toBe(true,);", None), // { "parserOptions": { "ecmaVersion": 2017 } }, + ("expect(a === b).toBe(false);", None), + ("expect(a === b).resolves.toBe(true);", None), + ("expect(a === b).resolves.toBe(false);", None), + ("expect(a === b).not.toBe(true);", None), + ("expect(a === b).not.toBe(false);", None), + ("expect(a === b).resolves.not.toBe(true);", None), + ("expect(a === b).resolves.not.toBe(false);", None), + (r#"expect(a === b)["resolves"].not.toBe(false);"#, None), + (r#"expect(a === b)["resolves"]["not"]["toBe"](false);"#, None), + ("expect(a !== b).toBe(true);", None), + ("expect(a !== b).toBe(false);", None), + ("expect(a !== b).resolves.toBe(true);", None), + ("expect(a !== b).resolves.toBe(false);", None), + ("expect(a !== b).not.toBe(true);", None), + ("expect(a !== b).not.toBe(false);", None), + ("expect(a !== b).resolves.not.toBe(true);", None), + ("expect(a !== b).resolves.not.toBe(false);", None), + ]; + + pass.extend(pass_vitest); + fail.extend(fail_vitest); + Tester::new(PreferEqualityMatcher::NAME, PreferEqualityMatcher::PLUGIN, pass, fail) .with_jest_plugin(true) .test_and_snapshot(); diff --git a/crates/oxc_linter/src/rules/jest/prefer_expect_resolves.rs b/crates/oxc_linter/src/rules/jest/prefer_expect_resolves.rs index 1236e1eb529f6..f6afa711ff156 100644 --- a/crates/oxc_linter/src/rules/jest/prefer_expect_resolves.rs +++ b/crates/oxc_linter/src/rules/jest/prefer_expect_resolves.rs @@ -150,6 +150,8 @@ impl PreferExpectResolves { fn tests() { use crate::tester::Tester; + // Note: Both Jest and Vitest share the same unit tests + let pass = vec![ ("expect.hasAssertions()", None), ( @@ -179,6 +181,7 @@ fn tests() { ", None, ), + ("expect().nothing();", None), ]; let fail = vec![ diff --git a/crates/oxc_linter/src/rules/jest/prefer_hooks_on_top.rs b/crates/oxc_linter/src/rules/jest/prefer_hooks_on_top.rs index 4522ad64cce82..7cdd4fc28641e 100644 --- a/crates/oxc_linter/src/rules/jest/prefer_hooks_on_top.rs +++ b/crates/oxc_linter/src/rules/jest/prefer_hooks_on_top.rs @@ -192,6 +192,8 @@ impl PreferHooksOnTop { fn test() { use crate::tester::Tester; + // Note: Both Jest and Vitest share the same unit tests + let pass = vec![ ( " diff --git a/crates/oxc_linter/src/rules/jest/prefer_mock_promise_shorthand.rs b/crates/oxc_linter/src/rules/jest/prefer_mock_promise_shorthand.rs index 48fadca7008ac..c356d05da0a96 100644 --- a/crates/oxc_linter/src/rules/jest/prefer_mock_promise_shorthand.rs +++ b/crates/oxc_linter/src/rules/jest/prefer_mock_promise_shorthand.rs @@ -189,7 +189,7 @@ impl PreferMockPromiseShorthand { fn test() { use crate::tester::Tester; - let pass = vec![ + let mut pass = vec![ ("describe()", None), ("it()", None), ("describe.skip()", None), @@ -248,7 +248,7 @@ fn test() { ("aVariable.mockReturnValue(Promise.all([1, 2, 3]));", None), ]; - let fail = vec![ + let mut fail = vec![ ("aVariable.mockImplementation(() => Promise.reject(42, 25))", None), ("jest.fn().mockImplementation(() => Promise.reject(42))", None), ("aVariable.mockImplementation(() => Promise.resolve(42))", None), @@ -310,7 +310,7 @@ fn test() { ), ]; - let fix = vec![ + let mut fix = vec![ ( "jest.fn().mockImplementation(() => Promise.resolve(42))", "jest.fn().mockResolvedValue(42)", @@ -431,6 +431,95 @@ fn test() { // ), ]; + let pass_vitest = vec![ + ("describe()", None), + ("it()", None), + ("describe.skip()", None), + ("it.skip()", None), + ("test()", None), + ("test.skip()", None), + ("var appliedOnly = describe.only; appliedOnly.apply(describe)", None), + ("var calledOnly = it.only; calledOnly.call(it)", None), + ("it.each()()", None), + ("it.each`table`()", None), + ("test.each()()", None), + ("test.each`table`()", None), + ("test.concurrent()", None), + ("vi.fn().mockResolvedValue(42)", None), + ("vi.fn(() => Promise.resolve(42))", None), + ("vi.fn(() => Promise.reject(42))", None), + ("aVariable.mockImplementation", None), + ("aVariable.mockImplementation()", None), + ("aVariable.mockImplementation([])", None), + ("aVariable.mockImplementation(() => {})", None), + ("aVariable.mockImplementation(() => [])", None), + ("aVariable.mockReturnValue(() => Promise.resolve(1))", None), + ("aVariable.mockReturnValue(Promise.resolve(1).then(() => 1))", None), + ("aVariable.mockReturnValue(Promise.reject(1).then(() => 1))", None), + ("aVariable.mockReturnValue(Promise.reject().then(() => 1))", None), + ("aVariable.mockReturnValue(new Promise(resolve => resolve(1)))", None), + ("aVariable.mockReturnValue(new Promise((_, reject) => reject(1)))", None), + ("vi.spyOn(Thingy, 'method').mockImplementation(param => Promise.resolve(param));", None), + ]; + + let fail_vitest = vec![ + ("vi.fn().mockImplementation(() => Promise.resolve(42))", None), + ("vi.fn().mockImplementation(() => Promise.reject(42))", None), + ("aVariable.mockImplementation(() => Promise.resolve(42))", None), + ("aVariable.mockImplementation(() => { return Promise.resolve(42) })", None), + ("aVariable.mockImplementation(() => Promise.reject(42))", None), + ("aVariable.mockImplementation(() => Promise.reject(42),)", None), // { "parserOptions": { "ecmaVersion": 2017 } }, + ("aVariable.mockImplementationOnce(() => Promise.resolve(42))", None), + ("aVariable.mockImplementationOnce(() => Promise.reject(42))", None), + ("vi.fn().mockReturnValue(Promise.resolve(42))", None), + ("vi.fn().mockReturnValue(Promise.reject(42))", None), + ("aVariable.mockReturnValue(Promise.resolve(42))", None), + ("aVariable.mockReturnValue(Promise.reject(42))", None), + ("aVariable.mockReturnValueOnce(Promise.resolve(42))", None), + ("aVariable.mockReturnValueOnce(Promise.reject(42))", None), + ("aVariable.mockReturnValue(Promise.resolve({ target: 'world', message: 'hello' }))", None), + ("aVariable.mockImplementation(() => Promise.reject(42)).mockImplementation(() => Promise.resolve(42)).mockReturnValue(Promise.reject(42))", None), + ("aVariable.mockReturnValueOnce(Promise.reject(42)).mockImplementation(() => Promise.resolve(42)).mockReturnValueOnce(Promise.reject(42))", None), + ("aVariable.mockReturnValueOnce(Promise.reject(new Error('oh noes!')))", None), + ("vi.fn().mockReturnValue(Promise.resolve(42), xyz)", None), + ("vi.fn().mockImplementation(() => Promise.reject(42), xyz)", None), + ("aVariable.mockReturnValueOnce(Promise.resolve(42, xyz))", None), + ("aVariable.mockReturnValueOnce(Promise.resolve())", None), + ]; + + let fix_vitest = vec![ + ("vi.fn().mockImplementation(() => Promise.resolve(42))", "vi.fn().mockResolvedValue(42)", None), + ("vi.fn().mockImplementation(() => Promise.reject(42))", "vi.fn().mockRejectedValue(42)", None), + ("aVariable.mockImplementation(() => Promise.resolve(42))", "aVariable.mockResolvedValue(42)", None), + ("aVariable.mockImplementation(() => { return Promise.resolve(42) })", "aVariable.mockResolvedValue(42)", None), + ("aVariable.mockImplementation(() => Promise.reject(42))", "aVariable.mockRejectedValue(42)", None), + ("aVariable.mockImplementation(() => Promise.reject(42),)", "aVariable.mockRejectedValue(42,)", None), + ("aVariable.mockImplementationOnce(() => Promise.resolve(42))", "aVariable.mockResolvedValueOnce(42)", None), + ("aVariable.mockImplementationOnce(() => Promise.reject(42))", "aVariable.mockRejectedValueOnce(42)", None), + ("vi.fn().mockReturnValue(Promise.resolve(42))", "vi.fn().mockResolvedValue(42)", None), + ("vi.fn().mockReturnValue(Promise.reject(42))", "vi.fn().mockRejectedValue(42)", None), + ("aVariable.mockReturnValue(Promise.resolve(42))", "aVariable.mockResolvedValue(42)", None), + ("aVariable.mockReturnValue(Promise.reject(42))", "aVariable.mockRejectedValue(42)", None), + ("aVariable.mockReturnValueOnce(Promise.resolve(42))", "aVariable.mockResolvedValueOnce(42)", None), + ("aVariable.mockReturnValueOnce(Promise.reject(42))", "aVariable.mockRejectedValueOnce(42)", None), + // Todo: Fixed + // ( + // "aVariable.mockReturnValue(Promise.resolve({ target: 'world', message: 'hello' }))", + // "aVariable.mockResolvedValue({ target: 'world', message: 'hello' })", + // None, + // ), + ("aVariable.mockImplementation(() => Promise.reject(42)).mockImplementation(() => Promise.resolve(42)).mockReturnValue(Promise.reject(42))", "aVariable.mockRejectedValue(42).mockResolvedValue(42).mockRejectedValue(42)", None), + ("aVariable.mockReturnValueOnce(Promise.reject(42)).mockImplementation(() => Promise.resolve(42)).mockReturnValueOnce(Promise.reject(42))", "aVariable.mockRejectedValueOnce(42).mockResolvedValue(42).mockRejectedValueOnce(42)", None), + ("aVariable.mockReturnValueOnce(Promise.reject(new Error('oh noes!')))", "aVariable.mockRejectedValueOnce(new Error('oh noes!'))", None), + ("vi.fn().mockReturnValue(Promise.resolve(42), xyz)", "vi.fn().mockResolvedValue(42, xyz)", None), + ("vi.fn().mockImplementation(() => Promise.reject(42), xyz)", "vi.fn().mockRejectedValue(42, xyz)", None), + ("aVariable.mockReturnValueOnce(Promise.resolve())", "aVariable.mockResolvedValueOnce(undefined)", None) + ]; + + pass.extend(pass_vitest); + fail.extend(fail_vitest); + fix.extend(fix_vitest); + Tester::new(PreferMockPromiseShorthand::NAME, PreferMockPromiseShorthand::PLUGIN, pass, fail) .with_jest_plugin(true) .expect_fix(fix) diff --git a/crates/oxc_linter/src/rules/jest/prefer_strict_equal.rs b/crates/oxc_linter/src/rules/jest/prefer_strict_equal.rs index 8f8b70a43384d..b638bd4d46e80 100644 --- a/crates/oxc_linter/src/rules/jest/prefer_strict_equal.rs +++ b/crates/oxc_linter/src/rules/jest/prefer_strict_equal.rs @@ -75,6 +75,8 @@ impl PreferStrictEqual { fn test() { use crate::tester::Tester; + // Note: Both Jest and Vitest share the same unit tests + let pass = vec![ ("expect(something).toStrictEqual(somethingElse);", None), ("a().toEqual('b')", None), diff --git a/crates/oxc_linter/src/rules/jest/prefer_to_have_length.rs b/crates/oxc_linter/src/rules/jest/prefer_to_have_length.rs index bad5020dd7e5d..1576827faacb3 100644 --- a/crates/oxc_linter/src/rules/jest/prefer_to_have_length.rs +++ b/crates/oxc_linter/src/rules/jest/prefer_to_have_length.rs @@ -191,6 +191,8 @@ impl PreferToHaveLength { fn tests() { use crate::tester::Tester; + // Note: Both Jest and Vitest share the same unit tests + let pass = vec![ ("expect.hasAssertions", None), ("expect.hasAssertions()", None), @@ -202,6 +204,7 @@ fn tests() { ("expect(user.getUserName(5)).resolves.toEqual('Paul')", None), ("expect(user.getUserName(5)).rejects.toEqual('Paul')", None), ("expect(a);", None), + ("expect().toBe();", None), ]; let fail = vec![ @@ -229,6 +232,7 @@ fn tests() { let fix = vec![ ("expect(files[\"length\"]).not.toBe(1);", "expect(files).not.toHaveLength(1);", None), + (r#"expect(files["length"]).toBe(1,);"#, "expect(files).toHaveLength(1,);", None), ( "expect(files[\"length\"])[\"resolves\"].toBe(1,);", "expect(files)[\"resolves\"].toHaveLength(1,);", diff --git a/crates/oxc_linter/src/rules/jest/prefer_todo.rs b/crates/oxc_linter/src/rules/jest/prefer_todo.rs index 28eaa2ce0768d..6e0ee4d6dc30f 100644 --- a/crates/oxc_linter/src/rules/jest/prefer_todo.rs +++ b/crates/oxc_linter/src/rules/jest/prefer_todo.rs @@ -183,6 +183,8 @@ fn build_code<'a>(fixer: RuleFixer<'_, 'a>, expr: &CallExpression<'a>) -> RuleFi fn tests() { use crate::tester::Tester; + // Note: Both Jest and Vitest share the same unit tests + let pass = vec![ ("test()", None), ("test.concurrent()", None), @@ -227,6 +229,8 @@ fn tests() { ("test(`i need to write this test`);", "test.todo(`i need to write this test`);", None), ("it.skip('foo', function () {})", "it.todo('foo')", None), ("it(`i need to write this test`, () => {})", "it.todo(`i need to write this test`)", None), + ("it('foo', function () {})", "it.todo('foo')", None), + ("it('foo', () => {})", "it.todo('foo')", None), ( "test.skip('i need to write this test', () => {});", "test.todo('i need to write this test');", diff --git a/crates/oxc_linter/src/rules/jest/require_to_throw_message.rs b/crates/oxc_linter/src/rules/jest/require_to_throw_message.rs index 50e20c6001134..a7b24bd52f67b 100644 --- a/crates/oxc_linter/src/rules/jest/require_to_throw_message.rs +++ b/crates/oxc_linter/src/rules/jest/require_to_throw_message.rs @@ -91,6 +91,8 @@ impl RequireToThrowMessage { fn test() { use crate::tester::Tester; + // Note: Both Jest and Vitest share the same unit tests + let pass = vec![ // String ("expect(() => { throw new Error('a'); }).toThrow('a');", None), diff --git a/crates/oxc_linter/src/rules/jest/require_top_level_describe.rs b/crates/oxc_linter/src/rules/jest/require_top_level_describe.rs index 7d7722209eedc..8699ea65e4259 100644 --- a/crates/oxc_linter/src/rules/jest/require_top_level_describe.rs +++ b/crates/oxc_linter/src/rules/jest/require_top_level_describe.rs @@ -194,6 +194,8 @@ impl RequireTopLevelDescribe { fn test() { use crate::tester::Tester; + // Note: Both Jest and Vitest share the same unit tests + let pass = vec![ ("it.each()", None), ("describe(\"test suite\", () => { test(\"my test\") });", None), diff --git a/crates/oxc_linter/src/snapshots/jest_max_expects.snap b/crates/oxc_linter/src/snapshots/jest_max_expects.snap index 5f94658280d39..9cb7e6e91807c 100644 --- a/crates/oxc_linter/src/snapshots/jest_max_expects.snap +++ b/crates/oxc_linter/src/snapshots/jest_max_expects.snap @@ -82,3 +82,39 @@ snapshot_kind: text 5 │ }); ╰──── help: Too many assertion calls (2) - maximum allowed is 1 + + ⚠ eslint-plugin-jest(max-expects): Enforces a maximum number assertion calls in a test body. + ╭─[max_expects.tsx:7:11] + 6 │ expect(true).toBeDefined(); + 7 │ expect(true).toBeDefined(); + · ────── + 8 │ }); + ╰──── + help: Too many assertion calls (6) - maximum allowed is 5 + + ⚠ eslint-plugin-jest(max-expects): Enforces a maximum number assertion calls in a test body. + ╭─[max_expects.tsx:7:10] + 6 │ expect(true).toBeDefined(); + 7 │ expect(true).toBeDefined(); + · ────── + 8 │ }); + ╰──── + help: Too many assertion calls (6) - maximum allowed is 5 + + ⚠ eslint-plugin-jest(max-expects): Enforces a maximum number assertion calls in a test body. + ╭─[max_expects.tsx:15:10] + 14 │ expect(true).toBeDefined(); + 15 │ expect(true).toBeDefined(); + · ────── + 16 │ }); + ╰──── + help: Too many assertion calls (6) - maximum allowed is 5 + + ⚠ eslint-plugin-jest(max-expects): Enforces a maximum number assertion calls in a test body. + ╭─[max_expects.tsx:3:10] + 2 │ expect(true).toBeDefined(); + 3 │ expect(true).toBeDefined(); + · ────── + 4 │ }); + ╰──── + help: Too many assertion calls (2) - maximum allowed is 1 diff --git a/crates/oxc_linter/src/snapshots/jest_max_nested_describe.snap b/crates/oxc_linter/src/snapshots/jest_max_nested_describe.snap index 47444b8b9d09b..9e128348ec743 100644 --- a/crates/oxc_linter/src/snapshots/jest_max_nested_describe.snap +++ b/crates/oxc_linter/src/snapshots/jest_max_nested_describe.snap @@ -117,3 +117,31 @@ snapshot_kind: text 7 │ }); ╰──── help: Too many nested describe calls (2) - maximum allowed is 1 + + ⚠ eslint-plugin-jest(max-nested-describe): Enforces a maximum depth to nested describe calls. + ╭─[max_nested_describe.tsx:7:37] + 6 │ describe('another suite', () => { + 7 │ ╭─▶ describe('another suite', () => { + 8 │ │ + 9 │ ╰─▶ }) + 10 │ }) + ╰──── + help: Too many nested describe calls (6) - maximum allowed is 5 + + ⚠ eslint-plugin-jest(max-nested-describe): Enforces a maximum depth to nested describe calls. + ╭─[max_nested_describe.tsx:7:37] + 6 │ describe('another suite', () => { + 7 │ ╭─▶ describe('another suite', () => { + 8 │ │ it('skipped test', () => { + 9 │ │ // Test skipped, as tests are running in Only mode + 10 │ │ assert.equal(Math.sqrt(4), 3) + 11 │ │ }) + 12 │ │ + 13 │ │ it.only('test', () => { + 14 │ │ // Only this test (and others marked with only) are run + 15 │ │ assert.equal(Math.sqrt(4), 2) + 16 │ │ }) + 17 │ ╰─▶ }) + 18 │ }) + ╰──── + help: Too many nested describe calls (6) - maximum allowed is 5 diff --git a/crates/oxc_linter/src/snapshots/jest_no_duplicate_hooks.snap b/crates/oxc_linter/src/snapshots/jest_no_duplicate_hooks.snap index 6fcbccad94b96..891dc6e630883 100644 --- a/crates/oxc_linter/src/snapshots/jest_no_duplicate_hooks.snap +++ b/crates/oxc_linter/src/snapshots/jest_no_duplicate_hooks.snap @@ -163,3 +163,57 @@ snapshot_kind: text 12 │ ╰──── help: Describe blocks can only have one of each hook. Consider consolidating the duplicate hooks into a single call. + + ⚠ eslint-plugin-jest(no-duplicate-hooks): Duplicate "beforeEach" in describe block. + ╭─[no_duplicate_hooks.tsx:4:21] + 3 │ beforeEach(() => {}), + 4 │ beforeEach(() => {}), + · ──────────────────── + 5 │ test("bar", () => { + ╰──── + help: Describe blocks can only have one of each hook. Consider consolidating the duplicate hooks into a single call. + + ⚠ eslint-plugin-jest(no-duplicate-hooks): Duplicate "afterEach" in describe block. + ╭─[no_duplicate_hooks.tsx:4:21] + 3 │ afterEach(() => {}), + 4 │ afterEach(() => {}), + · ─────────────────── + 5 │ test("bar", () => { + ╰──── + help: Describe blocks can only have one of each hook. Consider consolidating the duplicate hooks into a single call. + + ⚠ eslint-plugin-jest(no-duplicate-hooks): Duplicate "beforeEach" in describe block. + ╭─[no_duplicate_hooks.tsx:11:21] + 10 │ beforeEach(() => {}), + 11 │ beforeEach(() => {}), + · ──────────────────── + 12 │ beforeAll(() => {}), + ╰──── + help: Describe blocks can only have one of each hook. Consider consolidating the duplicate hooks into a single call. + + ⚠ eslint-plugin-jest(no-duplicate-hooks): Duplicate "beforeEach" in describe block. + ╭─[no_duplicate_hooks.tsx:11:21] + 10 │ beforeEach(() => {}), + 11 │ beforeEach(() => {}), + · ──────────────────── + 12 │ beforeAll(() => {}), + ╰──── + help: Describe blocks can only have one of each hook. Consider consolidating the duplicate hooks into a single call. + + ⚠ eslint-plugin-jest(no-duplicate-hooks): Duplicate "beforeEach" in describe block. + ╭─[no_duplicate_hooks.tsx:4:21] + 3 │ beforeEach(() => {}); + 4 │ beforeEach(() => {}); + · ──────────────────── + 5 │ + ╰──── + help: Describe blocks can only have one of each hook. Consider consolidating the duplicate hooks into a single call. + + ⚠ eslint-plugin-jest(no-duplicate-hooks): Duplicate "beforeEach" in describe block. + ╭─[no_duplicate_hooks.tsx:11:25] + 10 │ beforeEach(() => {}); + 11 │ beforeEach(() => {}); + · ──────────────────── + 12 │ + ╰──── + help: Describe blocks can only have one of each hook. Consider consolidating the duplicate hooks into a single call. diff --git a/crates/oxc_linter/src/snapshots/jest_no_hooks.snap b/crates/oxc_linter/src/snapshots/jest_no_hooks.snap index 1222b6c352b85..0d22da2c3239f 100644 --- a/crates/oxc_linter/src/snapshots/jest_no_hooks.snap +++ b/crates/oxc_linter/src/snapshots/jest_no_hooks.snap @@ -39,3 +39,41 @@ snapshot_kind: text · ────────── 6 │ ╰──── + + ⚠ eslint-plugin-jest(no-hooks): Do not use setup or teardown hooks + ╭─[no_hooks.tsx:1:1] + 1 │ beforeAll(() => {}) + · ───────── + ╰──── + + ⚠ eslint-plugin-jest(no-hooks): Do not use setup or teardown hooks + ╭─[no_hooks.tsx:1:1] + 1 │ beforeEach(() => {}) + · ────────── + ╰──── + + ⚠ eslint-plugin-jest(no-hooks): Do not use setup or teardown hooks + ╭─[no_hooks.tsx:1:1] + 1 │ afterAll(() => {}) + · ──────── + ╰──── + + ⚠ eslint-plugin-jest(no-hooks): Do not use setup or teardown hooks + ╭─[no_hooks.tsx:1:1] + 1 │ afterEach(() => {}) + · ───────── + ╰──── + + ⚠ eslint-plugin-jest(no-hooks): Do not use setup or teardown hooks + ╭─[no_hooks.tsx:1:1] + 1 │ beforeEach(() => {}); afterEach(() => { vi.resetModules() }); + · ────────── + ╰──── + + ⚠ eslint-plugin-jest(no-hooks): Do not use setup or teardown hooks + ╭─[no_hooks.tsx:4:8] + 3 │ afterEach(() => {}); + 4 │ beforeEach(() => { vi.resetModules() }); + · ────────── + 5 │ + ╰──── diff --git a/crates/oxc_linter/src/snapshots/jest_prefer_comparison_matcher.snap b/crates/oxc_linter/src/snapshots/jest_prefer_comparison_matcher.snap index 7bc8b5fc30996..6578bc20f3c27 100644 --- a/crates/oxc_linter/src/snapshots/jest_prefer_comparison_matcher.snap +++ b/crates/oxc_linter/src/snapshots/jest_prefer_comparison_matcher.snap @@ -1261,3 +1261,52 @@ snapshot_kind: text · ─────────────── ╰──── help: Prefer using `"toBeLessThanOrEqual"` instead + + ⚠ eslint-plugin-jest(prefer-comparison-matcher): Suggest using the built-in comparison matchers + ╭─[prefer_comparison_matcher.tsx:1:15] + 1 │ expect(a > b).toBe(true) + · ──── + ╰──── + help: Prefer using `"toBeGreaterThan"` instead + + ⚠ eslint-plugin-jest(prefer-comparison-matcher): Suggest using the built-in comparison matchers + ╭─[prefer_comparison_matcher.tsx:1:15] + 1 │ expect(a < b).toBe(true) + · ──── + ╰──── + help: Prefer using `"toBeLessThan"` instead + + ⚠ eslint-plugin-jest(prefer-comparison-matcher): Suggest using the built-in comparison matchers + ╭─[prefer_comparison_matcher.tsx:1:16] + 1 │ expect(a >= b).toBe(true) + · ──── + ╰──── + help: Prefer using `"toBeGreaterThanOrEqual"` instead + + ⚠ eslint-plugin-jest(prefer-comparison-matcher): Suggest using the built-in comparison matchers + ╭─[prefer_comparison_matcher.tsx:1:16] + 1 │ expect(a <= b).toBe(true) + · ──── + ╰──── + help: Prefer using `"toBeLessThanOrEqual"` instead + + ⚠ eslint-plugin-jest(prefer-comparison-matcher): Suggest using the built-in comparison matchers + ╭─[prefer_comparison_matcher.tsx:1:19] + 1 │ expect(a > b).not.toBe(true) + · ──── + ╰──── + help: Prefer using `"toBeLessThanOrEqual"` instead + + ⚠ eslint-plugin-jest(prefer-comparison-matcher): Suggest using the built-in comparison matchers + ╭─[prefer_comparison_matcher.tsx:1:19] + 1 │ expect(a < b).not.toBe(true) + · ──── + ╰──── + help: Prefer using `"toBeGreaterThanOrEqual"` instead + + ⚠ eslint-plugin-jest(prefer-comparison-matcher): Suggest using the built-in comparison matchers + ╭─[prefer_comparison_matcher.tsx:1:20] + 1 │ expect(a >= b).not.toBe(true) + · ──── + ╰──── + help: Prefer using `"toBeLessThan"` instead diff --git a/crates/oxc_linter/src/snapshots/jest_prefer_equality_matcher.snap b/crates/oxc_linter/src/snapshots/jest_prefer_equality_matcher.snap index 1125db4c2737b..a781997465e8e 100644 --- a/crates/oxc_linter/src/snapshots/jest_prefer_equality_matcher.snap +++ b/crates/oxc_linter/src/snapshots/jest_prefer_equality_matcher.snap @@ -57,3 +57,136 @@ snapshot_kind: text · ──── ╰──── help: Prefer using one of the equality matchers instead + + ⚠ eslint-plugin-jest(prefer-equality-matcher): Suggest using the built-in equality matchers. + ╭─[prefer_equality_matcher.tsx:1:17] + 1 │ expect(a === b).toBe(true); + · ──── + ╰──── + help: Prefer using one of the equality matchers instead + + ⚠ eslint-plugin-jest(prefer-equality-matcher): Suggest using the built-in equality matchers. + ╭─[prefer_equality_matcher.tsx:1:18] + 1 │ expect(a === b,).toBe(true,); + · ──── + ╰──── + help: Prefer using one of the equality matchers instead + + ⚠ eslint-plugin-jest(prefer-equality-matcher): Suggest using the built-in equality matchers. + ╭─[prefer_equality_matcher.tsx:1:17] + 1 │ expect(a === b).toBe(false); + · ──── + ╰──── + help: Prefer using one of the equality matchers instead + + ⚠ eslint-plugin-jest(prefer-equality-matcher): Suggest using the built-in equality matchers. + ╭─[prefer_equality_matcher.tsx:1:26] + 1 │ expect(a === b).resolves.toBe(true); + · ──── + ╰──── + help: Prefer using one of the equality matchers instead + + ⚠ eslint-plugin-jest(prefer-equality-matcher): Suggest using the built-in equality matchers. + ╭─[prefer_equality_matcher.tsx:1:26] + 1 │ expect(a === b).resolves.toBe(false); + · ──── + ╰──── + help: Prefer using one of the equality matchers instead + + ⚠ eslint-plugin-jest(prefer-equality-matcher): Suggest using the built-in equality matchers. + ╭─[prefer_equality_matcher.tsx:1:21] + 1 │ expect(a === b).not.toBe(true); + · ──── + ╰──── + help: Prefer using one of the equality matchers instead + + ⚠ eslint-plugin-jest(prefer-equality-matcher): Suggest using the built-in equality matchers. + ╭─[prefer_equality_matcher.tsx:1:21] + 1 │ expect(a === b).not.toBe(false); + · ──── + ╰──── + help: Prefer using one of the equality matchers instead + + ⚠ eslint-plugin-jest(prefer-equality-matcher): Suggest using the built-in equality matchers. + ╭─[prefer_equality_matcher.tsx:1:30] + 1 │ expect(a === b).resolves.not.toBe(true); + · ──── + ╰──── + help: Prefer using one of the equality matchers instead + + ⚠ eslint-plugin-jest(prefer-equality-matcher): Suggest using the built-in equality matchers. + ╭─[prefer_equality_matcher.tsx:1:30] + 1 │ expect(a === b).resolves.not.toBe(false); + · ──── + ╰──── + help: Prefer using one of the equality matchers instead + + ⚠ eslint-plugin-jest(prefer-equality-matcher): Suggest using the built-in equality matchers. + ╭─[prefer_equality_matcher.tsx:1:33] + 1 │ expect(a === b)["resolves"].not.toBe(false); + · ──── + ╰──── + help: Prefer using one of the equality matchers instead + + ⚠ eslint-plugin-jest(prefer-equality-matcher): Suggest using the built-in equality matchers. + ╭─[prefer_equality_matcher.tsx:1:36] + 1 │ expect(a === b)["resolves"]["not"]["toBe"](false); + · ────── + ╰──── + help: Prefer using one of the equality matchers instead + + ⚠ eslint-plugin-jest(prefer-equality-matcher): Suggest using the built-in equality matchers. + ╭─[prefer_equality_matcher.tsx:1:17] + 1 │ expect(a !== b).toBe(true); + · ──── + ╰──── + help: Prefer using one of the equality matchers instead + + ⚠ eslint-plugin-jest(prefer-equality-matcher): Suggest using the built-in equality matchers. + ╭─[prefer_equality_matcher.tsx:1:17] + 1 │ expect(a !== b).toBe(false); + · ──── + ╰──── + help: Prefer using one of the equality matchers instead + + ⚠ eslint-plugin-jest(prefer-equality-matcher): Suggest using the built-in equality matchers. + ╭─[prefer_equality_matcher.tsx:1:26] + 1 │ expect(a !== b).resolves.toBe(true); + · ──── + ╰──── + help: Prefer using one of the equality matchers instead + + ⚠ eslint-plugin-jest(prefer-equality-matcher): Suggest using the built-in equality matchers. + ╭─[prefer_equality_matcher.tsx:1:26] + 1 │ expect(a !== b).resolves.toBe(false); + · ──── + ╰──── + help: Prefer using one of the equality matchers instead + + ⚠ eslint-plugin-jest(prefer-equality-matcher): Suggest using the built-in equality matchers. + ╭─[prefer_equality_matcher.tsx:1:21] + 1 │ expect(a !== b).not.toBe(true); + · ──── + ╰──── + help: Prefer using one of the equality matchers instead + + ⚠ eslint-plugin-jest(prefer-equality-matcher): Suggest using the built-in equality matchers. + ╭─[prefer_equality_matcher.tsx:1:21] + 1 │ expect(a !== b).not.toBe(false); + · ──── + ╰──── + help: Prefer using one of the equality matchers instead + + ⚠ eslint-plugin-jest(prefer-equality-matcher): Suggest using the built-in equality matchers. + ╭─[prefer_equality_matcher.tsx:1:30] + 1 │ expect(a !== b).resolves.not.toBe(true); + · ──── + ╰──── + help: Prefer using one of the equality matchers instead + + ⚠ eslint-plugin-jest(prefer-equality-matcher): Suggest using the built-in equality matchers. + ╭─[prefer_equality_matcher.tsx:1:30] + 1 │ expect(a !== b).resolves.not.toBe(false); + · ──── + ╰──── + help: Prefer using one of the equality matchers instead diff --git a/crates/oxc_linter/src/snapshots/jest_prefer_mock_promise_shorthand.snap b/crates/oxc_linter/src/snapshots/jest_prefer_mock_promise_shorthand.snap index ee80920509047..129d50656079b 100644 --- a/crates/oxc_linter/src/snapshots/jest_prefer_mock_promise_shorthand.snap +++ b/crates/oxc_linter/src/snapshots/jest_prefer_mock_promise_shorthand.snap @@ -206,3 +206,185 @@ snapshot_kind: text · ─────────────── ╰──── help: Prefer "mockRejectedValue" + + ⚠ eslint-plugin-jest(prefer-mock-promise-shorthand): Prefer mock resolved/rejected shorthands for promises + ╭─[prefer_mock_promise_shorthand.tsx:1:9] + 1 │ vi.fn().mockImplementation(() => Promise.resolve(42)) + · ────────────────── + ╰──── + help: Prefer "mockResolvedValue" + + ⚠ eslint-plugin-jest(prefer-mock-promise-shorthand): Prefer mock resolved/rejected shorthands for promises + ╭─[prefer_mock_promise_shorthand.tsx:1:9] + 1 │ vi.fn().mockImplementation(() => Promise.reject(42)) + · ────────────────── + ╰──── + help: Prefer "mockRejectedValue" + + ⚠ eslint-plugin-jest(prefer-mock-promise-shorthand): Prefer mock resolved/rejected shorthands for promises + ╭─[prefer_mock_promise_shorthand.tsx:1:11] + 1 │ aVariable.mockImplementation(() => Promise.resolve(42)) + · ────────────────── + ╰──── + help: Prefer "mockResolvedValue" + + ⚠ eslint-plugin-jest(prefer-mock-promise-shorthand): Prefer mock resolved/rejected shorthands for promises + ╭─[prefer_mock_promise_shorthand.tsx:1:11] + 1 │ aVariable.mockImplementation(() => { return Promise.resolve(42) }) + · ────────────────── + ╰──── + help: Prefer "mockResolvedValue" + + ⚠ eslint-plugin-jest(prefer-mock-promise-shorthand): Prefer mock resolved/rejected shorthands for promises + ╭─[prefer_mock_promise_shorthand.tsx:1:11] + 1 │ aVariable.mockImplementation(() => Promise.reject(42)) + · ────────────────── + ╰──── + help: Prefer "mockRejectedValue" + + ⚠ eslint-plugin-jest(prefer-mock-promise-shorthand): Prefer mock resolved/rejected shorthands for promises + ╭─[prefer_mock_promise_shorthand.tsx:1:11] + 1 │ aVariable.mockImplementation(() => Promise.reject(42),) + · ────────────────── + ╰──── + help: Prefer "mockRejectedValue" + + ⚠ eslint-plugin-jest(prefer-mock-promise-shorthand): Prefer mock resolved/rejected shorthands for promises + ╭─[prefer_mock_promise_shorthand.tsx:1:11] + 1 │ aVariable.mockImplementationOnce(() => Promise.resolve(42)) + · ────────────────────── + ╰──── + help: Prefer "mockResolvedValueOnce" + + ⚠ eslint-plugin-jest(prefer-mock-promise-shorthand): Prefer mock resolved/rejected shorthands for promises + ╭─[prefer_mock_promise_shorthand.tsx:1:11] + 1 │ aVariable.mockImplementationOnce(() => Promise.reject(42)) + · ────────────────────── + ╰──── + help: Prefer "mockRejectedValueOnce" + + ⚠ eslint-plugin-jest(prefer-mock-promise-shorthand): Prefer mock resolved/rejected shorthands for promises + ╭─[prefer_mock_promise_shorthand.tsx:1:9] + 1 │ vi.fn().mockReturnValue(Promise.resolve(42)) + · ─────────────── + ╰──── + help: Prefer "mockResolvedValue" + + ⚠ eslint-plugin-jest(prefer-mock-promise-shorthand): Prefer mock resolved/rejected shorthands for promises + ╭─[prefer_mock_promise_shorthand.tsx:1:9] + 1 │ vi.fn().mockReturnValue(Promise.reject(42)) + · ─────────────── + ╰──── + help: Prefer "mockRejectedValue" + + ⚠ eslint-plugin-jest(prefer-mock-promise-shorthand): Prefer mock resolved/rejected shorthands for promises + ╭─[prefer_mock_promise_shorthand.tsx:1:11] + 1 │ aVariable.mockReturnValue(Promise.resolve(42)) + · ─────────────── + ╰──── + help: Prefer "mockResolvedValue" + + ⚠ eslint-plugin-jest(prefer-mock-promise-shorthand): Prefer mock resolved/rejected shorthands for promises + ╭─[prefer_mock_promise_shorthand.tsx:1:11] + 1 │ aVariable.mockReturnValue(Promise.reject(42)) + · ─────────────── + ╰──── + help: Prefer "mockRejectedValue" + + ⚠ eslint-plugin-jest(prefer-mock-promise-shorthand): Prefer mock resolved/rejected shorthands for promises + ╭─[prefer_mock_promise_shorthand.tsx:1:11] + 1 │ aVariable.mockReturnValueOnce(Promise.resolve(42)) + · ─────────────────── + ╰──── + help: Prefer "mockResolvedValueOnce" + + ⚠ eslint-plugin-jest(prefer-mock-promise-shorthand): Prefer mock resolved/rejected shorthands for promises + ╭─[prefer_mock_promise_shorthand.tsx:1:11] + 1 │ aVariable.mockReturnValueOnce(Promise.reject(42)) + · ─────────────────── + ╰──── + help: Prefer "mockRejectedValueOnce" + + ⚠ eslint-plugin-jest(prefer-mock-promise-shorthand): Prefer mock resolved/rejected shorthands for promises + ╭─[prefer_mock_promise_shorthand.tsx:1:11] + 1 │ aVariable.mockReturnValue(Promise.resolve({ target: 'world', message: 'hello' })) + · ─────────────── + ╰──── + help: Prefer "mockResolvedValue" + + ⚠ eslint-plugin-jest(prefer-mock-promise-shorthand): Prefer mock resolved/rejected shorthands for promises + ╭─[prefer_mock_promise_shorthand.tsx:1:102] + 1 │ aVariable.mockImplementation(() => Promise.reject(42)).mockImplementation(() => Promise.resolve(42)).mockReturnValue(Promise.reject(42)) + · ─────────────── + ╰──── + help: Prefer "mockRejectedValue" + + ⚠ eslint-plugin-jest(prefer-mock-promise-shorthand): Prefer mock resolved/rejected shorthands for promises + ╭─[prefer_mock_promise_shorthand.tsx:1:56] + 1 │ aVariable.mockImplementation(() => Promise.reject(42)).mockImplementation(() => Promise.resolve(42)).mockReturnValue(Promise.reject(42)) + · ────────────────── + ╰──── + help: Prefer "mockResolvedValue" + + ⚠ eslint-plugin-jest(prefer-mock-promise-shorthand): Prefer mock resolved/rejected shorthands for promises + ╭─[prefer_mock_promise_shorthand.tsx:1:11] + 1 │ aVariable.mockImplementation(() => Promise.reject(42)).mockImplementation(() => Promise.resolve(42)).mockReturnValue(Promise.reject(42)) + · ────────────────── + ╰──── + help: Prefer "mockRejectedValue" + + ⚠ eslint-plugin-jest(prefer-mock-promise-shorthand): Prefer mock resolved/rejected shorthands for promises + ╭─[prefer_mock_promise_shorthand.tsx:1:97] + 1 │ aVariable.mockReturnValueOnce(Promise.reject(42)).mockImplementation(() => Promise.resolve(42)).mockReturnValueOnce(Promise.reject(42)) + · ─────────────────── + ╰──── + help: Prefer "mockRejectedValueOnce" + + ⚠ eslint-plugin-jest(prefer-mock-promise-shorthand): Prefer mock resolved/rejected shorthands for promises + ╭─[prefer_mock_promise_shorthand.tsx:1:51] + 1 │ aVariable.mockReturnValueOnce(Promise.reject(42)).mockImplementation(() => Promise.resolve(42)).mockReturnValueOnce(Promise.reject(42)) + · ────────────────── + ╰──── + help: Prefer "mockResolvedValue" + + ⚠ eslint-plugin-jest(prefer-mock-promise-shorthand): Prefer mock resolved/rejected shorthands for promises + ╭─[prefer_mock_promise_shorthand.tsx:1:11] + 1 │ aVariable.mockReturnValueOnce(Promise.reject(42)).mockImplementation(() => Promise.resolve(42)).mockReturnValueOnce(Promise.reject(42)) + · ─────────────────── + ╰──── + help: Prefer "mockRejectedValueOnce" + + ⚠ eslint-plugin-jest(prefer-mock-promise-shorthand): Prefer mock resolved/rejected shorthands for promises + ╭─[prefer_mock_promise_shorthand.tsx:1:11] + 1 │ aVariable.mockReturnValueOnce(Promise.reject(new Error('oh noes!'))) + · ─────────────────── + ╰──── + help: Prefer "mockRejectedValueOnce" + + ⚠ eslint-plugin-jest(prefer-mock-promise-shorthand): Prefer mock resolved/rejected shorthands for promises + ╭─[prefer_mock_promise_shorthand.tsx:1:9] + 1 │ vi.fn().mockReturnValue(Promise.resolve(42), xyz) + · ─────────────── + ╰──── + help: Prefer "mockResolvedValue" + + ⚠ eslint-plugin-jest(prefer-mock-promise-shorthand): Prefer mock resolved/rejected shorthands for promises + ╭─[prefer_mock_promise_shorthand.tsx:1:9] + 1 │ vi.fn().mockImplementation(() => Promise.reject(42), xyz) + · ────────────────── + ╰──── + help: Prefer "mockRejectedValue" + + ⚠ eslint-plugin-jest(prefer-mock-promise-shorthand): Prefer mock resolved/rejected shorthands for promises + ╭─[prefer_mock_promise_shorthand.tsx:1:11] + 1 │ aVariable.mockReturnValueOnce(Promise.resolve(42, xyz)) + · ─────────────────── + ╰──── + help: Prefer "mockResolvedValueOnce" + + ⚠ eslint-plugin-jest(prefer-mock-promise-shorthand): Prefer mock resolved/rejected shorthands for promises + ╭─[prefer_mock_promise_shorthand.tsx:1:11] + 1 │ aVariable.mockReturnValueOnce(Promise.resolve()) + · ─────────────────── + ╰──── + help: Prefer "mockResolvedValueOnce" diff --git a/crates/oxc_linter/src/utils/mod.rs b/crates/oxc_linter/src/utils/mod.rs index 457338cee643c..42347d2deaf99 100644 --- a/crates/oxc_linter/src/utils/mod.rs +++ b/crates/oxc_linter/src/utils/mod.rs @@ -20,17 +20,34 @@ pub use self::{ const VITEST_COMPATIBLE_JEST_RULES: phf::Set<&'static str> = phf::phf_set! { "consistent-test-it", "expect-expect", + "max-expects", + "max-nested-describe", "no-alias-methods", + "no-commented-out-tests", "no-conditional-expect", "no-conditional-in-test", - "no-commented-out-tests", "no-disabled-tests", + "no-duplicate-hooks", "no-focused-tests", + "no-hooks", "no-identical-title", + "no-interpolation-in-snapshots", "no-restricted-jest-methods", + "no-restricted-matchers", "no-test-prefixes", + "no-test-return-statement", + "prefer-comparison-matcher", "prefer-each", + "prefer-equality-matcher", + "prefer-expect-resolves", "prefer-hooks-in-order", + "prefer-hooks-on-top", + "prefer-mock-promise-shorthand", + "prefer-strict-equal", + "prefer-to-have-length", + "prefer-todo", + "require-to-throw-message", + "require-top-level-describe", "valid-describe-callback", "valid-expect", };