-
Notifications
You must be signed in to change notification settings - Fork 98
Description
Description
vitest/consistent-test-it reports a false positive when test.extend() or it.extend() is used to create a custom test function at module scope. The rule flags the .extend() call based on the identity of the original import (test vs it), but .extend() returns a new function that may be assigned to a different name for use in a different scope.
Reproduction
https://github.com/gtbuchanan/vitest-eslint-consistent-test-it-repro
git clone https://github.com/gtbuchanan/vitest-eslint-consistent-test-it-repro
cd vitest-eslint-consistent-test-it-repro
npm install
npx eslint .Case 1: it-extend-to-it.test.ts
import { it as base, describe } from 'vitest';
const it = base.extend<{ fixture: string }>({
fixture: async ({}, use) => {
await use('hello');
},
});
describe('example', () => {
it('should not warn', ({ fixture, expect }) => {
expect(fixture).toBe('hello');
});
});Warns: Prefer using test instead of it on the base.extend(...) line (module scope).
Expected: No warning — the extended function is named it and used correctly inside describe.
Case 2: it-extend-to-test.test.ts
import { describe, it } from 'vitest';
const test = it.extend<{ fixture: string }>({
fixture: async ({}, use) => {
await use('hello');
},
});
describe('example', () => {
test('should not warn', ({ fixture, expect }) => {
expect(fixture).toBe('hello');
});
});Warns: Prefer using test instead of it on the it.extend(...) line (module scope).
Expected: No warning — the extended function is named test and the it.extend() call is just the factory, not a test invocation.
Root cause
The rule treats .extend() calls as if they were test invocations, applying the same scope-based naming rules (test at top level, it inside describe). But .extend() is a factory that returns a new function — the scope where .extend() is called is irrelevant; only the scope where the returned function is invoked matters.
Environment
@vitest/eslint-plugin: 1.6.12eslint: 9.xtypescript-eslint: required to reproduce (the parser enables the plugin to resolve the import identity)