### Install ESLint Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/README.md Install ESLint as a development dependency. ```sh npm i eslint --save-dev ``` -------------------------------- ### Configuration Example Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-hooks.md Illustrates how to configure the vitest/no-hooks rule to allow specific hooks. ```json { "vitest/no-hooks": [ "error", { "allow": ["afterEach", "afterAll"] } ] } ``` -------------------------------- ### Configuration Example Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-standalone-expect.md Configure the rule to specify additional test block functions. ```json { "vitest/no-standalone-expect": [ "error", { "additionalTestBlockFunctions": ["test"] } ] } ``` -------------------------------- ### Correct Hook Order Example Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-hooks-in-order.md Demonstrates the correct order for Vitest hooks. ```js // good beforeAll(() => { createMyDatabase() }) afterAll(() => { removeMyDatabase() }) ``` -------------------------------- ### Correct code example Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/padding-around-after-each-blocks.md Shows correct usage with proper padding around afterEach blocks. ```javascript const someText = 'hoge' afterEach(() => {}) describe('foo', () => {}) ``` -------------------------------- ### Correct code example Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/padding-around-after-all-blocks.md Examples of correct code for this rule. ```javascript const someText = 'hoge' afterAll(() => {}) describe('foo', () => {}) ``` -------------------------------- ### Correct code example for padding-around-describe-blocks Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/padding-around-describe-blocks.md This example shows correct code with proper padding around describe blocks. ```javascript const someText = 'hoge' describe('hoge', () => {}) describe('foo', () => {}) ``` -------------------------------- ### Install Vitest ESLint Plugin Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/README.md Install the Vitest ESLint plugin as a development dependency. ```sh npm install @vitest/eslint-plugin --save-dev ``` -------------------------------- ### ESLint Configuration for Consistent .each/.for Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/consistent-each-for.md Example ESLint configuration to enforce `.for` for `test`/`it` and `.each` for `describe`/`suite`. ```javascript // eslint.config.js export default [ { rules: { 'vitest/consistent-each-for': [ 'warn', { test: 'for', it: 'for', describe: 'each', suite: 'each', }, ], }, }, ] ``` -------------------------------- ### Correct Code Example Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-hooks.md Shows the correct way to structure tests without using beforeEach and afterEach hooks. ```javascript /* eslint vitest/no-hooks: "error" */ function setupFoo(options) { /* ... */ } function setupBar(options) { /* ... */ } describe('foo', () => { it('does something', () => { const foo = setupFoo() expect(foo.doesSomething()).toBe(true) }) it('does something with bar', () => { const foo = setupFoo() const bar = setupBar() expect(foo.doesSomething(bar)).toBe(true) }) }) ``` -------------------------------- ### Configuration for require-top-level-describe Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/require-top-level-describe.md Example ESLint configuration to enable the require-top-level-describe rule with a limit of 2 top-level describe blocks. ```json { "vitest/require-top-level-describe": [ "error", { "maxNumberOfTopLevelDescribes": 2 } ] } ``` -------------------------------- ### Incorrect code example for padding-around-describe-blocks Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/padding-around-describe-blocks.md This example shows incorrect code where describe blocks lack padding. ```javascript const someText = 'hoge' describe('hoge', () => {}) describe('foo', () => {}) ``` -------------------------------- ### Correct usage of toBeCalledOnce() Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-called-once.md This example demonstrates the correct usage of `toBeCalledOnce()` and `toHaveBeenCalledOnce()` for asserting a single call. ```typescript test('foo', () => { const mock = vi.fn() mock('foo') expect(mock).toBeCalledOnce() expect(mock).toHaveBeenCalledOnce() }) ``` -------------------------------- ### Incorrect Hook Order Example Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-hooks-in-order.md Demonstrates a violation of the hook order rule. ```js // bad afterAll(() => { removeMyDatabase() }) beforeAll(() => { createMyDatabase() }) ``` -------------------------------- ### Incorrect code example Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/padding-around-after-each-blocks.md Shows incorrect usage where padding is missing around afterEach blocks. ```javascript const someText = 'hoge' afterEach(() => {}) describe('foo', () => {}) ``` -------------------------------- ### Configuration: assertFunctionNames Option Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/expect-expect.md Customizes which function names are recognized as assertions. This example uses 'expect' as the assertion function. ```json { "vitest/expect-expect": [ "error", { "assertFunctionNames": ["expect"], "additionalTestBlockFunctions": [] } ] } ``` -------------------------------- ### Correct code with padding around beforeEach Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/padding-around-before-each-blocks.md This example demonstrates the correct usage with proper padding around the `beforeEach` block, adhering to the rule. ```javascript const someText = 'hoge' beforeEach(() => {}) describe('foo', () => {}) ``` -------------------------------- ### Allowed hook usage for setup/teardown Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/require-hook.md This pattern is not flagged because `database.connect()` is correctly placed within a `before` hook. This ensures setup logic runs before the tests within the `describe` block. ```typescript describe('foo', () => { before(() => { database.connect() }) test('bar', () => { // ... }) }) ``` -------------------------------- ### ESLint Configuration for valid-title Rule Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/valid-title.md Example ESLint configuration object for the vitest/valid-title rule, demonstrating various options. ```json { "vitest/valid-title": [ "error", { "ignoreTypeOfDescribeName": false, "allowArguments": false, "disallowedWords": ["skip", "only"], "mustNotMatch": ["^\\s+$", "^\\s*\\d+\\s*$"], "mustMatch": ["^\\s*\\w+\\s*$"] } ] } ``` -------------------------------- ### Incorrect code example Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/padding-around-after-all-blocks.md Examples of incorrect code for this rule. ```javascript const someText = 'hoge' afterAll(() => {}) describe('foo', () => {}) ``` -------------------------------- ### Incorrect Code Example Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-hooks.md Demonstrates the incorrect usage of beforeEach and afterEach hooks within Vitest describe blocks. ```javascript /* eslint vitest/no-hooks: "error" */ function setupFoo(options) { /* ... */ } function setupBar(options) { /* ... */ } describe('foo', () => { let foo beforeEach(() => { foo = setupFoo() }) afterEach(() => { foo = null }) it('does something', () => { expect(foo.doesSomething()).toBe(true) }) describe('with bar', () => { let bar beforeEach(() => { bar = setupBar() }) afterEach(() => { bar = null }) it('does something with bar', () => { expect(foo.doesSomething(bar)).toBe(true) }) }) }) ``` -------------------------------- ### Allow standard 'it' and 'test' calls Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-focused-tests.md Examples of correct code that uses standard `it` or `test` functions without `.only`. ```javascript it('test', () => { // ... }) test('it', () => { /* ... */ }) ``` -------------------------------- ### Allow single beforeEach hook Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-duplicate-hooks.md This example demonstrates correct usage with a single 'beforeEach' hook, which adheres to the rule's requirements. ```typescript test('foo', () => { beforeEach(() => {}) }) ``` -------------------------------- ### Correct describe block structure Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/max-nested-describe.md This example demonstrates a valid describe block structure that adheres to the rule's constraints. ```javascript describe('inner', () => { // ... }) ``` -------------------------------- ### Configuration Example: Preferring 'test' with 'fn' option Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/consistent-test-it.md Illustrates the rule configuration where 'test' is preferred globally ('fn' option). It shows valid 'test' and 'test.only' calls, and invalid 'it' and 'it.only' calls. ```javascript /*eslint vitest/consistent-test-it: ["error", {"fn": "test"}]*/ test('it works', () => { // <-- Valid // ... }) test.only('it works', () => { // <-- Valid // ... }) it('it works', () => { // <-- Invalid // ... }) it.only('it works', () => { // <-- Invalid // ... }) ``` -------------------------------- ### Require hook for setup/teardown calls Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/require-hook.md This pattern is flagged because `database.connect()` and `database.disconnect()` are called directly within the `describe` block, not within a hook. Setup and teardown should be wrapped in `before*` and `after*` hooks respectively. ```typescript import { database } from './api' describe('foo', () => { database.connect() test('bar', () => { // ... }) database.disconnect() }) ``` -------------------------------- ### Correct usage of toBeFalsy() Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-to-be-falsy.md Examples of code that adheres to the prefer-to-be-falsy rule. These demonstrate the preferred way to check for falsy values. ```javascript expect(foo).toBeFalsy() expectTypeOf(foo).toBeFalsy() ``` -------------------------------- ### Allow `skip` suffix in describe.each Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-test-prefixes.md This example shows the correct usage of the `skip` suffix with `describe.each`. This is the preferred way to skip tests. ```javascript describe.skip.each([])('foo', function () {}) ``` -------------------------------- ### Correct padding around expect statements Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/padding-around-expect-groups.md This example demonstrates the correct usage with proper padding around expect statements, adhering to the rule. ```javascript test('test', () => { let abc = 123 expect(abc).toEqual(123) expect(123).toEqual(abc) abc = 456 expect(abc).toEqual(456) }) ``` -------------------------------- ### Configuration: additionalTestBlockFunctions Option Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/expect-expect.md Specifies additional function names that should be treated as test blocks. This example designates 'checkForMe' as a test block function. ```json { "rules": { "vitest/expect-expect": [ "error", { "additionalTestBlockFunctions": ["checkForMe"] } ] } } ``` -------------------------------- ### Correct code with padding around test blocks Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/padding-around-test-blocks.md This example shows correctly padded 'test' blocks, adhering to the rule. It serves as a reference for proper formatting. ```javascript const someText = 'hoge' test('hoge', () => {}) test('foo', () => {}) ``` -------------------------------- ### Correct code with padding around it blocks Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/padding-around-test-blocks.md This example illustrates correct code with proper padding around 'it' blocks. It demonstrates the expected format for compliant test suites. ```javascript const someText = 'hoge' it('hoge', () => {}) it('foo', () => {}) ``` -------------------------------- ### Allow enabled tests Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-disabled-tests.md This snippet shows an example of an enabled test that adheres to the rule. ```typescript test('foo', () => { // ... }) ``` -------------------------------- ### OK: Specified vi.fn() types Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/require-mock-type-parameters.md These examples demonstrate correct usage by providing explicit type parameters to `vi.fn()`, ensuring more precise type definitions for mocked functions. ```typescript import { vi } from 'vitest' test('foo', () => { const myMockedFnOne = vi.fn<(arg1: string, arg2: boolean) => number>() const myMockedFnTwo = vi.fn<() => void>() const myMockedFnThree = vi.fn() }) ``` -------------------------------- ### Correct expect.poll usage with await Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/require-awaited-expect-poll.md This example demonstrates the correct usage of `expect.poll` by awaiting its result, ensuring the promise is handled. ```javascript test('element exists', async () => { asyncInjectElement() await expect .poll(() => document.querySelector('.element')) .toBeInTheDocument() }) ``` -------------------------------- ### Disallow `x` prefix in describe.each Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-test-prefixes.md This example shows incorrect usage of the `x` prefix with `describe.each`. Use `describe.skip.each` instead. ```javascript xdescribe.each([])('foo', function () {}) ``` -------------------------------- ### Correct code: Avoiding restricted 'not' matcher Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-restricted-matchers.md This example shows the correct way to write the assertion by avoiding the restricted 'not' matcher. ```javascript expect(a).toBe(b) ``` -------------------------------- ### Incorrect code with missing padding around beforeEach Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/padding-around-before-each-blocks.md This example shows code that violates the padding rule, with `beforeEach` lacking surrounding blank lines. ```javascript const someText = 'hoge' beforeEach(() => {}) describe('foo', () => {}) ``` -------------------------------- ### Correct code with max: 1 Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/max-expects.md This example demonstrates a test with a single expect call, which is compliant with the rule when max is set to 1. ```javascript test('foo', () => { expect(1).toBe(1) }) ``` -------------------------------- ### Disallow focused 'it' and 'test' calls Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-focused-tests.md Examples of incorrect code that uses `.only` with `it` or `test` functions. ```javascript it.only('test', () => { // ... }) test.only('it', () => { // ... }) ``` -------------------------------- ### Allowing Dynamic Arguments in Test Titles Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/valid-title.md Example of correct code when `allowArguments` is true, permitting dynamic variables as titles for `describe` and `it`. ```js describe('name', () => { it('name', () => {}) }) ``` -------------------------------- ### Correct Code: Snapshot Within Size Limit Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-large-snapshots.md This example shows a test case where the snapshot content is within the configured maxSize, thus passing the no-large-snapshots rule. ```js test('large snapshot', () => { expect('a'.repeat(50)).toMatchSnapshot() }) ``` -------------------------------- ### Correct: Standard test without conditional logic Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-conditional-tests.md This example demonstrates the correct way to write a test without any conditional logic, ensuring it always runs. ```javascript describe('my tests', () => { it('is awesome', () => { doTheThing() }) }) ``` -------------------------------- ### Incorrect usage of toBeCalledTimes(1) Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-called-once.md This example shows incorrect usage where `toBeCalledTimes(1)` is used instead of `toBeCalledOnce()`. ```typescript test('foo', () => { const mock = vi.fn() mock('foo') expect(mock).toBeCalledTimes(1) expect(mock).toHaveBeenCalledTimes(1) }) ``` -------------------------------- ### Concurrent tests with expect Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-done-callback.md Example of a concurrent test using Vitest's 'expect' for snapshot testing. This pattern is valid and does not use the 'done' callback. ```javascript test.concurrent('foo', ({ expect }) => { expect(1).toMatchSnapshot() }) ``` -------------------------------- ### Incorrect expect.poll usage Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/require-awaited-expect-poll.md This example shows an incorrect usage where `expect.poll` is not awaited or returned, potentially leading to race conditions. ```javascript test('element exists', () => { asyncInjectElement() expect.poll(() => document.querySelector('.element')).toBeInTheDocument() }) ``` -------------------------------- ### Incorrect code: Using restricted 'not' matcher Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-restricted-matchers.md This example demonstrates incorrect usage of the 'not' matcher, which is disallowed by the rule configuration. ```javascript expect(a).not.toBe(b) ``` -------------------------------- ### Warnings: Callback function parameters are not allowed Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/valid-describe-callback.md The describe callback function should not contain parameters. This example shows a violation where 'done' is used as a parameter. ```javascript describe('myfunc', (done) => { // }) ``` -------------------------------- ### Configure Vitest Unbound Method Rule Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/unbound-method.md Example ESLint configuration to enable the vitest/unbound-method rule, disabling the base @typescript-eslint/unbound-method rule and enabling the Vitest-specific one for test files. ```json5 { parser: '@typescript-eslint/parser', parserOptions: { project: 'tsconfig.json', ecmaVersion: 2020, sourceType: 'module', }, overrides: [ { files: ['test/**'], plugins: ['vitest'], rules: { '@typescript-eslint/unbound-method': 'off', 'vitest/unbound-method': 'error', }, }, ], rules: { '@typescript-eslint/unbound-method': 'error', }, } ``` -------------------------------- ### Incorrect Test Title Case Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-lowercase-title.md This example shows an incorrect test title that violates the rule by starting with an uppercase letter. Use this snippet to identify violations. ```javascript test('It works', () => { // ... }) ``` -------------------------------- ### Enforcing explicit timeouts in tests Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/require-test-timeout.md Demonstrates how to correctly define timeouts for tests. Includes examples for numeric timeouts, options objects, and file-level configurations. ```typescript // bad it('slow test', async () => { await doSomethingSlow() }) ``` ```typescript // good (numeric timeout) test('slow test', async () => { await doSomethingSlow() }, 1000) ``` ```typescript // good (options object) test('slow test', { timeout: 1000 }, async () => { await doSomethingSlow() }) ``` ```typescript // good (file-level) vi.setConfig({ testTimeout: 1000 }) test('slow test', async () => { await doSomethingSlow() }) ``` -------------------------------- ### Incorrect code with identical test titles Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-identical-title.md This example shows two 'it' blocks with the exact same title, which violates the rule. ```javascript it('is awesome', () => { /* ... */ }) it('is awesome', () => { /* ... */ }) ``` -------------------------------- ### Incorrect Code: Large Snapshot Exceeding Limit Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-large-snapshots.md This example demonstrates a test case that will fail the no-large-snapshots rule due to the snapshot content exceeding the configured maxSize. ```js test('large snapshot', () => { expect('a'.repeat(100)).toMatchSnapshot() }) ``` -------------------------------- ### Warnings: No return statements allowed in describe callback Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/valid-describe-callback.md The describe callback function should not contain any return statements. This example shows a violation where a Promise is returned. ```javascript describe('myfunc', () => { // no return statements are allowed in a block of a callback function return Promise.resolve().then(() => { // }) }) ``` -------------------------------- ### Incorrect nested describe blocks Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/max-nested-describe.md This example shows code that violates the rule when `max` is set to 1, due to excessive nesting. ```javascript describe('outer', () => { describe('inner', () => { // ... }) }) ``` -------------------------------- ### Correct expect.poll usage with return Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/require-awaited-expect-poll.md This example shows another correct usage where the `expect.poll` call is returned, ensuring the promise is handled by the test runner. ```javascript test('element exists', () => { asyncInjectElement() return expect .poll(() => document.querySelector('.element')) .toBeInTheDocument() }) ``` -------------------------------- ### Incorrect padding around expect statements Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/padding-around-expect-groups.md This example shows code that violates the padding rule, with expect statements lacking proper spacing. ```javascript test('test', () => { let abc = 123 expect(abc).toEqual(123) expect(123).toEqual(abc) abc = 456 expect(abc).toEqual(456) }) ``` -------------------------------- ### Using vi.spyOn for mocking Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-spy-on.md This demonstrates the recommended way to mock object properties using `vi.spyOn`. It provides a more robust and explicit way to mock. ```typescript vi.spyOn(Date, 'now') vi.spyOn(Date, 'now').mockImplementation(() => 10) ``` -------------------------------- ### Describe block with concurrent tests Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-done-callback.md Shows how to structure concurrent tests within a 'describe' block in Vitest. This example uses the 'expect' API and is a valid asynchronous test structure. ```javascript describe.concurrent('foo', () => { test('foo', ({ expect }) => { expect(1).toBe(1) }) }) ``` -------------------------------- ### Correct code with unique test titles Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-identical-title.md This example demonstrates unique titles for 'it' blocks, satisfying the rule's requirement for distinct test identifiers. ```javascript it('is awesome', () => { /* ... */ }) it('is very awesome', () => { /* ... */ }) ``` -------------------------------- ### Correct concurrent snapshot test with local context (named parameter) Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/require-local-test-context-for-concurrent-snapshots.md This example shows another correct way to use the local test context by passing it as a named parameter and accessing `expect` through it. This is a valid alternative for managing snapshot assertions in concurrent tests. ```javascript test.concurrent('myLogic', (context) => { context.expect(true).toMatchSnapshot() }) ``` -------------------------------- ### Correct `it` Title with Specific `mustMatch` Rule Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/valid-title.md Example of correct code when `mustMatch` is configured with a specific regex for `it` titles, and the title 'should be a number.' matches. ```js // The describe title is checked with the default regex, so it's valid describe('foo', () => { // This check succeeds because the title matches the regex it('should be a number.', () => { expect(1).toBe(1) }) }) ``` -------------------------------- ### Incorrect code with return statement Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-test-return-statement.md This example shows an incorrect usage of a return statement within a Vitest test. The `return` keyword before `expect` is unnecessary and disallowed by the rule. ```typescript import { test } from 'vitest' test('foo', () => { return expect(1).toBe(1) }) ``` -------------------------------- ### Correct Usage: vi.unmock at top level Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/hoisted-apis-on-top.md This example shows vi.unmock correctly placed at the top level of the file. This usage is compliant with the hoisted-apis-on-top rule. ```javascript vi.unmock(() => {}) if (condition) { // ... } ``` -------------------------------- ### Incorrect: Separate calls to `toHaveBeenCalledOnce` and `toHaveBeenCalledWith` Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-called-exactly-once-with.md This example shows incorrect usage where a mock function is asserted to have been called once and then separately asserted to have been called with specific arguments. This pattern can be simplified. ```javascript test('foo', () => { const mock = vi.fn() mock('foo') expect(mock).toHaveBeenCalledOnce() expect(mock).toHaveBeenCalledWith('foo') }) ``` -------------------------------- ### Incorrect: Using `toHaveBeenCalledExactlyOnceWith` with incorrect arguments Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-called-exactly-once-with.md This example demonstrates a scenario where `toHaveBeenCalledExactlyOnceWith` is used, but the arguments do not match the actual call. The rule flags this as it implies a misunderstanding or a potential error in assertion. ```javascript test('foo', () => { const mock = vi.fn() mock('foo') expect(mock).toHaveBeenCalledExactlyOnceWith('foo') }) ``` -------------------------------- ### Warnings: Returning a value from a describe block is not allowed Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/valid-describe-callback.md Returning a value directly from a describe block is not allowed. This example shows a violation where an arrow function returning an it block is used. ```javascript describe('myfunc', () = it('should do something', () => { // })) ``` -------------------------------- ### Configure ESLint with Vitest Plugin (ESLint v9+) Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/README.md Set up eslint.config.js to use the Vitest ESLint plugin, enabling recommended rules and custom configurations like max-nested-describe. ```js import { defineConfig } from 'eslint/config' import vitest from '@vitest/eslint-plugin' export default defineConfig({ files: ['tests/**'], // or any other pattern plugins: { vitest, }, rules: { ...vitest.configs.recommended.rules, // you can also use vitest.configs.all.rules to enable all rules 'vitest/max-nested-describe': ['error', { max: 3 }], // you can also modify rules' behavior using option like this }, }) ``` -------------------------------- ### Disallow disabled tests Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-disabled-tests.md This snippet shows an example of a disabled test that the rule will flag. ```typescript test.skip('foo', () => { // ... }) ``` -------------------------------- ### Incorrect code with adjacent test blocks Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/padding-around-test-blocks.md This example shows incorrect code where test blocks are not separated by padding. Use this to identify violations of the padding rule. ```javascript const someText = 'hoge' test('hoge', () => {}) test('foo', () => {}) ``` -------------------------------- ### Correct code without return statement Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-test-return-statement.md This example demonstrates the correct way to write a Vitest test without using a return statement. The `expect` assertion is called directly, which is the preferred style. ```typescript import { test } from 'vitest' test('foo', () => { expect(1).toBe(1) }) ``` -------------------------------- ### Correct concurrent snapshot test with local context (destructured) Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/require-local-test-context-for-concurrent-snapshots.md This example demonstrates the correct usage by destructuring the `expect` function from the test context argument in a concurrent test. This ensures that snapshot assertions are properly scoped. ```javascript test.concurrent('myLogic', ({ expect }) => { expect(true).toMatchSnapshot() }) ``` -------------------------------- ### Enable Recommended Vitest Configuration (ESLint v9+) Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/README.md Apply the recommended shareable configuration for the Vitest ESLint plugin using vitest.configs.recommended in eslint.config.js. ```js import { defineConfig } from 'eslint/config' import vitest from '@vitest/eslint-plugin' export default defineConfig({ files: ['tests/**'], // or any other pattern ...vitest.configs.recommended, }) ``` -------------------------------- ### Incorrect usage of toBe(false) Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-to-be-falsy.md Examples of code that violates the prefer-to-be-falsy rule. These should be refactored to use toBeFalsy(). ```javascript expect(foo).toBe(false) expectTypeOf(foo).toBe(false) ``` -------------------------------- ### Incorrect code with adjacent it blocks Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/padding-around-test-blocks.md This example demonstrates incorrect code with adjacent 'it' blocks, violating the padding requirement. This highlights the need for blank lines around test definitions. ```javascript const someText = 'hoge' it('hoge', () => {}) it('foo', () => {}) ``` -------------------------------- ### Correct Usage Instead of .todo Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/warn-todo.md Shows correct alternatives to `.todo` by using an empty array with `describe`, `it`, and `test` functions. ```javascript describe([])('foo', () => {}) ``` ```javascript it([])('foo', () => {}) ``` ```javascript test([])('foo', () => {}) ``` -------------------------------- ### Manual loop vs. describe.each Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-each.md Demonstrates the incorrect usage of a manual loop for defining parameterized tests and the preferred `describe.each` approach. ```javascript // bad for (const item of items) { describe(item, () => { expect(item).toBe('foo') }) } // good describe.each(items)('item', (item) => { expect(item).toBe('foo') }) ``` -------------------------------- ### Incorrect Usage: vi.mock inside test body Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/hoisted-apis-on-top.md This example shows vi.mock being used inside an 'it' block, which is considered incorrect usage by the rule. Hoisted APIs should precede test definitions. ```javascript describe('suite', () => { it('test', async () => { vi.mock('some-module', () => {}) const sm = await import('some-module') // ... }) }) ``` -------------------------------- ### Correct code with 'multi' option Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-snapshot-hint.md Demonstrates correct usage of snapshot matchers with hints when the 'multi' option is enabled. ```typescript const snapshotOutput = ({ stdout, stderr }, hints) => { expect(stdout).toMatchSnapshot({}, `stdout: ${hints.stdout}`) expect(stderr).toMatchSnapshot({}, `stderr: ${hints.stderr}`) } describe('cli', () => { describe('--version flag', () => { it('prints the version', async () => { snapshotOutput(await runCli(['--version']), { stdout: 'version string', stderr: 'empty', }) }) }) describe('--config flag', () => { it('reads the config', async () => { const { stdout } = await runCli(['--config', 'vitest.config.js']) expect(stdout).toMatchSnapshot() }) it('prints nothing to stderr', async () => { const { stderr } = await runCli(['--config', 'vitest.config.js']) expect(stderr).toMatchInlineSnapshot() }) describe('when the file does not exist', () => { it('throws an error', async () => { await expect( runCli(['--config', 'does-not-exist.js']), ).rejects.toThrowErrorMatchingSnapshot() }) }) }) }) ``` -------------------------------- ### Configuration option for max expects Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/max-expects.md Illustrates the configuration object for the max-expects rule, specifying the maximum number of expect calls allowed. ```json { max: number } ``` -------------------------------- ### Configure ESLint with Vitest Plugin (.eslintrc JSON) Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/README.md Configure the Vitest ESLint plugin by adding it to the plugins section of an .eslintrc JSON file. ```json { "plugins": ["@vitest"] } ``` -------------------------------- ### Incorrect code with max: 1 Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/max-expects.md This example shows a test with two expect calls, violating the rule when max is set to 1. ```javascript test('foo', () => { expect(1).toBe(1) expect(2).toBe(2) }) ``` -------------------------------- ### Correct Test Title Without Disallowed Words Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/valid-title.md Example of correct code when `disallowedWords` is set to `['skip', 'only']` and a standard `it` block is used. ```js describe('foo', () => { it('should be skipped', () => { expect(1).toBe(1) }) }) ``` -------------------------------- ### Configuration: Rule options Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/require-mock-type-parameters.md This JSON configuration shows how to enable the `checkImportFunctions` option for the `require-mock-type-parameters` rule, which extends the check to `vi.importActual` and `vi.importMock`. ```json { "vitest/require-mock-type-parameters": [ "error", { "checkImportFunctions": false } ] } ``` -------------------------------- ### Correct Usage of expect.toBeTypeOf Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-expect-type-of.md Shows the correct and recommended pattern using `expect(...).toBeTypeOf(type)` for runtime type checking. This approach provides a cleaner API and improved error reporting. ```typescript import { test, expect } from 'vitest' test('type checking', () => { expect('hello').toBeTypeOf('string') expect(42).toBeTypeOf('number') expect(true).toBeTypeOf('boolean') expect({}).toBeTypeOf('object') expect(() => {}).toBeTypeOf('function') expect(Symbol()).toBeTypeOf('symbol') expect(123n).toBeTypeOf('bigint') expect(undefined).toBeTypeOf('undefined') }) ``` -------------------------------- ### Allow importing from regular directories Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-mocks-import.md This snippet demonstrates a passing case where a module is imported from a regular directory, not '__mocks__'. This is the preferred way to import modules. ```typescript import { foo } from 'foo' ``` -------------------------------- ### Correct Code with Allowed Hook Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-hooks.md Shows correct usage when 'afterEach' is allowed, demonstrating that 'beforeEach' is flagged but 'afterEach' is not. ```javascript /* eslint vitest/no-hooks: ["error", { "allow": ["afterEach"] }] */ function setupFoo(options) { /* ... */ } afterEach(() => { vi.resetModules() }) test('foo does this', () => { const foo = setupFoo() // ... }) test('foo does that', () => { const foo = setupFoo() // ... }) ``` -------------------------------- ### Incorrect: Conditional test using if statement Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-conditional-tests.md This example shows an incorrect usage where a test is wrapped in an 'if' statement, which can lead to the test being skipped. ```javascript describe('my tests', () => { if (true) { it('is awesome', () => { doTheThing() }) } }) ``` -------------------------------- ### Use vi.mocked() for typed mocks Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-vi-mocked.md These patterns are not warnings and demonstrate the recommended usage of `vi.mocked()` for properly typing mocked functions in Vitest. This ensures better type safety and readability. ```javascript vi.mocked(foo).mockReturnValue(1) ``` ```javascript const mock = vi.mocked(foo).mockReturnValue(1) ``` ```javascript vi.mocked(Obj.foo).mockReturnValue(1) ``` ```javascript vi.mocked([].foo).mockReturnValue(1) ``` -------------------------------- ### Correct padding around beforeAll Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/padding-around-before-all-blocks.md This snippet demonstrates the correct usage with proper padding before and after the beforeAll block, adhering to the rule's requirements. ```javascript const someText = 'hoge' beforeAll(() => {}) describe('foo', () => {}) ``` -------------------------------- ### Configure Vitest Plugin with Legacy ESLint Config Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/README.md Use the legacy-recommended or legacy-all configuration for the Vitest ESLint plugin with older ESLint versions. ```js { "extends": ["plugin:@vitest/legacy-recommended"] // or legacy-all } ``` -------------------------------- ### Correct code importing vitest Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-import-node-test.md This snippet shows the correct way to import test functions from 'vitest'. This is the expected pattern when using Vitest. ```typescript import { test, expect } from 'vitest' test('foo', () => { expect(1).toBe(1) }) ``` -------------------------------- ### ESLint Configuration for no-large-snapshots Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-large-snapshots.md Configure the vitest/no-large-snapshots rule with custom limits for maxSize, inlineMaxSize, and allowedSnapshots. ```json { "vitest/no-large-snapshots": [ "error", { "maxSize": 50, "inlineMaxSize": 0, "allowedSnapshots": {} } ] } ``` -------------------------------- ### Disallow duplicate beforeEach hook Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-duplicate-hooks.md This example shows incorrect usage where a 'beforeEach' hook is declared twice within the same test. The rule flags this as a violation. ```typescript test('foo', () => { beforeEach(() => {}) beforeEach(() => {}) // duplicate beforeEach }) ``` -------------------------------- ### Enable All Vitest Rules (ESLint v9+) Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/README.md Enable all available rules provided by the Vitest ESLint plugin by using vitest.configs.all in eslint.config.js. ```js import { defineConfig } from 'eslint/config' import vitest from '@vitest/eslint-plugin' export default defineConfig({ files: ['tests/**'], // or any other pattern ...vitest.configs.all, }) ``` -------------------------------- ### Warning: Using mockImplementation for simple return values Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-mock-return-shorthand.md Avoid using mockImplementation for simple return values. Prefer shorthand methods like mockResolvedValue or mockRejectedValue. ```javascript vi.fn().mockImplementation(() => 'hello world') ``` ```javascript vi.spyOn(fs.promises, 'readFile').mockImplementationOnce(() => Promise.reject(new Error('oh noes!')) ) ``` ```javascript myFunction .mockImplementationOnce(() => 42) .mockImplementationOnce(() => Promise.resolve(42)) .mockReturnValue(0) ``` -------------------------------- ### Using dynamic import() in vi.mock() Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-import-in-mock.md This pattern is not considered a warning as it correctly uses dynamic `import()` within `vi.mock()` or `vi.doMock()`, ensuring better type information and IntelliSense. ```javascript vi.mock(import('./path/to/module')) ``` ```javascript vi.doMock(import('./path/to/module')) ``` -------------------------------- ### Correct Usage with Dynamic Arguments Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/valid-title.md Illustrates correct code when `allowArguments` is true, allowing dynamic variables like `foo` and `hoge` as test titles. ```js describe(foo, () => { it(hoge, () => {}) }) ``` -------------------------------- ### Incorrect .todo Usage Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/warn-todo.md Demonstrates incorrect usage of `.todo` with `describe`, `it`, and `test` functions. ```javascript describe.todo('foo', () => {}) ``` ```javascript it.todo('foo', () => {}) ``` ```javascript test.todo('foo', () => {}) ``` -------------------------------- ### Configuration for allowed function calls Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/require-hook.md This JSON configuration allows specific function calls, such as `database.connect`, to be used outside of hooks. This is useful for methods that are safe to call directly or have no side effects relevant to test setup/teardown. ```json { "vitest/require-hook": [ "error", { "allowedFunctionCalls": ["database.connect"] } ] } ``` -------------------------------- ### Disallow conditional logic in tests Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-conditional-in-test.md This snippet shows an example of a test that violates the rule by using an 'if' statement. Ensure all test logic is directly executable. ```javascript test('my test', () => { if (true) { doTheThing() } }) ``` -------------------------------- ### ESLint configuration for no-conditional-expect Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-conditional-expect.md This JSON snippet shows how to configure the 'vitest/no-conditional-expect' rule with the 'expectAssertions' option enabled. ```json { "rules": { "vitest/no-conditional-expect": ["error", { "expectAssertions": true }] } } ``` -------------------------------- ### Enable Vitest Plugin with Type-Testing (ESLint v9+) Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/README.md Configure eslint.config.js to enable Vitest's type-testing feature, ensuring rules account for type-related assertions. ```js import { defineConfig } from 'eslint/config' import tseslint from 'typescript-eslint' import vitest from '@vitest/eslint-plugin' export default defineConfig( // see https://typescript-eslint.io tseslint.configs.recommended, { languageOptions: { parserOptions: { projectService: true, }, }, }, { files: ['tests/**'], // or any other pattern plugins: { vitest, }, rules: { ...vitest.configs.recommended.rules, }, settings: { vitest: { typecheck: true, }, }, languageOptions: { globals: { ...vitest.environments.env.globals, }, }, }, ) ``` -------------------------------- ### Valid describe callback with nested it block Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/valid-describe-callback.md A valid describe callback can contain nested it blocks. This example shows a standard structure without disallowed parameters or return statements. ```javascript describe('myfunc', () => { it('should do something', () => { // }) }) ``` -------------------------------- ### Correct Code with assertFunctionNames Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/expect-expect.md Demonstrates a test case that passes when using a custom assertion function name defined in the configuration. ```javascript import CheckForMe from 'check-for-me' test('myLogic', () => { expect('myLogic').toBe('myOutput') }) ``` -------------------------------- ### Prefer dynamic import() in vi.mock() Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-import-in-mock.md Use dynamic `import()` within `vi.mock()` to improve type information and IntelliSense for the mocked module. This is the recommended pattern. ```javascript vi.mock('./path/to/module') ``` ```javascript vi.doMock('./path/to/module') ``` -------------------------------- ### Correct code with 'always' option Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-snapshot-hint.md Demonstrates correct usage of snapshot matchers with hints when the 'always' option is enabled. ```typescript const snapshotOutput = ({ stdout, stderr }, hints) => { expect(stdout).toMatchSnapshot({}, `stdout: ${hints.stdout}`) expect(stderr).toMatchSnapshot({}, `stderr: ${hints.stderr}`) } describe('cli', () => { describe('--version flag', () => { it('prints the version', async () => { snapshotOutput(await runCli(['--version']), { stdout: 'version string', stderr: 'empty', }) }) }) describe('--config flag', () => { it('reads the config', async () => { const { stdout } = await runCli(['--config', 'vitest.config.js']) expect(stdout).toMatchSnapshot({}, 'stdout: config settings') }) it('prints nothing to stderr', async () => { const { stderr } = await runCli(['--config', 'vitest.config.js']) expect(stderr).toMatchInlineSnapshot() }) describe('when the file does not exist', () => { it('throws an error', async () => { await expect( runCli(['--config', 'does-not-exist.js']), ).rejects.toThrowErrorMatchingSnapshot('stderr: config error') }) }) }) }) ``` -------------------------------- ### Rule Configuration: Preferring vitest Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/consistent-vitest-vi.md This JSON configuration object specifies that the 'vitest' keyword should be preferred over 'vi' for the rule. ```json { "type": "object", "properties": { "fn": { "enum": ["vi", "vitest"] } }, "additionalProperties": false } ``` -------------------------------- ### Incorrect Usage: spyOn Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-restricted-vi-methods.md Demonstrates incorrect usage of vi.spyOn when it's restricted by the rule. ```js test('plays video', () => { const spy = vi.spyOn(video, 'play') // ... }) ``` -------------------------------- ### Consistent Order of Hooks Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-hooks-in-order.md Defines the recommended order for Vitest hooks. ```js // consistent order of hooks ;['beforeAll', 'beforeEach', 'afterEach', 'afterAll'] ``` -------------------------------- ### Configure Custom Fixtures with Vitest ESLint Plugin (ESLint v9+) Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/README.md Specify custom fixture locations using 'vitestImports' in eslint.config.js to help the plugin recognize them. ```js import { defineConfig } from 'eslint/config' import vitest from '@vitest/eslint-plugin' export default defineConfig({ files: ['tests/**'], // or any other pattern plugins: { vitest, }, rules: { ...vitest.configs.recommended.rules, }, settings: { vitest: { vitestImports: ['@/tests/fixtures', /test-extend$/], }, }, }) ``` -------------------------------- ### Incorrect concurrent snapshot test without local context Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/require-local-test-context-for-concurrent-snapshots.md This example shows an incorrect usage where `toMatchSnapshot` is called without the `expect` function from the local test context in a concurrent test. This can lead to issues with snapshot management in concurrent test runners. ```javascript test.concurrent('myLogic', () => { expect(true).toMatchSnapshot() }) describe.concurrent('something', () => { test('myLogic', () => { expect(true).toMatchInlineSnapshot() }) }) ``` -------------------------------- ### Use original methods instead of aliases Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-alias-methods.md This snippet demonstrates the correct usage of original assertion methods. This is the preferred way to write assertions. ```javascript expect(a).toHaveBeenCalled() ``` -------------------------------- ### Allow async/await in tests Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-done-callback.md This snippet demonstrates the correct usage of async/await for asynchronous operations in Vitest tests, which is the preferred alternative to the 'done' callback. ```javascript test('foo', async () => { await new Promise((resolve) => setTimeout(resolve, 1000)) }) ``` ```javascript test('foo', async () => { await new Promise((resolve) => setTimeout(() => resolve(), 1000)) }) ``` ```javascript test('foo', async () => { await new Promise((resolve) => setTimeout(() => { resolve() }, 1000), ) }) ``` ```javascript test('foo', async () => { await new Promise((resolve) => setTimeout(() => { resolve() }, 1000), ) }) ``` -------------------------------- ### Concurrent tests with context.expect Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-done-callback.md Demonstrates a concurrent test using the 'context.expect' API provided by Vitest. This is a valid asynchronous test pattern. ```javascript test.concurrent('foo', (context) => { context.expect(1).toBe(1) }) ``` -------------------------------- ### Correct Code: Consistent vitest Usage Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/consistent-vitest-vi.md This snippet illustrates the correct usage where only 'vitest' is used, demonstrating an alternative to the 'vi' preference. ```javascript vitest.mock('./src/calculator.ts', { spy: true }) vitest.stubEnv('NODE_ENV', 'production') ``` -------------------------------- ### Correct Usage of test.todo Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-todo.md This pattern is not flagged by the rule and represents the recommended way to mark unimplemented tests. ```javascript test.todo('foo') ``` -------------------------------- ### Correct Usage: vi.mock at top level Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/hoisted-apis-on-top.md This snippet demonstrates the correct placement of vi.mock at the top level of the file, before any describe or it blocks. This adheres to the rule's requirements. ```javascript vi.mock('some-module', () => {}) describe('suite', () => { it('test', async () => { const sm = await import('some-module') // ... }) }) ``` -------------------------------- ### Correct Usage of 'test' Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/consistent-test-it.md Shows correct code where only 'test' is used for defining test cases. This adheres to the rule when 'test' is the preferred function. ```javascript test('it works', () => { // ... }) ``` -------------------------------- ### Rule Configuration Options Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-lowercase-title.md This JSON configuration shows the available options for the prefer-lowercase-title rule, including 'ignore', 'allowedPrefixes', 'ignoreTopLevelDescribe', and 'lowercaseFirstCharacterOnly'. Adjust these options to customize rule behavior. ```json { "type": "object", "properties": { "ignore": { "type": "array", "items": { "enum": ["describe", "test", "it"] }, "additionalProperties": false }, "allowedPrefixes": { "type": "array", "items": { "type": "string" }, "additionalItems": false }, "ignoreTopLevelDescribe": { "type": "boolean", "default": false }, "lowercaseFirstCharacterOnly": { "type": "boolean", "default": true } }, "additionalProperties": false } ``` -------------------------------- ### Prefer Hooks on Top in Vitest Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-hooks-on-top.md Illustrates the correct and incorrect placement of hooks relative to test cases in Vitest. Hooks should precede test cases for better readability. ```typescript // bad describe('foo', () => { it('bar', () => { // ... }) beforeEach(() => { // ... }) }) // good describe('foo', () => { beforeEach(() => { // ... }) it('bar', () => { // ... }) }) ``` -------------------------------- ### Configure Restricted vi Methods Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-restricted-vi-methods.md Configure the rule to disallow specific vi methods. Use a string for a custom message or null for a default message. ```json { "vitest/no-restricted-vi-methods": [ "error", { "advanceTimersByTime": null, "spyOn": "Don't use spies" } ] } ``` -------------------------------- ### Valid alternatives using `toHaveBeenCalledTimes` Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-to-have-been-called-times.md These patterns are not warnings as they correctly use `toHaveBeenCalledTimes()` for checking mock call counts or other valid assertions. ```javascript expect(someFunction).toHaveBeenCalledTimes(1) expect(someFunction).toHaveBeenCalledTimes(0) ``` ```javascript expect(someFunction).not.toHaveBeenCalledTimes(0) ``` ```javascript expect(uncalledFunction).not.toBeCalled() ``` ```javascript expect(method.mock.calls[0][0]).toStrictEqual(value) ``` -------------------------------- ### Allow static strings or direct values in snapshots Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-interpolation-in-snapshots.md This demonstrates valid snapshot usage without string interpolation. Ensure snapshots contain static strings or directly match values. ```typescript expect('foo').toMatchSnapshot() ``` ```typescript expect('foo').toMatchSnapshot('foo') ``` ```typescript expect('foo').toMatchSnapshot(bar) ``` -------------------------------- ### Configuration to restrict 'not' matcher Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-restricted-matchers.md Configure the 'no-restricted-matchers' rule to disallow the 'not' matcher. This JSON configuration specifies the rule and its options. ```json { "vitest/no-restricted-matchers": [ "error", { "not": null } ] } ``` -------------------------------- ### Correct Code: Consistent vi Usage Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/consistent-vitest-vi.md This snippet shows the correct usage where only 'vi' is used, adhering to the rule's preference for a single namespace. ```javascript vi.mock('./src/calculator.ts', { spy: true }) vi.stubEnv('NODE_ENV', 'production') ``` -------------------------------- ### Incorrect Code with Allowed Hook Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-hooks.md Demonstrates incorrect usage when only 'afterEach' is allowed, showing a violation with 'beforeEach'. ```javascript /* eslint vitest/no-hooks: ["error", { "allow": ["afterEach"] }] */ function setupFoo(options) { /* ... */ } let foo beforeEach(() => { foo = setupFoo() }) afterEach(() => { vi.resetModules() }) test('foo does this', () => { // ... }) test('foo does that', () => { // ... }) ``` -------------------------------- ### Correct Usage: vi.hoisted at top level Source: https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/hoisted-apis-on-top.md This snippet illustrates the correct usage of vi.hoisted at the top level of the file. This placement ensures it is recognized as a hoisted API. ```javascript vi.hoisted(() => {}) if (condition) { // ... } ```