Summary
The vitest/* plugin rules only fire when test functions (it, test, describe, expect, hooks, etc.) are imported from vitest (or aliased sources like vite-plus/test). They do not recognize @effect/vitest as a valid vitest import source, so 28 of the 35 rules I tested silently fail to fire on test files that import from it.
@effect/vitest is the official Effect testing integration: https://effect.website/docs/livesdk/testing/. It re-exports the entire vitest API (export * from "vitest") plus Effect-aware helpers (it.effect, it.live, layer(...), it.layer(...), it.effect.prop, etc.). It is the recommended way to test Effect code with Vitest, per the Effect testing guide.
Environment
- oxlint: bundled via
vite-plus (@oxlint/[email protected], @oxlint/[email protected])
- Invoked via:
vp lint (Vite+ CLI)
@effect/vitest: 4.0.0-beta.83
vitest: aliased to @voidzero-dev/vite-plus-test@latest via pnpm npm: override (a vitest fork) — same behavior reproduces with stock vitest
Reproduction
Two identical probe files, differing only in the import source:
// probe-effect.test.ts
import { describe, expect, it, test } from "@effect/vitest";
describe("probe", () => {
test("mixed test and it usage", () => {}); // consistent-test-it should flag
it("prefer-todo: empty body", () => {}); // prefer-todo + expect-expect should flag
it("require-test-timeout: no timeout", () => {}); // require-test-timeout should flag
it("prefer-strict-equal: uses toEqual", () => {
// prefer-strict-equal should flag
expect({ a: 1 }).toEqual({ a: 1 });
});
it.only("no-focused-tests: focused test", () => {}); // no-focused-tests should flag
// ... plus cases for prefer-to-be, no-alias-methods, valid-expect, etc.
});
// probe-plain.test.ts — identical body, different import
import { describe, expect, it, test } from "vitest";
// (same body as above)
Result
$ oxlint probe-effect.test.ts # imports from @effect/vitest
Found 0 warnings and 0 errors. # <- no vitest rules fire (only TS rules fire)
$ oxlint probe-plain.test.ts # imports from vitest
Found 0 warnings and 102 errors. # <- 24 distinct vitest rules fire correctly
Rules affected
I tested 35 vitest rules with trigger cases. 28 silently fail to fire when the import source is @effect/vitest; 7 fire regardless of import source.
Silently broken on @effect/vitest (28)
These rules require resolving the import source to vitest and do not recognize @effect/vitest:
| Rule |
Category |
vitest/consistent-test-it |
style (test/it consistency) |
vitest/expect-expect |
best-practice (test has no assertions) |
vitest/max-expects |
best-practice (too many assertions) |
vitest/no-alias-methods |
style (e.g. toBeCalled → toHaveBeenCalled) |
vitest/no-conditional-expect |
best-practice |
vitest/no-disabled-tests |
best-practice (it.skip) |
vitest/no-duplicate-hooks |
best-practice |
vitest/no-focused-tests |
best-practice (it.only) |
vitest/no-hooks |
style |
vitest/no-identical-title |
best-practice |
vitest/prefer-called-once |
style |
vitest/prefer-called-times |
style |
vitest/prefer-called-with |
style |
vitest/prefer-comparison-matcher |
style |
vitest/prefer-expect-assertions |
best-practice |
vitest/prefer-expect-type-of |
style |
vitest/prefer-strict-equal |
style (toEqual → toStrictEqual) |
vitest/prefer-to-be |
style (toEqual → toBe for primitives) |
vitest/prefer-to-be-falsy |
style |
vitest/prefer-to-be-truthy |
style |
vitest/prefer-to-contain |
style |
vitest/prefer-to-have-length |
style |
vitest/prefer-todo |
style (empty body → it.todo) |
vitest/require-awaited-expect-poll |
best-practice |
vitest/require-test-timeout |
best-practice (missing timeout) |
vitest/require-to-throw-message |
best-practice |
vitest/require-top-level-describe |
style |
vitest/valid-expect |
best-practice (expect(x) without matcher) |
Work regardless of import source (7)
These appear to pattern-match on call syntax rather than resolving the import source, so they fire on both:
vitest/no-conditional-in-test
vitest/no-test-return-statement
vitest/prefer-hooks-in-order
vitest/prefer-mock-promise-shorthand
vitest/prefer-mock-return-shorthand
vitest/prefer-spy-on
vitest/require-mock-type-parameters
Suggested fix
Treat @effect/vitest as a recognized vitest import source. Two possible approaches:
- Hardcode
@effect/vitest alongside vitest in the vitest plugin's import-source recognizer (smallest change).
- Make it configurable — add an option like
vitestImportSources: ["vitest", "@effect/vitest", ...] to the plugin config so projects can register additional re-exporting packages (more flexible; also covers vite-plus/test, private wrappers, etc.).
Option 2 would also resolve the related false-positive on vitest/no-importing-vitest-globals (which flags @effect/vitest imports as "global vitest functions" because it doesn't recognize the package as a valid vitest source). That rule currently has to be disabled in Effect projects, which then loses its protection on plain-vitest files in the same repo.
Related
Summary
The
vitest/*plugin rules only fire when test functions (it,test,describe,expect, hooks, etc.) are imported fromvitest(or aliased sources likevite-plus/test). They do not recognize@effect/vitestas a valid vitest import source, so 28 of the 35 rules I tested silently fail to fire on test files that import from it.@effect/vitestis the official Effect testing integration: https://effect.website/docs/livesdk/testing/. It re-exports the entire vitest API (export * from "vitest") plus Effect-aware helpers (it.effect,it.live,layer(...),it.layer(...),it.effect.prop, etc.). It is the recommended way to test Effect code with Vitest, per the Effect testing guide.Environment
vite-plus(@oxlint/[email protected],@oxlint/[email protected])vp lint(Vite+ CLI)@effect/vitest:4.0.0-beta.83vitest: aliased to@voidzero-dev/vite-plus-test@latestvia pnpmnpm:override (a vitest fork) — same behavior reproduces with stockvitestReproduction
Two identical probe files, differing only in the import source:
Result
Rules affected
I tested 35 vitest rules with trigger cases. 28 silently fail to fire when the import source is
@effect/vitest; 7 fire regardless of import source.Silently broken on
@effect/vitest(28)These rules require resolving the import source to
vitestand do not recognize@effect/vitest:vitest/consistent-test-itvitest/expect-expectvitest/max-expectsvitest/no-alias-methodstoBeCalled→toHaveBeenCalled)vitest/no-conditional-expectvitest/no-disabled-testsit.skip)vitest/no-duplicate-hooksvitest/no-focused-testsit.only)vitest/no-hooksvitest/no-identical-titlevitest/prefer-called-oncevitest/prefer-called-timesvitest/prefer-called-withvitest/prefer-comparison-matchervitest/prefer-expect-assertionsvitest/prefer-expect-type-ofvitest/prefer-strict-equaltoEqual→toStrictEqual)vitest/prefer-to-betoEqual→toBefor primitives)vitest/prefer-to-be-falsyvitest/prefer-to-be-truthyvitest/prefer-to-containvitest/prefer-to-have-lengthvitest/prefer-todoit.todo)vitest/require-awaited-expect-pollvitest/require-test-timeoutvitest/require-to-throw-messagevitest/require-top-level-describevitest/valid-expectexpect(x)without matcher)Work regardless of import source (7)
These appear to pattern-match on call syntax rather than resolving the import source, so they fire on both:
vitest/no-conditional-in-testvitest/no-test-return-statementvitest/prefer-hooks-in-ordervitest/prefer-mock-promise-shorthandvitest/prefer-mock-return-shorthandvitest/prefer-spy-onvitest/require-mock-type-parametersSuggested fix
Treat
@effect/vitestas a recognized vitest import source. Two possible approaches:@effect/vitestalongsidevitestin the vitest plugin's import-source recognizer (smallest change).vitestImportSources: ["vitest", "@effect/vitest", ...]to the plugin config so projects can register additional re-exporting packages (more flexible; also coversvite-plus/test, private wrappers, etc.).Option 2 would also resolve the related false-positive on
vitest/no-importing-vitest-globals(which flags@effect/vitestimports as "global vitest functions" because it doesn't recognize the package as a valid vitest source). That rule currently has to be disabled in Effect projects, which then loses its protection on plain-vitest files in the same repo.Related
@effect/vitestpackage: https://github.com/Effect-TS/effect-smol/tree/main/packages/vitest@effect/vitestas the entrypoint for all Effect tests): https://effect.website/docs/livesdk/testing/vitest/consistent-test-itrule docs: https://oxc.rs/docs/guide/usage/linter/rules/vitest/consistent-test-it.html