From a5e1a593152e6719d9be478fd13f3291b0d9d6d8 Mon Sep 17 00:00:00 2001 From: jimmy-guzman Date: Tue, 5 Nov 2024 16:34:42 -0600 Subject: [PATCH] =?UTF-8?q?feat:=20=E2=9C=A8=20use=20`@vitest/eslint-plugi?= =?UTF-8?q?n`=20for=20`vitest`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 1 + pnpm-lock.yaml | 24 ++ scripts/typegen.ts | 7 +- src/configs/testing.spec.ts | 29 +- src/configs/testing.ts | 5 +- src/factory.spec.ts | 2 - src/rules.gen.d.ts | 402 ++++++++++++++++++++ src/rules/__snapshots__/vitest.spec.ts.snap | 105 +++-- src/rules/vitest.ts | 60 ++- 9 files changed, 538 insertions(+), 97 deletions(-) diff --git a/package.json b/package.json index bb88e48..6a7c724 100644 --- a/package.json +++ b/package.json @@ -53,6 +53,7 @@ "@types/eslint": "9.6.1", "@typescript-eslint/parser": "^8.16.0", "@typescript-eslint/utils": "^8.16.0", + "@vitest/eslint-plugin": "^1.1.14", "astro-eslint-parser": "^1.1.0", "eslint-config-prettier": "^9.1.0", "eslint-import-resolver-typescript": "^3.6.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 63d2006..f9e5d5a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -26,6 +26,9 @@ importers: '@typescript-eslint/utils': specifier: ^8.16.0 version: 8.16.0(eslint@9.15.0(jiti@2.4.1))(typescript@5.7.2) + '@vitest/eslint-plugin': + specifier: ^1.1.14 + version: 1.1.14(@typescript-eslint/utils@8.16.0(eslint@9.15.0(jiti@2.4.1))(typescript@5.7.2))(eslint@9.15.0(jiti@2.4.1))(typescript@5.7.2)(vitest@2.1.6(@types/node@22.10.1)) astro-eslint-parser: specifier: ^1.1.0 version: 1.1.0(typescript@5.7.2) @@ -1695,6 +1698,19 @@ packages: '@vitest/browser': optional: true + '@vitest/eslint-plugin@1.1.14': + resolution: {integrity: sha512-ej0cT5rUt7uvwxuu7Qxkm7fI+eaOq8vD34qGpuRoXCdvOybOlE5GDqtgvVCYbxLANkcRJfm5VDU1TnJmQRHi9g==} + peerDependencies: + '@typescript-eslint/utils': '>= 8.0' + eslint: '>= 8.57.0' + typescript: '>= 5.0.0' + vitest: '*' + peerDependenciesMeta: + typescript: + optional: true + vitest: + optional: true + '@vitest/expect@2.1.6': resolution: {integrity: sha512-9M1UR9CAmrhJOMoSwVnPh2rELPKhYo0m/CSgqw9PyStpxtkwhmdM6XYlXGKeYyERY1N6EIuzkQ7e3Lm1WKCoUg==} @@ -6769,6 +6785,14 @@ snapshots: transitivePeerDependencies: - supports-color + '@vitest/eslint-plugin@1.1.14(@typescript-eslint/utils@8.16.0(eslint@9.15.0(jiti@2.4.1))(typescript@5.7.2))(eslint@9.15.0(jiti@2.4.1))(typescript@5.7.2)(vitest@2.1.6(@types/node@22.10.1))': + dependencies: + '@typescript-eslint/utils': 8.16.0(eslint@9.15.0(jiti@2.4.1))(typescript@5.7.2) + eslint: 9.15.0(jiti@2.4.1) + optionalDependencies: + typescript: 5.7.2 + vitest: 2.1.6(@types/node@22.10.1) + '@vitest/expect@2.1.6': dependencies: '@vitest/spy': 2.1.6 diff --git a/scripts/typegen.ts b/scripts/typegen.ts index e136d06..4b6b918 100644 --- a/scripts/typegen.ts +++ b/scripts/typegen.ts @@ -5,7 +5,12 @@ import { builtinRules } from "eslint/use-at-your-own-risk"; import eslintConfig from "../src"; -const configs = await eslintConfig(); +const configs = await eslintConfig({ + testing: { + // TODO: remove when framework approach is removed + framework: "jest", + }, +}); const ruleDts = await flatConfigsToRulesDTS( [ diff --git a/src/configs/testing.spec.ts b/src/configs/testing.spec.ts index 1de5ae5..852e2a7 100644 --- a/src/configs/testing.spec.ts +++ b/src/configs/testing.spec.ts @@ -1,36 +1,15 @@ -import { ALLOWED_VITEST_FUNCS } from "../constants"; import { testingConfig } from "./testing"; describe("testingConfig", () => { - it("should create default config w/ vitest overrides", async () => { + it("should create default config w/ vitest", async () => { const [vitest] = await testingConfig({}, false); - expect(vitest?.rules).toStrictEqual( - expect.objectContaining({ - "jest/no-deprecated-functions": "off", - "jest/require-hook": [ - "error", - { - allowedFunctionCalls: ALLOWED_VITEST_FUNCS, - }, - ], - }), - ); + expect(vitest?.name).toBe("jimmy.codes/vitest"); }); - it("should create default config w/o vitest overrides", async () => { + it("should create default config w/ jest", async () => { const [jest] = await testingConfig({ framework: "jest" }, false); - expect(jest?.rules).toStrictEqual( - expect.not.objectContaining({ - "jest/no-deprecated-functions": "off", - "jest/require-hook": [ - "error", - { - allowedFunctionCalls: ALLOWED_VITEST_FUNCS, - }, - ], - }), - ); + expect(jest?.name).toBe("jimmy.codes/jest"); }); }); diff --git a/src/configs/testing.ts b/src/configs/testing.ts index 2c800a7..a45b8a2 100644 --- a/src/configs/testing.ts +++ b/src/configs/testing.ts @@ -16,12 +16,11 @@ export const testingConfig = async ( const configs: TypedConfigItem[] = []; if (isVitest) { - const jestPlugin = await interopDefault(import("eslint-plugin-jest")); + const vitestPlugin = await interopDefault(import("@vitest/eslint-plugin")); configs.push({ files: GLOB_TESTS, - ignores: GLOB_E2E, - ...jestPlugin.configs["flat/recommended"], + ...vitestPlugin.configs.recommended, name: "jimmy.codes/vitest", rules: await vitestRules(), }); diff --git a/src/factory.spec.ts b/src/factory.spec.ts index d15aee1..4997f7a 100644 --- a/src/factory.spec.ts +++ b/src/factory.spec.ts @@ -235,7 +235,6 @@ describe("eslintConfig", () => { it("should include react-query when auto detection is enabled", async () => { vi.mocked(isPackageExists).mockImplementation((name) => { - // eslint-disable-next-line jest/no-conditional-in-test -- this condition is only for the mock. return name === "react" || name === "@tanstack/react-query"; }); @@ -289,7 +288,6 @@ describe("eslintConfig", () => { it("should include test-library when auto detection is enabled", async () => { vi.mocked(isPackageExists).mockImplementation((name) => { - // eslint-disable-next-line jest/no-conditional-in-test -- this condition is only for the mock. return name === "@testing-library/react" || name === "vitest"; }); diff --git a/src/rules.gen.d.ts b/src/rules.gen.d.ts index 366de1d..d0ebc4a 100644 --- a/src/rules.gen.d.ts +++ b/src/rules.gen.d.ts @@ -5692,6 +5692,317 @@ export interface RuleOptions { * @see https://eslint.org/docs/latest/rules/vars-on-top */ 'vars-on-top'?: Linter.RuleEntry<[]> + /** + * require .spec test file pattern + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/consistent-test-filename.md + */ + 'vitest/consistent-test-filename'?: Linter.RuleEntry + /** + * enforce using test or it but not both + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/consistent-test-it.md + */ + 'vitest/consistent-test-it'?: Linter.RuleEntry + /** + * enforce having expectation in test body + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/expect-expect.md + */ + 'vitest/expect-expect'?: Linter.RuleEntry + /** + * enforce a maximum number of expect per test + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/max-expects.md + */ + 'vitest/max-expects'?: Linter.RuleEntry + /** + * require describe block to be less than set max value or default value + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/max-nested-describe.md + */ + 'vitest/max-nested-describe'?: Linter.RuleEntry + /** + * disallow alias methods + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-alias-methods.md + */ + 'vitest/no-alias-methods'?: Linter.RuleEntry<[]> + /** + * disallow commented out tests + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-commented-out-tests.md + */ + 'vitest/no-commented-out-tests'?: Linter.RuleEntry<[]> + /** + * disallow conditional expects + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-conditional-expect.md + */ + 'vitest/no-conditional-expect'?: Linter.RuleEntry<[]> + /** + * disallow conditional tests + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-conditional-in-test.md + */ + 'vitest/no-conditional-in-test'?: Linter.RuleEntry<[]> + /** + * disallow conditional tests + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-conditional-tests.md + */ + 'vitest/no-conditional-tests'?: Linter.RuleEntry<[]> + /** + * disallow disabled tests + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-disabled-tests.md + */ + 'vitest/no-disabled-tests'?: Linter.RuleEntry<[]> + /** + * disallow using a callback in asynchronous tests and hooks + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-done-callback.md + * @deprecated + */ + 'vitest/no-done-callback'?: Linter.RuleEntry<[]> + /** + * disallow duplicate hooks and teardown hooks + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-duplicate-hooks.md + */ + 'vitest/no-duplicate-hooks'?: Linter.RuleEntry<[]> + /** + * disallow focused tests + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-focused-tests.md + */ + 'vitest/no-focused-tests'?: Linter.RuleEntry + /** + * disallow setup and teardown hooks + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-hooks.md + */ + 'vitest/no-hooks'?: Linter.RuleEntry + /** + * disallow identical titles + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-identical-title.md + */ + 'vitest/no-identical-title'?: Linter.RuleEntry<[]> + /** + * disallow importing `node:test` + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-import-node-test.md + */ + 'vitest/no-import-node-test'?: Linter.RuleEntry<[]> + /** + * disallow string interpolation in snapshots + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-interpolation-in-snapshots.md + */ + 'vitest/no-interpolation-in-snapshots'?: Linter.RuleEntry<[]> + /** + * disallow large snapshots + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-large-snapshots.md + */ + 'vitest/no-large-snapshots'?: Linter.RuleEntry + /** + * disallow importing from __mocks__ directory + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-mocks-import.md + */ + 'vitest/no-mocks-import'?: Linter.RuleEntry<[]> + /** + * disallow the use of certain matchers + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-restricted-matchers.md + */ + 'vitest/no-restricted-matchers'?: Linter.RuleEntry + /** + * disallow specific `vi.` methods + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-restricted-vi-methods.md + */ + 'vitest/no-restricted-vi-methods'?: Linter.RuleEntry + /** + * disallow using `expect` outside of `it` or `test` blocks + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-standalone-expect.md + */ + 'vitest/no-standalone-expect'?: Linter.RuleEntry + /** + * disallow using `test` as a prefix + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-test-prefixes.md + */ + 'vitest/no-test-prefixes'?: Linter.RuleEntry<[]> + /** + * disallow return statements in tests + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/no-test-return-statement.md + */ + 'vitest/no-test-return-statement'?: Linter.RuleEntry<[]> + /** + * Enforce padding around `afterAll` blocks + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/padding-around-after-all-blocks.md + */ + 'vitest/padding-around-after-all-blocks'?: Linter.RuleEntry<[]> + /** + * Enforce padding around `afterEach` blocks + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/padding-around-after-each-blocks.md + */ + 'vitest/padding-around-after-each-blocks'?: Linter.RuleEntry<[]> + /** + * Enforce padding around vitest functions + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/padding-around-all.md + */ + 'vitest/padding-around-all'?: Linter.RuleEntry<[]> + /** + * Enforce padding around `beforeAll` blocks + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/padding-around-before-all-blocks.md + */ + 'vitest/padding-around-before-all-blocks'?: Linter.RuleEntry<[]> + /** + * Enforce padding around `beforeEach` blocks + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/padding-around-before-each-blocks.md + */ + 'vitest/padding-around-before-each-blocks'?: Linter.RuleEntry<[]> + /** + * Enforce padding around `describe` blocks + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/padding-around-describe-blocks.md + */ + 'vitest/padding-around-describe-blocks'?: Linter.RuleEntry<[]> + /** + * Enforce padding around `expect` groups + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/padding-around-expect-groups.md + */ + 'vitest/padding-around-expect-groups'?: Linter.RuleEntry<[]> + /** + * Enforce padding around afterAll blocks + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/padding-around-test-blocks.md + */ + 'vitest/padding-around-test-blocks'?: Linter.RuleEntry<[]> + /** + * enforce using `toBeCalledWith()` or `toHaveBeenCalledWith()` + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-called-with.md + */ + 'vitest/prefer-called-with'?: Linter.RuleEntry<[]> + /** + * enforce using the built-in comparison matchers + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-comparison-matcher.md + */ + 'vitest/prefer-comparison-matcher'?: Linter.RuleEntry<[]> + /** + * enforce using `each` rather than manual loops + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-each.md + */ + 'vitest/prefer-each'?: Linter.RuleEntry<[]> + /** + * enforce using the built-in quality matchers + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-equality-matcher.md + */ + 'vitest/prefer-equality-matcher'?: Linter.RuleEntry<[]> + /** + * enforce using expect assertions instead of callbacks + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-expect-assertions.md + */ + 'vitest/prefer-expect-assertions'?: Linter.RuleEntry + /** + * enforce using `expect().resolves` over `expect(await ...)` syntax + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-expect-resolves.md + */ + 'vitest/prefer-expect-resolves'?: Linter.RuleEntry<[]> + /** + * enforce having hooks in consistent order + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-hooks-in-order.md + */ + 'vitest/prefer-hooks-in-order'?: Linter.RuleEntry<[]> + /** + * enforce having hooks before any test cases + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-hooks-on-top.md + */ + 'vitest/prefer-hooks-on-top'?: Linter.RuleEntry<[]> + /** + * enforce lowercase titles + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-lowercase-title.md + */ + 'vitest/prefer-lowercase-title'?: Linter.RuleEntry + /** + * enforce mock resolved/rejected shorthands for promises + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-mock-promise-shorthand.md + */ + 'vitest/prefer-mock-promise-shorthand'?: Linter.RuleEntry<[]> + /** + * enforce including a hint with external snapshots + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-snapshot-hint.md + */ + 'vitest/prefer-snapshot-hint'?: Linter.RuleEntry + /** + * enforce using `vi.spyOn` + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-spy-on.md + */ + 'vitest/prefer-spy-on'?: Linter.RuleEntry<[]> + /** + * enforce strict equal over equal + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-strict-equal.md + */ + 'vitest/prefer-strict-equal'?: Linter.RuleEntry<[]> + /** + * enforce using toBe() + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-to-be.md + */ + 'vitest/prefer-to-be'?: Linter.RuleEntry<[]> + /** + * enforce using toBeFalsy() + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-to-be-falsy.md + */ + 'vitest/prefer-to-be-falsy'?: Linter.RuleEntry<[]> + /** + * enforce using toBeObject() + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-to-be-object.md + */ + 'vitest/prefer-to-be-object'?: Linter.RuleEntry<[]> + /** + * enforce using `toBeTruthy` + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-to-be-truthy.md + */ + 'vitest/prefer-to-be-truthy'?: Linter.RuleEntry<[]> + /** + * enforce using toContain() + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-to-contain.md + */ + 'vitest/prefer-to-contain'?: Linter.RuleEntry<[]> + /** + * enforce using toHaveLength() + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-to-have-length.md + */ + 'vitest/prefer-to-have-length'?: Linter.RuleEntry<[]> + /** + * enforce using `test.todo` + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-todo.md + */ + 'vitest/prefer-todo'?: Linter.RuleEntry<[]> + /** + * Prefer `vi.mocked()` over `fn as Mock` + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/prefer-vi-mocked.md + */ + 'vitest/prefer-vi-mocked'?: Linter.RuleEntry<[]> + /** + * require setup and teardown to be within a hook + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/require-hook.md + */ + 'vitest/require-hook'?: Linter.RuleEntry + /** + * require local Test Context for concurrent snapshot tests + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/require-local-test-context-for-concurrent-snapshots.md + */ + 'vitest/require-local-test-context-for-concurrent-snapshots'?: Linter.RuleEntry<[]> + /** + * require toThrow() to be called with an error message + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/require-to-throw-message.md + */ + 'vitest/require-to-throw-message'?: Linter.RuleEntry<[]> + /** + * enforce that all tests are in a top-level describe + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/require-top-level-describe.md + */ + 'vitest/require-top-level-describe'?: Linter.RuleEntry + /** + * enforce valid describe callback + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/valid-describe-callback.md + */ + 'vitest/valid-describe-callback'?: Linter.RuleEntry<[]> + /** + * enforce valid `expect()` usage + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/valid-expect.md + */ + 'vitest/valid-expect'?: Linter.RuleEntry + /** + * Require promises that have expectations in their chain to be valid + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/valid-expect-in-promise.md + */ + 'vitest/valid-expect-in-promise'?: Linter.RuleEntry<[]> + /** + * enforce valid titles + * @see https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/valid-title.md + */ + 'vitest/valid-title'?: Linter.RuleEntry /** * Require parentheses around immediate `function` invocations * @see https://eslint.org/docs/latest/rules/wrap-iife @@ -10771,6 +11082,97 @@ type UseIsnan = []|[{ type ValidTypeof = []|[{ requireStringLiterals?: boolean }] +// ----- vitest/consistent-test-filename ----- +type VitestConsistentTestFilename = []|[{ + pattern?: string + allTestPattern?: string +}] +// ----- vitest/consistent-test-it ----- +type VitestConsistentTestIt = []|[{ + fn?: ("test" | "it") + withinDescribe?: ("test" | "it") +}] +// ----- vitest/expect-expect ----- +type VitestExpectExpect = []|[{ + assertFunctionNames?: string[] + additionalTestBlockFunctions?: string[] +}] +// ----- vitest/max-expects ----- +type VitestMaxExpects = []|[{ + max?: number +}] +// ----- vitest/max-nested-describe ----- +type VitestMaxNestedDescribe = []|[{ + max?: number +}] +// ----- vitest/no-focused-tests ----- +type VitestNoFocusedTests = []|[{ + fixable?: boolean +}] +// ----- vitest/no-hooks ----- +type VitestNoHooks = []|[{ + allow?: unknown[] +}] +// ----- vitest/no-large-snapshots ----- +type VitestNoLargeSnapshots = []|[{ + maxSize?: number + inlineMaxSize?: number + allowedSnapshots?: { + [k: string]: unknown[] | undefined + } +}] +// ----- vitest/no-restricted-matchers ----- +type VitestNoRestrictedMatchers = []|[{ + [k: string]: (string | null) | undefined +}] +// ----- vitest/no-restricted-vi-methods ----- +type VitestNoRestrictedViMethods = []|[{ + [k: string]: (string | null) | undefined +}] +// ----- vitest/no-standalone-expect ----- +type VitestNoStandaloneExpect = []|[{ + additionaltestblockfunctions?: string[] + [k: string]: unknown | undefined +}] +// ----- vitest/prefer-expect-assertions ----- +type VitestPreferExpectAssertions = []|[{ + onlyFunctionsWithAsyncKeyword?: boolean + onlyFunctionsWithExpectInLoop?: boolean + onlyFunctionsWithExpectInCallback?: boolean +}] +// ----- vitest/prefer-lowercase-title ----- +type VitestPreferLowercaseTitle = []|[{ + ignore?: ("describe" | "test" | "it")[] + allowedPrefixes?: string[] + ignoreTopLevelDescribe?: boolean + lowercaseFirstCharacterOnly?: boolean +}] +// ----- vitest/prefer-snapshot-hint ----- +type VitestPreferSnapshotHint = []|[("always" | "multi")] +// ----- vitest/require-hook ----- +type VitestRequireHook = []|[{ + allowedFunctionCalls?: string[] +}] +// ----- vitest/require-top-level-describe ----- +type VitestRequireTopLevelDescribe = []|[{ + maxNumberOfTopLevelDescribes?: number +}] +// ----- vitest/valid-expect ----- +type VitestValidExpect = []|[{ + alwaysAwait?: boolean + asyncMatchers?: string[] + minArgs?: number + maxArgs?: number +}] +// ----- vitest/valid-title ----- +type VitestValidTitle = []|[{ + ignoreTypeOfDescribeName?: boolean + allowArguments?: boolean + disallowedWords?: string[] + [k: string]: (string | [string]|[string, string] | { + [k: string]: (string | [string]|[string, string]) | undefined + }) +}] // ----- wrap-iife ----- type WrapIife = []|[("outside" | "inside" | "any")]|[("outside" | "inside" | "any"), { functionPrototypeMethods?: boolean diff --git a/src/rules/__snapshots__/vitest.spec.ts.snap b/src/rules/__snapshots__/vitest.spec.ts.snap index 5533b32..dc72e88 100644 --- a/src/rules/__snapshots__/vitest.spec.ts.snap +++ b/src/rules/__snapshots__/vitest.spec.ts.snap @@ -2,71 +2,56 @@ exports[`should create vitest rules 1`] = ` { - "jest/consistent-test-it": [ + "vitest/consistent-test-it": [ "error", { "fn": "test", "withinDescribe": "it", }, ], - "jest/expect-expect": "error", - "jest/no-alias-methods": "error", - "jest/no-commented-out-tests": "error", - "jest/no-conditional-expect": "error", - "jest/no-conditional-in-test": "error", - "jest/no-confusing-set-timeout": "error", - "jest/no-deprecated-functions": "off", - "jest/no-disabled-tests": "warn", - "jest/no-done-callback": "error", - "jest/no-duplicate-hooks": "error", - "jest/no-export": "error", - "jest/no-focused-tests": "error", - "jest/no-hooks": "off", - "jest/no-identical-title": "error", - "jest/no-interpolation-in-snapshots": "error", - "jest/no-jasmine-globals": "error", - "jest/no-large-snapshots": "off", - "jest/no-mocks-import": "error", - "jest/no-restricted-jest-methods": "off", - "jest/no-restricted-matchers": "off", - "jest/no-standalone-expect": "error", - "jest/no-test-prefixes": "error", - "jest/no-test-return-statement": "error", - "jest/no-untyped-mock-factory": "off", - "jest/prefer-called-with": "error", - "jest/prefer-comparison-matcher": "error", - "jest/prefer-each": "error", - "jest/prefer-equality-matcher": "error", - "jest/prefer-expect-assertions": "off", - "jest/prefer-expect-resolves": "error", - "jest/prefer-hooks-in-order": "error", - "jest/prefer-hooks-on-top": "error", - "jest/prefer-lowercase-title": "off", - "jest/prefer-mock-promise-shorthand": "error", - "jest/prefer-snapshot-hint": "error", - "jest/prefer-spy-on": "off", - "jest/prefer-strict-equal": "error", - "jest/prefer-to-be": "error", - "jest/prefer-to-contain": "error", - "jest/prefer-to-have-length": "error", - "jest/prefer-todo": "warn", - "jest/require-hook": [ - "error", - { - "allowedFunctionCalls": [ - "vi.mock", - "describe", - "expect", - "it", - ], - }, - ], - "jest/require-to-throw-message": "error", - "jest/require-top-level-describe": "off", - "jest/unbound-method": "off", - "jest/valid-describe-callback": "error", - "jest/valid-expect": "error", - "jest/valid-expect-in-promise": "error", - "jest/valid-title": "error", + "vitest/expect-expect": "error", + "vitest/no-alias-methods": "error", + "vitest/no-commented-out-tests": "error", + "vitest/no-conditional-in-test": "error", + "vitest/no-disabled-tests": "warn", + "vitest/no-done-callback": "error", + "vitest/no-duplicate-hooks": "error", + "vitest/no-focused-tests": "error", + "vitest/no-hooks": "off", + "vitest/no-identical-title": "error", + "vitest/no-import-node-test": "error", + "vitest/no-interpolation-in-snapshots": "error", + "vitest/no-large-snapshots": "off", + "vitest/no-mocks-import": "error", + "vitest/no-restricted-matchers": "off", + "vitest/no-restricted-vi-methods": "off", + "vitest/no-standalone-expect": "error", + "vitest/no-test-prefixes": "error", + "vitest/no-test-return-statement": "error", + "vitest/prefer-called-with": "error", + "vitest/prefer-comparison-matcher": "error", + "vitest/prefer-each": "error", + "vitest/prefer-equality-matcher": "error", + "vitest/prefer-expect-assertions": "off", + "vitest/prefer-expect-resolves": "error", + "vitest/prefer-hooks-in-order": "error", + "vitest/prefer-hooks-on-top": "error", + "vitest/prefer-lowercase-title": "off", + "vitest/prefer-mock-promise-shorthand": "error", + "vitest/prefer-snapshot-hint": "error", + "vitest/prefer-spy-on": "off", + "vitest/prefer-strict-equal": "error", + "vitest/prefer-to-be": "error", + "vitest/prefer-to-contain": "error", + "vitest/prefer-to-have-length": "error", + "vitest/prefer-todo": "warn", + "vitest/require-hook": "error", + "vitest/require-local-test-context-for-concurrent-snapshots": "error", + "vitest/require-to-throw-message": "error", + "vitest/require-top-level-describe": "off", + "vitest/valid-describe-callback": "error", + "vitest/valid-expect": "error", + "vitest/valid-expect-in-promise": "error", + "vitest/valid-title": "error", } `; diff --git a/src/rules/vitest.ts b/src/rules/vitest.ts index fa7ca2c..e1d4895 100644 --- a/src/rules/vitest.ts +++ b/src/rules/vitest.ts @@ -1,17 +1,65 @@ import type { Rules } from "../types"; -import { ALLOWED_VITEST_FUNCS } from "../constants"; -import { jestRules } from "./jest"; +import { interopDefault } from "../utils/interop-default"; export const vitestRules = async () => { + const vitestPlugin = await interopDefault(import("@vitest/eslint-plugin")); + return { - ...(await jestRules()), - "jest/no-deprecated-functions": "off", - "jest/require-hook": [ + ...vitestPlugin.configs.recommended.rules, + "vitest/consistent-test-it": [ "error", { - allowedFunctionCalls: ALLOWED_VITEST_FUNCS, + fn: "test", + withinDescribe: "it", }, ], + "vitest/no-alias-methods": "error", + "vitest/no-commented-out-tests": "error", + "vitest/no-conditional-in-test": "error", + // "vitest/no-confusing-set-timeout": "error", // missing + // "vitest/no-deprecated-functions": "error", // missing + "vitest/no-disabled-tests": "warn", + "vitest/no-done-callback": "error", + "vitest/no-duplicate-hooks": "error", + // "vitest/no-export": "error", // missing + "vitest/no-focused-tests": "error", + "vitest/no-hooks": "off", + "vitest/no-identical-title": "error", + "vitest/no-interpolation-in-snapshots": "error", + // "vitest/no-jasmine-globals": "error", // missing + "vitest/no-large-snapshots": "off", + "vitest/no-mocks-import": "error", + "vitest/no-restricted-matchers": "off", + "vitest/no-restricted-vi-methods": "off", + "vitest/no-standalone-expect": "error", + "vitest/no-test-prefixes": "error", + "vitest/no-test-return-statement": "error", + // "vitest/no-untyped-mock-factory": "off", // requires typescript + "vitest/prefer-called-with": "error", + "vitest/prefer-comparison-matcher": "error", + "vitest/prefer-each": "error", + "vitest/prefer-equality-matcher": "error", + "vitest/prefer-expect-assertions": "off", + "vitest/prefer-expect-resolves": "error", + "vitest/prefer-hooks-in-order": "error", + "vitest/prefer-hooks-on-top": "error", + "vitest/prefer-lowercase-title": "off", + "vitest/prefer-mock-promise-shorthand": "error", + "vitest/prefer-snapshot-hint": "error", + "vitest/prefer-spy-on": "off", + "vitest/prefer-strict-equal": "error", + "vitest/prefer-to-be": "error", + "vitest/prefer-to-contain": "error", + "vitest/prefer-to-have-length": "error", + "vitest/prefer-todo": "warn", + "vitest/require-hook": "error", + "vitest/require-to-throw-message": "error", + "vitest/require-top-level-describe": "off", + // "vitest/unbound-method": "off", // requires typescript, missing https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/unbound-method.md + "vitest/valid-describe-callback": "error", + "vitest/valid-expect": "error", + "vitest/valid-expect-in-promise": "error", + "vitest/valid-title": "error", } satisfies Rules; };