feat(linter): add more Vitest compatible Jest rules (#8445)

There are many `eslint-plugin-vitest` rules that have an equivalent Rust
implementation for the Jest plugin. This PR ports all Jest rules that
passes the Vitest plugin's unit tests.

Some existing Jest rule implementations are not included in the
compatible list, for example:
- `no-large-snapshots` - difference in config initial values
- `no-mocks-import` - mention of the word "Jest" in diagnostics
- `prefer-called-with` - Vitest plugin implements a fix but Jest plugin
didn't
- `prefer-spy-on` - mention of the word "Jest" in diagnostics
- `prefer-to-contain` - the fix is missing
- `valid-title` - configuration options are slightly different

To get a list of already implemented Jest rules, simply run:
```bash
ls crates/oxc_linter/src/rules/jest | sed 's/\.rs$//;s/_/-/g'
```
This commit is contained in:
Anson Heung 2025-01-17 13:59:37 +08:00 committed by GitHub
parent a4ae4505f1
commit 7ab14cc41c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
25 changed files with 1132 additions and 14 deletions

View file

@ -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();

View file

@ -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();

View file

@ -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();

View file

@ -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();

View file

@ -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),

View file

@ -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),

View file

@ -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),

View file

@ -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)

View file

@ -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();

View file

@ -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![

View file

@ -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![
(
"

View file

@ -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)

View file

@ -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),

View file

@ -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,);",

View file

@ -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');",

View file

@ -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),

View file

@ -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),

View file

@ -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

View file

@ -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

View file

@ -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.

View file

@ -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 │
╰────

View file

@ -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

View file

@ -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

View file

@ -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"

View file

@ -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",
};