chore: update ESLint to v9 (#15531)

This commit is contained in:
fisker Cheung 2025-03-05 21:49:46 +08:00 committed by GitHub
parent 28b4469e69
commit 4e7d916ec6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
72 changed files with 1488 additions and 1418 deletions

View File

@ -1,19 +0,0 @@
!.*
**/coverage/**
**/node_modules/**
bin/
packages/*/build/**
packages/*/dist/**
website/.docusaurus
website/build
website/node_modules
website/i18n/*.js
website/static
# Third-party script
packages/jest-diff/src/cleanupSemantic.ts
e2e/native-esm/wasm-bindgen/index_bg.js
**/.yarn
**/.pnp.*

View File

@ -1,18 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
exports.rules = {
'ban-types-eventually': require('@typescript-eslint/eslint-plugin').rules[
'ban-types'
],
'prefer-rest-params-eventually':
require('eslint/use-at-your-own-risk').builtinRules.get(
'prefer-rest-params',
),
'prefer-spread-eventually':
require('eslint/use-at-your-own-risk').builtinRules.get('prefer-spread'),
};

18
.eslintplugin/index.mjs Normal file
View File

@ -0,0 +1,18 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import {builtinRules} from 'eslint/use-at-your-own-risk';
import typescriptEslint from 'typescript-eslint';
const rules = {
'no-restricted-types-eventually':
typescriptEslint.plugin.rules['no-restricted-types'],
'prefer-rest-params-eventually': builtinRules.get('prefer-rest-params'),
'prefer-spread-eventually': builtinRules.get('prefer-spread'),
};
export default {rules};

View File

@ -1,734 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/* eslint-disable sort-keys */
const fs = require('fs');
const path = require('path');
const {sync: readPkg} = require('read-pkg');
function getPackages() {
const PACKAGES_DIR = path.resolve(__dirname, 'packages');
const packages = fs
.readdirSync(PACKAGES_DIR)
.map(file => path.resolve(PACKAGES_DIR, file))
.filter(f => fs.lstatSync(path.resolve(f)).isDirectory())
.filter(f => fs.existsSync(path.join(path.resolve(f), 'package.json')));
return packages.map(packageDir => {
const pkg = readPkg({cwd: packageDir});
return pkg.name;
});
}
module.exports = {
env: {
es2020: true,
},
extends: [
'eslint:recommended',
'plugin:markdown/recommended',
'plugin:import/errors',
'plugin:@eslint-community/eslint-comments/recommended',
'plugin:unicorn/recommended',
'plugin:promise/recommended',
'plugin:prettier/recommended',
],
globals: {
console: 'readonly',
},
overrides: [
{
extends: [
'plugin:@typescript-eslint/eslint-recommended',
'plugin:@typescript-eslint/strict',
'plugin:@typescript-eslint/stylistic',
'plugin:import/typescript',
],
files: ['*.ts', '*.tsx'],
plugins: ['@typescript-eslint/eslint-plugin', 'local'],
rules: {
'@typescript-eslint/array-type': ['error', {default: 'generic'}],
'@typescript-eslint/ban-types': 'error',
'@typescript-eslint/consistent-type-imports': [
'error',
{fixStyle: 'inline-type-imports', disallowTypeAnnotations: false},
],
'@typescript-eslint/no-import-type-side-effects': 'error',
'@typescript-eslint/no-inferrable-types': 'error',
'@typescript-eslint/no-unused-vars': [
'error',
{argsIgnorePattern: '^_'},
],
'@typescript-eslint/prefer-ts-expect-error': 'error',
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/consistent-indexed-object-style': 'off',
// TS verifies these
'consistent-return': 'off',
'no-dupe-class-members': 'off',
'no-unused-vars': 'off',
'@typescript-eslint/no-dynamic-delete': 'off',
// TODO: enable at some point
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-non-null-assertion': 'off',
'@typescript-eslint/no-invalid-void-type': 'off',
'@typescript-eslint/consistent-type-definitions': 'off',
// not needed to be enforced for TS
'import/namespace': 'off',
},
},
{
files: [
'packages/jest-mock/src/__tests__/index.test.ts',
'packages/jest-mock/src/index.ts',
'packages/pretty-format/src/__tests__/Immutable.test.ts',
'packages/pretty-format/src/__tests__/prettyFormat.test.ts',
],
rules: {
'local/prefer-rest-params-eventually': 'warn',
'prefer-rest-params': 'off',
},
},
{
files: [
'packages/expect/src/index.ts',
'packages/jest-fake-timers/src/legacyFakeTimers.ts',
'packages/jest-jasmine2/src/jestExpect.ts',
],
rules: {
'local/prefer-spread-eventually': 'warn',
'prefer-spread': 'off',
},
},
{
files: [
'e2e/babel-plugin-jest-hoist/__tests__/typescript.test.ts',
'e2e/coverage-remapping/covered.ts',
'packages/expect/src/matchers.ts',
'packages/expect/src/print.ts',
'packages/expect/src/toThrowMatchers.ts',
'packages/expect-utils/src/utils.ts',
'packages/jest-core/src/collectHandles.ts',
'packages/jest-core/src/plugins/UpdateSnapshotsInteractive.ts',
'packages/jest-leak-detector/src/index.ts',
'packages/jest-matcher-utils/src/index.ts',
'packages/jest-mock/src/__tests__/index.test.ts',
'packages/jest-mock/src/index.ts',
'packages/jest-snapshot/src/index.ts',
'packages/jest-snapshot/src/printSnapshot.ts',
'packages/jest-snapshot/src/types.ts',
'packages/jest-util/src/convertDescriptorToString.ts',
'packages/pretty-format/src/index.ts',
'packages/pretty-format/src/plugins/DOMCollection.ts',
],
rules: {
'@typescript-eslint/ban-types': [
'error',
// TODO: remove these overrides: https://github.com/jestjs/jest/issues/10177
{types: {Function: false, object: false, '{}': false}},
],
'local/ban-types-eventually': [
'warn',
{
types: {
// none of these types are in use, so can be errored on
Boolean: false,
Number: false,
Object: false,
String: false,
Symbol: false,
},
},
],
},
},
{
files: 'e2e/coverage-remapping/covered.ts',
rules: {
'no-constant-binary-expression': 'off',
'no-constant-condition': 'off',
},
},
// 'eslint-plugin-jest' rules for test and test related files
{
files: [
'**/__mocks__/**',
'**/__tests__/**',
'**/*.md/**',
'**/*.test.*',
'e2e/babel-plugin-jest-hoist/mockFile.js',
'e2e/failures/macros.js',
'e2e/test-in-root/*.js',
'e2e/test-match/test-suites/*',
'e2e/test-match-default/dot-spec-tests/*',
'packages/test-utils/src/ConditionalTest.ts',
],
env: {'jest/globals': true},
excludedFiles: ['**/__typetests__/**'],
extends: ['plugin:jest/style'],
plugins: ['jest'],
rules: {
'jest/no-alias-methods': 'error',
'jest/no-focused-tests': 'error',
'jest/no-identical-title': 'error',
'jest/require-to-throw-message': 'error',
'jest/valid-expect': 'error',
},
},
{
files: ['e2e/__tests__/*'],
rules: {
'jest/no-restricted-jest-methods': [
'error',
{
fn: 'Please use fixtures instead of mocks in the end-to-end tests.',
mock: 'Please use fixtures instead of mocks in the end-to-end tests.',
doMock:
'Please use fixtures instead of mocks in the end-to-end tests.',
setMock:
'Please use fixtures instead of mocks in the end-to-end tests.',
spyOn:
'Please use fixtures instead of mocks in the end-to-end tests.',
},
],
},
},
// to make it more suitable for running on code examples in docs/ folder
{
files: ['**/*.md/**'],
rules: {
'@typescript-eslint/no-unused-vars': 'off',
'@typescript-eslint/no-empty-function': 'off',
'@typescript-eslint/no-namespace': 'off',
'@typescript-eslint/no-empty-interface': 'off',
'consistent-return': 'off',
'import/export': 'off',
'import/no-extraneous-dependencies': 'off',
'import/no-unresolved': 'off',
'jest/no-focused-tests': 'off',
'jest/require-to-throw-message': 'off',
'no-console': 'off',
'no-constant-condition': 'off',
'no-undef': 'off',
'no-unused-vars': 'off',
'sort-keys': 'off',
'unicorn/consistent-function-scoping': 'off',
'unicorn/error-message': 'off',
'unicorn/no-anonymous-default-export': 'off',
'unicorn/no-await-expression-member': 'off',
'unicorn/no-static-only-class': 'off',
'unicorn/prefer-number-properties': 'off',
'unicorn/prefer-string-raw': 'off',
'unicorn/prefer-global-this': 'off',
},
},
// demonstration of matchers usage
{
files: ['**/UsingMatchers.md/**'],
rules: {
'jest/prefer-to-be': 'off',
},
},
// demonstration of 'jest/valid-expect' rule
{
files: [
'**/2017-05-06-jest-20-delightful-testing-multi-project-runner.md/**',
],
rules: {
'jest/valid-expect': 'off',
},
},
// Jest 11 did not had `toHaveLength` matcher
{
files: ['**/2016-04-12-jest-11.md/**'],
rules: {
'jest/prefer-to-have-length': 'off',
},
},
// snapshot in an example needs to keep escapes
{
files: [
'**/2017-02-21-jest-19-immersive-watch-mode-test-platform-improvements.md/**',
],
rules: {
'no-useless-escape': 'off',
},
},
// snapshots in examples plus inline snapshots need to keep backtick
{
files: ['**/*.md/**', 'e2e/custom-inline-snapshot-matchers/__tests__/*'],
rules: {
quotes: [
'error',
'single',
{allowTemplateLiterals: true, avoidEscape: true},
],
},
},
{
files: ['docs/**/*', 'website/**/*'],
rules: {
'no-redeclare': 'off',
'import/order': 'off',
'import/sort-keys': 'off',
'no-restricted-globals': ['off'],
'sort-keys': 'off',
},
},
{
files: ['examples/**/*'],
rules: {
'no-restricted-imports': 'off',
},
},
{
files: ['examples/angular/**/*'],
rules: {
// Angular DI for some reason doesn't work with type imports
'@typescript-eslint/consistent-type-imports': [
'error',
{prefer: 'no-type-imports', disallowTypeAnnotations: false},
],
},
},
{
files: 'packages/**/*.ts',
rules: {
'@typescript-eslint/explicit-module-boundary-types': 'error',
'import/no-anonymous-default-export': [
'error',
{
allowAnonymousClass: false,
allowAnonymousFunction: false,
allowArray: false,
allowArrowFunction: false,
allowCallExpression: false,
allowLiteral: false,
allowObject: true,
},
],
},
},
{
files: ['**/__tests__/**', '**/__mocks__/**'],
rules: {
'@typescript-eslint/ban-ts-comment': 'off',
'@typescript-eslint/no-empty-function': 'off',
'@typescript-eslint/class-literal-property-style': 'off',
},
},
{
files: [
'**/__tests__/**',
'**/__mocks__/**',
'packages/jest-jasmine2/src/jasmine/**/*',
'packages/expect/src/jasmineUtils.ts',
'**/vendor/**/*',
],
rules: {
'@typescript-eslint/explicit-module-boundary-types': 'off',
'unicorn/consistent-function-scoping': 'off',
'unicorn/no-await-expression-member': 'off',
'unicorn/prefer-spread': 'off',
'unicorn/prefer-string-raw': 'off',
},
},
{
files: [
'packages/jest-jasmine2/src/jasmine/**/*',
'packages/expect-utils/src/jasmineUtils.ts',
],
rules: {
'@typescript-eslint/ban-types': 'off',
'@eslint-community/eslint-comments/disable-enable-pair': 'off',
'@eslint-community/eslint-comments/no-unlimited-disable': 'off',
'prefer-rest-params': 'off',
'prefer-spread': 'off',
'sort-keys ': 'off',
},
},
{
files: [
'e2e/error-on-deprecated/__tests__/*',
'e2e/jasmine-async/__tests__/*',
],
globals: {
fail: 'readonly',
jasmine: 'readonly',
pending: 'readonly',
},
},
{
files: [
'e2e/**',
'website/**',
'**/__benchmarks__/**',
'**/__tests__/**',
'**/__typetests__/**',
'.eslintplugin/**',
],
rules: {
'import/no-extraneous-dependencies': 'off',
'unicorn/consistent-function-scoping': 'off',
'unicorn/error-message': 'off',
},
},
{
files: ['**/__typetests__/**'],
rules: {
'@typescript-eslint/no-empty-function': 'off',
'@typescript-eslint/no-invalid-void-type': 'off',
'@typescript-eslint/no-useless-constructor': 'off',
},
},
{
env: {node: true},
files: ['*.js', '*.jsx', '*.mjs', '*.cjs'],
},
{
files: [
'scripts/*',
'packages/*/__benchmarks__/test.js',
'packages/create-jest/src/runCreate.ts',
'packages/jest-repl/src/cli/runtime-cli.ts',
],
rules: {
'no-console': 'off',
},
},
{
files: [
'e2e/**',
'examples/**',
'website/**',
'**/__benchmarks__/**',
'**/__mocks__/**',
'**/__tests__/**',
'**/__typetests__/**',
],
rules: {
'@typescript-eslint/no-extraneous-class': 'off',
'@typescript-eslint/no-unused-vars': 'off',
'import/no-unresolved': 'off',
'no-console': 'off',
'no-unused-vars': 'off',
'unicorn/no-anonymous-default-export': 'off',
},
},
{
files: 'scripts/**/*',
rules: {
'unicorn/no-anonymous-default-export': 'off',
},
},
{
files: 'packages/jest-mock/src/__tests__/**/*',
rules: {
'unicorn/no-static-only-class': 'off',
},
},
{
files: '**/*.mjs',
rules: {
'unicorn/prefer-top-level-await': 'error',
},
},
{
files: [
'e2e/coverage-report/__mocks__/sumDependency.js',
'e2e/require-main-after-create-require/empty.js',
'packages/create-jest/src/__tests__/__fixtures__/**/*',
'packages/jest-core/src/__tests__/**/*',
'packages/jest-haste-map/src/__tests__/test_dotfiles_root/**/*',
'packages/jest-resolve/src/__mocks__/**/*',
],
rules: {
'unicorn/no-empty-file': 'off',
},
},
{
files: 'packages/expect/src/__tests__/*.test.js',
rules: {
'unicorn/prefer-number-properties': 'off',
},
},
],
parser: '@typescript-eslint/parser',
parserOptions: {
sourceType: 'module',
},
plugins: ['import', 'jsdoc'],
rules: {
'accessor-pairs': ['warn', {setWithoutGet: true}],
'block-scoped-var': 'off',
'callback-return': 'off',
camelcase: ['off', {properties: 'always'}],
complexity: 'off',
'consistent-return': 'warn',
'consistent-this': ['off', 'self'],
'constructor-super': 'error',
'default-case': 'off',
'dot-notation': 'off',
eqeqeq: ['error', 'smart'],
'@eslint-community/eslint-comments/disable-enable-pair': [
'error',
{allowWholeFile: true},
],
'@eslint-community/eslint-comments/no-unused-disable': 'error',
'func-names': 'off',
'func-style': ['off', 'declaration'],
'global-require': 'off',
'guard-for-in': 'off',
'handle-callback-err': 'off',
'id-length': 'off',
'id-match': 'off',
'import/no-duplicates': 'error',
'import/no-extraneous-dependencies': [
'error',
{
devDependencies: [
'**/__mocks__/**',
'**/__tests__/**',
'**/__typetests__/**',
'**/?(*.)(spec|test).js?(x)',
'scripts/**',
'babel.config.js',
'testSetupFile.js',
'.eslintrc.cjs',
],
},
],
'import/no-unresolved': ['error', {ignore: ['fsevents']}],
'import/order': [
'error',
{
alphabetize: {
order: 'asc',
},
// this is the default order except for added `internal` in the middle
groups: [
'builtin',
'external',
'internal',
'parent',
'sibling',
'index',
],
'newlines-between': 'never',
},
],
'init-declarations': 'off',
'jsdoc/check-alignment': 'error',
'lines-around-comment': 'off',
'max-depth': 'off',
'max-nested-callbacks': 'off',
'max-params': 'off',
'max-statements': 'off',
'new-cap': 'off',
'new-parens': 'error',
'newline-after-var': 'off',
'no-alert': 'off',
'no-array-constructor': 'error',
'no-bitwise': 'warn',
'no-caller': 'error',
'no-case-declarations': 'off',
'no-class-assign': 'warn',
'no-cond-assign': 'off',
'no-confusing-arrow': 'off',
'no-console': [
'warn',
{allow: ['warn', 'error', 'time', 'timeEnd', 'timeStamp']},
],
'no-const-assign': 'error',
'no-constant-condition': 'error',
'no-constant-binary-expression': 'error',
'no-continue': 'off',
'no-control-regex': 'off',
'no-debugger': 'error',
'no-delete-var': 'error',
'no-div-regex': 'off',
'no-dupe-args': 'error',
'no-dupe-class-members': 'error',
'no-dupe-keys': 'error',
'no-duplicate-case': 'error',
'no-duplicate-imports': 'error',
'no-else-return': 'off',
'no-empty': 'off',
'no-empty-character-class': 'warn',
'no-empty-pattern': 'warn',
'no-eq-null': 'off',
'no-eval': 'error',
'no-ex-assign': 'warn',
'no-extend-native': 'warn',
'no-extra-bind': 'warn',
'no-extra-boolean-cast': 'warn',
'no-fallthrough': 'warn',
'no-floating-decimal': 'error',
'no-func-assign': 'error',
'no-implicit-coercion': 'off',
'no-implied-eval': 'error',
'no-inline-comments': 'off',
'no-inner-declarations': 'off',
'no-invalid-regexp': 'warn',
'no-invalid-this': 'off',
'no-irregular-whitespace': 'error',
'no-iterator': 'off',
'no-label-var': 'warn',
'no-labels': ['error', {allowLoop: true, allowSwitch: true}],
'no-lonely-if': 'off',
'no-loop-func': 'off',
'no-magic-numbers': 'off',
'no-mixed-requires': 'off',
'no-mixed-spaces-and-tabs': 'error',
'no-multi-str': 'error',
'no-multiple-empty-lines': 'off',
'no-native-reassign': ['error', {exceptions: ['Map', 'Set']}],
'no-negated-in-lhs': 'error',
'no-new': 'warn',
'no-new-func': 'error',
'no-new-object': 'warn',
'no-new-require': 'off',
'no-new-wrappers': 'warn',
'no-obj-calls': 'error',
'no-octal': 'warn',
'no-octal-escape': 'warn',
'no-param-reassign': 'off',
'no-plusplus': 'off',
'no-process-env': 'off',
'no-process-exit': 'off',
'no-proto': 'error',
'no-prototype-builtins': 'error',
'no-redeclare': 'warn',
'no-regex-spaces': 'warn',
'no-restricted-globals': [
'error',
{message: 'Use `globalThis` instead.', name: 'global'},
],
'no-restricted-imports': [
'error',
{message: 'Please use graceful-fs instead.', name: 'fs'},
],
'no-restricted-modules': 'off',
'no-restricted-syntax': 'off',
'no-return-assign': 'off',
'no-script-url': 'error',
'no-self-compare': 'warn',
'no-sequences': 'warn',
'no-shadow': 'off',
'no-shadow-restricted-names': 'warn',
'no-sparse-arrays': 'error',
'no-sync': 'off',
'no-ternary': 'off',
'no-this-before-super': 'error',
'no-throw-literal': 'error',
'no-undef': 'error',
'no-undef-init': 'off',
'no-undefined': 'off',
'no-underscore-dangle': 'off',
'no-unneeded-ternary': 'warn',
'no-unreachable': 'error',
'no-unused-expressions': 'off',
'no-unused-vars': ['error', {argsIgnorePattern: '^_'}],
'no-use-before-define': 'off',
'no-useless-call': 'error',
'no-useless-computed-key': 'error',
'no-useless-concat': 'error',
'no-var': 'error',
'no-void': 'off',
'no-warn-comments': 'off',
'no-with': 'off',
'object-shorthand': 'error',
'one-var': ['warn', {initialized: 'never'}],
'operator-assignment': ['warn', 'always'],
'operator-linebreak': 'off',
'padded-blocks': 'off',
'prefer-arrow-callback': ['error', {allowNamedFunctions: true}],
'prefer-const': 'error',
'prefer-template': 'error',
'promise/always-return': 'off',
'promise/catch-or-return': 'off',
'promise/no-callback-in-promise': 'off',
quotes: [
'error',
'single',
{allowTemplateLiterals: false, avoidEscape: true},
],
radix: 'warn',
'require-jsdoc': 'off',
'require-yield': 'off',
'sort-imports': ['error', {ignoreDeclarationSort: true}],
'sort-keys': 'error',
'sort-vars': 'off',
'spaced-comment': ['off', 'always', {exceptions: ['eslint', 'global']}],
strict: 'off',
'use-isnan': 'error',
'valid-jsdoc': 'off',
'valid-typeof': 'error',
'vars-on-top': 'off',
'wrap-iife': 'off',
'wrap-regex': 'off',
yoda: 'off',
// doesn't work without ESModuleInterop
'unicorn/import-style': 'off',
// we're a CJS project
'unicorn/prefer-module': 'off',
// enforced by `@typescript-eslint/no-this-alias` already
'unicorn/no-this-assignment': 'off',
// Not an issue with TypeScript
'unicorn/no-array-callback-reference': 'off',
// reduce is fine
'unicorn/no-array-reduce': 'off',
// this is very aggressive (600+ files changed). might make sense to apply bit by bit over time?
'unicorn/prevent-abbreviations': 'off',
// nah
'unicorn/consistent-destructuring': 'off',
'unicorn/no-lonely-if': 'off',
'unicorn/no-null': 'off',
'unicorn/no-process-exit': 'off',
'unicorn/no-useless-undefined': 'off',
'unicorn/prefer-event-target': 'off',
'unicorn/prefer-switch': 'off',
'unicorn/prefer-ternary': 'off',
'unicorn/prefer-top-level-await': 'off',
'unicorn/switch-case-braces': 'off',
// TODO: decide whether or not we want these
'unicorn/filename-case': 'off',
'unicorn/prefer-reflect-apply': 'off',
'unicorn/prefer-string-raw': 'off',
'unicorn/prefer-structured-clone': 'off',
// enabling this is blocked by https://github.com/microsoft/rushstack/issues/2780
'unicorn/prefer-export-from': 'off',
// enabling this is blocked by https://github.com/jestjs/jest/pull/14297
'unicorn/prefer-node-protocol': 'off',
},
settings: {
'import/ignore': ['react-native'],
// using `new RegExp` makes sure to escape `/`
'import/internal-regex': new RegExp(
getPackages()
.map(pkg => `^${pkg}$`)
.join('|'),
).source,
'import/resolver': {
typescript: {},
},
},
};

View File

@ -27,32 +27,32 @@ Object {
"loc": Object {
"end": Object {
"column": 39,
"line": 11,
"line": 9,
},
"start": Object {
"column": 27,
"line": 11,
"line": 9,
},
},
"locations": Array [
Object {
"end": Object {
"column": 35,
"line": 11,
"line": 9,
},
"start": Object {
"column": 34,
"line": 11,
"line": 9,
},
},
Object {
"end": Object {
"column": 39,
"line": 11,
"line": 9,
},
"start": Object {
"column": 38,
"line": 11,
"line": 9,
},
},
],
@ -62,32 +62,32 @@ Object {
"loc": Object {
"end": Object {
"column": 39,
"line": 12,
"line": 10,
},
"start": Object {
"column": 27,
"line": 12,
"line": 10,
},
},
"locations": Array [
Object {
"end": Object {
"column": 35,
"line": 12,
"line": 10,
},
"start": Object {
"column": 34,
"line": 12,
"line": 10,
},
},
Object {
"end": Object {
"column": 39,
"line": 12,
"line": 10,
},
"start": Object {
"column": 38,
"line": 12,
"line": 10,
},
},
],
@ -97,42 +97,42 @@ Object {
"loc": Object {
"end": Object {
"column": 48,
"line": 13,
"line": 11,
},
"start": Object {
"column": 27,
"line": 13,
"line": 11,
},
},
"locations": Array [
Object {
"end": Object {
"column": 31,
"line": 13,
"line": 11,
},
"start": Object {
"column": 27,
"line": 13,
"line": 11,
},
},
Object {
"end": Object {
"column": 39,
"line": 13,
"line": 11,
},
"start": Object {
"column": 35,
"line": 13,
"line": 11,
},
},
Object {
"end": Object {
"column": 48,
"line": 13,
"line": 11,
},
"start": Object {
"column": 43,
"line": 13,
"line": 11,
},
},
],
@ -142,32 +142,32 @@ Object {
"loc": Object {
"end": Object {
"column": 53,
"line": 14,
"line": 12,
},
"start": Object {
"column": 23,
"line": 14,
"line": 12,
},
},
"locations": Array [
Object {
"end": Object {
"column": 40,
"line": 14,
"line": 12,
},
"start": Object {
"column": 30,
"line": 14,
"line": 12,
},
},
Object {
"end": Object {
"column": 53,
"line": 14,
"line": 12,
},
"start": Object {
"column": 43,
"line": 14,
"line": 12,
},
},
],
@ -184,21 +184,21 @@ Object {
"decl": Object {
"end": Object {
"column": 26,
"line": 10,
"line": 8,
},
"start": Object {
"column": 16,
"line": 10,
"line": 8,
},
},
"loc": Object {
"end": Object {
"column": 1,
"line": 17,
"line": 15,
},
"start": Object {
"column": 47,
"line": 10,
"line": 8,
},
},
"name": "difference",
@ -207,21 +207,21 @@ Object {
"decl": Object {
"end": Object {
"column": 36,
"line": 14,
"line": 12,
},
"start": Object {
"column": 30,
"line": 14,
"line": 12,
},
},
"loc": Object {
"end": Object {
"column": 40,
"line": 14,
"line": 12,
},
"start": Object {
"column": 30,
"line": 14,
"line": 12,
},
},
"name": "(anonymous_1)",
@ -230,21 +230,21 @@ Object {
"decl": Object {
"end": Object {
"column": 49,
"line": 14,
"line": 12,
},
"start": Object {
"column": 43,
"line": 14,
"line": 12,
},
},
"loc": Object {
"end": Object {
"column": 53,
"line": 14,
"line": 12,
},
"start": Object {
"column": 43,
"line": 14,
"line": 12,
},
},
"name": "(anonymous_2)",
@ -265,81 +265,81 @@ Object {
"0": Object {
"end": Object {
"column": 16,
"line": 10,
"line": 8,
},
"start": Object {
"column": 0,
"line": 10,
"line": 8,
},
},
"1": Object {
"end": Object {
"column": 39,
"line": 11,
"line": 9,
},
"start": Object {
"column": 27,
"line": 11,
"line": 9,
},
},
"2": Object {
"end": Object {
"column": 39,
"line": 12,
"line": 10,
},
"start": Object {
"column": 27,
"line": 12,
"line": 10,
},
},
"3": Object {
"end": Object {
"column": 48,
"line": 13,
"line": 11,
},
"start": Object {
"column": 27,
"line": 13,
"line": 11,
},
},
"4": Object {
"end": Object {
"column": 53,
"line": 14,
"line": 12,
},
"start": Object {
"column": 23,
"line": 14,
"line": 12,
},
},
"5": Object {
"end": Object {
"column": 41,
"line": 14,
"line": 12,
},
"start": Object {
"column": 36,
"line": 14,
"line": 12,
},
},
"6": Object {
"end": Object {
"column": 54,
"line": 14,
"line": 12,
},
"start": Object {
"column": 49,
"line": 14,
"line": 12,
},
},
"7": Object {
"end": Object {
"column": 15,
"line": 16,
"line": 14,
},
"start": Object {
"column": 2,
"line": 16,
"line": 14,
},
},
},

View File

@ -41,7 +41,7 @@ exports[`moduleNameMapper wrong array configuration 1`] = `
12 | module.exports = () => 'test';
13 |
at createNoMappedModuleFoundError (../../packages/jest-resolve/build/index.js:1184:17)
at createNoMappedModuleFoundError (../../packages/jest-resolve/build/index.js:1182:17)
at Object.require (index.js:10:1)
at Object.require (__tests__/index.js:10:20)"
`;
@ -71,7 +71,7 @@ exports[`moduleNameMapper wrong configuration 1`] = `
12 | module.exports = () => 'test';
13 |
at createNoMappedModuleFoundError (../../packages/jest-resolve/build/index.js:1184:17)
at createNoMappedModuleFoundError (../../packages/jest-resolve/build/index.js:1182:17)
at Object.require (index.js:10:1)
at Object.require (__tests__/index.js:10:20)"
`;

View File

@ -26,7 +26,7 @@ exports[`shows a proper error from deep requires 1`] = `
12 | test('dummy', () => {
13 | expect(1).toBe(1);
at Resolver._throwModNotFoundError (../../packages/jest-resolve/build/index.js:937:11)
at Resolver._throwModNotFoundError (../../packages/jest-resolve/build/index.js:935:11)
at Object.<anonymous> (node_modules/discord.js/src/index.js:21:12)
at Object.require (__tests__/test.js:10:1)"
`;

View File

@ -37,7 +37,7 @@ exports[`show error message with matching files 1`] = `
| ^
9 |
at Resolver._throwModNotFoundError (../../packages/jest-resolve/build/index.js:937:11)
at Resolver._throwModNotFoundError (../../packages/jest-resolve/build/index.js:935:11)
at Object.require (index.js:8:18)
at Object.require (__tests__/test.js:8:11)"
`;

View File

@ -103,7 +103,7 @@ exports[`Wrong globals for environment print useful error when it explodes durin
ReferenceError: document is not defined
11 | /* eslint-env browser */
11 | /* global document */
12 |
> 13 | const div = document.createElement('div');
| ^

View File

@ -6,11 +6,10 @@
*
*/
/* eslint-disable local/ban-types-eventually */
import {color} from '../entry';
import type {Color} from '../types';
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
jest.mock('some-module', () => ({}) as Partial<{}>, {virtual: true});
jest.mock('../entry', () => {

View File

@ -5,7 +5,7 @@
* LICENSE file in the root directory of this source tree.
*/
/* eslint-env browser */
/* global HTMLDivElement */
'use strict';

View File

@ -5,7 +5,7 @@
* LICENSE file in the root directory of this source tree.
*/
/* eslint-env browser */
/* global document */
'use strict';

View File

@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/* eslint-env browser */
/* global document */
'use strict';
beforeEach(() => {

View File

@ -5,5 +5,5 @@
* LICENSE file in the root directory of this source tree.
*/
// eslint-disable-next-line @typescript-eslint/no-empty-interface
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
export interface obj {}

View File

@ -5,8 +5,6 @@
* LICENSE file in the root directory of this source tree.
*/
/* eslint-disable local/ban-types-eventually */
export function difference(a: number, b: number): number {
const branch1: boolean = true ? 1 : 0;
const branch2: boolean = true ? 1 : 0;

View File

@ -6,7 +6,7 @@
*
*/
/* eslint-env browser */
/* global document */
test('use toBe compare two div', () => {
const div1 = document.createElement('div');

View File

@ -5,7 +5,6 @@
* LICENSE file in the root directory of this source tree.
*/
'use strict';
/*eslint-env browser */
test('found url jestjs.io', () => {
expect(globalThis.location.href).toBe('https://jestjs.io/');

View File

@ -7,7 +7,7 @@
* @jest-environment jsdom
*/
/* eslint-env browser */
/* global document */
'use strict';

View File

@ -7,7 +7,7 @@
* @jest-environment jsdom
*/
'use strict';
/* eslint-env browser*/
/* global document */
test('stub', () => {
const element = document.createElement('div');

View File

@ -8,7 +8,6 @@
* @jest-environment-options {"url": "https://jestjs.io/"}
*/
'use strict';
/*eslint-env browser */
test('use jsdom and set the URL in this test file', () => {
expect(globalThis.location.href).toBe('https://jestjs.io/');

View File

@ -8,7 +8,7 @@
*
*/
/* eslint-env browser */
/* global document */
const div = document.createElement('div');

View File

@ -8,7 +8,7 @@
*
*/
/* eslint-env browser */
/* global document, window */
'use strict';

839
eslint.config.mjs Normal file
View File

@ -0,0 +1,839 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/* eslint-disable sort-keys */
import fs from 'fs';
import path from 'path';
import eslintJs from '@eslint/js';
import eslintPluginEslintCommentsConfigs from '@eslint-community/eslint-plugin-eslint-comments/configs';
import eslintPluginImport from 'eslint-plugin-import';
import eslintPluginJest from 'eslint-plugin-jest';
import eslintPluginJsdoc from 'eslint-plugin-jsdoc';
import eslintPluginMarkdown from 'eslint-plugin-markdown';
import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended';
import eslintPluginPromise from 'eslint-plugin-promise';
import eslintPluginUnicorn from 'eslint-plugin-unicorn';
import globals from 'globals';
import {sync as readPkg} from 'read-pkg';
import typescriptEslint from 'typescript-eslint';
import eslintPluginLocal from './.eslintplugin/index.mjs';
function getPackages() {
const PACKAGES_DIR = path.resolve(import.meta.dirname, 'packages');
const packages = fs
.readdirSync(PACKAGES_DIR)
.map(file => path.resolve(PACKAGES_DIR, file))
.filter(f => fs.lstatSync(path.resolve(f)).isDirectory())
.filter(f => fs.existsSync(path.join(path.resolve(f), 'package.json')));
return packages.map(packageDir => {
const pkg = readPkg({cwd: packageDir});
return pkg.name;
});
}
const config = typescriptEslint.config(
eslintJs.configs.recommended,
eslintPluginMarkdown.configs.recommended,
eslintPluginImport.flatConfigs.errors,
eslintPluginEslintCommentsConfigs.recommended,
eslintPluginUnicorn.configs.recommended,
eslintPluginPromise.configs['flat/recommended'],
eslintPluginPrettierRecommended,
{
languageOptions: {globals: {...globals.builtins, console: 'readonly'}},
plugins: {jsdoc: eslintPluginJsdoc, local: eslintPluginLocal},
settings: {
'import/ignore': ['react-native'],
// using `new RegExp` makes sure to escape `/`
'import/internal-regex': new RegExp(
getPackages()
.map(pkg => `^${pkg}$`)
.join('|'),
).source,
'import/resolver': {
typescript: {},
},
},
rules: {
'accessor-pairs': ['warn', {setWithoutGet: true}],
'block-scoped-var': 'off',
'callback-return': 'off',
camelcase: ['off', {properties: 'always'}],
complexity: 'off',
'consistent-return': 'warn',
'consistent-this': ['off', 'self'],
'constructor-super': 'error',
'default-case': 'off',
'dot-notation': 'off',
eqeqeq: ['error', 'smart'],
'@eslint-community/eslint-comments/disable-enable-pair': [
'error',
{allowWholeFile: true},
],
'@eslint-community/eslint-comments/no-unused-disable': 'error',
'func-names': 'off',
'func-style': ['off', 'declaration'],
'global-require': 'off',
'guard-for-in': 'off',
'handle-callback-err': 'off',
'id-length': 'off',
'id-match': 'off',
'import/no-duplicates': 'error',
'import/no-extraneous-dependencies': [
'error',
{
devDependencies: [
'**/__mocks__/**',
'**/__tests__/**',
'**/__typetests__/**',
'**/?(*.)(spec|test).js?(x)',
'scripts/**',
'babel.config.js',
'testSetupFile.js',
'eslint.config.mjs',
],
},
],
'import/no-unresolved': ['error', {ignore: ['fsevents']}],
'import/order': [
'error',
{
alphabetize: {
order: 'asc',
},
// this is the default order except for added `internal` in the middle
groups: [
'builtin',
'external',
'internal',
'parent',
'sibling',
'index',
],
'newlines-between': 'never',
},
],
'init-declarations': 'off',
'jsdoc/check-alignment': 'error',
'lines-around-comment': 'off',
'max-depth': 'off',
'max-nested-callbacks': 'off',
'max-params': 'off',
'max-statements': 'off',
'new-cap': 'off',
'new-parens': 'error',
'newline-after-var': 'off',
'no-alert': 'off',
'no-array-constructor': 'error',
'no-bitwise': 'warn',
'no-caller': 'error',
'no-case-declarations': 'off',
'no-class-assign': 'warn',
'no-cond-assign': 'off',
'no-confusing-arrow': 'off',
'no-console': [
'warn',
{allow: ['warn', 'error', 'time', 'timeEnd', 'timeStamp']},
],
'no-const-assign': 'error',
'no-constant-condition': 'error',
'no-constant-binary-expression': 'error',
'no-continue': 'off',
'no-control-regex': 'off',
'no-debugger': 'error',
'no-delete-var': 'error',
'no-div-regex': 'off',
'no-dupe-args': 'error',
'no-dupe-class-members': 'error',
'no-dupe-keys': 'error',
'no-duplicate-case': 'error',
'no-duplicate-imports': 'error',
'no-else-return': 'off',
'no-empty': 'off',
'no-empty-character-class': 'warn',
'no-empty-pattern': 'warn',
'no-eq-null': 'off',
'no-eval': 'error',
'no-ex-assign': 'warn',
'no-extend-native': 'warn',
'no-extra-bind': 'warn',
'no-extra-boolean-cast': 'warn',
'no-fallthrough': 'warn',
'no-floating-decimal': 'error',
'no-func-assign': 'error',
'no-implicit-coercion': 'off',
'no-implied-eval': 'error',
'no-inline-comments': 'off',
'no-inner-declarations': 'off',
'no-invalid-regexp': 'warn',
'no-invalid-this': 'off',
'no-irregular-whitespace': 'error',
'no-iterator': 'off',
'no-label-var': 'warn',
'no-labels': ['error', {allowLoop: true, allowSwitch: true}],
'no-lonely-if': 'off',
'no-loop-func': 'off',
'no-magic-numbers': 'off',
'no-mixed-requires': 'off',
'no-mixed-spaces-and-tabs': 'error',
'no-multi-str': 'error',
'no-multiple-empty-lines': 'off',
'no-native-reassign': ['error', {exceptions: ['Map', 'Set']}],
'no-negated-in-lhs': 'error',
'no-new': 'warn',
'no-new-func': 'error',
'no-new-object': 'warn',
'no-new-require': 'off',
'no-new-wrappers': 'warn',
'no-obj-calls': 'error',
'no-octal': 'warn',
'no-octal-escape': 'warn',
'no-param-reassign': 'off',
'no-plusplus': 'off',
'no-process-env': 'off',
'no-process-exit': 'off',
'no-proto': 'error',
'no-prototype-builtins': 'error',
'no-redeclare': 'warn',
'no-regex-spaces': 'warn',
'no-restricted-globals': [
'error',
{message: 'Use `globalThis` instead.', name: 'global'},
],
'no-restricted-imports': [
'error',
{message: 'Please use graceful-fs instead.', name: 'fs'},
],
'no-restricted-modules': 'off',
'no-restricted-syntax': 'off',
'no-return-assign': 'off',
'no-script-url': 'error',
'no-self-compare': 'warn',
'no-sequences': 'warn',
'no-shadow': 'off',
'no-shadow-restricted-names': 'warn',
'no-sparse-arrays': 'error',
'no-sync': 'off',
'no-ternary': 'off',
'no-this-before-super': 'error',
'no-throw-literal': 'error',
'no-undef': 'error',
'no-undef-init': 'off',
'no-undefined': 'off',
'no-underscore-dangle': 'off',
'no-unneeded-ternary': 'warn',
'no-unreachable': 'error',
'no-unused-expressions': 'off',
'no-unused-vars': ['error', {argsIgnorePattern: '^_'}],
'no-use-before-define': 'off',
'no-useless-call': 'error',
'no-useless-computed-key': 'error',
'no-useless-concat': 'error',
'no-var': 'error',
'no-void': 'off',
'no-warn-comments': 'off',
'no-with': 'off',
'object-shorthand': 'error',
'one-var': ['warn', {initialized: 'never'}],
'operator-assignment': ['warn', 'always'],
'operator-linebreak': 'off',
'padded-blocks': 'off',
'prefer-arrow-callback': ['error', {allowNamedFunctions: true}],
'prefer-const': 'error',
'prefer-template': 'error',
'promise/always-return': 'off',
'promise/catch-or-return': 'off',
'promise/no-callback-in-promise': 'off',
quotes: [
'error',
'single',
{allowTemplateLiterals: false, avoidEscape: true},
],
radix: 'warn',
'require-jsdoc': 'off',
'require-yield': 'off',
'sort-imports': ['error', {ignoreDeclarationSort: true}],
'sort-keys': 'error',
'sort-vars': 'off',
'spaced-comment': ['off', 'always', {exceptions: ['eslint', 'global']}],
strict: 'off',
'use-isnan': 'error',
'valid-jsdoc': 'off',
'valid-typeof': 'error',
'vars-on-top': 'off',
'wrap-iife': 'off',
'wrap-regex': 'off',
yoda: 'off',
// doesn't work without ESModuleInterop
'unicorn/import-style': 'off',
// we're a CJS project
'unicorn/prefer-module': 'off',
// enforced by `@typescript-eslint/no-this-alias` already
'unicorn/no-this-assignment': 'off',
// Not an issue with TypeScript
'unicorn/no-array-callback-reference': 'off',
// reduce is fine
'unicorn/no-array-reduce': 'off',
// this is very aggressive (600+ files changed). might make sense to apply bit by bit over time?
'unicorn/prevent-abbreviations': 'off',
// nah
'unicorn/consistent-destructuring': 'off',
'unicorn/no-lonely-if': 'off',
'unicorn/no-null': 'off',
'unicorn/no-process-exit': 'off',
'unicorn/no-useless-undefined': 'off',
'unicorn/prefer-event-target': 'off',
'unicorn/prefer-switch': 'off',
'unicorn/prefer-ternary': 'off',
'unicorn/prefer-top-level-await': 'off',
'unicorn/switch-case-braces': 'off',
// TODO: decide whether or not we want these
'unicorn/filename-case': 'off',
'unicorn/prefer-reflect-apply': 'off',
'unicorn/prefer-string-raw': 'off',
'unicorn/prefer-structured-clone': 'off',
// enabling this is blocked by https://github.com/microsoft/rushstack/issues/2780
'unicorn/prefer-export-from': 'off',
// enabling this is blocked by https://github.com/jestjs/jest/pull/14297
'unicorn/prefer-node-protocol': 'off',
},
},
[
typescriptEslint.configs.eslintRecommended,
typescriptEslint.configs.strict,
typescriptEslint.configs.stylistic,
eslintPluginImport.flatConfigs.typescript,
{
rules: {
'@typescript-eslint/array-type': ['error', {default: 'generic'}],
'@typescript-eslint/no-restricted-types': 'error',
'@typescript-eslint/consistent-type-imports': [
'error',
{fixStyle: 'inline-type-imports', disallowTypeAnnotations: false},
],
'@typescript-eslint/no-import-type-side-effects': 'error',
'@typescript-eslint/no-inferrable-types': 'error',
'@typescript-eslint/no-unused-vars': [
'error',
{argsIgnorePattern: '^_'},
],
'@typescript-eslint/prefer-ts-expect-error': 'error',
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/consistent-indexed-object-style': 'off',
// TS verifies these
'consistent-return': 'off',
'no-dupe-class-members': 'off',
'no-unused-vars': 'off',
'@typescript-eslint/no-dynamic-delete': 'off',
// TODO: enable at some point
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-non-null-assertion': 'off',
'@typescript-eslint/no-invalid-void-type': 'off',
'@typescript-eslint/consistent-type-definitions': 'off',
'@typescript-eslint/no-require-imports': 'off',
'import/no-unresolved': 'off',
'@typescript-eslint/no-unsafe-function-type': 'off',
// not needed to be enforced for TS
'import/namespace': 'off',
},
},
]
.flat()
.map(config => ({...config, files: ['**/*.ts', '**/*.tsx']})),
{
files: [
'packages/jest-mock/src/__tests__/index.test.ts',
'packages/jest-mock/src/index.ts',
'packages/pretty-format/src/__tests__/Immutable.test.ts',
'packages/pretty-format/src/__tests__/prettyFormat.test.ts',
],
rules: {
'local/prefer-rest-params-eventually': 'warn',
'prefer-rest-params': 'off',
},
},
{
files: [
'packages/expect/src/index.ts',
'packages/jest-fake-timers/src/legacyFakeTimers.ts',
'packages/jest-jasmine2/src/jestExpect.ts',
],
rules: {
'local/prefer-spread-eventually': 'warn',
'prefer-spread': 'off',
},
},
{
files: [
'e2e/babel-plugin-jest-hoist/__tests__/typescript.test.ts',
'e2e/coverage-remapping/covered.ts',
'packages/expect/src/matchers.ts',
'packages/expect/src/print.ts',
'packages/expect/src/toThrowMatchers.ts',
'packages/expect-utils/src/utils.ts',
'packages/jest-core/src/collectHandles.ts',
'packages/jest-core/src/plugins/UpdateSnapshotsInteractive.ts',
'packages/jest-leak-detector/src/index.ts',
'packages/jest-matcher-utils/src/index.ts',
'packages/jest-mock/src/__tests__/index.test.ts',
'packages/jest-mock/src/index.ts',
'packages/jest-snapshot/src/index.ts',
'packages/jest-snapshot/src/printSnapshot.ts',
'packages/jest-snapshot/src/types.ts',
'packages/jest-util/src/convertDescriptorToString.ts',
'packages/pretty-format/src/index.ts',
'packages/pretty-format/src/plugins/DOMCollection.ts',
],
rules: {
'local/no-restricted-types-eventually': [
'warn',
{
types: {
// none of these types are in use, so can be errored on
Boolean: true,
Number: true,
Object: true,
String: true,
Symbol: true,
},
},
],
},
},
{
files: ['e2e/coverage-remapping/covered.ts'],
rules: {
'no-constant-binary-expression': 'off',
'no-constant-condition': 'off',
},
},
// 'eslint-plugin-jest' rules for test and test related files
{
files: [
'**/__mocks__/**',
'**/__tests__/**',
'**/*.md/**',
'**/*.test.*',
'e2e/babel-plugin-jest-hoist/mockFile.js',
'e2e/failures/macros.js',
'e2e/test-in-root/*.js',
'e2e/test-match/test-suites/*',
'e2e/test-match-default/dot-spec-tests/*',
'packages/test-utils/src/ConditionalTest.ts',
],
...eslintPluginJest.configs['flat/style'],
ignores: ['**/__typetests__/**'],
rules: {
...eslintPluginJest.configs['flat/style'].rules,
'jest/no-alias-methods': 'error',
'jest/no-focused-tests': 'error',
'jest/no-identical-title': 'error',
'jest/require-to-throw-message': 'error',
'jest/valid-expect': 'error',
'import/order': 'off',
},
},
{
files: ['e2e/__tests__/*'],
rules: {
'jest/no-restricted-jest-methods': [
'error',
{
fn: 'Please use fixtures instead of mocks in the end-to-end tests.',
mock: 'Please use fixtures instead of mocks in the end-to-end tests.',
doMock:
'Please use fixtures instead of mocks in the end-to-end tests.',
setMock:
'Please use fixtures instead of mocks in the end-to-end tests.',
spyOn:
'Please use fixtures instead of mocks in the end-to-end tests.',
},
],
},
},
{
files: [
'website/docusaurus.config.js',
'website/fetchSupporters.js',
'website/src/prism/themeLight.js',
'website/src/prism/themeDark.js',
'website/babel.config.js',
'website/i18n.js',
'website/fetchSupporters.js',
],
languageOptions: {
sourceType: 'commonjs',
globals: globals.node,
},
},
{
files: ['website/src/**/*.js', 'examples/**/*.js'],
languageOptions: {
parserOptions: {ecmaFeatures: {jsx: true}},
globals: globals.browser,
},
},
// to make it more suitable for running on code examples in docs/ folder
{
files: ['**/*.md/**'],
languageOptions: {parserOptions: {ecmaFeatures: {jsx: true}}},
linterOptions: {reportUnusedDisableDirectives: 'off'},
rules: {
'@typescript-eslint/no-unused-vars': 'off',
'@typescript-eslint/no-empty-function': 'off',
'@typescript-eslint/no-namespace': 'off',
'@typescript-eslint/no-empty-interface': 'off',
'consistent-return': 'off',
'import/export': 'off',
'import/no-extraneous-dependencies': 'off',
'import/no-unresolved': 'off',
'jest/no-focused-tests': 'off',
'jest/require-to-throw-message': 'off',
'no-console': 'off',
'no-constant-condition': 'off',
'no-undef': 'off',
'no-unused-vars': 'off',
'sort-keys': 'off',
'unicorn/consistent-function-scoping': 'off',
'unicorn/error-message': 'off',
'unicorn/no-anonymous-default-export': 'off',
'unicorn/no-await-expression-member': 'off',
'unicorn/no-static-only-class': 'off',
'unicorn/prefer-number-properties': 'off',
'unicorn/prefer-string-raw': 'off',
'unicorn/prefer-global-this': 'off',
// The following disabled when upgrade ESLint to v9, some of them make sense to enable
'prefer-template': 'off',
'@typescript-eslint/no-require-imports': 'off',
'import/default': 'off',
'jest/prefer-to-have-length': 'off',
'unicorn/prefer-at': 'off',
'unicorn/numeric-separators-style': 'off',
},
},
// demonstration of matchers usage
{
files: ['**/UsingMatchers.md/**'],
rules: {
'jest/prefer-to-be': 'off',
},
},
// demonstration of 'jest/valid-expect' rule
{
files: [
'**/2017-05-06-jest-20-delightful-testing-multi-project-runner.md/**',
],
rules: {
'jest/valid-expect': 'off',
},
},
// Jest 11 did not had `toHaveLength` matcher
{
files: ['**/2016-04-12-jest-11.md/**'],
rules: {
'jest/prefer-to-have-length': 'off',
},
},
// snapshot in an example needs to keep escapes
{
files: [
'**/2017-02-21-jest-19-immersive-watch-mode-test-platform-improvements.md/**',
],
rules: {
'no-useless-escape': 'off',
},
},
// snapshots in examples plus inline snapshots need to keep backtick
{
files: ['**/*.md/**', 'e2e/custom-inline-snapshot-matchers/__tests__/*'],
rules: {
quotes: [
'error',
'single',
{allowTemplateLiterals: true, avoidEscape: true},
],
},
},
{
files: ['docs/**/*', 'website/**/*'],
rules: {
'no-redeclare': 'off',
'import/order': 'off',
'import/sort-keys': 'off',
'no-restricted-globals': ['off'],
'sort-keys': 'off',
},
},
{
files: ['examples/**/*', 'eslint.config.mjs'],
rules: {
'no-restricted-imports': 'off',
},
},
{
files: ['examples/angular/**/*.ts'],
rules: {
// Angular DI for some reason doesn't work with type imports
'@typescript-eslint/consistent-type-imports': [
'error',
{prefer: 'no-type-imports', disallowTypeAnnotations: false},
],
},
},
{
files: ['packages/**/*.ts'],
rules: {
'@typescript-eslint/explicit-module-boundary-types': 'error',
'import/no-anonymous-default-export': [
'error',
{
allowAnonymousClass: false,
allowAnonymousFunction: false,
allowArray: false,
allowArrowFunction: false,
allowCallExpression: false,
allowLiteral: false,
allowObject: true,
},
],
},
},
{
files: ['**/__tests__/**', '**/__mocks__/**'],
rules: {
'@typescript-eslint/ban-ts-comment': 'off',
'@typescript-eslint/no-empty-function': 'off',
'@typescript-eslint/class-literal-property-style': 'off',
},
},
{
files: [
'**/__tests__/**',
'**/__mocks__/**',
'packages/jest-jasmine2/src/jasmine/**/*',
'packages/expect/src/jasmineUtils.ts',
'**/vendor/**/*',
],
rules: {
'@typescript-eslint/explicit-module-boundary-types': 'off',
'unicorn/consistent-function-scoping': 'off',
'unicorn/no-await-expression-member': 'off',
'unicorn/prefer-spread': 'off',
'unicorn/prefer-string-raw': 'off',
},
},
{
files: [
'packages/jest-jasmine2/src/jasmine/**/*',
'packages/expect-utils/src/jasmineUtils.ts',
],
rules: {
'@typescript-eslint/ban-types': 'off',
'@eslint-community/eslint-comments/disable-enable-pair': 'off',
'@eslint-community/eslint-comments/no-unlimited-disable': 'off',
'prefer-rest-params': 'off',
'prefer-spread': 'off',
'sort-keys ': 'off',
},
},
{
files: [
'e2e/error-on-deprecated/__tests__/*',
'e2e/jasmine-async/__tests__/*',
],
languageOptions: {
globals: {
fail: 'readonly',
jasmine: 'readonly',
pending: 'readonly',
},
},
},
{
files: [
'e2e/**',
'website/**',
'**/__benchmarks__/**',
'**/__tests__/**',
'**/__typetests__/**',
'.eslintplugin/**',
],
rules: {
'import/no-extraneous-dependencies': 'off',
'unicorn/consistent-function-scoping': 'off',
'unicorn/error-message': 'off',
},
},
{
files: ['**/__typetests__/**'],
rules: {
'@typescript-eslint/no-empty-function': 'off',
'@typescript-eslint/no-invalid-void-type': 'off',
'@typescript-eslint/no-useless-constructor': 'off',
},
},
{
languageOptions: {globals: globals.node},
files: ['**/*.js', '**/*.jsx', '**/*.mjs', '**/*.cjs'],
},
{
files: [
'scripts/*',
'packages/*/__benchmarks__/test.js',
'packages/create-jest/src/runCreate.ts',
'packages/jest-repl/src/cli/runtime-cli.ts',
],
rules: {
'no-console': 'off',
},
},
{
files: [
'e2e/**',
'examples/**',
'website/**',
'**/__benchmarks__/**',
'**/__mocks__/**',
'**/__tests__/**',
'**/__typetests__/**',
],
rules: {
'@typescript-eslint/no-extraneous-class': 'off',
'@typescript-eslint/no-unused-vars': 'off',
'import/no-unresolved': 'off',
'no-console': 'off',
'no-unused-vars': 'off',
'unicorn/no-anonymous-default-export': 'off',
},
},
{
files: ['scripts/**/*'],
rules: {
'unicorn/no-anonymous-default-export': 'off',
},
},
{
files: ['packages/jest-mock/src/__tests__/**/*'],
rules: {
'unicorn/no-static-only-class': 'off',
},
},
{
files: ['**/*.mjs'],
rules: {
'unicorn/prefer-top-level-await': 'error',
},
},
{
files: [
'e2e/expect-async-matcher/__tests__/failure.test.js',
'e2e/expect-async-matcher/__tests__/success.test.js',
'e2e/transform/babel-jest-async/__tests__/babelJest.test.js',
],
rules: {
'import/namespace': 'off',
'import/default': 'off',
},
},
{
files: [
'e2e/coverage-report/__mocks__/sumDependency.js',
'e2e/require-main-after-create-require/empty.js',
'packages/create-jest/src/__tests__/__fixtures__/**/*',
'packages/jest-core/src/__tests__/**/*',
'packages/jest-haste-map/src/__tests__/test_dotfiles_root/**/*',
'packages/jest-resolve/src/__mocks__/**/*',
],
rules: {
'unicorn/no-empty-file': 'off',
},
},
{
files: ['packages/expect/src/__tests__/*.test.js'],
rules: {
'unicorn/prefer-number-properties': 'off',
},
},
{
ignores: [
'!.*',
'**/coverage/**',
'**/node_modules/**',
'bin/',
'packages/*/build/**',
'packages/*/dist/**',
'website/.docusaurus',
'website/build',
'website/node_modules',
'website/i18n/*.js',
'website/static',
// Third-party script
'packages/jest-diff/src/cleanupSemantic.ts',
'e2e/native-esm/wasm-bindgen/index_bg.js',
'**/.yarn',
'**/.pnp.*',
'**/*.snap',
'**/*.json',
// JS Syntax error
'{docs,website/versioned_docs/version-*}/ECMAScriptModules.md',
'{docs,website/versioned_docs/version-*}/JestObjectAPI.md',
// Bug? Uses TS syntax
'e2e/babel-plugin-jest-hoist/__tests__/integration.test.js',
'e2e/coverage-report/notRequiredInTestSuite.js',
'e2e/expect-async-matcher/matchers.js',
'e2e/explicit-resource-management/__tests__/index.js',
'e2e/failures/__tests__/errorWithCause.test.js',
'e2e/failures/__tests__/errorWithCauseInDescribe.test.js',
'e2e/failures/macros.js',
'e2e/global-setup/invalidSetupWithNamedExport.js',
'e2e/global-setup/setup.js',
'e2e/global-setup/setupWithDefaultExport.js',
'e2e/global-teardown/invalidTeardownWithNamedExport.js',
'e2e/global-teardown/teardownWithDefaultExport.js',
'e2e/multi-project-babel/prj-1/index.js',
'e2e/multi-project-babel/prj-2/index.js',
'e2e/multi-project-babel/prj-3/src/index.js',
'e2e/multi-project-babel/prj-4/src/index.js',
'e2e/multi-project-babel/prj-5/src/index.js',
'e2e/native-esm/__tests__/native-esm-import-assertions.test.js',
'e2e/transform-linked-modules/ignored/symlink.js',
'e2e/global-setup/setupWithDefaultExport.js',
'e2e/global-setup/setupWithDefaultExport.js',
'e2e/failures/macros.js',
'e2e/transform/**/*',
'examples/react-native/index.js',
],
},
);
export default config;

View File

@ -1,7 +1,5 @@
// Copyright (c) Meta Platforms, Inc. and affiliates.. All Rights Reserved.
/* global document */
'use strict';
jest.mock('../fetchCurrentUser.js');

View File

@ -10,7 +10,8 @@
"@babel/preset-typescript": "^7.0.0",
"@babel/register": "^7.0.0",
"@crowdin/cli": "^4.0.0",
"@eslint-community/eslint-plugin-eslint-comments": "^4.0.0",
"@eslint-community/eslint-plugin-eslint-comments": "^4.4.1",
"@eslint/js": "^9.21.0",
"@jest/globals": "workspace:*",
"@jest/test-utils": "workspace:*",
"@lerna-lite/cli": "^3.0.0",
@ -22,8 +23,6 @@
"@types/babel__template": "^7.0.2",
"@types/node": "^16.10.0",
"@types/which": "^3.0.0",
"@typescript-eslint/eslint-plugin": "^6.6.0",
"@typescript-eslint/parser": "^6.6.0",
"ansi-regex": "^5.0.1",
"ansi-styles": "^5.0.0",
"babel-jest": "workspace:*",
@ -31,20 +30,20 @@
"camelcase": "^6.2.0",
"chalk": "^4.0.0",
"dedent": "^1.0.0",
"eslint": "^8.8.0",
"eslint-config-prettier": "^10.0.0",
"eslint-import-resolver-typescript": "^3.2.5",
"eslint-plugin-import": "^2.6.0",
"eslint-plugin-jest": "^28.0.0",
"eslint": "^9.21.0",
"eslint-config-prettier": "^10.0.2",
"eslint-import-resolver-typescript": "^3.8.3",
"eslint-plugin-import": "^2.31.0",
"eslint-plugin-jest": "^28.11.0",
"eslint-plugin-jsdoc": "^50.0.0",
"eslint-plugin-local": "link:./.eslintplugin",
"eslint-plugin-markdown": "^3.0.0",
"eslint-plugin-prettier": "^5.0.0",
"eslint-plugin-promise": "^6.1.1",
"eslint-plugin-unicorn": "^56.0.0",
"eslint-plugin-markdown": "^5.1.0",
"eslint-plugin-prettier": "^5.2.3",
"eslint-plugin-promise": "^7.2.1",
"eslint-plugin-unicorn": "^57.0.0",
"execa": "^5.0.0",
"find-process": "^1.4.1",
"glob": "^10.3.10",
"globals": "^16.0.0",
"graceful-fs": "^4.2.9",
"isbinaryfile": "^5.0.0",
"istanbul-lib-coverage": "^3.0.0",
@ -80,6 +79,7 @@
"ts-node": "^10.5.0",
"tstyche": "^3.0.0",
"typescript": "^5.0.4",
"typescript-eslint": "^8.26.0",
"webpack": "^5.68.0",
"webpack-node-externals": "^3.0.0",
"which": "^4.0.0"

View File

@ -371,7 +371,7 @@ export default function jestHoist(): PluginObj<{
if (hoistedJestGetters.has(callExpr.node)) {
const mockStmt = callExpr.getStatementParent();
if (mockStmt && mockStmt.parentPath.isBlock()) {
if (mockStmt?.parentPath.isBlock()) {
stack.at(-1)!.calls.push(mockStmt.node);
mockStmt.remove();
}

View File

@ -15,9 +15,11 @@ const modifyPackageJson = ({
shouldModifyScripts: boolean;
}): string => {
if (shouldModifyScripts) {
projectPackageJson.scripts
? (projectPackageJson.scripts.test = 'jest')
: (projectPackageJson.scripts = {test: 'jest'});
if (projectPackageJson.scripts) {
projectPackageJson.scripts.test = 'jest';
} else {
projectPackageJson.scripts = {test: 'jest'};
}
}
delete projectPackageJson.jest;

View File

@ -9,8 +9,6 @@
/// <reference lib="dom" />
/* eslint-env browser */
import {isError} from '../utils';
// Copied from https://github.com/graingert/angular.js/blob/a43574052e9775cbc1d7dd8a086752c979b0f020/test/AngularSpec.js#L1883

View File

@ -9,7 +9,7 @@
/// <reference lib="dom" />
/* eslint-env browser*/
/* global document */
import {expect} from '@jest/globals';

View File

@ -97,26 +97,32 @@ class Any extends AsymmetricMatcher<any> {
asymmetricMatch(other: unknown) {
if (this.sample === String) {
// eslint-disable-next-line unicorn/no-instanceof-builtins
return typeof other === 'string' || other instanceof String;
}
if (this.sample === Number) {
// eslint-disable-next-line unicorn/no-instanceof-builtins
return typeof other === 'number' || other instanceof Number;
}
if (this.sample === Function) {
// eslint-disable-next-line unicorn/no-instanceof-builtins
return typeof other === 'function' || other instanceof Function;
}
if (this.sample === Boolean) {
// eslint-disable-next-line unicorn/no-instanceof-builtins
return typeof other === 'boolean' || other instanceof Boolean;
}
if (this.sample === BigInt) {
// eslint-disable-next-line unicorn/no-instanceof-builtins
return typeof other === 'bigint' || other instanceof BigInt;
}
if (this.sample === Symbol) {
// eslint-disable-next-line unicorn/no-instanceof-builtins
return typeof other === 'symbol' || other instanceof Symbol;
}

View File

@ -6,8 +6,6 @@
*
*/
/* eslint-disable local/ban-types-eventually */
import {
arrayBufferEquality,
equals,

View File

@ -6,8 +6,6 @@
*
*/
/* eslint-disable local/ban-types-eventually */
import {
EXPECTED_COLOR,
INVERTED_COLOR,

View File

@ -6,8 +6,6 @@
*
*/
/* eslint-disable local/ban-types-eventually */
import {isError} from '@jest/expect-utils';
import {
EXPECTED_COLOR,

View File

@ -13,8 +13,8 @@ Circus is a flux-based test runner for Jest that is fast, maintainable, and simp
Circus allows you to bind to events via an optional event handler on any [custom environment](https://jestjs.io/docs/configuration#testenvironment-string). See the [type definitions][type-definitions] for more information on the events and state data currently available.
```js
import {Event, State} from 'jest-circus';
```ts
import type {Event, State} from 'jest-circus';
import {TestEnvironment as NodeEnvironment} from 'jest-environment-node';
class MyCustomEnvironment extends NodeEnvironment {

View File

@ -73,7 +73,7 @@ export default class BufferedConsole extends Console {
override assert(value: unknown, message?: string | Error): void {
try {
assert(value, message);
assert.ok(value, message);
} catch (error) {
if (!(error instanceof AssertionError)) {
throw error;

View File

@ -52,7 +52,7 @@ export default class CustomConsole extends Console {
override assert(value: unknown, message?: string | Error): asserts value {
try {
assert(value, message);
assert.ok(value, message);
} catch (error) {
if (!(error instanceof AssertionError)) {
throw error;

View File

@ -66,7 +66,9 @@ export default class ReporterDispatcher {
options: ReporterOnStartOptions,
): Promise<void> {
for (const reporter of this._reporters) {
reporter.onRunStart && (await reporter.onRunStart(results, options));
if (reporter.onRunStart) {
await reporter.onRunStart(results, options);
}
}
}

View File

@ -351,15 +351,18 @@ class TestScheduler {
switch (reporter) {
case 'default':
summaryOptions = options;
verbose
? this.addReporter(new VerboseReporter(this._globalConfig))
: this.addReporter(new DefaultReporter(this._globalConfig));
this.addReporter(
verbose
? new VerboseReporter(this._globalConfig)
: new DefaultReporter(this._globalConfig),
);
break;
case 'github-actions':
GITHUB_ACTIONS &&
if (GITHUB_ACTIONS) {
this.addReporter(
new GitHubActionsReporter(this._globalConfig, options),
);
}
break;
case 'summary':
summaryOptions = options;

View File

@ -8,7 +8,6 @@
import chalk from 'chalk';
import {TestPathPatterns} from '@jest/pattern';
// eslint-disable-next-line import/order
import {JestHook, KEYS, TestWatcher} from 'jest-watcher';
const runJestMock = jest.fn();

View File

@ -8,7 +8,6 @@
import chalk from 'chalk';
import {TestPathPatterns} from '@jest/pattern';
// eslint-disable-next-line import/order
import {KEYS} from 'jest-watcher';
const runJestMock = jest.fn();

View File

@ -8,7 +8,6 @@
import chalk from 'chalk';
import {TestPathPatterns} from '@jest/pattern';
// eslint-disable-next-line import/order
import {KEYS} from 'jest-watcher';
const runJestMock = jest.fn();

View File

@ -225,24 +225,26 @@ const _run10000 = async (
);
performance.mark('jest/buildContextsAndHasteMaps:end');
globalConfig.watch || globalConfig.watchAll
? await runWatch(
contexts,
configs,
hasDeprecationWarnings,
globalConfig,
outputStream,
hasteMapInstances,
filter,
)
: await runWithoutWatch(
globalConfig,
contexts,
outputStream,
onComplete,
changedFilesPromise,
filter,
);
if (globalConfig.watch || globalConfig.watchAll) {
await runWatch(
contexts,
configs,
hasDeprecationWarnings,
globalConfig,
outputStream,
hasteMapInstances,
filter,
);
} else {
await runWithoutWatch(
globalConfig,
contexts,
outputStream,
onComplete,
changedFilesPromise,
filter,
);
}
};
const runWatch = async (

View File

@ -5,8 +5,6 @@
* LICENSE file in the root directory of this source tree.
*/
/* eslint-disable local/ban-types-eventually */
import * as asyncHooks from 'async_hooks';
import {promisify} from 'util';
import * as v8 from 'v8';
@ -77,6 +75,7 @@ export default function collectHandles(): HandleCollectionResult {
asyncId,
type,
triggerAsyncId,
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
resource: {} | NodeJS.Timeout,
) {
// Skip resources that should not generally prevent the process from

View File

@ -5,8 +5,6 @@
* LICENSE file in the root directory of this source tree.
*/
/* eslint-disable local/ban-types-eventually */
import type {AggregatedResult, AssertionLocation} from '@jest/test-result';
import type {Config} from '@jest/types';
import {

View File

@ -234,7 +234,7 @@ export default async function runJest({
console.log(testsListOutput);
}
onComplete && onComplete(makeEmptyAggregatedTestResult());
onComplete?.(makeEmptyAggregatedTestResult());
return;
}

View File

@ -287,7 +287,9 @@ export default async function watch(
}
testWatcher = new TestWatcher({isWatchMode: true});
isInteractive && outputStream.write(specialChars.CLEAR);
if (isInteractive) {
outputStream.write(specialChars.CLEAR);
}
preRunMessagePrint(outputStream);
isRunning = true;
const configs = contexts.map(context => context.config);

View File

@ -52,18 +52,20 @@ export default function bind<EachCallback extends Global.TestCallback>(
: buildTemplateTests(title, table, taggedTemplateData);
for (const row of tests) {
needsEachError
? cb(
row.title,
applyArguments(supportsDone, row.arguments, test),
timeout,
errorWithStack,
)
: cb(
row.title,
applyArguments(supportsDone, row.arguments, test),
timeout,
);
if (needsEachError) {
cb(
row.title,
applyArguments(supportsDone, row.arguments, test),
timeout,
errorWithStack,
);
} else {
cb(
row.title,
applyArguments(supportsDone, row.arguments, test),
timeout,
);
}
}
return;

View File

@ -11,7 +11,7 @@ import * as path from 'path';
import anymatch, {type Matcher} from 'anymatch';
import * as fs from 'graceful-fs';
import micromatch = require('micromatch');
// @ts-expect-error no types
// @ts-expect-error -- no types
import walker from 'walker';
// eslint-disable-next-line @typescript-eslint/prefer-ts-expect-error, @typescript-eslint/ban-ts-comment

View File

@ -79,7 +79,7 @@ const patchJasmine = () => {
const onStart = attr.onStart;
attr.onStart = (context: JasmineSpec) => {
jestExpect.setState({currentTestName: context.getFullName()});
onStart && onStart.call(attr, context);
onStart?.call(attr, context);
};
super(attr);
}

View File

@ -9,7 +9,7 @@
/// <reference lib="dom" />
/* eslint-env browser*/
/* global document */
import deepCyclicCopyReplaceable from '../deepCyclicCopyReplaceable';

View File

@ -5,8 +5,6 @@
* LICENSE file in the root directory of this source tree.
*/
/* eslint-disable local/ban-types-eventually */
import chalk = require('chalk');
import {
DIFF_DELETE,

View File

@ -140,7 +140,7 @@ export const formatExecError = (
const subErrors = [];
if (typeof error === 'string' || !error) {
error || (error = 'EMPTY ERROR');
error ||= 'EMPTY ERROR';
message = '';
stack = error;
} else {

View File

@ -86,7 +86,6 @@ describe('jest.fn()', () => {
});
test('models typings of mocked function', () => {
// eslint-disable-next-line @typescript-eslint/ban-types
expect(fn()).type.toBeAssignableTo<Function>();
expect(fn()).type.toBe<Mock<(...args: Array<unknown>) => unknown>>();
@ -423,7 +422,6 @@ describe('jest.spyOn()', () => {
const spy = spyOn(spiedObject, 'methodA');
test('models typings of spied object', () => {
// eslint-disable-next-line @typescript-eslint/ban-types
expect(spy).type.not.toBeAssignableTo<Function>();
expect(spy()).type.toRaiseError();
@ -469,10 +467,9 @@ describe('jest.spyOn()', () => {
).type.toBe<SpiedFunction<typeof Array.isArray>>();
expect(spyOn(spiedArray, 'isArray')).type.toRaiseError();
expect(
// eslint-disable-next-line @typescript-eslint/ban-types
spyOn(spiedFunction as unknown as Function, 'toString'),
).type.toBe<SpiedFunction<typeof spiedFunction.toString>>();
expect(spyOn(spiedFunction as unknown as Function, 'toString')).type.toBe<
SpiedFunction<typeof spiedFunction.toString>
>();
expect(spyOn(spiedFunction, 'toString')).type.toRaiseError();
expect(spyOn(globalThis, 'Date')).type.toBe<SpiedClass<typeof Date>>();

View File

@ -17,6 +17,7 @@ import type {
class SomeClass {
propertyB = 123;
private _propertyC: undefined;
// eslint-disable-next-line no-unused-private-class-members
#propertyD = 'abc';
constructor(public propertyA: string) {}
@ -42,6 +43,7 @@ class IndexClass {
propertyB = {b: 123};
private _propertyC = {c: undefined};
// eslint-disable-next-line no-unused-private-class-members
#propertyD = 'abc';
constructor(public propertyA: {a: string}) {}

View File

@ -6,7 +6,7 @@
*
*/
/* eslint-disable local/ban-types-eventually, local/prefer-rest-params-eventually */
/* eslint-disable local/prefer-rest-params-eventually */
import * as util from 'util';
import {type Context, createContext, runInContext, runInNewContext} from 'vm';

View File

@ -9,8 +9,6 @@
/// <reference lib="dom" />
/* eslint-env browser*/
function exampleDispatch() {
globalThis.dispatchEvent(new CustomEvent('event', {}));
}

View File

@ -7,7 +7,7 @@
/// <reference lib="ESNext.Disposable" preserve="true" />
/* eslint-disable local/ban-types-eventually, local/prefer-rest-params-eventually */
/* eslint-disable local/prefer-rest-params-eventually */
import {isPromise} from 'jest-util';

View File

@ -95,7 +95,6 @@ export function findClosestPackageJson(start: string): string | undefined {
dir = dirname(dir);
}
// eslint-disable-next-line no-constant-condition
while (true) {
const pkgJsonFile = resolve(dir, './package.json');
const hasPackageJson = isFile(pkgJsonFile);

View File

@ -324,6 +324,7 @@ async function runTestInternal(
// Access all stacks before uninstalling sourcemaps
let e = error;
while (typeof e === 'object' && e !== null && 'stack' in e) {
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
e.stack;
e = e?.cause;
}

View File

@ -589,7 +589,7 @@ export default class Runtime {
'You are trying to `import` a file after the Jest environment has been torn down.',
);
process.exitCode = 1;
// @ts-expect-error - exiting
// @ts-expect-error -- exiting
return;
}
if (this.isInsideTestCode === false) {

View File

@ -481,7 +481,7 @@ const _toThrowErrorMatchingSnapshot = (
const {context, hint, inlineSnapshot, isInline, matcherName, received} =
config;
context.dontThrow && context.dontThrow();
context.dontThrow?.();
const {isNot, promise} = context;

View File

@ -426,7 +426,7 @@ class ScriptTransformer {
// That means that the transform has a custom instrumentation
// logic and will handle it based on `config.collectCoverage` option
const transformWillInstrument =
shouldCallTransform && transformer && transformer.canInstrument;
shouldCallTransform && transformer?.canInstrument;
// Apply instrumentation to the code if necessary, keeping the instrumented code and new map
let map = transformed.map;

View File

@ -25,7 +25,6 @@ export type GeneratorReturningTestFn = (
this: TestContext,
) => TestReturnValueGenerator;
// eslint-disable-next-line @typescript-eslint/ban-types
export type NameLike = number | Function;
export type TestName = string;

View File

@ -74,8 +74,7 @@ const _validate = (
) {
// skip validating unknown options inside blacklisted paths
} else {
options.unknown &&
options.unknown(config, exampleConfig, key, options, path);
options.unknown?.(config, exampleConfig, key, options, path);
}
if (

View File

@ -133,7 +133,6 @@ class MinHeap<TItem extends HeapItem> {
nodes[0] = lastElement ?? null;
const element = nodes[0]!;
// eslint-disable-next-line no-constant-condition
while (true) {
let swapIndex = null;
const rightChildIndex = (index + 1) * 2;

View File

@ -125,6 +125,7 @@ export default abstract class WorkerAbstract
* killed off.
*/
protected _shutdown(): void {
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
this.state === WorkerStates.SHUT_DOWN;
// End the permanent stream so the merged stream end too

View File

@ -20,7 +20,6 @@ async function leakMemory() {
);
let i = Number.MAX_SAFE_INTEGER / 2;
// eslint-disable-next-line no-constant-condition
while (true) {
i++;

View File

@ -9,7 +9,7 @@
/// <reference lib="dom" />
/* eslint-env browser*/
/* global document */
import {plugins} from '../';
import setPrettyPrint from './setPrettyPrint';

View File

@ -9,7 +9,7 @@
/// <reference lib="dom" />
/* eslint-env browser*/
/* global document */
import prettyFormat, {plugins} from '../';
import setPrettyPrint from './setPrettyPrint';

View File

@ -5,8 +5,6 @@
* LICENSE file in the root directory of this source tree.
*/
/* eslint-disable local/ban-types-eventually */
import style = require('ansi-styles');
import {
printIteratorEntries,

View File

@ -12,7 +12,9 @@ import * as path from 'path';
import * as url from 'url';
import chalk from 'chalk';
import {ESLint} from 'eslint';
import eslintPluginJest from 'eslint-plugin-jest';
import pLimit from 'p-limit';
import typescriptEslint from 'typescript-eslint';
import {getPackagesWithTsConfig} from './buildUtils.mjs';
// we want to limit the number of processes we spawn
@ -83,84 +85,134 @@ try {
cache: true,
cacheLocation: path.resolve(packageDir, '.eslintcache'),
cwd: monorepoRoot,
extensions: ['.ts'],
fix,
fixTypes: ['problem', 'suggestion', 'layout'],
overrideConfig: {
extends: [
'plugin:@typescript-eslint/recommended-type-checked',
'plugin:@typescript-eslint/stylistic-type-checked',
],
overrides: [
{
files: ['**/__tests__/**'],
plugins: ['jest'],
rules: {
'@typescript-eslint/unbound-method': 'off',
'@typescript-eslint/no-empty-function': 'off',
'@typescript-eslint/no-non-null-assertion': 'off',
'jest/unbound-method': 'error',
overrideConfig: typescriptEslint.config(
typescriptEslint.configs.recommendedTypeChecked,
typescriptEslint.configs.stylisticTypeChecked,
{
languageOptions: {
parserOptions: {
EXPERIMENTAL_useProjectService: true,
project: ['./tsconfig.json', `${packageDir}/tsconfig.json`],
tsconfigRootDir: monorepoRoot,
},
},
{
files: 'packages/jest-types/src/Circus.ts',
rules: {
// We're faking nominal types
'@typescript-eslint/no-duplicate-type-constituents': 'off',
// this file has `Exception`, which is `unknown`
'@typescript-eslint/no-redundant-type-constituents': 'off',
},
rules: {
'@typescript-eslint/consistent-type-exports': 'error',
'@typescript-eslint/dot-notation': 'error',
'@typescript-eslint/no-base-to-string': [
'error',
// https://github.com/typescript-eslint/typescript-eslint/issues/1655#issuecomment-593639305
{ignoredTypeNames: ['AssertionError', 'Error']},
],
'@typescript-eslint/no-duplicate-type-constituents': 'error',
'@typescript-eslint/no-redundant-type-constituents': 'error',
'@typescript-eslint/no-unnecessary-template-expression':
'error',
'@typescript-eslint/non-nullable-type-assertion-style': 'error',
'@typescript-eslint/prefer-nullish-coalescing': 'error',
'@typescript-eslint/prefer-readonly': 'error',
// TODO: activate this at some point
// '@typescript-eslint/prefer-readonly-parameter-types': 'error',
'@typescript-eslint/prefer-reduce-type-parameter': 'error',
'@typescript-eslint/return-await': 'error',
'@typescript-eslint/strict-boolean-expressions': 'error',
'@typescript-eslint/switch-exhaustiveness-check': 'error',
// TODO: enable this
'@typescript-eslint/no-explicit-any': 'off',
// disable the ones we disable in main config
'@typescript-eslint/no-invalid-void-type': 'off',
'@typescript-eslint/no-dynamic-delete': 'off',
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/consistent-type-definitions': 'off',
// nah
'@typescript-eslint/consistent-indexed-object-style': 'off',
'@typescript-eslint/require-await': 'off',
// TODO: enable these
'@typescript-eslint/no-require-imports': 'off',
'@typescript-eslint/no-unsafe-call': 'off',
'@typescript-eslint/no-unsafe-member-access': 'off',
'@typescript-eslint/no-unsafe-assignment': 'off',
'@typescript-eslint/no-unsafe-argument': 'off',
'@typescript-eslint/no-unsafe-return': 'off',
'@typescript-eslint/prefer-regexp-exec': 'off',
},
// {
// files: ['packages/babel-plugin-jest-hoist/src/index.ts'],
// rules: {
// '@typescript-eslint/strict-boolean-expressions': 'off',
// },
// },
],
parser: '@typescript-eslint/parser',
parserOptions: {
EXPERIMENTAL_useProjectService: true,
project: ['./tsconfig.json', `${packageDir}/tsconfig.json`],
tsconfigRootDir: monorepoRoot,
},
plugins: ['@typescript-eslint'],
root: true,
rules: {
'@typescript-eslint/consistent-type-exports': 'error',
'@typescript-eslint/dot-notation': 'error',
'@typescript-eslint/no-base-to-string': [
'error',
// https://github.com/typescript-eslint/typescript-eslint/issues/1655#issuecomment-593639305
{ignoredTypeNames: ['AssertionError', 'Error']},
{
files: ['**/__tests__/**'],
plugins: {jest: eslintPluginJest},
rules: {
'@typescript-eslint/unbound-method': 'off',
'@typescript-eslint/no-empty-function': 'off',
'@typescript-eslint/no-non-null-assertion': 'off',
'jest/unbound-method': 'error',
},
},
{
files: ['packages/jest-types/src/Global.ts'],
rules: {
'@typescript-eslint/no-unsafe-function-type': 'off',
},
},
{
files: ['packages/create-jest/src/generateConfigFile.ts'],
rules: {
'@typescript-eslint/restrict-template-expressions': 'off',
},
},
{
files: [
'packages/jest-types/src/Circus.ts',
'packages/create-jest/src/generateConfigFile.ts',
'packages/jest-environment-jsdom-abstract/src/index.ts',
'packages/jest-environment/src/index.ts',
'packages/jest-globals/src/index.ts',
'packages/jest-test-result/src/types.ts',
'packages/jest-test-sequencer/src/index.ts',
'packages/jest-types/src/Circus.ts',
'packages/jest-types/src/Config.ts',
'packages/jest-types/src/Global.ts',
'packages/test-globals/src/index.ts',
],
'@typescript-eslint/no-duplicate-type-constituents': 'error',
'@typescript-eslint/no-redundant-type-constituents': 'error',
'@typescript-eslint/no-useless-template-literals': 'error',
'@typescript-eslint/non-nullable-type-assertion-style': 'error',
'@typescript-eslint/prefer-nullish-coalescing': 'error',
'@typescript-eslint/prefer-readonly': 'error',
// TODO: activate this at some point
// '@typescript-eslint/prefer-readonly-parameter-types': 'error',
'@typescript-eslint/prefer-reduce-type-parameter': 'error',
'@typescript-eslint/return-await': 'error',
'@typescript-eslint/strict-boolean-expressions': 'error',
'@typescript-eslint/switch-exhaustiveness-check': 'error',
// TODO: enable this
'@typescript-eslint/no-explicit-any': 'off',
// disable the ones we disable in main config
'@typescript-eslint/no-invalid-void-type': 'off',
'@typescript-eslint/no-dynamic-delete': 'off',
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/consistent-type-definitions': 'off',
// nah
'@typescript-eslint/consistent-indexed-object-style': 'off',
'@typescript-eslint/require-await': 'off',
rules: {
// We're faking nominal types
'@typescript-eslint/no-duplicate-type-constituents': 'off',
// this file has `Exception`, which is `unknown`
'@typescript-eslint/no-redundant-type-constituents': 'off',
},
},
},
{
files: [
'packages/babel-plugin-jest-hoist/src/index.ts',
'packages/babel-jest/src/index.ts',
'packages/babel-plugin-jest-hoist/src/index.ts',
'packages/packages/create-jest/src/runCreate.ts',
'packages/babel-jest/src/index.ts',
'packages/babel-jest/src/index.ts',
'packages/create-jest/src/runCreate.ts',
'packages/jest-changed-files/src/index.ts',
'packages/jest-console/src/BufferedConsole.ts',
'packages/jest-console/src/CustomConsole.ts',
'packages/jest-environment-jsdom-abstract/src/index.ts',
'packages/jest-resolve-dependencies/src/index.ts',
'packages/jest-test-result/src/formatTestResults.ts',
'packages/jest-test-result/src/helpers.ts',
'packages/jest-test-sequencer/src/index.ts',
'packages/jest-transform/src/ScriptTransformer.ts',
'packages/jest-transform/src/shouldInstrument.ts',
],
rules: {
'@typescript-eslint/strict-boolean-expressions': 'off',
},
},
{ignores: ['**/*.js', '**/*.cjs', '**/*.mjs']},
),
});
const filesToLint = packageDir.endsWith('e2e')

740
yarn.lock

File diff suppressed because it is too large Load Diff