From 325b65aae3ec0acebce2930fc20fb2f06f936f92 Mon Sep 17 00:00:00 2001 From: Brody McKee Date: Tue, 5 Mar 2024 11:22:35 +1100 Subject: [PATCH] feat(eslint): add `vitest` config (#96) --- README.md | 1 + eslint/rules/vitest.js | 16 +++++++ eslint/vitest.js | 3 ++ package.json | 1 + pnpm-lock.yaml | 99 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 120 insertions(+) create mode 100644 eslint/rules/vitest.js create mode 100644 eslint/vitest.js diff --git a/README.md b/README.md index d79bcc7..5a86113 100644 --- a/README.md +++ b/README.md @@ -88,6 +88,7 @@ The following additional configs are available: - `@vercel/style-guide/eslint/playwright-test` - `@vercel/style-guide/eslint/react` - `@vercel/style-guide/eslint/typescript` (requires `typescript` to be installed and [additional configuration](#configuring-eslint-for-typescript)) +- `@vercel/style-guide/eslint/vitest` > You'll need to use `require.resolve` to provide ESLint with absolute paths, > due to an issue around ESLint config resolution (see diff --git a/eslint/rules/vitest.js b/eslint/rules/vitest.js new file mode 100644 index 0000000..d2866d3 --- /dev/null +++ b/eslint/rules/vitest.js @@ -0,0 +1,16 @@ +module.exports = { + rules: { + /** + * Disallow duplicate setup and teardown hooks. + * + * 🚫 Not fixable - https://github.com/veritem/eslint-plugin-vitest/blob/HEAD/docs/rules/no-duplicate-hooks.md + */ + 'vitest/no-duplicate-hooks': 'error', + /** + * Require lowercase test names. + * + * 🔧 Fixable - https://github.com/veritem/eslint-plugin-vitest/blob/HEAD/docs/rules/prefer-lowercase-title.md + */ + 'vitest/prefer-lowercase-title': 'warn', + }, +}; diff --git a/eslint/vitest.js b/eslint/vitest.js new file mode 100644 index 0000000..a400288 --- /dev/null +++ b/eslint/vitest.js @@ -0,0 +1,3 @@ +module.exports = { + extends: ['plugin:vitest/recommended', require.resolve('./rules/vitest')], +}; diff --git a/package.json b/package.json index 710edd0..75269f5 100644 --- a/package.json +++ b/package.json @@ -55,6 +55,7 @@ "eslint-plugin-testing-library": "^6.0.1", "eslint-plugin-tsdoc": "^0.2.17", "eslint-plugin-unicorn": "^48.0.1", + "eslint-plugin-vitest": "^0.3.22", "prettier-plugin-packagejson": "^2.4.5" }, "devDependencies": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c759f6b..529d281 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -62,6 +62,9 @@ dependencies: eslint-plugin-unicorn: specifier: ^48.0.1 version: 48.0.1(eslint@8.48.0) + eslint-plugin-vitest: + specifier: ^0.3.22 + version: 0.3.22(@typescript-eslint/eslint-plugin@6.5.0)(eslint@8.48.0)(typescript@5.2.2) prettier-plugin-packagejson: specifier: ^2.4.5 version: 2.4.5(prettier@3.0.2) @@ -998,6 +1001,14 @@ packages: '@typescript-eslint/visitor-keys': 5.62.0 dev: false + /@typescript-eslint/scope-manager@6.21.0: + resolution: {integrity: sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==} + engines: {node: ^16.0.0 || >=18.0.0} + dependencies: + '@typescript-eslint/types': 6.21.0 + '@typescript-eslint/visitor-keys': 6.21.0 + dev: false + /@typescript-eslint/scope-manager@6.5.0: resolution: {integrity: sha512-A8hZ7OlxURricpycp5kdPTH3XnjG85UpJS6Fn4VzeoH4T388gQJ/PGP4ole5NfKt4WDVhmLaQ/dBLNDC4Xl/Kw==} engines: {node: ^16.0.0 || >=18.0.0} @@ -1036,6 +1047,11 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: false + /@typescript-eslint/types@6.21.0: + resolution: {integrity: sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==} + engines: {node: ^16.0.0 || >=18.0.0} + dev: false + /@typescript-eslint/types@6.5.0: resolution: {integrity: sha512-eqLLOEF5/lU8jW3Bw+8auf4lZSbbljHR2saKnYqON12G/WsJrGeeDHWuQePoEf9ro22+JkbPfWQwKEC5WwLQ3w==} engines: {node: ^16.0.0 || >=18.0.0} @@ -1083,6 +1099,28 @@ packages: - supports-color dev: false + /@typescript-eslint/typescript-estree@6.21.0(typescript@5.2.2): + resolution: {integrity: sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/types': 6.21.0 + '@typescript-eslint/visitor-keys': 6.21.0 + debug: 4.3.4 + globby: 11.1.0 + is-glob: 4.0.3 + minimatch: 9.0.3 + semver: 7.5.4 + ts-api-utils: 1.0.2(typescript@5.2.2) + typescript: 5.2.2 + transitivePeerDependencies: + - supports-color + dev: false + /@typescript-eslint/typescript-estree@6.5.0(typescript@5.2.2): resolution: {integrity: sha512-q0rGwSe9e5Kk/XzliB9h2LBc9tmXX25G0833r7kffbl5437FPWb2tbpIV9wAATebC/018pGa9fwPDuvGN+LxWQ==} engines: {node: ^16.0.0 || >=18.0.0} @@ -1142,6 +1180,25 @@ packages: - typescript dev: false + /@typescript-eslint/utils@6.21.0(eslint@8.48.0)(typescript@5.2.2): + resolution: {integrity: sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.48.0) + '@types/json-schema': 7.0.12 + '@types/semver': 7.5.1 + '@typescript-eslint/scope-manager': 6.21.0 + '@typescript-eslint/types': 6.21.0 + '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.2.2) + eslint: 8.48.0 + semver: 7.5.4 + transitivePeerDependencies: + - supports-color + - typescript + dev: false + /@typescript-eslint/utils@6.5.0(eslint@8.48.0)(typescript@5.2.2): resolution: {integrity: sha512-9nqtjkNykFzeVtt9Pj6lyR9WEdd8npPhhIPM992FWVkZuS6tmxHfGVnlUcjpUP2hv8r4w35nT33mlxd+Be1ACQ==} engines: {node: ^16.0.0 || >=18.0.0} @@ -1177,6 +1234,14 @@ packages: eslint-visitor-keys: 3.4.3 dev: false + /@typescript-eslint/visitor-keys@6.21.0: + resolution: {integrity: sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==} + engines: {node: ^16.0.0 || >=18.0.0} + dependencies: + '@typescript-eslint/types': 6.21.0 + eslint-visitor-keys: 3.4.3 + dev: false + /@typescript-eslint/visitor-keys@6.5.0: resolution: {integrity: sha512-yCB/2wkbv3hPsh02ZS8dFQnij9VVQXJMN/gbQsaaY+zxALkZnxa/wagvLEFsAWMPv7d7lxQmNsIzGU1w/T/WyA==} engines: {node: ^16.0.0 || >=18.0.0} @@ -1453,6 +1518,12 @@ packages: balanced-match: 1.0.2 concat-map: 0.0.1 + /brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + dependencies: + balanced-match: 1.0.2 + dev: false + /braces@3.0.2: resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} engines: {node: '>=8'} @@ -2314,6 +2385,27 @@ packages: strip-indent: 3.0.0 dev: false + /eslint-plugin-vitest@0.3.22(@typescript-eslint/eslint-plugin@6.5.0)(eslint@8.48.0)(typescript@5.2.2): + resolution: {integrity: sha512-atkFGQ7aVgcuSeSMDqnyevIyUpfBPMnosksgEPrKE7Y8xQlqG/5z2IQ6UDau05zXaaFv7Iz8uzqvIuKshjZ0Zw==} + engines: {node: ^18.0.0 || >= 20.0.0} + peerDependencies: + '@typescript-eslint/eslint-plugin': '*' + eslint: '>=8.0.0' + vitest: '*' + peerDependenciesMeta: + '@typescript-eslint/eslint-plugin': + optional: true + vitest: + optional: true + dependencies: + '@typescript-eslint/eslint-plugin': 6.5.0(@typescript-eslint/parser@6.5.0)(eslint@8.48.0)(typescript@5.2.2) + '@typescript-eslint/utils': 6.21.0(eslint@8.48.0)(typescript@5.2.2) + eslint: 8.48.0 + transitivePeerDependencies: + - supports-color + - typescript + dev: false + /eslint-scope@5.1.1: resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} engines: {node: '>=8.0.0'} @@ -3658,6 +3750,13 @@ packages: dependencies: brace-expansion: 1.1.11 + /minimatch@9.0.3: + resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} + engines: {node: '>=16 || 14 >=14.17'} + dependencies: + brace-expansion: 2.0.1 + dev: false + /minimist-options@4.1.0: resolution: {integrity: sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==} engines: {node: '>= 6'}