diff --git a/docs/Migration.md b/docs/Migration.md index 262f7cb12..ef03d0276 100644 --- a/docs/Migration.md +++ b/docs/Migration.md @@ -18,7 +18,7 @@ For example, if the repository previously using Jest for testing: - `eslint-plugin-jest`, `jest`, and other Jest-related packages will be uninstalled - Any Jest config file like `jest.config.js` will be deleted -- `eslint-plugin-vitest`, `vitest`, and other Vitest-related packages will be installed +- `@vitest/eslint-plugin`, `vitest`, and other Vitest-related packages will be installed - A `vitest.config.ts` file will be created You'll then need to manually go through the following two steps to set up tooling on GitHub: diff --git a/docs/Tooling.md b/docs/Tooling.md index 37b10f0ce..180ded8a2 100644 --- a/docs/Tooling.md +++ b/docs/Tooling.md @@ -192,8 +192,8 @@ pnpm run lint:knip Additionally: +- [`@vitest/eslint-plugin`](https://github.com/vitest-dev/eslint-plugin-vitest) will be added to the ESLint config to lint for Vitest-specific issues - [`console-fail-test`](https://github.com/JoshuaKGoldberg/console-fail-test) will also be added to ensure tests don't accidentally log to the console. -- [`eslint-plugin-vitest`](https://github.com/veritem/eslint-plugin-vitest) will be added to the ESLint config to lint for Vitest-specific issues Running tests in watch mode: diff --git a/eslint.config.js b/eslint.config.js index cd03c8c85..6a5a2a17f 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -10,6 +10,7 @@ If you're interested in learning more, see the 'getting started' docs on: import eslint from "@eslint/js"; import comments from "@eslint-community/eslint-plugin-eslint-comments/configs"; +import vitest from "@vitest/eslint-plugin"; import jsdoc from "eslint-plugin-jsdoc"; import jsonc from "eslint-plugin-jsonc"; import markdown from "eslint-plugin-markdown"; @@ -17,7 +18,6 @@ import n from "eslint-plugin-n"; import packageJson from "eslint-plugin-package-json/configs/recommended"; import perfectionist from "eslint-plugin-perfectionist"; import * as regexp from "eslint-plugin-regexp"; -import vitest from "eslint-plugin-vitest"; import yml from "eslint-plugin-yml"; import tseslint from "typescript-eslint"; diff --git a/package.json b/package.json index 08c7cb4cb..2d5963b8f 100644 --- a/package.json +++ b/package.json @@ -72,6 +72,7 @@ "@types/node": "^22.1.0", "@types/parse-author": "^2.0.3", "@vitest/coverage-v8": "^2.0.5", + "@vitest/eslint-plugin": "^1.0.1", "c8": "^10.1.2", "console-fail-test": "^0.4.4", "cspell": "^8.13.1", @@ -83,7 +84,6 @@ "eslint-plugin-package-json": "^0.15.2", "eslint-plugin-perfectionist": "^3.1.3", "eslint-plugin-regexp": "^2.6.0", - "eslint-plugin-vitest": "^0.5.4", "eslint-plugin-yml": "^1.14.0", "globby": "^14.0.2", "husky": "^9.1.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6ccb5ef4e..598a8ecf0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -96,6 +96,9 @@ importers: '@vitest/coverage-v8': specifier: ^2.0.5 version: 2.0.5(vitest@2.0.5(@types/node@22.1.0)) + '@vitest/eslint-plugin': + specifier: ^1.0.1 + version: 1.0.1(@typescript-eslint/utils@8.0.1(eslint@9.8.0)(typescript@5.5.4))(eslint@9.8.0)(typescript@5.5.4)(vitest@2.0.5(@types/node@22.1.0)) c8: specifier: ^10.1.2 version: 10.1.2 @@ -129,9 +132,6 @@ importers: eslint-plugin-regexp: specifier: ^2.6.0 version: 2.6.0(eslint@9.8.0) - eslint-plugin-vitest: - specifier: ^0.5.4 - version: 0.5.4(eslint@9.8.0)(typescript@5.5.4)(vitest@2.0.5(@types/node@22.1.0)) eslint-plugin-yml: specifier: ^1.14.0 version: 1.14.0(eslint@9.8.0) @@ -1398,10 +1398,6 @@ packages: typescript: optional: true - '@typescript-eslint/scope-manager@7.18.0': - resolution: {integrity: sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==} - engines: {node: ^18.18.0 || >=20.0.0} - '@typescript-eslint/scope-manager@8.0.1': resolution: {integrity: sha512-NpixInP5dm7uukMiRyiHjRKkom5RIFA4dfiHvalanD2cF0CLUuQqxfg8PtEUo9yqJI2bBhF+pcSafqnG3UBnRQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -1415,23 +1411,10 @@ packages: typescript: optional: true - '@typescript-eslint/types@7.18.0': - resolution: {integrity: sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==} - engines: {node: ^18.18.0 || >=20.0.0} - '@typescript-eslint/types@8.0.1': resolution: {integrity: sha512-PpqTVT3yCA/bIgJ12czBuE3iBlM3g4inRSC5J0QOdQFAn07TYrYEQBBKgXH1lQpglup+Zy6c1fxuwTk4MTNKIw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@7.18.0': - resolution: {integrity: sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==} - engines: {node: ^18.18.0 || >=20.0.0} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - '@typescript-eslint/typescript-estree@8.0.1': resolution: {integrity: sha512-8V9hriRvZQXPWU3bbiUV4Epo7EvgM6RTs+sUmxp5G//dBGy402S7Fx0W0QkB2fb4obCF8SInoUzvTYtc3bkb5w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -1441,22 +1424,12 @@ packages: typescript: optional: true - '@typescript-eslint/utils@7.18.0': - resolution: {integrity: sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw==} - engines: {node: ^18.18.0 || >=20.0.0} - peerDependencies: - eslint: ^8.56.0 - '@typescript-eslint/utils@8.0.1': resolution: {integrity: sha512-CBFR0G0sCt0+fzfnKaciu9IBsKvEKYwN9UZ+eeogK1fYHg4Qxk1yf/wLQkLXlq8wbU2dFlgAesxt8Gi76E8RTA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 - '@typescript-eslint/visitor-keys@7.18.0': - resolution: {integrity: sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==} - engines: {node: ^18.18.0 || >=20.0.0} - '@typescript-eslint/visitor-keys@8.0.1': resolution: {integrity: sha512-W5E+o0UfUcK5EgchLZsyVWqARmsM7v54/qEq6PY3YI5arkgmCzHiuk0zKSJJbm71V0xdRna4BGomkCTXz2/LkQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -1466,6 +1439,21 @@ packages: peerDependencies: vitest: 2.0.5 + '@vitest/eslint-plugin@1.0.1': + resolution: {integrity: sha512-albpL56cL9XMwHJWCWZqjDxkuDkBXBF3WpPGOv6q2WA3cipCP41cKEwfSGktoRNGmPN77wuX452O8pM+z+ApNw==} + peerDependencies: + '@typescript-eslint/utils': '>= 8.0' + eslint: '>= 8.57.0' + typescript: '>= 5.0.0' + vitest: '*' + peerDependenciesMeta: + '@typescript-eslint/utils': + optional: true + typescript: + optional: true + vitest: + optional: true + '@vitest/expect@2.0.5': resolution: {integrity: sha512-yHZtwuP7JZivj65Gxoi8upUN2OzHTi3zVfjwdpu2WrvCZPLwsJ2Ey5ILIPccoW23dd/zQBlJ4/dhi7DWNyXCpA==} @@ -2260,19 +2248,6 @@ packages: peerDependencies: eslint: '>=8.44.0' - eslint-plugin-vitest@0.5.4: - resolution: {integrity: sha512-um+odCkccAHU53WdKAw39MY61+1x990uXjSPguUCq3VcEHdqJrOb8OTMrbYlY6f9jAKx7x98kLVlIe3RJeJqoQ==} - engines: {node: ^18.0.0 || >= 20.0.0} - peerDependencies: - '@typescript-eslint/eslint-plugin': '*' - eslint: ^8.57.0 || ^9.0.0 - vitest: '*' - peerDependenciesMeta: - '@typescript-eslint/eslint-plugin': - optional: true - vitest: - optional: true - eslint-plugin-yml@1.14.0: resolution: {integrity: sha512-ESUpgYPOcAYQO9czugcX5OqRvn/ydDVwGCPXY4YjPqc09rHaUVUA6IE6HLQys4rXk/S+qx3EwTd1wHCwam/OWQ==} engines: {node: ^14.17.0 || >=16.0.0} @@ -5390,11 +5365,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@7.18.0': - dependencies: - '@typescript-eslint/types': 7.18.0 - '@typescript-eslint/visitor-keys': 7.18.0 - '@typescript-eslint/scope-manager@8.0.1': dependencies: '@typescript-eslint/types': 8.0.1 @@ -5412,25 +5382,8 @@ snapshots: - eslint - supports-color - '@typescript-eslint/types@7.18.0': {} - '@typescript-eslint/types@8.0.1': {} - '@typescript-eslint/typescript-estree@7.18.0(typescript@5.5.4)': - dependencies: - '@typescript-eslint/types': 7.18.0 - '@typescript-eslint/visitor-keys': 7.18.0 - debug: 4.3.6 - globby: 11.1.0 - is-glob: 4.0.3 - minimatch: 9.0.5 - semver: 7.6.3 - ts-api-utils: 1.3.0(typescript@5.5.4) - optionalDependencies: - typescript: 5.5.4 - transitivePeerDependencies: - - supports-color - '@typescript-eslint/typescript-estree@8.0.1(typescript@5.5.4)': dependencies: '@typescript-eslint/types': 8.0.1 @@ -5446,17 +5399,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@7.18.0(eslint@9.8.0)(typescript@5.5.4)': - dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@9.8.0) - '@typescript-eslint/scope-manager': 7.18.0 - '@typescript-eslint/types': 7.18.0 - '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.5.4) - eslint: 9.8.0 - transitivePeerDependencies: - - supports-color - - typescript - '@typescript-eslint/utils@8.0.1(eslint@9.8.0)(typescript@5.5.4)': dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@9.8.0) @@ -5468,11 +5410,6 @@ snapshots: - supports-color - typescript - '@typescript-eslint/visitor-keys@7.18.0': - dependencies: - '@typescript-eslint/types': 7.18.0 - eslint-visitor-keys: 3.4.3 - '@typescript-eslint/visitor-keys@8.0.1': dependencies: '@typescript-eslint/types': 8.0.1 @@ -5496,6 +5433,14 @@ snapshots: transitivePeerDependencies: - supports-color + '@vitest/eslint-plugin@1.0.1(@typescript-eslint/utils@8.0.1(eslint@9.8.0)(typescript@5.5.4))(eslint@9.8.0)(typescript@5.5.4)(vitest@2.0.5(@types/node@22.1.0))': + dependencies: + eslint: 9.8.0 + optionalDependencies: + '@typescript-eslint/utils': 8.0.1(eslint@9.8.0)(typescript@5.5.4) + typescript: 5.5.4 + vitest: 2.0.5(@types/node@22.1.0) + '@vitest/expect@2.0.5': dependencies: '@vitest/spy': 2.0.5 @@ -6427,16 +6372,6 @@ snapshots: regexp-ast-analysis: 0.7.1 scslre: 0.3.0 - eslint-plugin-vitest@0.5.4(eslint@9.8.0)(typescript@5.5.4)(vitest@2.0.5(@types/node@22.1.0)): - dependencies: - '@typescript-eslint/utils': 7.18.0(eslint@9.8.0)(typescript@5.5.4) - eslint: 9.8.0 - optionalDependencies: - vitest: 2.0.5(@types/node@22.1.0) - transitivePeerDependencies: - - supports-color - - typescript - eslint-plugin-yml@1.14.0(eslint@9.8.0): dependencies: debug: 4.3.6 diff --git a/script/__snapshots__/migrate-test-e2e.ts.snap b/script/__snapshots__/migrate-test-e2e.ts.snap index f680a0754..d63b57813 100644 --- a/script/__snapshots__/migrate-test-e2e.ts.snap +++ b/script/__snapshots__/migrate-test-e2e.ts.snap @@ -110,7 +110,7 @@ exports[`expected file changes > eslint.config.js 1`] = ` - import eslint from "@eslint/js"; import comments from "@eslint-community/eslint-plugin-eslint-comments/configs"; - import jsdoc from "eslint-plugin-jsdoc"; + import vitest from "@vitest/eslint-plugin"; @@ ... @@ export default tseslint.config( languageOptions: { parserOptions: { diff --git a/src/steps/finalizeDependencies.test.ts b/src/steps/finalizeDependencies.test.ts index a8a513ccc..8bb34ad9e 100644 --- a/src/steps/finalizeDependencies.test.ts +++ b/src/steps/finalizeDependencies.test.ts @@ -38,7 +38,7 @@ describe("finalize", () => { expect(mockExecaCommand.mock.calls).toMatchInlineSnapshot(` [ [ - "pnpm add @eslint-community/eslint-plugin-eslint-comments@latest @eslint/js@latest @release-it/conventional-changelog@latest @types/eslint-plugin-markdown@latest @types/eslint__js@latest @types/node@latest @vitest/coverage-v8@latest all-contributors-cli@latest console-fail-test@latest cspell@latest eslint@latest eslint-plugin-jsdoc@latest eslint-plugin-jsonc@latest eslint-plugin-markdown@latest eslint-plugin-n@latest eslint-plugin-package-json@latest eslint-plugin-perfectionist@latest eslint-plugin-regexp@latest eslint-plugin-vitest@latest eslint-plugin-yml@latest husky@latest jsonc-eslint-parser@latest knip@latest lint-staged@latest markdownlint@latest markdownlint-cli@latest prettier@latest prettier-plugin-curly@latest prettier-plugin-packagejson@latest prettier-plugin-sh@latest release-it@latest sentences-per-line@latest tsup@latest typescript@latest typescript-eslint@latest vitest@latest -D", + "pnpm add @eslint-community/eslint-plugin-eslint-comments@latest @eslint/js@latest @release-it/conventional-changelog@latest @types/eslint-plugin-markdown@latest @types/eslint__js@latest @types/node@latest @vitest/coverage-v8@latest @vitest/eslint-plugin@latest all-contributors-cli@latest console-fail-test@latest cspell@latest eslint@latest eslint-plugin-jsdoc@latest eslint-plugin-jsonc@latest eslint-plugin-markdown@latest eslint-plugin-n@latest eslint-plugin-package-json@latest eslint-plugin-perfectionist@latest eslint-plugin-regexp@latest eslint-plugin-yml@latest husky@latest jsonc-eslint-parser@latest knip@latest lint-staged@latest markdownlint@latest markdownlint-cli@latest prettier@latest prettier-plugin-curly@latest prettier-plugin-packagejson@latest prettier-plugin-sh@latest release-it@latest sentences-per-line@latest tsup@latest typescript@latest typescript-eslint@latest vitest@latest -D", ], [ "npx all-contributors-cli generate", @@ -59,7 +59,7 @@ describe("finalize", () => { expect(mockExecaCommand.mock.calls).toMatchInlineSnapshot(` [ [ - "pnpm add @eslint-community/eslint-plugin-eslint-comments@latest @eslint/js@latest @release-it/conventional-changelog@latest @types/eslint-plugin-markdown@latest @types/eslint__js@latest @types/node@latest @vitest/coverage-v8@latest all-contributors-cli@latest console-fail-test@latest cspell@latest eslint@latest eslint-plugin-jsdoc@latest eslint-plugin-jsonc@latest eslint-plugin-markdown@latest eslint-plugin-n@latest eslint-plugin-package-json@latest eslint-plugin-perfectionist@latest eslint-plugin-regexp@latest eslint-plugin-vitest@latest eslint-plugin-yml@latest husky@latest jsonc-eslint-parser@latest knip@latest lint-staged@latest markdownlint@latest markdownlint-cli@latest prettier@latest prettier-plugin-curly@latest prettier-plugin-packagejson@latest prettier-plugin-sh@latest release-it@latest sentences-per-line@latest tsup@latest typescript@latest typescript-eslint@latest vitest@latest -D --offline", + "pnpm add @eslint-community/eslint-plugin-eslint-comments@latest @eslint/js@latest @release-it/conventional-changelog@latest @types/eslint-plugin-markdown@latest @types/eslint__js@latest @types/node@latest @vitest/coverage-v8@latest @vitest/eslint-plugin@latest all-contributors-cli@latest console-fail-test@latest cspell@latest eslint@latest eslint-plugin-jsdoc@latest eslint-plugin-jsonc@latest eslint-plugin-markdown@latest eslint-plugin-n@latest eslint-plugin-package-json@latest eslint-plugin-perfectionist@latest eslint-plugin-regexp@latest eslint-plugin-yml@latest husky@latest jsonc-eslint-parser@latest knip@latest lint-staged@latest markdownlint@latest markdownlint-cli@latest prettier@latest prettier-plugin-curly@latest prettier-plugin-packagejson@latest prettier-plugin-sh@latest release-it@latest sentences-per-line@latest tsup@latest typescript@latest typescript-eslint@latest vitest@latest -D --offline", ], [ "npx all-contributors-cli generate", diff --git a/src/steps/finalizeDependencies.ts b/src/steps/finalizeDependencies.ts index 23dc0dc0d..732be0418 100644 --- a/src/steps/finalizeDependencies.ts +++ b/src/steps/finalizeDependencies.ts @@ -50,8 +50,8 @@ export async function finalizeDependencies(options: Options) { ? [] : [ "@vitest/coverage-v8", + "@vitest/eslint-plugin", "console-fail-test", - "eslint-plugin-vitest", "vitest", ]), ] diff --git a/src/steps/writing/creation/createESLintConfig.test.ts b/src/steps/writing/creation/createESLintConfig.test.ts index 72c49c1ce..8cc16329d 100644 --- a/src/steps/writing/creation/createESLintConfig.test.ts +++ b/src/steps/writing/creation/createESLintConfig.test.ts @@ -110,6 +110,7 @@ describe("createESLintConfig", () => { .toMatchInlineSnapshot(` "import eslint from "@eslint/js"; import comments from "@eslint-community/eslint-plugin-eslint-comments/configs"; + import vitest from "@vitest/eslint-plugin"; import jsdoc from "eslint-plugin-jsdoc"; import jsonc from "eslint-plugin-jsonc"; import markdown from "eslint-plugin-markdown"; @@ -117,7 +118,6 @@ describe("createESLintConfig", () => { import packageJson from "eslint-plugin-package-json/configs/recommended"; import perfectionist from "eslint-plugin-perfectionist"; import * as regexp from "eslint-plugin-regexp"; - import vitest from "eslint-plugin-vitest"; import yml from "eslint-plugin-yml"; import tseslint from "typescript-eslint"; diff --git a/src/steps/writing/creation/createESLintConfig.ts b/src/steps/writing/creation/createESLintConfig.ts index 7b2180b76..e7a425e66 100644 --- a/src/steps/writing/creation/createESLintConfig.ts +++ b/src/steps/writing/creation/createESLintConfig.ts @@ -8,6 +8,7 @@ export async function createESLintConfig(options: Options) { `import eslint from "@eslint/js";`, !options.excludeLintESLint && `import comments from "@eslint-community/eslint-plugin-eslint-comments/configs";`, + !options.excludeTests && `import vitest from "@vitest/eslint-plugin";`, !options.excludeLintJSDoc && `import jsdoc from "eslint-plugin-jsdoc";`, !options.excludeLintJson && `import jsonc from "eslint-plugin-jsonc";`, !options.excludeLintMd && `import markdown from "eslint-plugin-markdown";`, @@ -18,7 +19,6 @@ export async function createESLintConfig(options: Options) { `import perfectionist from "eslint-plugin-perfectionist";`, !options.excludeLintRegex && `import * as regexp from "eslint-plugin-regexp";`, - !options.excludeTests && `import vitest from "eslint-plugin-vitest";`, !options.excludeLintYml && `import yml from "eslint-plugin-yml";`, `import tseslint from "typescript-eslint";`, ].filter(Boolean);