diff --git a/.depcheckrc b/.depcheckrc index c0aef18..a7a4f1c 100644 --- a/.depcheckrc +++ b/.depcheckrc @@ -1,6 +1,7 @@ ignores: [ "eslint-plugin-eslint-comments", "eslint-plugin-inclusive-language", + "eslint-plugin-jest", "eslint-plugin-promise", "eslint-plugin-sort-destructure-keys", "eslint-plugin-sort-exports", diff --git a/config/eslint/build-config.ts b/config/eslint/build-config.ts index 3e6c423..b6552fb 100644 --- a/config/eslint/build-config.ts +++ b/config/eslint/build-config.ts @@ -1,10 +1,14 @@ import ESLintComments from './rules/eslint-comments' import InclusiveLanguage from './rules/inclusive-language' +import { JestRules, JestTypescriptRules } from './rules/jest' import PromiseRules from './rules/promise' import SortDestructureKeys from './rules/sort-destructure-keys' import SortExports from './rules/sort-exports' const buildConfig = () => ({ + env: { + 'jest/globals': true, + }, plugins: [ 'eslint-comments', 'inclusive-language', @@ -19,6 +23,20 @@ const buildConfig = () => ({ ...SortDestructureKeys, ...SortExports, }, + overrides: [{ + files: ['*.spec.*', '*.test.*'], + plugins: [ + 'jest', + ], + rules: { + ...JestRules, + }, + }, { + files: ['*.spec.ts', '*.spec.tsx', '*.test.ts', '*.test.tsx'], + rules: { + ...JestTypescriptRules, + }, + }], }) export default buildConfig diff --git a/config/eslint/rules/jest.ts b/config/eslint/rules/jest.ts new file mode 100644 index 0000000..f32688b --- /dev/null +++ b/config/eslint/rules/jest.ts @@ -0,0 +1,70 @@ +// https://github.com/jest-community/eslint-plugin-jest + +export const JestRules = { + 'jest/consistent-test-it': 2, + 'jest/expect-expect': [2, { + assertFunctionNames: ['expect', 'expect*'], + }], + 'jest/max-expects': 2, + 'jest/max-nested-describe': [2, { + max: 3, + }], + 'jest/no-alias-methods': 2, + 'jest/no-commented-out-tests': 2, + 'jest/no-conditional-expect': 2, + 'jest/no-conditional-in-test': 2, + 'jest/no-confusing-set-timeout': 2, + 'jest/no-deprecated-functions': 2, + 'jest/no-disabled-tests': 1, + 'jest/no-done-callback': 2, + 'jest/no-duplicate-hooks': 2, + 'jest/no-export': 2, + 'jest/no-focused-tests': 2, + 'jest/no-hooks': 0, + 'jest/no-identical-title': 2, + 'jest/no-interpolation-in-snapshots': 2, + 'jest/no-jasmine-globals': 2, + 'jest/no-large-snapshots': 0, + 'jest/no-mocks-import': 2, + 'jest/no-restricted-jest-methods': 0, + 'jest/no-restricted-matchers': 0, + 'jest/no-standalone-expect': [2, { + additionalTestBlockFunctions: ['each.test'], + }], + 'jest/no-test-prefixes': 2, + 'jest/no-test-return-statement': 2, + + 'jest/prefer-called-with': 2, + 'jest/prefer-comparison-matcher': 2, + 'jest/prefer-each': 2, + 'jest/prefer-equality-matcher': 2, + 'jest/prefer-expect-assertions': 0, + 'jest/prefer-expect-resolves': 2, + 'jest/prefer-hooks-in-order': 2, + 'jest/prefer-hooks-on-top': 2, + 'jest/prefer-importing-jest-globals': 0, + 'jest/prefer-jest-mocked': 2, + 'jest/prefer-lowercase-title': [2, { + ignore: ['describe'], + }], + 'jest/prefer-mock-promise-shorthand': 2, + 'jest/prefer-snapshot-hint': 0, + 'jest/prefer-spy-on': 2, + 'jest/prefer-strict-equal': 2, + 'jest/prefer-to-be': 2, + 'jest/prefer-to-contain': 2, + 'jest/prefer-to-have-length': 2, + 'jest/prefer-todo': 2, + 'jest/require-hook': 2, + 'jest/require-to-throw-message': 1, + 'jest/require-top-level-describe': 2, + 'jest/valid-describe-callback': 2, + 'jest/valid-expect': 2, + 'jest/valid-expect-in-promise': 2, + 'jest/valid-title': 2, +} + +export const JestTypescriptRules = { + 'jest/no-untyped-mock-factory': 2, + 'jest/unbound-method': 1, +} diff --git a/package.json b/package.json index 961a2e2..f224212 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "eslint": "9.4.0", "eslint-plugin-eslint-comments": "3.2.0", "eslint-plugin-inclusive-language": "2.2.1", + "eslint-plugin-jest": "28.6.0", "eslint-plugin-promise": "6.4.0", "eslint-plugin-sort-destructure-keys": "2.0.0", "eslint-plugin-sort-exports": "0.9.1", @@ -62,6 +63,7 @@ "eslint", "eslint-plugin-eslint-comments", "eslint-plugin-inclusive-language", + "eslint-plugin-jest", "eslint-plugin-promise", "eslint-plugin-sort-destructure-keys", "eslint-plugin-sort-exports", diff --git a/yarn.lock b/yarn.lock index bc296f2..c755caf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1173,7 +1173,7 @@ resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz#acad351d582d157bb145535db2a6ff53dd514b5c" integrity sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw== -"@eslint-community/eslint-utils@^4.2.0": +"@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": version "4.4.0" resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== @@ -1788,6 +1788,51 @@ dependencies: "@types/yargs-parser" "*" +"@typescript-eslint/scope-manager@7.16.1": + version "7.16.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-7.16.1.tgz#2b43041caabf8ddd74512b8b550b9fc53ca3afa1" + integrity sha512-nYpyv6ALte18gbMz323RM+vpFpTjfNdyakbf3nsLvF43uF9KeNC289SUEW3QLZ1xPtyINJ1dIsZOuWuSRIWygw== + dependencies: + "@typescript-eslint/types" "7.16.1" + "@typescript-eslint/visitor-keys" "7.16.1" + +"@typescript-eslint/types@7.16.1": + version "7.16.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-7.16.1.tgz#bbab066276d18e398bc64067b23f1ce84dfc6d8c" + integrity sha512-AQn9XqCzUXd4bAVEsAXM/Izk11Wx2u4H3BAfQVhSfzfDOm/wAON9nP7J5rpkCxts7E5TELmN845xTUCQrD1xIQ== + +"@typescript-eslint/typescript-estree@7.16.1": + version "7.16.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.1.tgz#9b145ba4fd1dde1986697e1ce57dc501a1736dd3" + integrity sha512-0vFPk8tMjj6apaAZ1HlwM8w7jbghC8jc1aRNJG5vN8Ym5miyhTQGMqU++kuBFDNKe9NcPeZ6x0zfSzV8xC1UlQ== + dependencies: + "@typescript-eslint/types" "7.16.1" + "@typescript-eslint/visitor-keys" "7.16.1" + debug "^4.3.4" + globby "^11.1.0" + is-glob "^4.0.3" + minimatch "^9.0.4" + semver "^7.6.0" + ts-api-utils "^1.3.0" + +"@typescript-eslint/utils@^6.0.0 || ^7.0.0": + version "7.16.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-7.16.1.tgz#df42dc8ca5a4603016fd102db0346cdab415cdb7" + integrity sha512-WrFM8nzCowV0he0RlkotGDujx78xudsxnGMBHI88l5J8wEhED6yBwaSLP99ygfrzAjsQvcYQ94quDwI0d7E1fA== + dependencies: + "@eslint-community/eslint-utils" "^4.4.0" + "@typescript-eslint/scope-manager" "7.16.1" + "@typescript-eslint/types" "7.16.1" + "@typescript-eslint/typescript-estree" "7.16.1" + +"@typescript-eslint/visitor-keys@7.16.1": + version "7.16.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.1.tgz#4287bcf44c34df811ff3bb4d269be6cfc7d8c74b" + integrity sha512-Qlzzx4sE4u3FsHTPQAAQFJFNOuqtuY0LFrZHwQ8IHK705XxBiWOFkfKRWu6niB7hwfgnwIpO4jTC75ozW1PHWg== + dependencies: + "@typescript-eslint/types" "7.16.1" + eslint-visitor-keys "^3.4.3" + acorn-jsx@^5.3.2: version "5.3.2" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" @@ -2409,6 +2454,13 @@ eslint-plugin-inclusive-language@2.2.1: dependencies: humps "^2.0.1" +eslint-plugin-jest@28.6.0: + version "28.6.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-28.6.0.tgz#8410588d60bcafa68a91b6ec272e4a415502302a" + integrity sha512-YG28E1/MIKwnz+e2H7VwYPzHUYU4aMa19w0yGcwXnnmJH6EfgHahTJ2un3IyraUxNfnz/KUhJAFXNNwWPo12tg== + dependencies: + "@typescript-eslint/utils" "^6.0.0 || ^7.0.0" + eslint-plugin-promise@6.4.0: version "6.4.0" resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-6.4.0.tgz#54926d53c79541efe9cea6ac1d823a58bbed1106" @@ -2436,7 +2488,7 @@ eslint-scope@^8.0.1: esrecurse "^4.3.0" estraverse "^5.2.0" -eslint-visitor-keys@^3.3.0: +eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.3: version "3.4.3" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== @@ -4113,6 +4165,11 @@ semver@^7.3.5, semver@^7.5.3, semver@^7.5.4: resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.2.tgz#1e3b34759f896e8f14d6134732ce798aeb0c6e13" integrity sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w== +semver@^7.6.0: + version "7.6.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143" + integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== + serialize-javascript@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-4.0.0.tgz#b525e1238489a5ecfc42afacc3fe99e666f4b1aa" @@ -4418,6 +4475,11 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" +ts-api-utils@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.3.0.tgz#4b490e27129f1e8e686b45cc4ab63714dc60eea1" + integrity sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ== + ts-jest@29.1.4: version "29.1.4" resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-29.1.4.tgz#26f8a55ce31e4d2ef7a1fd47dc7fa127e92793ef"