From c33f497ad8aec7c123c7374f7aff3e24025fe861 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Fri, 28 Apr 2023 13:40:00 +0930 Subject: [PATCH] feat: remove `RuleTester` in `/utils` in favour of the new `/rule-tester` package (#6816) --- packages/eslint-plugin-internal/package.json | 1 + .../tests/RuleTester.ts | 6 +- .../rules/no-poorly-typed-ts-props.test.ts | 4 +- .../no-typescript-default-import.test.ts | 46 +- .../tests/rules/no-typescript-estree.test.ts | 79 +- .../rules/plugin-test-formatting.test.ts | 4 +- .../tests/rules/prefer-ast-types-enum.test.ts | 69 +- packages/eslint-plugin/package.json | 1 + .../src/rules/consistent-type-assertions.ts | 4 +- packages/eslint-plugin/tests/RuleTester.ts | 87 ++- .../tests/eslint-rules/arrow-parens.test.ts | 3 +- .../tests/eslint-rules/no-dupe-args.test.ts | 3 +- .../eslint-rules/no-implicit-globals.test.ts | 3 +- .../no-restricted-globals.test.ts | 3 +- .../tests/eslint-rules/no-undef.test.ts | 3 +- .../tests/eslint-rules/prefer-const.test.ts | 3 +- .../tests/eslint-rules/strict.test.ts | 3 +- .../adjacent-overload-signatures.test.ts | 3 +- .../tests/rules/array-type.test.ts | 2 +- .../tests/rules/await-thenable.test.ts | 4 +- .../tests/rules/ban-ts-comment.test.ts | 3 +- .../tests/rules/ban-tslint-comment.test.ts | 3 +- .../tests/rules/ban-types.test.ts | 2 +- .../tests/rules/block-spacing.test.ts | 7 +- .../tests/rules/brace-style.test.ts | 3 +- .../class-literal-property-style.test.ts | 3 +- .../tests/rules/comma-dangle.test.ts | 3 +- .../tests/rules/comma-spacing.test.ts | 3 +- .../consistent-generic-constructors.test.ts | 3 +- .../consistent-indexed-object-style.test.ts | 3 +- .../rules/consistent-type-assertions.test.ts | 38 +- .../rules/consistent-type-definitions.test.ts | 3 +- .../rules/consistent-type-exports.test.ts | 4 +- .../rules/consistent-type-imports.test.ts | 4 +- .../tests/rules/default-param-last.test.ts | 3 +- .../tests/rules/dot-notation.test.ts | 4 +- .../explicit-function-return-type.test.ts | 99 +-- .../explicit-member-accessibility.test.ts | 53 +- .../explicit-module-boundary-types.test.ts | 6 +- .../tests/rules/func-call-spacing.test.ts | 2 +- .../tests/rules/indent/indent.test.ts | 2 +- .../tests/rules/init-declarations.test.ts | 2 +- .../tests/rules/key-spacing.test.ts | 3 +- .../tests/rules/keyword-spacing.test.ts | 2 +- .../tests/rules/lines-around-comment.test.ts | 2 +- .../rules/lines-between-class-members.test.ts | 3 +- .../rules/member-delimiter-style.test.ts | 3 +- .../tests/rules/member-ordering.test.ts | 5 +- ...habetically-case-insensitive-order.test.ts | 5 +- ...mber-ordering-alphabetically-order.test.ts | 5 +- ...ing-natural-case-insensitive-order.test.ts | 3 +- .../member-ordering-natural-order.test.ts | 3 +- .../member-ordering-optionalMembers.test.ts | 2 +- .../rules/method-signature-style.test.ts | 393 +++++++--- .../cases/createTestCases.ts | 2 +- .../naming-convention.test.ts | 4 +- .../tests/rules/no-array-constructor.test.ts | 2 +- .../tests/rules/no-base-to-string.test.ts | 4 +- .../no-confusing-non-null-assertion.test.ts | 3 +- .../no-confusing-void-expression.test.ts | 160 +++- .../tests/rules/no-dupe-class-members.test.ts | 3 +- .../rules/no-duplicate-enum-values.test.ts | 3 +- .../no-duplicate-type-constituents.test.ts | 4 +- .../tests/rules/no-dynamic-delete.test.ts | 4 +- .../tests/rules/no-empty-function.test.ts | 3 +- .../tests/rules/no-empty-interface.test.ts | 3 +- .../tests/rules/no-explicit-any.test.ts | 2 +- .../rules/no-extra-non-null-assertion.test.ts | 3 +- .../tests/rules/no-extra-parens.test.ts | 714 ++++++++++++----- .../tests/rules/no-extra-semi.test.ts | 3 +- .../tests/rules/no-extraneous-class.test.ts | 2 +- .../tests/rules/no-floating-promises.test.ts | 4 +- .../tests/rules/no-for-in-array.test.ts | 3 +- .../tests/rules/no-implied-eval.test.ts | 4 +- .../rules/no-import-type-side-effects.test.ts | 3 +- .../tests/rules/no-inferrable-types.test.ts | 2 +- .../tests/rules/no-invalid-this.test.ts | 3 +- .../tests/rules/no-invalid-void-type.test.ts | 3 +- .../tests/rules/no-loop-func.test.ts | 2 +- .../tests/rules/no-loss-of-precision.test.ts | 3 +- .../tests/rules/no-magic-numbers.test.ts | 3 +- .../no-meaningless-void-operator.test.ts | 4 +- .../tests/rules/no-misused-new.test.ts | 3 +- .../tests/rules/no-misused-promises.test.ts | 46 +- .../tests/rules/no-mixed-enums.test.ts | 4 +- .../tests/rules/no-namespace.test.ts | 3 +- ...n-null-asserted-nullish-coalescing.test.ts | 3 +- ...o-non-null-asserted-optional-chain.test.ts | 3 +- .../tests/rules/no-non-null-assertion.test.ts | 3 +- .../tests/rules/no-redeclare.test.ts | 2 +- .../no-redundant-type-constituents.test.ts | 4 +- .../tests/rules/no-require-imports.test.ts | 3 +- .../tests/rules/no-restricted-imports.test.ts | 2 +- .../rules/no-shadow/no-shadow-eslint.test.ts | 4 +- .../tests/rules/no-shadow/no-shadow.test.ts | 2 +- .../tests/rules/no-this-alias.test.ts | 2 +- .../tests/rules/no-throw-literal.test.ts | 4 +- .../tests/rules/no-type-alias.test.ts | 3 +- ...nnecessary-boolean-literal-compare.test.ts | 4 +- .../rules/no-unnecessary-condition.test.ts | 3 +- .../rules/no-unnecessary-qualifier.test.ts | 3 +- .../no-unnecessary-type-arguments.test.ts | 4 +- .../no-unnecessary-type-assertion.test.ts | 14 +- .../no-unnecessary-type-constraint.test.ts | 45 +- .../tests/rules/no-unsafe-argument.test.ts | 4 +- .../tests/rules/no-unsafe-assignment.test.ts | 217 +++--- .../tests/rules/no-unsafe-call.test.ts | 191 +++-- .../no-unsafe-declaration-merging.test.ts | 4 +- .../rules/no-unsafe-enum-comparison.test.ts | 4 +- .../rules/no-unsafe-member-access.test.ts | 153 ++-- .../tests/rules/no-unsafe-return.test.ts | 166 ++-- .../tests/rules/no-unused-expressions.test.ts | 2 +- .../no-unused-vars-eslint.test.ts | 4 +- .../no-unused-vars/no-unused-vars.test.ts | 11 +- .../tests/rules/no-use-before-define.test.ts | 2 +- .../rules/no-useless-constructor.test.ts | 2 +- .../rules/no-useless-empty-export.test.ts | 3 +- .../tests/rules/no-var-requires.test.ts | 3 +- .../non-nullable-type-assertion-style.test.ts | 4 +- .../tests/rules/object-curly-spacing.test.ts | 2 +- .../padding-line-between-statements.test.ts | 3 +- .../tests/rules/parameter-properties.test.ts | 3 +- .../tests/rules/prefer-as-const.test.ts | 3 +- .../rules/prefer-enum-initializers.test.ts | 3 +- .../tests/rules/prefer-for-of.test.ts | 3 +- .../tests/rules/prefer-function-type.test.ts | 2 +- .../tests/rules/prefer-includes.test.ts | 4 +- .../rules/prefer-literal-enum-member.test.ts | 3 +- .../rules/prefer-namespace-keyword.test.ts | 3 +- .../rules/prefer-nullish-coalescing.test.ts | 3 +- .../prefer-optional-chain.test.ts | 3 +- .../prefer-readonly-parameter-types.test.ts | 3 +- .../tests/rules/prefer-readonly.test.ts | 4 +- .../prefer-reduce-type-parameter.test.ts | 4 +- .../tests/rules/prefer-regexp-exec.test.ts | 4 +- .../rules/prefer-return-this-type.test.ts | 4 +- .../prefer-string-starts-ends-with.test.ts | 3 +- .../rules/prefer-ts-expect-error.test.ts | 3 +- .../rules/promise-function-async.test.ts | 4 +- .../eslint-plugin/tests/rules/quotes.test.ts | 3 +- .../rules/require-array-sort-compare.test.ts | 4 +- .../tests/rules/require-await.test.ts | 4 +- .../rules/restrict-plus-operands.test.ts | 4 +- .../restrict-template-expressions.test.ts | 4 +- .../tests/rules/return-await.test.ts | 4 +- .../eslint-plugin/tests/rules/semi.test.ts | 2 +- .../rules/sort-type-constituents.test.ts | 2 +- .../tests/rules/space-before-blocks.test.ts | 3 +- .../rules/space-before-function-paren.test.ts | 2 +- .../tests/rules/space-infix-ops.test.ts | 3 +- .../rules/strict-boolean-expressions.test.ts | 240 ++++-- .../rules/switch-exhaustiveness-check.test.ts | 2 +- .../rules/triple-slash-reference.test.ts | 3 +- .../rules/type-annotation-spacing.test.ts | 2 +- .../eslint-plugin/tests/rules/typedef.test.ts | 4 +- .../tests/rules/unbound-method.test.ts | 3 +- .../tests/rules/unified-signatures.test.ts | 3 +- .../tests/util/getWrappingFixer.test.ts | 3 +- .../tests/util/isNodeEqual.test.ts | 3 +- .../eslint-plugin/tools/generate-configs.ts | 13 +- .../eslint-utils/batchedSingleLineTests.ts | 73 -- packages/utils/src/eslint-utils/index.ts | 2 - .../eslint-utils/rule-tester/RuleTester.ts | 314 -------- .../rule-tester/dependencyConstraints.ts | 63 -- .../batchedSingleLineTests.test.ts | 81 -- .../rule-tester/RuleTester.test.ts | 737 ------------------ ...13-announcing-typescript-eslint-v6-beta.md | 43 +- 167 files changed, 2138 insertions(+), 2450 deletions(-) delete mode 100644 packages/utils/src/eslint-utils/batchedSingleLineTests.ts delete mode 100644 packages/utils/src/eslint-utils/rule-tester/RuleTester.ts delete mode 100644 packages/utils/src/eslint-utils/rule-tester/dependencyConstraints.ts delete mode 100644 packages/utils/tests/eslint-utils/batchedSingleLineTests.test.ts delete mode 100644 packages/utils/tests/eslint-utils/rule-tester/RuleTester.test.ts diff --git a/packages/eslint-plugin-internal/package.json b/packages/eslint-plugin-internal/package.json index 9fb96041632..1df2a2256cc 100644 --- a/packages/eslint-plugin-internal/package.json +++ b/packages/eslint-plugin-internal/package.json @@ -14,6 +14,7 @@ }, "dependencies": { "@types/prettier": "*", + "@typescript-eslint/rule-tester": "5.59.1", "@typescript-eslint/scope-manager": "5.59.1", "@typescript-eslint/type-utils": "5.59.1", "@typescript-eslint/utils": "5.59.1", diff --git a/packages/eslint-plugin-internal/tests/RuleTester.ts b/packages/eslint-plugin-internal/tests/RuleTester.ts index 260e222194b..f56f93ee81f 100644 --- a/packages/eslint-plugin-internal/tests/RuleTester.ts +++ b/packages/eslint-plugin-internal/tests/RuleTester.ts @@ -1,10 +1,8 @@ -import { ESLintUtils } from '@typescript-eslint/utils'; import path from 'path'; function getFixturesRootDir(): string { return path.join(__dirname, 'fixtures'); } -const { batchedSingleLineTests, RuleTester } = ESLintUtils; - -export { RuleTester, batchedSingleLineTests, getFixturesRootDir }; +export { RuleTester } from '@typescript-eslint/rule-tester'; +export { getFixturesRootDir }; diff --git a/packages/eslint-plugin-internal/tests/rules/no-poorly-typed-ts-props.test.ts b/packages/eslint-plugin-internal/tests/rules/no-poorly-typed-ts-props.test.ts index b0b80f56cc3..5e75c5e2b7e 100644 --- a/packages/eslint-plugin-internal/tests/rules/no-poorly-typed-ts-props.test.ts +++ b/packages/eslint-plugin-internal/tests/rules/no-poorly-typed-ts-props.test.ts @@ -1,6 +1,8 @@ /* eslint-disable @typescript-eslint/internal/prefer-ast-types-enum */ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/no-poorly-typed-ts-props'; -import { getFixturesRootDir, RuleTester } from '../RuleTester'; +import { getFixturesRootDir } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin-internal/tests/rules/no-typescript-default-import.test.ts b/packages/eslint-plugin-internal/tests/rules/no-typescript-default-import.test.ts index 35d2f13d329..45590e5012d 100644 --- a/packages/eslint-plugin-internal/tests/rules/no-typescript-default-import.test.ts +++ b/packages/eslint-plugin-internal/tests/rules/no-typescript-default-import.test.ts @@ -1,5 +1,6 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/no-typescript-default-import'; -import { batchedSingleLineTests, RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', @@ -16,30 +17,21 @@ ruleTester.run('no-typescript-default-import', rule, { 'import ts = foo;', "import ts = require('nottypescript');", ], - invalid: batchedSingleLineTests({ - code: ` -import ts from 'typescript'; -import ts, { SyntaxKind } from 'typescript'; -import ts = require('typescript'); - `, - output: ` -import * as ts from 'typescript'; -import ts, { SyntaxKind } from 'typescript'; -import * as ts from 'typescript'; - `, - errors: [ - { - messageId: 'noTSDefaultImport', - line: 2, - }, - { - messageId: 'noTSDefaultImport', - line: 3, - }, - { - messageId: 'noTSDefaultImport', - line: 4, - }, - ], - }), + invalid: [ + { + code: "import ts from 'typescript';", + output: `import * as ts from 'typescript';`, + errors: [{ messageId: 'noTSDefaultImport' }], + }, + { + code: "import ts, { SyntaxKind } from 'typescript';", + output: null, + errors: [{ messageId: 'noTSDefaultImport' }], + }, + { + code: "import ts = require('typescript');", + output: `import * as ts from 'typescript';`, + errors: [{ messageId: 'noTSDefaultImport' }], + }, + ], }); diff --git a/packages/eslint-plugin-internal/tests/rules/no-typescript-estree.test.ts b/packages/eslint-plugin-internal/tests/rules/no-typescript-estree.test.ts index 1cde420e337..46eb2edabbe 100644 --- a/packages/eslint-plugin-internal/tests/rules/no-typescript-estree.test.ts +++ b/packages/eslint-plugin-internal/tests/rules/no-typescript-estree.test.ts @@ -1,5 +1,6 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/no-typescript-estree-import'; -import { batchedSingleLineTests, RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', @@ -14,48 +15,36 @@ ruleTester.run('no-typescript-estree-import', rule, { "import foo from '@typescript-eslint/utils';", "import * as foo from '@typescript-eslint/utils';", ], - invalid: batchedSingleLineTests({ - code: ` -import { foo } from '@typescript-eslint/typescript-estree'; -import foo from '@typescript-eslint/typescript-estree'; -import * as foo from '@typescript-eslint/typescript-estree'; -import { foo } from '@typescript-eslint/types'; -import foo from '@typescript-eslint/types'; -import * as foo from '@typescript-eslint/types'; - `, - output: ` -import { foo } from '@typescript-eslint/utils'; -import foo from '@typescript-eslint/utils'; -import * as foo from '@typescript-eslint/utils'; -import { foo } from '@typescript-eslint/utils'; -import foo from '@typescript-eslint/utils'; -import * as foo from '@typescript-eslint/utils'; - `, - errors: [ - { - messageId: 'dontImportPackage', - line: 2, - }, - { - messageId: 'dontImportPackage', - line: 3, - }, - { - messageId: 'dontImportPackage', - line: 4, - }, - { - messageId: 'dontImportPackage', - line: 5, - }, - { - messageId: 'dontImportPackage', - line: 6, - }, - { - messageId: 'dontImportPackage', - line: 7, - }, - ], - }), + invalid: [ + { + code: "import { foo } from '@typescript-eslint/typescript-estree';", + output: "import { foo } from '@typescript-eslint/utils';", + errors: [{ messageId: 'dontImportPackage' }], + }, + { + code: "import foo from '@typescript-eslint/typescript-estree';", + output: "import foo from '@typescript-eslint/utils';", + errors: [{ messageId: 'dontImportPackage' }], + }, + { + code: "import * as foo from '@typescript-eslint/typescript-estree';", + output: "import * as foo from '@typescript-eslint/utils';", + errors: [{ messageId: 'dontImportPackage' }], + }, + { + code: "import { foo } from '@typescript-eslint/types';", + output: "import { foo } from '@typescript-eslint/utils';", + errors: [{ messageId: 'dontImportPackage' }], + }, + { + code: "import foo from '@typescript-eslint/types';", + output: "import foo from '@typescript-eslint/utils';", + errors: [{ messageId: 'dontImportPackage' }], + }, + { + code: "import * as foo from '@typescript-eslint/types';", + output: "import * as foo from '@typescript-eslint/utils';", + errors: [{ messageId: 'dontImportPackage' }], + }, + ], }); diff --git a/packages/eslint-plugin-internal/tests/rules/plugin-test-formatting.test.ts b/packages/eslint-plugin-internal/tests/rules/plugin-test-formatting.test.ts index f5745996d38..f9dee0411ab 100644 --- a/packages/eslint-plugin-internal/tests/rules/plugin-test-formatting.test.ts +++ b/packages/eslint-plugin-internal/tests/rules/plugin-test-formatting.test.ts @@ -1,5 +1,7 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/plugin-test-formatting'; -import { getFixturesRootDir, RuleTester } from '../RuleTester'; +import { getFixturesRootDir } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin-internal/tests/rules/prefer-ast-types-enum.test.ts b/packages/eslint-plugin-internal/tests/rules/prefer-ast-types-enum.test.ts index ea162462ca6..44f9f6118ba 100644 --- a/packages/eslint-plugin-internal/tests/rules/prefer-ast-types-enum.test.ts +++ b/packages/eslint-plugin-internal/tests/rules/prefer-ast-types-enum.test.ts @@ -1,8 +1,8 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; import { DefinitionType } from '@typescript-eslint/scope-manager'; import { AST_NODE_TYPES, AST_TOKEN_TYPES } from '@typescript-eslint/utils'; import rule from '../../src/rules/prefer-ast-types-enum'; -import { batchedSingleLineTests, RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', @@ -29,33 +29,42 @@ ruleTester.run('prefer-ast-types-enum', rule, { } `, ], - invalid: batchedSingleLineTests({ - code: ` -node.type === 'Literal'; -node.type === 'Keyword'; -node.type === 'Parameter'; - `, - output: ` -node.type === AST_NODE_TYPES.Literal; -node.type === AST_TOKEN_TYPES.Keyword; -node.type === DefinitionType.Parameter; - `, - errors: [ - { - data: { enumName: 'AST_NODE_TYPES', literal: AST_NODE_TYPES.Literal }, - messageId: 'preferEnum', - line: 2, - }, - { - data: { enumName: 'AST_TOKEN_TYPES', literal: AST_TOKEN_TYPES.Keyword }, - messageId: 'preferEnum', - line: 3, - }, - { - data: { enumName: 'DefinitionType', literal: DefinitionType.Parameter }, - messageId: 'preferEnum', - line: 4, - }, - ], - }), + invalid: [ + { + code: "node.type === 'Literal';", + output: 'node.type === AST_NODE_TYPES.Literal;', + errors: [ + { + data: { enumName: 'AST_NODE_TYPES', literal: AST_NODE_TYPES.Literal }, + messageId: 'preferEnum', + }, + ], + }, + { + code: "node.type === 'Keyword';", + output: 'node.type === AST_TOKEN_TYPES.Keyword;', + errors: [ + { + data: { + enumName: 'AST_TOKEN_TYPES', + literal: AST_TOKEN_TYPES.Keyword, + }, + messageId: 'preferEnum', + }, + ], + }, + { + code: "node.type === 'Parameter';", + output: 'node.type === DefinitionType.Parameter;', + errors: [ + { + data: { + enumName: 'DefinitionType', + literal: DefinitionType.Parameter, + }, + messageId: 'preferEnum', + }, + ], + }, + ], }); diff --git a/packages/eslint-plugin/package.json b/packages/eslint-plugin/package.json index 6e99af1df7d..6045934efdd 100644 --- a/packages/eslint-plugin/package.json +++ b/packages/eslint-plugin/package.json @@ -72,6 +72,7 @@ "@types/natural-compare": "*", "@types/prettier": "*", "@typescript-eslint/rule-schema-to-typescript-types": "5.59.1", + "@typescript-eslint/rule-tester": "5.59.1", "cross-fetch": "*", "jest-specific-snapshot": "*", "json-schema": "*", diff --git a/packages/eslint-plugin/src/rules/consistent-type-assertions.ts b/packages/eslint-plugin/src/rules/consistent-type-assertions.ts index 942bc8f3de5..d8f84fb583e 100644 --- a/packages/eslint-plugin/src/rules/consistent-type-assertions.ts +++ b/packages/eslint-plugin/src/rules/consistent-type-assertions.ts @@ -4,7 +4,7 @@ import { AST_NODE_TYPES } from '@typescript-eslint/utils'; import * as util from '../util'; // intentionally mirroring the options -type MessageIds = +export type MessageIds = | 'as' | 'angle-bracket' | 'never' @@ -19,7 +19,7 @@ type OptUnion = | { assertionStyle: 'never'; }; -type Options = [OptUnion]; +export type Options = readonly [OptUnion]; export default util.createRule({ name: 'consistent-type-assertions', diff --git a/packages/eslint-plugin/tests/RuleTester.ts b/packages/eslint-plugin/tests/RuleTester.ts index efeaa707734..21abfa49c95 100644 --- a/packages/eslint-plugin/tests/RuleTester.ts +++ b/packages/eslint-plugin/tests/RuleTester.ts @@ -1,17 +1,80 @@ -import { ESLintUtils } from '@typescript-eslint/utils'; +import type { + InvalidTestCase, + ValidTestCase, +} from '@typescript-eslint/rule-tester'; import * as path from 'path'; -function getFixturesRootDir(): string { +export function getFixturesRootDir(): string { return path.join(__dirname, 'fixtures'); } -const { batchedSingleLineTests } = ESLintUtils; -export { - RuleTester, - RunTests, - ValidTestCase, - InvalidTestCase, - noFormat, -} from '@typescript-eslint/utils/eslint-utils/rule-tester'; - -export { batchedSingleLineTests, getFixturesRootDir }; +/** + * Converts a batch of single line tests into a number of separate test cases. + * This makes it easier to write tests which use the same options. + * + * Why wouldn't you just leave them as one test? + * Because it makes the test error messages harder to decipher. + * This way each line will fail separately, instead of them all failing together. + * + * @deprecated - DO NOT USE THIS FOR NEW RULES + */ +export function batchedSingleLineTests( + test: ValidTestCase, +): ValidTestCase[]; +/** + * Converts a batch of single line tests into a number of separate test cases. + * This makes it easier to write tests which use the same options. + * + * Why wouldn't you just leave them as one test? + * Because it makes the test error messages harder to decipher. + * This way each line will fail separately, instead of them all failing together. + * + * Make sure you have your line numbers correct for error reporting, as it will match + * the line numbers up with the split tests! + * + * @deprecated - DO NOT USE THIS FOR NEW RULES + */ +export function batchedSingleLineTests< + TMessageIds extends string, + TOptions extends readonly unknown[], +>( + test: InvalidTestCase, +): InvalidTestCase[]; +export function batchedSingleLineTests< + TMessageIds extends string, + TOptions extends readonly unknown[], +>( + options: ValidTestCase | InvalidTestCase, +): (ValidTestCase | InvalidTestCase)[] { + // -- eslint counts lines from 1 + const lineOffset = options.code.startsWith('\n') ? 2 : 1; + const output = + 'output' in options && options.output + ? options.output.trim().split('\n') + : null; + return options.code + .trim() + .split('\n') + .map((code, i) => { + const lineNum = i + lineOffset; + const errors = + 'errors' in options + ? options.errors.filter(e => e.line === lineNum) + : []; + const returnVal = { + ...options, + code, + errors: errors.map(e => ({ + ...e, + line: 1, + })), + }; + if (output?.[i]) { + return { + ...returnVal, + output: output[i], + }; + } + return returnVal; + }); +} diff --git a/packages/eslint-plugin/tests/eslint-rules/arrow-parens.test.ts b/packages/eslint-plugin/tests/eslint-rules/arrow-parens.test.ts index 664392b0923..de6a73e536c 100644 --- a/packages/eslint-plugin/tests/eslint-rules/arrow-parens.test.ts +++ b/packages/eslint-plugin/tests/eslint-rules/arrow-parens.test.ts @@ -1,5 +1,6 @@ +import { noFormat, RuleTester } from '@typescript-eslint/rule-tester'; + import { getESLintCoreRule } from '../../src/util/getESLintCoreRule'; -import { noFormat, RuleTester } from '../RuleTester'; const rule = getESLintCoreRule('arrow-parens'); diff --git a/packages/eslint-plugin/tests/eslint-rules/no-dupe-args.test.ts b/packages/eslint-plugin/tests/eslint-rules/no-dupe-args.test.ts index 5bc8d99490d..054d19140bf 100644 --- a/packages/eslint-plugin/tests/eslint-rules/no-dupe-args.test.ts +++ b/packages/eslint-plugin/tests/eslint-rules/no-dupe-args.test.ts @@ -1,5 +1,6 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import { getESLintCoreRule } from '../../src/util/getESLintCoreRule'; -import { RuleTester } from '../RuleTester'; const rule = getESLintCoreRule('no-dupe-args'); diff --git a/packages/eslint-plugin/tests/eslint-rules/no-implicit-globals.test.ts b/packages/eslint-plugin/tests/eslint-rules/no-implicit-globals.test.ts index eb3fea348b5..ba4d5cc1a43 100644 --- a/packages/eslint-plugin/tests/eslint-rules/no-implicit-globals.test.ts +++ b/packages/eslint-plugin/tests/eslint-rules/no-implicit-globals.test.ts @@ -1,5 +1,6 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import { getESLintCoreRule } from '../../src/util/getESLintCoreRule'; -import { RuleTester } from '../RuleTester'; const rule = getESLintCoreRule('no-implicit-globals'); const ruleTester = new RuleTester({ diff --git a/packages/eslint-plugin/tests/eslint-rules/no-restricted-globals.test.ts b/packages/eslint-plugin/tests/eslint-rules/no-restricted-globals.test.ts index 6061c8ebb4e..b015020fa5e 100644 --- a/packages/eslint-plugin/tests/eslint-rules/no-restricted-globals.test.ts +++ b/packages/eslint-plugin/tests/eslint-rules/no-restricted-globals.test.ts @@ -1,5 +1,6 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import { getESLintCoreRule } from '../../src/util/getESLintCoreRule'; -import { RuleTester } from '../RuleTester'; const rule = getESLintCoreRule('no-restricted-globals'); diff --git a/packages/eslint-plugin/tests/eslint-rules/no-undef.test.ts b/packages/eslint-plugin/tests/eslint-rules/no-undef.test.ts index 3335e04e741..252b6fe2f32 100644 --- a/packages/eslint-plugin/tests/eslint-rules/no-undef.test.ts +++ b/packages/eslint-plugin/tests/eslint-rules/no-undef.test.ts @@ -1,5 +1,6 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import { getESLintCoreRule } from '../../src/util/getESLintCoreRule'; -import { RuleTester } from '../RuleTester'; const rule = getESLintCoreRule('no-undef'); diff --git a/packages/eslint-plugin/tests/eslint-rules/prefer-const.test.ts b/packages/eslint-plugin/tests/eslint-rules/prefer-const.test.ts index d3bce8cfdee..e9d8350ff09 100644 --- a/packages/eslint-plugin/tests/eslint-rules/prefer-const.test.ts +++ b/packages/eslint-plugin/tests/eslint-rules/prefer-const.test.ts @@ -1,5 +1,6 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import { getESLintCoreRule } from '../../src/util/getESLintCoreRule'; -import { RuleTester } from '../RuleTester'; const rule = getESLintCoreRule('prefer-const'); diff --git a/packages/eslint-plugin/tests/eslint-rules/strict.test.ts b/packages/eslint-plugin/tests/eslint-rules/strict.test.ts index 83ad25a0605..a3146c36d7b 100644 --- a/packages/eslint-plugin/tests/eslint-rules/strict.test.ts +++ b/packages/eslint-plugin/tests/eslint-rules/strict.test.ts @@ -1,5 +1,6 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import { getESLintCoreRule } from '../../src/util/getESLintCoreRule'; -import { RuleTester } from '../RuleTester'; const rule = getESLintCoreRule('strict'); diff --git a/packages/eslint-plugin/tests/rules/adjacent-overload-signatures.test.ts b/packages/eslint-plugin/tests/rules/adjacent-overload-signatures.test.ts index 9a20771b4af..e834112f6ec 100644 --- a/packages/eslint-plugin/tests/rules/adjacent-overload-signatures.test.ts +++ b/packages/eslint-plugin/tests/rules/adjacent-overload-signatures.test.ts @@ -1,5 +1,6 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/adjacent-overload-signatures'; -import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/array-type.test.ts b/packages/eslint-plugin/tests/rules/array-type.test.ts index 04ab47d0b8a..9123e812a72 100644 --- a/packages/eslint-plugin/tests/rules/array-type.test.ts +++ b/packages/eslint-plugin/tests/rules/array-type.test.ts @@ -1,9 +1,9 @@ import * as parser from '@typescript-eslint/parser'; +import { RuleTester } from '@typescript-eslint/rule-tester'; import { TSESLint } from '@typescript-eslint/utils'; import type { OptionString } from '../../src/rules/array-type'; import rule from '../../src/rules/array-type'; -import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/await-thenable.test.ts b/packages/eslint-plugin/tests/rules/await-thenable.test.ts index 3dc786896c0..4b51a75ac8b 100644 --- a/packages/eslint-plugin/tests/rules/await-thenable.test.ts +++ b/packages/eslint-plugin/tests/rules/await-thenable.test.ts @@ -1,5 +1,7 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/await-thenable'; -import { getFixturesRootDir, RuleTester } from '../RuleTester'; +import { getFixturesRootDir } from '../RuleTester'; const rootDir = getFixturesRootDir(); const messageId = 'await'; diff --git a/packages/eslint-plugin/tests/rules/ban-ts-comment.test.ts b/packages/eslint-plugin/tests/rules/ban-ts-comment.test.ts index 54855f19cf3..271b2d27a03 100644 --- a/packages/eslint-plugin/tests/rules/ban-ts-comment.test.ts +++ b/packages/eslint-plugin/tests/rules/ban-ts-comment.test.ts @@ -1,5 +1,6 @@ +import { noFormat, RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/ban-ts-comment'; -import { noFormat, RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/ban-tslint-comment.test.ts b/packages/eslint-plugin/tests/rules/ban-tslint-comment.test.ts index 654bb18c2c6..01f6ec078a8 100644 --- a/packages/eslint-plugin/tests/rules/ban-tslint-comment.test.ts +++ b/packages/eslint-plugin/tests/rules/ban-tslint-comment.test.ts @@ -1,5 +1,6 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/ban-tslint-comment'; -import { RuleTester } from '../RuleTester'; interface Testable { code: string; diff --git a/packages/eslint-plugin/tests/rules/ban-types.test.ts b/packages/eslint-plugin/tests/rules/ban-types.test.ts index 440142c1044..858f78cd2cd 100644 --- a/packages/eslint-plugin/tests/rules/ban-types.test.ts +++ b/packages/eslint-plugin/tests/rules/ban-types.test.ts @@ -1,10 +1,10 @@ /* eslint-disable @typescript-eslint/internal/prefer-ast-types-enum */ +import { noFormat, RuleTester } from '@typescript-eslint/rule-tester'; import type { TSESLint } from '@typescript-eslint/utils'; import type { MessageIds, Options } from '../../src/rules/ban-types'; import rule, { TYPE_KEYWORDS } from '../../src/rules/ban-types'; import { objectReduceKey } from '../../src/util'; -import { noFormat, RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/block-spacing.test.ts b/packages/eslint-plugin/tests/rules/block-spacing.test.ts index 49578b8c061..3dac892e397 100644 --- a/packages/eslint-plugin/tests/rules/block-spacing.test.ts +++ b/packages/eslint-plugin/tests/rules/block-spacing.test.ts @@ -1,8 +1,11 @@ +import type { + InvalidTestCase, + ValidTestCase, +} from '@typescript-eslint/rule-tester'; +import { RuleTester } from '@typescript-eslint/rule-tester'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; import rule from '../../src/rules/block-spacing'; -import type { InvalidTestCase, ValidTestCase } from '../RuleTester'; -import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/brace-style.test.ts b/packages/eslint-plugin/tests/rules/brace-style.test.ts index 35bc5afe996..ec1ac6b3bc5 100644 --- a/packages/eslint-plugin/tests/rules/brace-style.test.ts +++ b/packages/eslint-plugin/tests/rules/brace-style.test.ts @@ -3,8 +3,9 @@ /* eslint "@typescript-eslint/internal/plugin-test-formatting": ["error", { formatWithPrettier: false }] */ /* eslint-enable eslint-comments/no-use */ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/brace-style'; -import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/class-literal-property-style.test.ts b/packages/eslint-plugin/tests/rules/class-literal-property-style.test.ts index af0aa203df7..b6bba64f4df 100644 --- a/packages/eslint-plugin/tests/rules/class-literal-property-style.test.ts +++ b/packages/eslint-plugin/tests/rules/class-literal-property-style.test.ts @@ -1,5 +1,6 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/class-literal-property-style'; -import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/comma-dangle.test.ts b/packages/eslint-plugin/tests/rules/comma-dangle.test.ts index 1e94e982971..2d4fdc562f8 100644 --- a/packages/eslint-plugin/tests/rules/comma-dangle.test.ts +++ b/packages/eslint-plugin/tests/rules/comma-dangle.test.ts @@ -2,8 +2,9 @@ // this rule tests the new lines, which prettier will want to fix and break the tests /* eslint "@typescript-eslint/internal/plugin-test-formatting": ["error", { formatWithPrettier: false }] */ /* eslint-enable eslint-comments/no-use */ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/comma-dangle'; -import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/comma-spacing.test.ts b/packages/eslint-plugin/tests/rules/comma-spacing.test.ts index 37eb6e2e3ad..2c5459b3d4a 100644 --- a/packages/eslint-plugin/tests/rules/comma-spacing.test.ts +++ b/packages/eslint-plugin/tests/rules/comma-spacing.test.ts @@ -3,8 +3,9 @@ /* eslint "@typescript-eslint/internal/plugin-test-formatting": ["error", { formatWithPrettier: false }] */ /* eslint-enable eslint-comments/no-use */ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/comma-spacing'; -import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/consistent-generic-constructors.test.ts b/packages/eslint-plugin/tests/rules/consistent-generic-constructors.test.ts index 6c53d13861c..f21dac8f639 100644 --- a/packages/eslint-plugin/tests/rules/consistent-generic-constructors.test.ts +++ b/packages/eslint-plugin/tests/rules/consistent-generic-constructors.test.ts @@ -1,5 +1,6 @@ +import { noFormat, RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/consistent-generic-constructors'; -import { noFormat, RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/consistent-indexed-object-style.test.ts b/packages/eslint-plugin/tests/rules/consistent-indexed-object-style.test.ts index 6bdc76362e0..2b1aa4661a9 100644 --- a/packages/eslint-plugin/tests/rules/consistent-indexed-object-style.test.ts +++ b/packages/eslint-plugin/tests/rules/consistent-indexed-object-style.test.ts @@ -1,5 +1,6 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/consistent-indexed-object-style'; -import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/consistent-type-assertions.test.ts b/packages/eslint-plugin/tests/rules/consistent-type-assertions.test.ts index 45f672af9e4..170aa8b1696 100644 --- a/packages/eslint-plugin/tests/rules/consistent-type-assertions.test.ts +++ b/packages/eslint-plugin/tests/rules/consistent-type-assertions.test.ts @@ -1,5 +1,13 @@ +/* eslint-disable deprecation/deprecation -- TODO - migrate this test away from `batchedSingleLineTests` */ + +import { RuleTester } from '@typescript-eslint/rule-tester'; + +import type { + MessageIds, + Options, +} from '../../src/rules/consistent-type-assertions'; import rule from '../../src/rules/consistent-type-assertions'; -import { batchedSingleLineTests, RuleTester } from '../RuleTester'; +import { batchedSingleLineTests } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', @@ -64,7 +72,7 @@ print?.call({ bar: 5 }) ruleTester.run('consistent-type-assertions', rule, { valid: [ - ...batchedSingleLineTests({ + ...batchedSingleLineTests({ code: AS_TESTS, options: [ { @@ -73,7 +81,7 @@ ruleTester.run('consistent-type-assertions', rule, { }, ], }), - ...batchedSingleLineTests({ + ...batchedSingleLineTests({ code: ANGLE_BRACKET_TESTS, options: [ { @@ -82,7 +90,7 @@ ruleTester.run('consistent-type-assertions', rule, { }, ], }), - ...batchedSingleLineTests({ + ...batchedSingleLineTests({ code: `${OBJECT_LITERAL_AS_CASTS.trimEnd()}${OBJECT_LITERAL_ARGUMENT_AS_CASTS}`, options: [ { @@ -91,7 +99,7 @@ ruleTester.run('consistent-type-assertions', rule, { }, ], }), - ...batchedSingleLineTests({ + ...batchedSingleLineTests({ code: `${OBJECT_LITERAL_ANGLE_BRACKET_CASTS.trimEnd()}${OBJECT_LITERAL_ARGUMENT_ANGLE_BRACKET_CASTS}`, options: [ { @@ -100,7 +108,7 @@ ruleTester.run('consistent-type-assertions', rule, { }, ], }), - ...batchedSingleLineTests({ + ...batchedSingleLineTests({ code: OBJECT_LITERAL_ARGUMENT_AS_CASTS, options: [ { @@ -109,7 +117,7 @@ ruleTester.run('consistent-type-assertions', rule, { }, ], }), - ...batchedSingleLineTests({ + ...batchedSingleLineTests({ code: OBJECT_LITERAL_ARGUMENT_ANGLE_BRACKET_CASTS, options: [ { @@ -150,7 +158,7 @@ ruleTester.run('consistent-type-assertions', rule, { }, ], invalid: [ - ...batchedSingleLineTests({ + ...batchedSingleLineTests({ code: AS_TESTS, options: [ { @@ -200,7 +208,7 @@ ruleTester.run('consistent-type-assertions', rule, { }, ], }), - ...batchedSingleLineTests({ + ...batchedSingleLineTests({ code: ANGLE_BRACKET_TESTS, options: [ { @@ -251,7 +259,7 @@ ruleTester.run('consistent-type-assertions', rule, { ], output: AS_TESTS, }), - ...batchedSingleLineTests({ + ...batchedSingleLineTests({ code: AS_TESTS_EXCEPT_CONST_CASE, options: [ { @@ -297,7 +305,7 @@ ruleTester.run('consistent-type-assertions', rule, { }, ], }), - ...batchedSingleLineTests({ + ...batchedSingleLineTests({ code: ANGLE_BRACKET_TESTS_EXCEPT_CONST_CASE, options: [ { @@ -343,7 +351,7 @@ ruleTester.run('consistent-type-assertions', rule, { }, ], }), - ...batchedSingleLineTests({ + ...batchedSingleLineTests({ code: OBJECT_LITERAL_AS_CASTS, options: [ { @@ -397,7 +405,7 @@ ruleTester.run('consistent-type-assertions', rule, { }, ], }), - ...batchedSingleLineTests({ + ...batchedSingleLineTests({ code: OBJECT_LITERAL_ANGLE_BRACKET_CASTS, options: [ { @@ -451,7 +459,7 @@ ruleTester.run('consistent-type-assertions', rule, { }, ], }), - ...batchedSingleLineTests({ + ...batchedSingleLineTests({ code: `${OBJECT_LITERAL_AS_CASTS.trimEnd()}${OBJECT_LITERAL_ARGUMENT_AS_CASTS}`, options: [ { @@ -582,7 +590,7 @@ ruleTester.run('consistent-type-assertions', rule, { }, ], }), - ...batchedSingleLineTests({ + ...batchedSingleLineTests({ code: `${OBJECT_LITERAL_ANGLE_BRACKET_CASTS.trimEnd()}${OBJECT_LITERAL_ARGUMENT_ANGLE_BRACKET_CASTS}`, options: [ { diff --git a/packages/eslint-plugin/tests/rules/consistent-type-definitions.test.ts b/packages/eslint-plugin/tests/rules/consistent-type-definitions.test.ts index 356162dcb6f..b0a2092994d 100644 --- a/packages/eslint-plugin/tests/rules/consistent-type-definitions.test.ts +++ b/packages/eslint-plugin/tests/rules/consistent-type-definitions.test.ts @@ -1,5 +1,6 @@ +import { noFormat, RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/consistent-type-definitions'; -import { noFormat, RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/consistent-type-exports.test.ts b/packages/eslint-plugin/tests/rules/consistent-type-exports.test.ts index 5ab0edf84f1..2b8cdf15bb2 100644 --- a/packages/eslint-plugin/tests/rules/consistent-type-exports.test.ts +++ b/packages/eslint-plugin/tests/rules/consistent-type-exports.test.ts @@ -1,5 +1,7 @@ +import { noFormat, RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/consistent-type-exports'; -import { getFixturesRootDir, noFormat, RuleTester } from '../RuleTester'; +import { getFixturesRootDir } from '../RuleTester'; const rootDir = getFixturesRootDir(); diff --git a/packages/eslint-plugin/tests/rules/consistent-type-imports.test.ts b/packages/eslint-plugin/tests/rules/consistent-type-imports.test.ts index 4d480066467..3c94e99ff14 100644 --- a/packages/eslint-plugin/tests/rules/consistent-type-imports.test.ts +++ b/packages/eslint-plugin/tests/rules/consistent-type-imports.test.ts @@ -1,5 +1,7 @@ +import { noFormat, RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/consistent-type-imports'; -import { getFixturesRootDir, noFormat, RuleTester } from '../RuleTester'; +import { getFixturesRootDir } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/default-param-last.test.ts b/packages/eslint-plugin/tests/rules/default-param-last.test.ts index aa0ffbc8743..317434d9d44 100644 --- a/packages/eslint-plugin/tests/rules/default-param-last.test.ts +++ b/packages/eslint-plugin/tests/rules/default-param-last.test.ts @@ -1,5 +1,6 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/default-param-last'; -import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/dot-notation.test.ts b/packages/eslint-plugin/tests/rules/dot-notation.test.ts index 9b6e2ba0fae..b7ebac3d412 100644 --- a/packages/eslint-plugin/tests/rules/dot-notation.test.ts +++ b/packages/eslint-plugin/tests/rules/dot-notation.test.ts @@ -1,5 +1,7 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/dot-notation'; -import { getFixturesRootDir, RuleTester } from '../RuleTester'; +import { getFixturesRootDir } from '../RuleTester'; const rootPath = getFixturesRootDir(); diff --git a/packages/eslint-plugin/tests/rules/explicit-function-return-type.test.ts b/packages/eslint-plugin/tests/rules/explicit-function-return-type.test.ts index d3c1a540192..a17a27dec17 100644 --- a/packages/eslint-plugin/tests/rules/explicit-function-return-type.test.ts +++ b/packages/eslint-plugin/tests/rules/explicit-function-return-type.test.ts @@ -1,5 +1,6 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/explicit-function-return-type'; -import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', @@ -8,7 +9,6 @@ const ruleTester = new RuleTester({ ruleTester.run('explicit-function-return-type', rule, { valid: [ { - filename: 'test.ts', code: ` function test(): void { return; @@ -16,7 +16,6 @@ function test(): void { `, }, { - filename: 'test.ts', code: ` var fn = function (): number { return 1; @@ -24,13 +23,11 @@ var fn = function (): number { `, }, { - filename: 'test.ts', code: ` var arrowFn = (): string => 'test'; `, }, { - filename: 'test.ts', code: ` class Test { constructor() {} @@ -46,7 +43,6 @@ class Test { `, }, { - filename: 'test.ts', code: 'fn(() => {});', options: [ { @@ -55,7 +51,6 @@ class Test { ], }, { - filename: 'test.ts', code: 'fn(function () {});', options: [ { @@ -64,7 +59,6 @@ class Test { ], }, { - filename: 'test.ts', code: '[function () {}, () => {}];', options: [ { @@ -73,7 +67,6 @@ class Test { ], }, { - filename: 'test.ts', code: '(function () {});', options: [ { @@ -82,7 +75,6 @@ class Test { ], }, { - filename: 'test.ts', code: '(() => {})();', options: [ { @@ -91,7 +83,6 @@ class Test { ], }, { - filename: 'test.ts', code: 'export default (): void => {};', options: [ { @@ -100,7 +91,6 @@ class Test { ], }, { - filename: 'test.ts', code: ` var arrowFn: Foo = () => 'test'; `, @@ -111,7 +101,6 @@ var arrowFn: Foo = () => 'test'; ], }, { - filename: 'test.ts', code: ` var funcExpr: Foo = function () { return 'test'; @@ -124,17 +113,14 @@ var funcExpr: Foo = function () { ], }, { - filename: 'test.ts', code: 'const x = (() => {}) as Foo;', options: [{ allowTypedFunctionExpressions: true }], }, { - filename: 'test.ts', code: 'const x = (() => {});', options: [{ allowTypedFunctionExpressions: true }], }, { - filename: 'test.ts', code: ` const x = { foo: () => {}, @@ -143,7 +129,6 @@ const x = { options: [{ allowTypedFunctionExpressions: true }], }, { - filename: 'test.ts', code: ` const x = { foo: () => {}, @@ -152,7 +137,6 @@ const x = { options: [{ allowTypedFunctionExpressions: true }], }, { - filename: 'test.ts', code: ` const x: Foo = { foo: () => {}, @@ -162,7 +146,6 @@ const x: Foo = { }, // https://github.com/typescript-eslint/typescript-eslint/issues/2864 { - filename: 'test.ts', code: ` const x = { foo: { bar: () => {} }, @@ -171,7 +154,6 @@ const x = { options: [{ allowTypedFunctionExpressions: true }], }, { - filename: 'test.ts', code: ` const x = { foo: { bar: () => {} }, @@ -180,7 +162,6 @@ const x = { options: [{ allowTypedFunctionExpressions: true }], }, { - filename: 'test.ts', code: ` const x: Foo = { foo: { bar: () => {} }, @@ -190,7 +171,6 @@ const x: Foo = { }, // https://github.com/typescript-eslint/typescript-eslint/issues/484 { - filename: 'test.ts', code: ` type MethodType = () => void; @@ -202,7 +182,6 @@ class App { }, // https://github.com/typescript-eslint/typescript-eslint/issues/525 { - filename: 'test.ts', code: ` const myObj = { set myProp(val) { @@ -212,21 +191,18 @@ const myObj = { `, }, { - filename: 'test.ts', code: ` () => (): void => {}; `, options: [{ allowHigherOrderFunctions: true }], }, { - filename: 'test.ts', code: ` () => function (): void {}; `, options: [{ allowHigherOrderFunctions: true }], }, { - filename: 'test.ts', code: ` () => { return (): void => {}; @@ -235,7 +211,6 @@ const myObj = { options: [{ allowHigherOrderFunctions: true }], }, { - filename: 'test.ts', code: ` () => { return function (): void {}; @@ -244,7 +219,6 @@ const myObj = { options: [{ allowHigherOrderFunctions: true }], }, { - filename: 'test.ts', code: ` function fn() { return (): void => {}; @@ -253,7 +227,6 @@ function fn() { options: [{ allowHigherOrderFunctions: true }], }, { - filename: 'test.ts', code: ` function fn() { return function (): void {}; @@ -262,7 +235,6 @@ function fn() { options: [{ allowHigherOrderFunctions: true }], }, { - filename: 'test.ts', code: ` function FunctionDeclaration() { return function FunctionExpression_Within_FunctionDeclaration() { @@ -281,7 +253,6 @@ function FunctionDeclaration() { options: [{ allowHigherOrderFunctions: true }], }, { - filename: 'test.ts', code: ` () => () => { return (): void => { @@ -293,7 +264,6 @@ function FunctionDeclaration() { }, // https://github.com/typescript-eslint/typescript-eslint/issues/679 { - filename: 'test.ts', code: ` declare function foo(arg: () => void): void; foo(() => 1); @@ -309,7 +279,6 @@ foo(() => ''); ], }, { - filename: 'test.ts', code: ` declare function foo(arg: () => void): void; foo?.(() => 1); @@ -325,7 +294,6 @@ foo?.(() => ''); ], }, { - filename: 'test.ts', code: ` class Accumulator { private count: number = 0; @@ -344,7 +312,6 @@ new Accumulator().accumulate(() => 1); ], }, { - filename: 'test.ts', code: ` declare function foo(arg: { meth: () => number }): void; foo({ @@ -370,7 +337,6 @@ foo({ ], }, { - filename: 'test.ts', code: ` const func = (value: number) => ({ type: 'X', value } as const); const func = (value: number) => ({ type: 'X', value } as const); @@ -384,7 +350,6 @@ const func = (value: number) => x as const; ], }, { - filename: 'test.ts', code: ` new Promise(resolve => {}); new Foo(1, () => {}); @@ -396,7 +361,6 @@ new Foo(1, () => {}); ], }, { - filename: 'test.ts', code: 'const log = (message: string) => void console.log(message);', options: [{ allowConciseArrowFunctionExpressionsStartingWithVoid: true }], }, @@ -441,7 +405,6 @@ const log = function (a: A): string { options: [{ allowFunctionsWithoutTypeParameters: true }], }, { - filename: 'test.ts', options: [ { allowedNames: ['test1', 'test2'], @@ -458,7 +421,6 @@ const foo = function test2() { `, }, { - filename: 'test.ts', options: [ { allowedNames: ['test1', 'test2'], @@ -474,7 +436,6 @@ const foo = function () { `, }, { - filename: 'test.ts', options: [ { allowedNames: ['test1', 'test2'], @@ -492,7 +453,6 @@ export const foo = { `, }, { - filename: 'test.ts', code: ` class Test { constructor() {} @@ -516,7 +476,6 @@ class Test { ], }, { - filename: 'test.ts', code: ` const x = { arrowFn: () => { @@ -534,7 +493,6 @@ const x = { ], }, { - filename: 'test.ts', code: ` type HigherOrderType = () => (arg1: string) => (arg2: number) => string; const x: HigherOrderType = () => arg1 => arg2 => 'foo'; @@ -547,7 +505,6 @@ const x: HigherOrderType = () => arg1 => arg2 => 'foo'; ], }, { - filename: 'test.ts', code: ` type HigherOrderType = () => (arg1: string) => (arg2: number) => string; const x: HigherOrderType = () => arg1 => arg2 => 'foo'; @@ -560,7 +517,6 @@ const x: HigherOrderType = () => arg1 => arg2 => 'foo'; ], }, { - filename: 'test.ts', code: ` interface Foo { foo: string; @@ -582,7 +538,6 @@ function foo(): Foo { ], }, { - filename: 'test.ts', code: ` type Foo = (arg1: string) => string; type Bar = (arg2: string) => T; @@ -596,7 +551,6 @@ const x: Bar = arg1 => arg2 => arg1 + arg2; ], }, { - filename: 'test.ts', code: ` let foo = function (): number { return 1; @@ -609,7 +563,6 @@ let foo = function (): number { ], }, { - filename: 'test.ts', code: ` const foo = (function () { return 1; @@ -622,7 +575,6 @@ const foo = (function () { ], }, { - filename: 'test.ts', code: ` const foo = (() => { return 1; @@ -635,7 +587,6 @@ const foo = (() => { ], }, { - filename: 'test.ts', code: ` const foo = ((arg: number): number => { return arg; @@ -648,7 +599,6 @@ const foo = ((arg: number): number => { ], }, { - filename: 'test.ts', code: ` const foo = (() => (() => 'foo')())(); `, @@ -659,7 +609,6 @@ const foo = (() => (() => 'foo')())(); ], }, { - filename: 'test.ts', code: ` let foo = (() => (): string => { return 'foo'; @@ -672,7 +621,6 @@ let foo = (() => (): string => { ], }, { - filename: 'test.ts', code: ` let foo = (() => (): string => { return 'foo'; @@ -686,7 +634,6 @@ let foo = (() => (): string => { ], }, { - filename: 'test.ts', code: ` let foo = (() => (): string => { return 'foo'; @@ -700,7 +647,6 @@ let foo = (() => (): string => { ], }, { - filename: 'test.ts', code: ` let foo = (() => (): void => {})()(); `, @@ -711,7 +657,6 @@ let foo = (() => (): void => {})()(); ], }, { - filename: 'test.ts', code: ` let foo = (() => (() => {})())(); `, @@ -724,7 +669,6 @@ let foo = (() => (() => {})())(); ], invalid: [ { - filename: 'test.ts', code: ` function test(a: number, b: number) { return; @@ -741,7 +685,6 @@ function test(a: number, b: number) { ], }, { - filename: 'test.ts', code: ` function test() { return; @@ -758,7 +701,6 @@ function test() { ], }, { - filename: 'test.ts', code: ` var fn = function () { return 1; @@ -775,7 +717,6 @@ var fn = function () { ], }, { - filename: 'test.ts', code: ` var arrowFn = () => 'test'; `, @@ -790,7 +731,6 @@ var arrowFn = () => 'test'; ], }, { - filename: 'test.ts', code: ` class Test { constructor() {} @@ -839,7 +779,6 @@ class Test { ], }, { - filename: 'test.ts', code: ` function test() { return; @@ -857,7 +796,6 @@ function test() { ], }, { - filename: 'test.ts', code: 'const foo = () => {};', options: [{ allowExpressions: true }], errors: [ @@ -871,7 +809,6 @@ function test() { ], }, { - filename: 'test.ts', code: 'const foo = function () {};', options: [{ allowExpressions: true }], errors: [ @@ -885,7 +822,6 @@ function test() { ], }, { - filename: 'test.ts', code: 'export default () => {};', options: [{ allowExpressions: true }], errors: [ @@ -899,7 +835,6 @@ function test() { ], }, { - filename: 'test.ts', code: 'export default function () {}', options: [{ allowExpressions: true }], errors: [ @@ -913,7 +848,6 @@ function test() { ], }, { - filename: 'test.ts', code: ` class Foo { public a = () => {}; @@ -964,7 +898,6 @@ class Foo { ], }, { - filename: 'test.ts', code: "var arrowFn = () => 'test';", options: [{ allowTypedFunctionExpressions: true }], errors: [ @@ -978,7 +911,6 @@ class Foo { ], }, { - filename: 'test.ts', code: ` var funcExpr = function () { return 'test'; @@ -997,7 +929,6 @@ var funcExpr = function () { }, { - filename: 'test.ts', code: 'const x = (() => {}) as Foo;', options: [{ allowTypedFunctionExpressions: false }], errors: [ @@ -1011,7 +942,6 @@ var funcExpr = function () { ], }, { - filename: 'test.ts', code: ` interface Foo {} const x = { @@ -1030,7 +960,6 @@ const x = { ], }, { - filename: 'test.ts', code: ` interface Foo {} const x: Foo = { @@ -1049,7 +978,6 @@ const x: Foo = { ], }, { - filename: 'test.ts', code: '() => () => {};', options: [{ allowHigherOrderFunctions: true }], errors: [ @@ -1063,7 +991,6 @@ const x: Foo = { ], }, { - filename: 'test.ts', code: '() => function () {};', options: [{ allowHigherOrderFunctions: true }], errors: [ @@ -1077,7 +1004,6 @@ const x: Foo = { ], }, { - filename: 'test.ts', code: ` () => { return () => {}; @@ -1095,7 +1021,6 @@ const x: Foo = { ], }, { - filename: 'test.ts', code: ` () => { return function () {}; @@ -1113,7 +1038,6 @@ const x: Foo = { ], }, { - filename: 'test.ts', code: ` function fn() { return () => {}; @@ -1131,7 +1055,6 @@ function fn() { ], }, { - filename: 'test.ts', code: ` function fn() { return function () {}; @@ -1149,7 +1072,6 @@ function fn() { ], }, { - filename: 'test.ts', code: ` function FunctionDeclaration() { return function FunctionExpression_Within_FunctionDeclaration() { @@ -1177,7 +1099,6 @@ function FunctionDeclaration() { ], }, { - filename: 'test.ts', code: ` () => () => { return () => { @@ -1198,7 +1119,6 @@ function FunctionDeclaration() { }, // https://github.com/typescript-eslint/typescript-eslint/issues/679 { - filename: 'test.ts', code: ` declare function foo(arg: () => void): void; foo(() => 1); @@ -1251,7 +1171,6 @@ foo(() => ''); ], }, { - filename: 'test.ts', code: ` class Accumulator { private count: number = 0; @@ -1279,7 +1198,6 @@ new Accumulator().accumulate(() => 1); ], }, { - filename: 'test.ts', code: '(() => true)();', options: [ { @@ -1297,7 +1215,6 @@ new Accumulator().accumulate(() => 1); ], }, { - filename: 'test.ts', code: ` declare function foo(arg: { meth: () => number }): void; foo({ @@ -1346,7 +1263,6 @@ foo({ ], }, { - filename: 'test.ts', code: ` type HigherOrderType = () => (arg1: string) => (arg2: number) => string; const x: HigherOrderType = () => arg1 => arg2 => 'foo'; @@ -1368,7 +1284,6 @@ const x: HigherOrderType = () => arg1 => arg2 => 'foo'; ], }, { - filename: 'test.ts', code: ` type HigherOrderType = () => (arg1: string) => (arg2: number) => string; const x: HigherOrderType = () => arg1 => arg2 => 'foo'; @@ -1404,7 +1319,6 @@ const x: HigherOrderType = () => arg1 => arg2 => 'foo'; ], }, { - filename: 'test.ts', code: ` const func = (value: number) => ({ type: 'X', value } as any); const func = (value: number) => ({ type: 'X', value } as Action); @@ -1432,7 +1346,6 @@ const func = (value: number) => ({ type: 'X', value } as Action); ], }, { - filename: 'test.ts', code: ` const func = (value: number) => ({ type: 'X', value } as const); `, @@ -1452,7 +1365,6 @@ const func = (value: number) => ({ type: 'X', value } as const); ], }, { - filename: 'test.ts', code: 'const log = (message: string) => void console.log(message);', options: [ { allowConciseArrowFunctionExpressionsStartingWithVoid: false }, @@ -1468,7 +1380,6 @@ const func = (value: number) => ({ type: 'X', value } as const); ], }, { - filename: 'test.ts', code: ` const log = (message: string) => { void console.log(message); @@ -1509,7 +1420,6 @@ const log = function (a: A) { options: [{ allowFunctionsWithoutTypeParameters: true }], }, { - filename: 'test.ts', options: [ { allowedNames: ['test', '1'], @@ -1585,7 +1495,6 @@ const x = { ], }, { - filename: 'test.ts', code: ` const ignoredName = 'notIgnoredName'; class Foo { @@ -1604,7 +1513,6 @@ class Foo { ], }, { - filename: 'test.ts', code: ` const foo = (function () { return 'foo'; @@ -1626,7 +1534,6 @@ const foo = (function () { ], }, { - filename: 'test.ts', code: ` const foo = (function () { return () => { @@ -1650,7 +1557,6 @@ const foo = (function () { ], }, { - filename: 'test.ts', code: ` let foo = function () { return 'foo'; @@ -1672,7 +1578,6 @@ let foo = function () { ], }, { - filename: 'test.ts', code: ` let foo = (() => () => {})()(); `, diff --git a/packages/eslint-plugin/tests/rules/explicit-member-accessibility.test.ts b/packages/eslint-plugin/tests/rules/explicit-member-accessibility.test.ts index 92ab931e121..081f3398ce2 100644 --- a/packages/eslint-plugin/tests/rules/explicit-member-accessibility.test.ts +++ b/packages/eslint-plugin/tests/rules/explicit-member-accessibility.test.ts @@ -1,5 +1,6 @@ +import { noFormat, RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/explicit-member-accessibility'; -import { noFormat, RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', @@ -8,7 +9,6 @@ const ruleTester = new RuleTester({ ruleTester.run('explicit-member-accessibility', rule, { valid: [ { - filename: 'test.ts', code: ` class Test { public constructor(private foo: string) {} @@ -22,7 +22,6 @@ class Test { ], }, { - filename: 'test.ts', code: ` class Test { public constructor(private readonly foo: string) {} @@ -36,7 +35,6 @@ class Test { ], }, { - filename: 'test.ts', code: ` class Test { public constructor(private foo: string) {} @@ -50,7 +48,6 @@ class Test { ], }, { - filename: 'test.ts', code: ` class Test { public constructor(protected foo: string) {} @@ -64,7 +61,6 @@ class Test { ], }, { - filename: 'test.ts', code: ` class Test { public constructor(public foo: string) {} @@ -78,7 +74,6 @@ class Test { ], }, { - filename: 'test.ts', code: ` class Test { public constructor(readonly foo: string) {} @@ -92,7 +87,6 @@ class Test { ], }, { - filename: 'test.ts', code: ` class Test { public constructor(private readonly foo: string) {} @@ -106,7 +100,6 @@ class Test { ], }, { - filename: 'test.ts', code: ` class Test { protected name: string; @@ -118,7 +111,6 @@ class Test { `, }, { - filename: 'test.ts', code: ` class Test { protected name: string; @@ -128,7 +120,6 @@ class Test { `, }, { - filename: 'test.ts', code: ` class Test { public constructor({ x, y }: { x: number; y: number }) {} @@ -136,7 +127,6 @@ class Test { `, }, { - filename: 'test.ts', code: ` class Test { protected name: string; @@ -149,7 +139,6 @@ class Test { options: [{ accessibility: 'explicit' }], }, { - filename: 'test.ts', code: ` class Test { protected name: string; @@ -162,7 +151,6 @@ class Test { options: [{ accessibility: 'no-public' }], }, { - filename: 'test.ts', code: ` class Test { name: string; @@ -178,7 +166,6 @@ class Test { options: [{ accessibility: 'no-public' }], }, { - filename: 'test.ts', code: ` class Test { private x: number; @@ -199,7 +186,6 @@ class Test { options: [{ overrides: { constructors: 'off', accessors: 'off' } }], }, { - filename: 'test.ts', code: ` class Test { private x: number; @@ -223,7 +209,6 @@ class Test { options: [{ overrides: { methods: 'off' } }], }, { - filename: 'test.ts', code: ` class Test { constructor(private x: number) {} @@ -232,7 +217,6 @@ class Test { options: [{ accessibility: 'no-public' }], }, { - filename: 'test.ts', code: ` class Test { constructor(public x: number) {} @@ -246,7 +230,6 @@ class Test { ], }, { - filename: 'test.ts', code: ` class Test { constructor(public foo: number) {} @@ -255,7 +238,6 @@ class Test { options: [{ accessibility: 'no-public' }], }, { - filename: 'test.ts', code: ` class Test { public getX() { @@ -266,7 +248,6 @@ class Test { options: [{ ignoredMethodNames: ['getX'] }], }, { - filename: 'test.ts', code: ` class Test { public static getX() { @@ -277,7 +258,6 @@ class Test { options: [{ ignoredMethodNames: ['getX'] }], }, { - filename: 'test.ts', code: ` class Test { get getX() { @@ -288,7 +268,6 @@ class Test { options: [{ ignoredMethodNames: ['getX'] }], }, { - filename: 'test.ts', code: ` class Test { getX() { @@ -299,7 +278,6 @@ class Test { options: [{ ignoredMethodNames: ['getX'] }], }, { - filename: 'test.ts', code: ` class Test { x = 2; @@ -308,7 +286,6 @@ class Test { options: [{ overrides: { properties: 'off' } }], }, { - filename: 'test.ts', code: ` class Test { private x = 2; @@ -317,7 +294,6 @@ class Test { options: [{ overrides: { properties: 'explicit' } }], }, { - filename: 'test.ts', code: ` class Test { x = 2; @@ -347,7 +323,6 @@ class Test { ], invalid: [ { - filename: 'test.ts', code: ` export class XXXX { public constructor(readonly value: string) {} @@ -399,7 +374,6 @@ export class XXXX { ], }, { - filename: 'test.ts', code: ` export class WithParameterProperty { public constructor(readonly value: string) {} @@ -442,7 +416,6 @@ export class WithParameterProperty { ], }, { - filename: 'test.ts', code: ` export class XXXX { public constructor(readonly samosa: string) {} @@ -493,7 +466,6 @@ export class XXXX { ], }, { - filename: 'test.ts', code: ` class Test { public constructor(readonly foo: string) {} @@ -541,7 +513,6 @@ class Test { ], }, { - filename: 'test.ts', code: ` class Test { x: number; @@ -604,7 +575,6 @@ class Test { ], }, { - filename: 'test.ts', code: ` class Test { private x: number; @@ -664,7 +634,6 @@ class Test { ], }, { - filename: 'test.ts', code: ` class Test { x?: number; @@ -771,7 +740,6 @@ class Test { ], }, { - filename: 'test.ts', code: ` class Test { protected name: string; @@ -804,7 +772,6 @@ class Test { `, }, { - filename: 'test.ts', code: ` class Test { protected name: string; @@ -837,7 +804,6 @@ class Test { `, }, { - filename: 'test.ts', code: ` class Test { public x: number; @@ -869,7 +835,6 @@ class Test { `, }, { - filename: 'test.ts', code: ` class Test { private x: number; @@ -1011,7 +976,6 @@ class Test { options: [{ overrides: { constructors: 'no-public' } }], }, { - filename: 'test.ts', code: ` class Test { private x: number; @@ -1213,7 +1177,6 @@ class Test { ], }, { - filename: 'test.ts', code: ` class Test { constructor(public x: number) {} @@ -1274,7 +1237,6 @@ class Test { ], }, { - filename: 'test.ts', code: ` class Test { constructor(public x: number) {} @@ -1318,7 +1280,6 @@ class Test { ], }, { - filename: 'test.ts', code: ` class Test { constructor(public readonly x: number) {} @@ -1344,7 +1305,6 @@ class Test { `, }, { - filename: 'test.ts', code: ` class Test { x = 2; @@ -1394,7 +1354,6 @@ class Test { ], }, { - filename: 'test.ts', code: ` class Test { public x = 2; @@ -1466,7 +1425,6 @@ class Test { ], }, { - filename: 'test.ts', code: noFormat` class Test { public /*public*/constructor(private foo: string) {} @@ -1491,7 +1449,6 @@ class Test { `, }, { - filename: 'test.ts', code: ` class Test { @public @@ -1519,7 +1476,6 @@ class Test { }, { - filename: 'test.ts', code: ` class Test { @public @@ -1546,7 +1502,6 @@ class Test { `, }, { - filename: 'test.ts', code: ` class Test { public foo = ''; @@ -1572,7 +1527,6 @@ class Test { }, { - filename: 'test.ts', code: noFormat` class Test { constructor(public/* Hi there */ readonly foo) {} @@ -1598,7 +1552,6 @@ class Test { `, }, { - filename: 'test.ts', code: ` class Test { constructor(public readonly foo: string) {} @@ -1623,7 +1576,6 @@ class Test { `, }, { - filename: 'test.ts', code: ` class EnsureWhiteSPaceSpan { public constructor() {} @@ -1649,7 +1601,6 @@ class EnsureWhiteSPaceSpan { `, }, { - filename: 'test.ts', code: ` class EnsureWhiteSPaceSpan { public /* */ constructor() {} diff --git a/packages/eslint-plugin/tests/rules/explicit-module-boundary-types.test.ts b/packages/eslint-plugin/tests/rules/explicit-module-boundary-types.test.ts index fbed6829fef..854aa1bfe34 100644 --- a/packages/eslint-plugin/tests/rules/explicit-module-boundary-types.test.ts +++ b/packages/eslint-plugin/tests/rules/explicit-module-boundary-types.test.ts @@ -1,5 +1,6 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/explicit-module-boundary-types'; -import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', @@ -197,7 +198,6 @@ export const x: Foo = { }, // https://github.com/typescript-eslint/typescript-eslint/issues/2864 { - filename: 'test.ts', code: ` export const x = { foo: { bar: () => {} }, @@ -206,7 +206,6 @@ export const x = { options: [{ allowTypedFunctionExpressions: true }], }, { - filename: 'test.ts', code: ` export const x = { foo: { bar: () => {} }, @@ -215,7 +214,6 @@ export const x = { options: [{ allowTypedFunctionExpressions: true }], }, { - filename: 'test.ts', code: ` export const x: Foo = { foo: { bar: () => {} }, diff --git a/packages/eslint-plugin/tests/rules/func-call-spacing.test.ts b/packages/eslint-plugin/tests/rules/func-call-spacing.test.ts index 52d7a74ce47..443e4e92f19 100644 --- a/packages/eslint-plugin/tests/rules/func-call-spacing.test.ts +++ b/packages/eslint-plugin/tests/rules/func-call-spacing.test.ts @@ -3,11 +3,11 @@ /* eslint "@typescript-eslint/internal/plugin-test-formatting": ["error", { formatWithPrettier: false }] */ /* eslint-enable eslint-comments/no-use */ +import { RuleTester } from '@typescript-eslint/rule-tester'; import type { TSESLint } from '@typescript-eslint/utils'; import type { MessageIds, Options } from '../../src/rules/func-call-spacing'; import rule from '../../src/rules/func-call-spacing'; -import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/indent/indent.test.ts b/packages/eslint-plugin/tests/rules/indent/indent.test.ts index 951ffb59ea7..5974cb5198e 100644 --- a/packages/eslint-plugin/tests/rules/indent/indent.test.ts +++ b/packages/eslint-plugin/tests/rules/indent/indent.test.ts @@ -3,6 +3,7 @@ /* eslint "@typescript-eslint/internal/plugin-test-formatting": ["error", { formatWithPrettier: false }] */ /* eslint-enable eslint-comments/no-use */ +import { RuleTester } from '@typescript-eslint/rule-tester'; import type { TSESLint } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; @@ -11,7 +12,6 @@ import type { InferMessageIdsTypeFromRule, InferOptionsTypeFromRule, } from '../../../src/util'; -import { RuleTester } from '../../RuleTester'; type MessageIds = InferMessageIdsTypeFromRule; type Options = InferOptionsTypeFromRule; diff --git a/packages/eslint-plugin/tests/rules/init-declarations.test.ts b/packages/eslint-plugin/tests/rules/init-declarations.test.ts index 953a7a6aced..f284cd10185 100644 --- a/packages/eslint-plugin/tests/rules/init-declarations.test.ts +++ b/packages/eslint-plugin/tests/rules/init-declarations.test.ts @@ -1,7 +1,7 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; import rule from '../../src/rules/init-declarations'; -import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/key-spacing.test.ts b/packages/eslint-plugin/tests/rules/key-spacing.test.ts index e7828e01ffe..a0e1c1e9872 100644 --- a/packages/eslint-plugin/tests/rules/key-spacing.test.ts +++ b/packages/eslint-plugin/tests/rules/key-spacing.test.ts @@ -2,8 +2,9 @@ // this rule tests the new lines, which prettier will want to fix and break the tests /* eslint "@typescript-eslint/internal/plugin-test-formatting": ["error", { formatWithPrettier: false }] */ /* eslint-enable eslint-comments/no-use */ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/key-spacing'; -import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/keyword-spacing.test.ts b/packages/eslint-plugin/tests/rules/keyword-spacing.test.ts index 58c740fbd5c..82db86a4b44 100644 --- a/packages/eslint-plugin/tests/rules/keyword-spacing.test.ts +++ b/packages/eslint-plugin/tests/rules/keyword-spacing.test.ts @@ -2,11 +2,11 @@ // this rule tests the spacing, which prettier will want to fix and break the tests /* eslint "@typescript-eslint/internal/plugin-test-formatting": ["error", { formatWithPrettier: false }] */ /* eslint-enable eslint-comments/no-use */ +import { RuleTester } from '@typescript-eslint/rule-tester'; import type { TSESLint } from '@typescript-eslint/utils'; import type { MessageIds, Options } from '../../src/rules/keyword-spacing'; import rule from '../../src/rules/keyword-spacing'; -import { RuleTester } from '../RuleTester'; //------------------------------------------------------------------------------ // Helpers diff --git a/packages/eslint-plugin/tests/rules/lines-around-comment.test.ts b/packages/eslint-plugin/tests/rules/lines-around-comment.test.ts index a312bb19cd0..368a5cd0567 100644 --- a/packages/eslint-plugin/tests/rules/lines-around-comment.test.ts +++ b/packages/eslint-plugin/tests/rules/lines-around-comment.test.ts @@ -1,7 +1,7 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; import { AST_TOKEN_TYPES } from '@typescript-eslint/utils'; import rule from '../../src/rules/lines-around-comment'; -import { RuleTester } from '../RuleTester'; import { unIndent } from './indent/utils'; const ruleTester = new RuleTester({ diff --git a/packages/eslint-plugin/tests/rules/lines-between-class-members.test.ts b/packages/eslint-plugin/tests/rules/lines-between-class-members.test.ts index bb55bbbf346..07a349dd88e 100644 --- a/packages/eslint-plugin/tests/rules/lines-between-class-members.test.ts +++ b/packages/eslint-plugin/tests/rules/lines-between-class-members.test.ts @@ -2,8 +2,9 @@ // this rule tests the new lines, which prettier will want to fix and break the tests /* eslint "@typescript-eslint/internal/plugin-test-formatting": ["error", { formatWithPrettier: false }] */ /* eslint-enable eslint-comments/no-use */ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/lines-between-class-members'; -import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/member-delimiter-style.test.ts b/packages/eslint-plugin/tests/rules/member-delimiter-style.test.ts index 1b618448a93..1f0645e2fc5 100644 --- a/packages/eslint-plugin/tests/rules/member-delimiter-style.test.ts +++ b/packages/eslint-plugin/tests/rules/member-delimiter-style.test.ts @@ -3,8 +3,9 @@ /* eslint "@typescript-eslint/internal/plugin-test-formatting": ["error", { formatWithPrettier: false }] */ /* eslint-enable eslint-comments/no-use */ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/member-delimiter-style'; -import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/member-ordering.test.ts b/packages/eslint-plugin/tests/rules/member-ordering.test.ts index 6eba24b000c..31eaaf86dee 100644 --- a/packages/eslint-plugin/tests/rules/member-ordering.test.ts +++ b/packages/eslint-plugin/tests/rules/member-ordering.test.ts @@ -1,7 +1,8 @@ +import type { RunTests } from '@typescript-eslint/rule-tester'; +import { RuleTester } from '@typescript-eslint/rule-tester'; + import type { MessageIds, Options } from '../../src/rules/member-ordering'; import rule from '../../src/rules/member-ordering'; -import type { RunTests } from '../RuleTester'; -import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/member-ordering/member-ordering-alphabetically-case-insensitive-order.test.ts b/packages/eslint-plugin/tests/rules/member-ordering/member-ordering-alphabetically-case-insensitive-order.test.ts index fd10c55fe91..46531f75267 100644 --- a/packages/eslint-plugin/tests/rules/member-ordering/member-ordering-alphabetically-case-insensitive-order.test.ts +++ b/packages/eslint-plugin/tests/rules/member-ordering/member-ordering-alphabetically-case-insensitive-order.test.ts @@ -1,7 +1,8 @@ +import type { RunTests } from '@typescript-eslint/rule-tester'; +import { RuleTester } from '@typescript-eslint/rule-tester'; + import type { MessageIds, Options } from '../../../src/rules/member-ordering'; import rule, { defaultOrder } from '../../../src/rules/member-ordering'; -import type { RunTests } from '../../RuleTester'; -import { RuleTester } from '../../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/member-ordering/member-ordering-alphabetically-order.test.ts b/packages/eslint-plugin/tests/rules/member-ordering/member-ordering-alphabetically-order.test.ts index 338b3a50ee9..1fdf812bedd 100644 --- a/packages/eslint-plugin/tests/rules/member-ordering/member-ordering-alphabetically-order.test.ts +++ b/packages/eslint-plugin/tests/rules/member-ordering/member-ordering-alphabetically-order.test.ts @@ -1,7 +1,8 @@ +import type { RunTests } from '@typescript-eslint/rule-tester'; +import { RuleTester } from '@typescript-eslint/rule-tester'; + import type { MessageIds, Options } from '../../../src/rules/member-ordering'; import rule, { defaultOrder } from '../../../src/rules/member-ordering'; -import type { RunTests } from '../../RuleTester'; -import { RuleTester } from '../../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/member-ordering/member-ordering-natural-case-insensitive-order.test.ts b/packages/eslint-plugin/tests/rules/member-ordering/member-ordering-natural-case-insensitive-order.test.ts index 782fee826d5..ac4c749c6fa 100644 --- a/packages/eslint-plugin/tests/rules/member-ordering/member-ordering-natural-case-insensitive-order.test.ts +++ b/packages/eslint-plugin/tests/rules/member-ordering/member-ordering-natural-case-insensitive-order.test.ts @@ -1,5 +1,6 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../../src/rules/member-ordering'; -import { RuleTester } from '../../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/member-ordering/member-ordering-natural-order.test.ts b/packages/eslint-plugin/tests/rules/member-ordering/member-ordering-natural-order.test.ts index c34677a81c7..63c6dd60cc2 100644 --- a/packages/eslint-plugin/tests/rules/member-ordering/member-ordering-natural-order.test.ts +++ b/packages/eslint-plugin/tests/rules/member-ordering/member-ordering-natural-order.test.ts @@ -1,5 +1,6 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../../src/rules/member-ordering'; -import { RuleTester } from '../../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/member-ordering/member-ordering-optionalMembers.test.ts b/packages/eslint-plugin/tests/rules/member-ordering/member-ordering-optionalMembers.test.ts index 612c7011b02..ac4991944e9 100644 --- a/packages/eslint-plugin/tests/rules/member-ordering/member-ordering-optionalMembers.test.ts +++ b/packages/eslint-plugin/tests/rules/member-ordering/member-ordering-optionalMembers.test.ts @@ -1,8 +1,8 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; import type { TSESLint } from '@typescript-eslint/utils'; import type { MessageIds, Options } from '../../../src/rules/member-ordering'; import rule from '../../../src/rules/member-ordering'; -import { RuleTester } from '../../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/method-signature-style.test.ts b/packages/eslint-plugin/tests/rules/method-signature-style.test.ts index 1fcd4f080fa..91053830e86 100644 --- a/packages/eslint-plugin/tests/rules/method-signature-style.test.ts +++ b/packages/eslint-plugin/tests/rules/method-signature-style.test.ts @@ -1,5 +1,6 @@ +import { noFormat, RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/method-signature-style'; -import { batchedSingleLineTests, noFormat, RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', @@ -68,105 +69,323 @@ interface Test { typescript: '4.3', }, }, - ...batchedSingleLineTests({ + { options: ['method'], - code: noFormat` - interface Test { f(a: string): number } - interface Test { ['f'](a: boolean): void } - interface Test { f(a: T): T } - interface Test { ['f'](a: T, b: T): T } - interface Test { 'f!'(/* b */ x: any /* c */): void } - type Test = { f(a: string): number } - type Test = { ['f']?(a: boolean): void } - type Test = { f?(a?: T): T } - type Test = { ['f']?(a: T, b: T): T } - `, - }), - ...batchedSingleLineTests({ + code: ` + interface Test { + f(a: string): number; + } + `, + }, + { options: ['method'], - code: noFormat` - interface Test { get f(): number } - interface Test { set f(value: number): void } - type Test = { get f(): number } - type Test = { set f(value: number): void } + code: ` + interface Test { + ['f'](a: boolean): void; + } + `, + }, + { + options: ['method'], + code: ` + interface Test { + f(a: T): T; + } + `, + }, + { + options: ['method'], + code: ` + interface Test { + ['f'](a: T, b: T): T; + } + `, + }, + { + options: ['method'], + code: ` + interface Test { + 'f!'(/* b */ x: any /* c */): void; + } + `, + }, + { + options: ['method'], + code: ` + type Test = { f(a: string): number }; + `, + }, + { + options: ['method'], + code: ` + type Test = { ['f']?(a: boolean): void }; + `, + }, + { + options: ['method'], + code: ` + type Test = { f?(a?: T): T }; + `, + }, + { + options: ['method'], + code: ` + type Test = { ['f']?(a: T, b: T): T }; + `, + }, + { + options: ['method'], + code: ` + interface Test { + get f(): number; + } `, dependencyConstraints: { typescript: '4.3', }, - }), + }, + { + options: ['method'], + code: ` + interface Test { + set f(value: number): void; + } + `, + dependencyConstraints: { + typescript: '4.3', + }, + }, + { + options: ['method'], + code: ` + type Test = { get f(): number }; + `, + dependencyConstraints: { + typescript: '4.3', + }, + }, + { + options: ['method'], + code: ` + type Test = { set f(value: number): void }; + `, + dependencyConstraints: { + typescript: '4.3', + }, + }, ], invalid: [ - ...batchedSingleLineTests({ - code: noFormat` - interface Test { f(a: string): number } - interface Test { ['f'](a: boolean): void } - interface Test { f(a: T): T } - interface Test { ['f'](a: T, b: T): T } - interface Test { 'f!'(/* b */ x: any /* c */): void } - type Test = { f(a: string): number } - type Test = { ['f']?(a: boolean): void } - type Test = { f?(a?: T): T } - type Test = { ['f']?(a: T, b: T): T } + { + code: ` + interface Test { + f(a: string): number; + } `, - errors: [ - { messageId: 'errorMethod', line: 2 }, - { messageId: 'errorMethod', line: 3 }, - { messageId: 'errorMethod', line: 4 }, - { messageId: 'errorMethod', line: 5 }, - { messageId: 'errorMethod', line: 6 }, - { messageId: 'errorMethod', line: 7 }, - { messageId: 'errorMethod', line: 8 }, - { messageId: 'errorMethod', line: 9 }, - { messageId: 'errorMethod', line: 10 }, - ], + errors: [{ messageId: 'errorMethod' }], + output: ` + interface Test { + f: (a: string) => number; + } + `, + }, + { + code: ` + interface Test { + ['f'](a: boolean): void; + } + `, + errors: [{ messageId: 'errorMethod' }], output: ` - interface Test { f: (a: string) => number } - interface Test { ['f']: (a: boolean) => void } - interface Test { f: (a: T) => T } - interface Test { ['f']: (a: T, b: T) => T } - interface Test { 'f!': (/* b */ x: any /* c */) => void } - type Test = { f: (a: string) => number } - type Test = { ['f']?: (a: boolean) => void } - type Test = { f?: (a?: T) => T } - type Test = { ['f']?: (a: T, b: T) => T } - `, - }), - ...batchedSingleLineTests({ + interface Test { + ['f']: (a: boolean) => void; + } + `, + }, + { + code: ` + interface Test { + f(a: T): T; + } + `, + errors: [{ messageId: 'errorMethod' }], + output: ` + interface Test { + f: (a: T) => T; + } + `, + }, + { + code: ` + interface Test { + ['f'](a: T, b: T): T; + } + `, + errors: [{ messageId: 'errorMethod' }], + output: ` + interface Test { + ['f']: (a: T, b: T) => T; + } + `, + }, + { + code: ` + interface Test { + 'f!'(/* b */ x: any /* c */): void; + } + `, + errors: [{ messageId: 'errorMethod' }], + output: ` + interface Test { + 'f!': (/* b */ x: any /* c */) => void; + } + `, + }, + { + code: ` + type Test = { f(a: string): number }; + `, + errors: [{ messageId: 'errorMethod' }], + output: ` + type Test = { f: (a: string) => number }; + `, + }, + { + code: ` + type Test = { ['f']?(a: boolean): void }; + `, + errors: [{ messageId: 'errorMethod' }], + output: ` + type Test = { ['f']?: (a: boolean) => void }; + `, + }, + { + code: ` + type Test = { f?(a?: T): T }; + `, + errors: [{ messageId: 'errorMethod' }], + output: ` + type Test = { f?: (a?: T) => T }; + `, + }, + { + code: ` + type Test = { ['f']?(a: T, b: T): T }; + `, + errors: [{ messageId: 'errorMethod' }], + output: ` + type Test = { ['f']?: (a: T, b: T) => T }; + `, + }, + { + code: ` + interface Test { + f: (a: string) => number; + } + `, options: ['method'], - code: noFormat` - interface Test { f: (a: string) => number } - interface Test { ['f']: (a: boolean) => void } - interface Test { f: (a: T) => T } - interface Test { ['f']: (a: T, b: T) => T } - interface Test { 'f!': (/* b */ x: any /* c */) => void } - type Test = { f: (a: string) => number } - type Test = { ['f']?: (a: boolean) => void } - type Test = { f?: (a?: T) => T } - type Test = { ['f']?: (a: T, b: T) => T } + errors: [{ messageId: 'errorProperty' }], + output: ` + interface Test { + f(a: string): number; + } `, - errors: [ - { messageId: 'errorProperty', line: 2 }, - { messageId: 'errorProperty', line: 3 }, - { messageId: 'errorProperty', line: 4 }, - { messageId: 'errorProperty', line: 5 }, - { messageId: 'errorProperty', line: 6 }, - { messageId: 'errorProperty', line: 7 }, - { messageId: 'errorProperty', line: 8 }, - { messageId: 'errorProperty', line: 9 }, - { messageId: 'errorProperty', line: 10 }, - ], + }, + { + code: ` + interface Test { + ['f']: (a: boolean) => void; + } + `, + options: ['method'], + errors: [{ messageId: 'errorProperty' }], output: ` - interface Test { f(a: string): number } - interface Test { ['f'](a: boolean): void } - interface Test { f(a: T): T } - interface Test { ['f'](a: T, b: T): T } - interface Test { 'f!'(/* b */ x: any /* c */): void } - type Test = { f(a: string): number } - type Test = { ['f']?(a: boolean): void } - type Test = { f?(a?: T): T } - type Test = { ['f']?(a: T, b: T): T } - `, - }), + interface Test { + ['f'](a: boolean): void; + } + `, + }, + { + code: ` + interface Test { + f: (a: T) => T; + } + `, + options: ['method'], + errors: [{ messageId: 'errorProperty' }], + output: ` + interface Test { + f(a: T): T; + } + `, + }, + { + code: ` + interface Test { + ['f']: (a: T, b: T) => T; + } + `, + options: ['method'], + errors: [{ messageId: 'errorProperty' }], + output: ` + interface Test { + ['f'](a: T, b: T): T; + } + `, + }, + { + code: ` + interface Test { + 'f!': (/* b */ x: any /* c */) => void; + } + `, + options: ['method'], + errors: [{ messageId: 'errorProperty' }], + output: ` + interface Test { + 'f!'(/* b */ x: any /* c */): void; + } + `, + }, + { + code: ` + type Test = { f: (a: string) => number }; + `, + options: ['method'], + errors: [{ messageId: 'errorProperty' }], + output: ` + type Test = { f(a: string): number }; + `, + }, + { + code: ` + type Test = { ['f']?: (a: boolean) => void }; + `, + options: ['method'], + errors: [{ messageId: 'errorProperty' }], + output: ` + type Test = { ['f']?(a: boolean): void }; + `, + }, + { + code: ` + type Test = { f?: (a?: T) => T }; + `, + options: ['method'], + errors: [{ messageId: 'errorProperty' }], + output: ` + type Test = { f?(a?: T): T }; + `, + }, + { + code: ` + type Test = { ['f']?: (a: T, b: T) => T }; + `, + options: ['method'], + errors: [{ messageId: 'errorProperty' }], + output: ` + type Test = { ['f']?(a: T, b: T): T }; + `, + }, { code: noFormat` interface Foo { diff --git a/packages/eslint-plugin/tests/rules/naming-convention/cases/createTestCases.ts b/packages/eslint-plugin/tests/rules/naming-convention/cases/createTestCases.ts index 20f357b8a9c..cdb37896e8c 100644 --- a/packages/eslint-plugin/tests/rules/naming-convention/cases/createTestCases.ts +++ b/packages/eslint-plugin/tests/rules/naming-convention/cases/createTestCases.ts @@ -1,3 +1,4 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; import type { TSESLint } from '@typescript-eslint/utils'; import type { @@ -10,7 +11,6 @@ import type { Selector, } from '../../../../src/rules/naming-convention-utils'; import { selectorTypeToMessageString } from '../../../../src/rules/naming-convention-utils'; -import { RuleTester } from '../../../RuleTester'; export const formatTestNames: Readonly< Record> diff --git a/packages/eslint-plugin/tests/rules/naming-convention/naming-convention.test.ts b/packages/eslint-plugin/tests/rules/naming-convention/naming-convention.test.ts index df222f2dcb3..75156ebb2ce 100644 --- a/packages/eslint-plugin/tests/rules/naming-convention/naming-convention.test.ts +++ b/packages/eslint-plugin/tests/rules/naming-convention/naming-convention.test.ts @@ -1,6 +1,8 @@ /* eslint-disable @typescript-eslint/internal/prefer-ast-types-enum */ +import { noFormat, RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../../src/rules/naming-convention'; -import { getFixturesRootDir, noFormat, RuleTester } from '../../RuleTester'; +import { getFixturesRootDir } from '../../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/no-array-constructor.test.ts b/packages/eslint-plugin/tests/rules/no-array-constructor.test.ts index a50d2c08f83..4f358940089 100644 --- a/packages/eslint-plugin/tests/rules/no-array-constructor.test.ts +++ b/packages/eslint-plugin/tests/rules/no-array-constructor.test.ts @@ -1,7 +1,7 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; import rule from '../../src/rules/no-array-constructor'; -import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/no-base-to-string.test.ts b/packages/eslint-plugin/tests/rules/no-base-to-string.test.ts index 9e2f1fde608..a16b08056bd 100644 --- a/packages/eslint-plugin/tests/rules/no-base-to-string.test.ts +++ b/packages/eslint-plugin/tests/rules/no-base-to-string.test.ts @@ -1,5 +1,7 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/no-base-to-string'; -import { getFixturesRootDir, RuleTester } from '../RuleTester'; +import { getFixturesRootDir } from '../RuleTester'; const rootDir = getFixturesRootDir(); const ruleTester = new RuleTester({ diff --git a/packages/eslint-plugin/tests/rules/no-confusing-non-null-assertion.test.ts b/packages/eslint-plugin/tests/rules/no-confusing-non-null-assertion.test.ts index 333b0182559..ede6c266ad0 100644 --- a/packages/eslint-plugin/tests/rules/no-confusing-non-null-assertion.test.ts +++ b/packages/eslint-plugin/tests/rules/no-confusing-non-null-assertion.test.ts @@ -3,8 +3,9 @@ /* eslint "@typescript-eslint/internal/plugin-test-formatting": ["error", { formatWithPrettier: false }] */ /* eslint-enable eslint-comments/no-use */ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/no-confusing-non-null-assertion'; -import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/no-confusing-void-expression.test.ts b/packages/eslint-plugin/tests/rules/no-confusing-void-expression.test.ts index b0133a10b3c..a6b5cab492c 100644 --- a/packages/eslint-plugin/tests/rules/no-confusing-void-expression.test.ts +++ b/packages/eslint-plugin/tests/rules/no-confusing-void-expression.test.ts @@ -1,14 +1,7 @@ -import type { - MessageId, - Options, -} from '../../src/rules/no-confusing-void-expression'; +import { noFormat, RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/no-confusing-void-expression'; -import { - batchedSingleLineTests, - getFixturesRootDir, - noFormat, - RuleTester, -} from '../RuleTester'; +import { getFixturesRootDir } from '../RuleTester'; const rootPath = getFixturesRootDir(); const ruleTester = new RuleTester({ @@ -21,42 +14,99 @@ const ruleTester = new RuleTester({ ruleTester.run('no-confusing-void-expression', rule, { valid: [ - ...batchedSingleLineTests({ - code: ` - () => Math.random(); - console.log('foo'); - foo && console.log(foo); - foo || console.log(foo); - foo ? console.log(true) : console.log(false); - console?.log('foo'); - `, - }), + '() => Math.random();', + "console.log('foo');", + 'foo && console.log(foo);', + 'foo || console.log(foo);', + 'foo ? console.log(true) : console.log(false);', + "console?.log('foo');", - ...batchedSingleLineTests({ + { options: [{ ignoreArrowShorthand: true }], code: ` () => console.log('foo'); + `, + }, + { + options: [{ ignoreArrowShorthand: true }], + code: ` foo => foo && console.log(foo); + `, + }, + { + options: [{ ignoreArrowShorthand: true }], + code: ` foo => foo || console.log(foo); + `, + }, + { + options: [{ ignoreArrowShorthand: true }], + code: ` foo => (foo ? console.log(true) : console.log(false)); `, - }), + }, - ...batchedSingleLineTests({ + { options: [{ ignoreVoidOperator: true }], code: ` !void console.log('foo'); + `, + }, + { + options: [{ ignoreVoidOperator: true }], + code: ` +void (foo && console.log(foo)); + `, + }, + { + options: [{ ignoreVoidOperator: true }], + code: ` -void (foo || console.log(foo)); + `, + }, + { + options: [{ ignoreVoidOperator: true }], + code: ` () => void ((foo && void console.log(true)) || console.log(false)); + `, + }, + { + options: [{ ignoreVoidOperator: true }], + code: ` const x = void (foo ? console.log(true) : console.log(false)); + `, + }, + { + options: [{ ignoreVoidOperator: true }], + code: ` !(foo && void console.log(foo)); + `, + }, + { + options: [{ ignoreVoidOperator: true }], + code: ` !!(foo || void console.log(foo)); + `, + }, + { + options: [{ ignoreVoidOperator: true }], + code: ` const x = (foo && void console.log(true)) || void console.log(false); + `, + }, + { + options: [{ ignoreVoidOperator: true }], + code: ` () => (foo ? void console.log(true) : void console.log(false)); + `, + }, + { + options: [{ ignoreVoidOperator: true }], + code: ` return void console.log('foo'); `, - }), + }, + ` function cool(input: string) { return console.log(input), input; @@ -72,32 +122,66 @@ function cool(input: string) { ], invalid: [ - ...batchedSingleLineTests({ + { code: ` const x = console.log('foo'); + `, + errors: [{ column: 19, messageId: 'invalidVoidExpr' }], + }, + { + code: ` const x = console?.log('foo'); + `, + errors: [{ column: 19, messageId: 'invalidVoidExpr' }], + }, + { + code: ` console.error(console.log('foo')); + `, + errors: [{ column: 23, messageId: 'invalidVoidExpr' }], + }, + { + code: ` [console.log('foo')]; + `, + errors: [{ column: 10, messageId: 'invalidVoidExpr' }], + }, + { + code: ` ({ x: console.log('foo') }); + `, + errors: [{ column: 15, messageId: 'invalidVoidExpr' }], + }, + { + code: ` void console.log('foo'); + `, + errors: [{ column: 14, messageId: 'invalidVoidExpr' }], + }, + { + code: ` console.log('foo') ? true : false; + `, + errors: [{ column: 9, messageId: 'invalidVoidExpr' }], + }, + { + code: ` (console.log('foo') && true) || false; + `, + errors: [{ column: 10, messageId: 'invalidVoidExpr' }], + }, + { + code: ` (cond && console.log('ok')) || console.log('error'); + `, + errors: [{ column: 18, messageId: 'invalidVoidExpr' }], + }, + { + code: ` !console.log('foo'); `, - errors: [ - { line: 2, column: 11, messageId: 'invalidVoidExpr' }, - { line: 3, column: 19, messageId: 'invalidVoidExpr' }, - { line: 4, column: 23, messageId: 'invalidVoidExpr' }, - { line: 5, column: 10, messageId: 'invalidVoidExpr' }, - { line: 6, column: 15, messageId: 'invalidVoidExpr' }, - { line: 7, column: 14, messageId: 'invalidVoidExpr' }, - { line: 8, column: 9, messageId: 'invalidVoidExpr' }, - { line: 9, column: 10, messageId: 'invalidVoidExpr' }, - { line: 10, column: 18, messageId: 'invalidVoidExpr' }, - { line: 11, column: 10, messageId: 'invalidVoidExpr' }, - ], - }), + errors: [{ column: 10, messageId: 'invalidVoidExpr' }], + }, { code: ` diff --git a/packages/eslint-plugin/tests/rules/no-dupe-class-members.test.ts b/packages/eslint-plugin/tests/rules/no-dupe-class-members.test.ts index fe99fba8631..9639917baef 100644 --- a/packages/eslint-plugin/tests/rules/no-dupe-class-members.test.ts +++ b/packages/eslint-plugin/tests/rules/no-dupe-class-members.test.ts @@ -1,5 +1,6 @@ +import { noFormat, RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/no-dupe-class-members'; -import { noFormat, RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/no-duplicate-enum-values.test.ts b/packages/eslint-plugin/tests/rules/no-duplicate-enum-values.test.ts index 037579d12bb..809248f714f 100644 --- a/packages/eslint-plugin/tests/rules/no-duplicate-enum-values.test.ts +++ b/packages/eslint-plugin/tests/rules/no-duplicate-enum-values.test.ts @@ -1,5 +1,6 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/no-duplicate-enum-values'; -import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/no-duplicate-type-constituents.test.ts b/packages/eslint-plugin/tests/rules/no-duplicate-type-constituents.test.ts index c1b57d8914b..376e3fa2268 100644 --- a/packages/eslint-plugin/tests/rules/no-duplicate-type-constituents.test.ts +++ b/packages/eslint-plugin/tests/rules/no-duplicate-type-constituents.test.ts @@ -1,5 +1,7 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/no-duplicate-type-constituents'; -import { getFixturesRootDir, RuleTester } from '../RuleTester'; +import { getFixturesRootDir } from '../RuleTester'; const rootPath = getFixturesRootDir(); diff --git a/packages/eslint-plugin/tests/rules/no-dynamic-delete.test.ts b/packages/eslint-plugin/tests/rules/no-dynamic-delete.test.ts index 40aece28bc5..b58bc177184 100644 --- a/packages/eslint-plugin/tests/rules/no-dynamic-delete.test.ts +++ b/packages/eslint-plugin/tests/rules/no-dynamic-delete.test.ts @@ -1,5 +1,7 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/no-dynamic-delete'; -import { getFixturesRootDir, RuleTester } from '../RuleTester'; +import { getFixturesRootDir } from '../RuleTester'; const rootPath = getFixturesRootDir(); diff --git a/packages/eslint-plugin/tests/rules/no-empty-function.test.ts b/packages/eslint-plugin/tests/rules/no-empty-function.test.ts index a054989c48e..d24ad789e59 100644 --- a/packages/eslint-plugin/tests/rules/no-empty-function.test.ts +++ b/packages/eslint-plugin/tests/rules/no-empty-function.test.ts @@ -1,5 +1,6 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/no-empty-function'; -import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/no-empty-interface.test.ts b/packages/eslint-plugin/tests/rules/no-empty-interface.test.ts index 893deaf01d6..3711f874a3b 100644 --- a/packages/eslint-plugin/tests/rules/no-empty-interface.test.ts +++ b/packages/eslint-plugin/tests/rules/no-empty-interface.test.ts @@ -1,5 +1,6 @@ +import { noFormat, RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/no-empty-interface'; -import { noFormat, RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/no-explicit-any.test.ts b/packages/eslint-plugin/tests/rules/no-explicit-any.test.ts index 01d894d1802..2dc995cb66f 100644 --- a/packages/eslint-plugin/tests/rules/no-explicit-any.test.ts +++ b/packages/eslint-plugin/tests/rules/no-explicit-any.test.ts @@ -1,8 +1,8 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; import type { TSESLint } from '@typescript-eslint/utils'; import type { MessageIds, Options } from '../../src/rules/no-explicit-any'; import rule from '../../src/rules/no-explicit-any'; -import { RuleTester } from '../RuleTester'; type InvalidTestCase = TSESLint.InvalidTestCase; type SuggestionOutput = TSESLint.SuggestionOutput; diff --git a/packages/eslint-plugin/tests/rules/no-extra-non-null-assertion.test.ts b/packages/eslint-plugin/tests/rules/no-extra-non-null-assertion.test.ts index 3deb4bfaec2..7b9ab5338af 100644 --- a/packages/eslint-plugin/tests/rules/no-extra-non-null-assertion.test.ts +++ b/packages/eslint-plugin/tests/rules/no-extra-non-null-assertion.test.ts @@ -1,5 +1,6 @@ +import { noFormat, RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/no-extra-non-null-assertion'; -import { noFormat, RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/no-extra-parens.test.ts b/packages/eslint-plugin/tests/rules/no-extra-parens.test.ts index 369f55101f2..6aad779b2b7 100644 --- a/packages/eslint-plugin/tests/rules/no-extra-parens.test.ts +++ b/packages/eslint-plugin/tests/rules/no-extra-parens.test.ts @@ -3,8 +3,9 @@ /* eslint "@typescript-eslint/internal/plugin-test-formatting": ["error", { formatWithPrettier: false }] */ /* eslint-enable eslint-comments/no-use */ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/no-extra-parens'; -import { batchedSingleLineTests, RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parserOptions: { @@ -17,31 +18,42 @@ const ruleTester = new RuleTester({ ruleTester.run('no-extra-parens', rule, { valid: [ - ...batchedSingleLineTests({ - code: ` -async function f(arg: any) { await (arg as Promise); } -async function f(arg: Promise) { await arg; } -(0).toString(); -(function(){}) ? a() : b(); -(/^a$/).test(x); -for (a of (b, c)); -for (a of b); -for (a in b, c); -for (a in b); -a(1); -new a(1); -a(1); - `, - }), - ...batchedSingleLineTests({ + 'async function f(arg: any) { await (arg as Promise); }', + 'async function f(arg: Promise) { await arg; }', + '(0).toString();', + '(function(){}) ? a() : b();', + '(/^a$/).test(x);', + 'for (a of (b, c));', + 'for (a of b);', + 'for (a in b, c);', + 'for (a in b);', + "a(1);", + "new a(1);", + 'a(1);', + { code: ` while ((foo = bar())) {} + `, + options: ['all', { conditionalAssign: false }], + }, + { + code: ` if ((foo = bar())) {} + `, + options: ['all', { conditionalAssign: false }], + }, + { + code: ` do; while ((foo = bar())) + `, + options: ['all', { conditionalAssign: false }], + }, + { + code: ` for (;(a = b);); `, options: ['all', { conditionalAssign: false }], - }), + }, { code: ` function a(b) { @@ -66,14 +78,24 @@ for (;(a = b);); code: 'b => b ? (c = d) : (c = e);', options: ['all', { returnAssign: false }], }, - ...batchedSingleLineTests({ + { code: ` x = a || (b && c); + `, + options: ['all', { nestedBinaryExpressions: false }], + }, + { + code: ` x = a + (b * c); + `, + options: ['all', { nestedBinaryExpressions: false }], + }, + { + code: ` x = (a * b) / c; `, options: ['all', { nestedBinaryExpressions: false }], - }), + }, { code: ` const Component = (
) @@ -100,140 +122,391 @@ const Component = ( `, options: ['all', { ignoreJSX: 'multi-line' }], }, - ...batchedSingleLineTests({ + { code: ` const Component = (
) + `, + options: ['all', { ignoreJSX: 'single-line' }], + }, + { + code: ` const Component = (

) `, options: ['all', { ignoreJSX: 'single-line' }], - }), - ...batchedSingleLineTests({ + }, + { code: ` const b = a => 1 ? 2 : 3; + `, + options: ['all', { enforceForArrowConditionals: false }], + }, + { + code: ` const d = c => (1 ? 2 : 3); `, options: ['all', { enforceForArrowConditionals: false }], - }), - ...batchedSingleLineTests({ + }, + { code: ` (0).toString(); + `, + options: ['functions'], + }, + { + code: ` (Object.prototype.toString.call()); + `, + options: ['functions'], + }, + { + code: ` ({}.toString.call()); + `, + options: ['functions'], + }, + { + code: ` (function(){} ? a() : b()); + `, + options: ['functions'], + }, + { + code: ` (/^a$/).test(x); + `, + options: ['functions'], + }, + { + code: ` a = (b * c); -(a * b) + c; -typeof (a); `, options: ['functions'], - }), - ...batchedSingleLineTests({ + }, + { code: ` -const x = (1 as 1) | (1 as 1); -const x = (<1>1) | (<1>1); -const x = (1 as 1) | 2; -const x = (1 as 1) + 2 + 2; -const x = 1 + 1 + (2 as 2); -const x = 1 | (2 as 2); -const x = (<1>1) | 2; -const x = 1 | (<2>2); -t.true((me.get as SinonStub).calledWithExactly('/foo', other)); -t.true((me.get).calledWithExactly('/foo', other)); -(requestInit.headers as Headers).get('Cookie'); -( requestInit.headers).get('Cookie'); -class Foo {} -class Foo extends (Bar as any) {} -const foo = class {}; -const foo = class extends (Bar as any) {} +(a * b) + c; `, - parserOptions: { - ecmaFeatures: { - jsx: false, - }, - }, - }), - ...batchedSingleLineTests({ + options: ['functions'], + }, + { code: ` -[a as b]; -() => (1 as 1); -x = a as b; -const x = (1 as 1) | 2; -const x = 1 | (2 as 2); -const x = await (foo as Promise); -const res2 = (fn as foo)(); -(x as boolean) ? 1 : 0; -x ? (1 as 1) : 2; -x ? 1 : (2 as 2); -while (foo as boolean) {}; -do {} while (foo as boolean); -for (let i of ([] as Foo)) {} -for (let i in ({} as Foo)) {} -for ((1 as 1);;) {} -for (;(1 as 1);) {} -for (;;(1 as 1)) {} -if (1 as 1) {} -const x = (1 as 1).toString(); -new (1 as 1)(); -const x = { ...(1 as 1), ...{} }; -throw (1 as 1); -throw 1; -const x = !(1 as 1); -const x = (1 as 1)++; -function *x() { yield (1 as 1); yield 1; } -switch (foo) { case 1: case (2 as 2): break; default: break; } - `, - options: [ - 'all', - { - nestedBinaryExpressions: false, - }, - ], - }), - ...batchedSingleLineTests({ +typeof (a); + `, + options: ['functions'], + }, + { + code: 'const x = (1 as 1) | (1 as 1);', + parserOptions: { ecmaFeatures: { jsx: false } }, + }, + { + code: 'const x = (<1>1) | (<1>1);', + parserOptions: { ecmaFeatures: { jsx: false } }, + }, + { + code: 'const x = (1 as 1) | 2;', + parserOptions: { ecmaFeatures: { jsx: false } }, + }, + { + code: 'const x = (1 as 1) + 2 + 2;', + parserOptions: { ecmaFeatures: { jsx: false } }, + }, + { + code: 'const x = 1 + 1 + (2 as 2);', + parserOptions: { ecmaFeatures: { jsx: false } }, + }, + { + code: 'const x = 1 | (2 as 2);', + parserOptions: { ecmaFeatures: { jsx: false } }, + }, + { + code: 'const x = (<1>1) | 2;', + parserOptions: { ecmaFeatures: { jsx: false } }, + }, + { + code: 'const x = 1 | (<2>2);', + parserOptions: { ecmaFeatures: { jsx: false } }, + }, + { + code: "t.true((me.get as SinonStub).calledWithExactly('/foo', other));", + parserOptions: { ecmaFeatures: { jsx: false } }, + }, + { + code: "t.true((me.get).calledWithExactly('/foo', other));", + parserOptions: { ecmaFeatures: { jsx: false } }, + }, + { + code: "(requestInit.headers as Headers).get('Cookie');", + parserOptions: { ecmaFeatures: { jsx: false } }, + }, + { + code: "( requestInit.headers).get('Cookie');", + parserOptions: { ecmaFeatures: { jsx: false } }, + }, + { code: 'class Foo {}', parserOptions: { ecmaFeatures: { jsx: false } } }, + { + code: 'class Foo extends (Bar as any) {}', + parserOptions: { ecmaFeatures: { jsx: false } }, + }, + { + code: 'const foo = class {};', + parserOptions: { ecmaFeatures: { jsx: false } }, + }, + { + code: 'const foo = class extends (Bar as any) {}', + parserOptions: { ecmaFeatures: { jsx: false } }, + }, + + { code: '[a as b];', options: ['all', { nestedBinaryExpressions: false }] }, + { + code: '() => (1 as 1);', + options: ['all', { nestedBinaryExpressions: false }], + }, + { + code: 'x = a as b;', + options: ['all', { nestedBinaryExpressions: false }], + }, + { + code: 'const x = (1 as 1) | 2;', + options: ['all', { nestedBinaryExpressions: false }], + }, + { + code: 'const x = 1 | (2 as 2);', + options: ['all', { nestedBinaryExpressions: false }], + }, + { + code: 'const x = await (foo as Promise);', + options: ['all', { nestedBinaryExpressions: false }], + }, + { + code: 'const res2 = (fn as foo)();', + options: ['all', { nestedBinaryExpressions: false }], + }, + { + code: '(x as boolean) ? 1 : 0;', + options: ['all', { nestedBinaryExpressions: false }], + }, + { + code: 'x ? (1 as 1) : 2;', + options: ['all', { nestedBinaryExpressions: false }], + }, + { + code: 'x ? 1 : (2 as 2);', + options: ['all', { nestedBinaryExpressions: false }], + }, + { + code: 'while (foo as boolean) {};', + options: ['all', { nestedBinaryExpressions: false }], + }, + { + code: 'do {} while (foo as boolean);', + options: ['all', { nestedBinaryExpressions: false }], + }, + { + code: 'for (let i of ([] as Foo)) {}', + options: ['all', { nestedBinaryExpressions: false }], + }, + { + code: 'for (let i in ({} as Foo)) {}', + options: ['all', { nestedBinaryExpressions: false }], + }, + { + code: 'for ((1 as 1);;) {}', + options: ['all', { nestedBinaryExpressions: false }], + }, + { + code: 'for (;(1 as 1);) {}', + options: ['all', { nestedBinaryExpressions: false }], + }, + { + code: 'for (;;(1 as 1)) {}', + options: ['all', { nestedBinaryExpressions: false }], + }, + { + code: 'if (1 as 1) {}', + options: ['all', { nestedBinaryExpressions: false }], + }, + { + code: 'const x = (1 as 1).toString();', + options: ['all', { nestedBinaryExpressions: false }], + }, + { + code: 'new (1 as 1)();', + options: ['all', { nestedBinaryExpressions: false }], + }, + { + code: 'const x = { ...(1 as 1), ...{} };', + options: ['all', { nestedBinaryExpressions: false }], + }, + { + code: 'throw (1 as 1);', + options: ['all', { nestedBinaryExpressions: false }], + }, + { code: 'throw 1;', options: ['all', { nestedBinaryExpressions: false }] }, + { + code: 'const x = !(1 as 1);', + options: ['all', { nestedBinaryExpressions: false }], + }, + { + code: 'const x = (1 as 1)++;', + options: ['all', { nestedBinaryExpressions: false }], + }, + { + code: 'function *x() { yield (1 as 1); yield 1; }', + options: ['all', { nestedBinaryExpressions: false }], + }, + { + code: 'switch (foo) { case 1: case (2 as 2): break; default: break; }', + options: ['all', { nestedBinaryExpressions: false }], + }, + + { + code: '[a];', + parserOptions: { ecmaFeatures: { jsx: false } }, + options: ['all', { nestedBinaryExpressions: false }], + }, + { + code: '() => (<1>1);', + parserOptions: { ecmaFeatures: { jsx: false } }, + options: ['all', { nestedBinaryExpressions: false }], + }, + { + code: 'x = a;', + parserOptions: { ecmaFeatures: { jsx: false } }, + options: ['all', { nestedBinaryExpressions: false }], + }, + { + code: 'const x = (<1>1) | 2;', + parserOptions: { ecmaFeatures: { jsx: false } }, + options: ['all', { nestedBinaryExpressions: false }], + }, + { + code: 'const x = 1 | (<2>2);', + parserOptions: { ecmaFeatures: { jsx: false } }, + options: ['all', { nestedBinaryExpressions: false }], + }, + { + code: 'const x = await (>foo);', + parserOptions: { ecmaFeatures: { jsx: false } }, + options: ['all', { nestedBinaryExpressions: false }], + }, + { + code: 'const res2 = (fn)();', + parserOptions: { ecmaFeatures: { jsx: false } }, + options: ['all', { nestedBinaryExpressions: false }], + }, + { + code: '(x) ? 1 : 0;', + parserOptions: { ecmaFeatures: { jsx: false } }, + options: ['all', { nestedBinaryExpressions: false }], + }, + { + code: 'x ? (<1>1) : 2;', + parserOptions: { ecmaFeatures: { jsx: false } }, + options: ['all', { nestedBinaryExpressions: false }], + }, + { + code: 'x ? 1 : (<2>2);', + parserOptions: { ecmaFeatures: { jsx: false } }, + options: ['all', { nestedBinaryExpressions: false }], + }, + { + code: 'while (foo) {};', + parserOptions: { ecmaFeatures: { jsx: false } }, + options: ['all', { nestedBinaryExpressions: false }], + }, + { + code: 'do {} while (foo);', + parserOptions: { ecmaFeatures: { jsx: false } }, + options: ['all', { nestedBinaryExpressions: false }], + }, + { + code: 'for (let i of ([])) {}', + parserOptions: { ecmaFeatures: { jsx: false } }, + options: ['all', { nestedBinaryExpressions: false }], + }, + { + code: 'for (let i in ({})) {}', + parserOptions: { ecmaFeatures: { jsx: false } }, + options: ['all', { nestedBinaryExpressions: false }], + }, + { + code: 'for ((<1>1);;) {}', + parserOptions: { ecmaFeatures: { jsx: false } }, + options: ['all', { nestedBinaryExpressions: false }], + }, + { + code: 'for (;(<1>1);) {}', + parserOptions: { ecmaFeatures: { jsx: false } }, + options: ['all', { nestedBinaryExpressions: false }], + }, + { + code: 'for (;;(<1>1)) {}', + parserOptions: { ecmaFeatures: { jsx: false } }, + options: ['all', { nestedBinaryExpressions: false }], + }, + { + code: 'if (<1>1) {}', + parserOptions: { ecmaFeatures: { jsx: false } }, + options: ['all', { nestedBinaryExpressions: false }], + }, + { + code: 'const x = (<1>1).toString();', + parserOptions: { ecmaFeatures: { jsx: false } }, + options: ['all', { nestedBinaryExpressions: false }], + }, + { + code: 'new (<1>1)();', + parserOptions: { ecmaFeatures: { jsx: false } }, + options: ['all', { nestedBinaryExpressions: false }], + }, + { + code: 'const x = { ...(<1>1), ...{} };', + parserOptions: { ecmaFeatures: { jsx: false } }, + options: ['all', { nestedBinaryExpressions: false }], + }, + { + code: 'throw (<1>1);', + parserOptions: { ecmaFeatures: { jsx: false } }, + options: ['all', { nestedBinaryExpressions: false }], + }, + { + code: 'throw 1;', + parserOptions: { ecmaFeatures: { jsx: false } }, + options: ['all', { nestedBinaryExpressions: false }], + }, + { + code: 'const x = !(<1>1);', + parserOptions: { ecmaFeatures: { jsx: false } }, + options: ['all', { nestedBinaryExpressions: false }], + }, + { + code: 'const x = (<1>1)++;', + parserOptions: { ecmaFeatures: { jsx: false } }, + options: ['all', { nestedBinaryExpressions: false }], + }, + { + code: 'function *x() { yield (<1>1); yield 1; }', + parserOptions: { ecmaFeatures: { jsx: false } }, + options: ['all', { nestedBinaryExpressions: false }], + }, + { + code: 'switch (foo) { case 1: case (<2>2): break; default: break; }', + parserOptions: { ecmaFeatures: { jsx: false } }, + options: ['all', { nestedBinaryExpressions: false }], + }, + + { code: ` -[a]; -() => (<1>1); -x = a; -const x = (<1>1) | 2; -const x = 1 | (<2>2); -const x = await (>foo); -const res2 = (fn)(); -(x) ? 1 : 0; -x ? (<1>1) : 2; -x ? 1 : (<2>2); -while (foo) {}; -do {} while (foo); -for (let i of ([])) {} -for (let i in ({})) {} -for ((<1>1);;) {} -for (;(<1>1);) {} -for (;;(<1>1)) {} -if (<1>1) {} -const x = (<1>1).toString(); -new (<1>1)(); -const x = { ...(<1>1), ...{} }; -throw (<1>1); -throw 1; -const x = !(<1>1); -const x = (<1>1)++; -function *x() { yield (<1>1); yield 1; } -switch (foo) { case 1: case (<2>2): break; default: break; } +declare const f: (x: T) => any `, parserOptions: { ecmaFeatures: { - jsx: false, + jsx: true, }, }, - options: [ - 'all', - { - nestedBinaryExpressions: false, - }, - ], - }), - ...batchedSingleLineTests({ + }, + { code: ` -declare const f: (x: T) => any f<(number | string)[]>(['a', 1]) `, parserOptions: { @@ -241,146 +514,192 @@ f<(number | string)[]>(['a', 1]) jsx: true, }, }, - }), + }, ], invalid: [ - ...batchedSingleLineTests({ - code: ` -a = (b * c); -(a * b) + c; -for (a in (b, c)); -for (a in (b)); -for (a of (b)); -typeof (a); -a((1)); -new a((1)); -a<(A)>((1)); -async function f(arg: Promise) { await (arg); } -async function f(arg: any) { await ((arg as Promise)); } -class Foo extends ((Bar as any)) {} -class Foo extends (Bar) {} -const foo = class extends ((Bar as any)) {} -const foo = class extends (Bar) {} - `, - output: ` -a = b * c; -a * b + c; -for (a in b, c); -for (a in b); -for (a of b); -typeof a; -a(1); -new a(1); -a<(A)>(1); -async function f(arg: Promise) { await arg; } -async function f(arg: any) { await (arg as Promise); } -class Foo extends (Bar as any) {} -class Foo extends Bar {} -const foo = class extends (Bar as any) {} -const foo = class extends Bar {} - `, + { + code: 'a = (b * c);', + output: 'a = b * c;', errors: [ { messageId: 'unexpected', - line: 2, column: 5, }, + ], + }, + { + code: '(a * b) + c;', + output: 'a * b + c;', + errors: [ { messageId: 'unexpected', - line: 3, column: 1, }, + ], + }, + { + code: 'for (a in (b, c));', + output: 'for (a in b, c);', + errors: [ { messageId: 'unexpected', - line: 4, column: 11, }, + ], + }, + { + code: 'for (a in (b));', + output: 'for (a in b);', + errors: [ { messageId: 'unexpected', - line: 5, column: 11, }, + ], + }, + { + code: 'for (a of (b));', + output: 'for (a of b);', + errors: [ { messageId: 'unexpected', - line: 6, column: 11, }, + ], + }, + { + code: 'typeof (a);', + output: 'typeof a;', + errors: [ { messageId: 'unexpected', - line: 7, column: 8, }, + ], + }, + { + code: "a((1));", + output: "a(1);", + errors: [ { messageId: 'unexpected', - line: 8, column: 15, }, + ], + }, + { + code: "new a((1));", + output: "new a(1);", + errors: [ { messageId: 'unexpected', - line: 9, column: 19, }, + ], + }, + { + code: 'a<(A)>((1));', + output: 'a<(A)>(1);', + errors: [ { messageId: 'unexpected', - line: 10, column: 8, }, + ], + }, + { + code: 'async function f(arg: Promise) { await (arg); }', + output: 'async function f(arg: Promise) { await arg; }', + errors: [ { messageId: 'unexpected', - line: 11, column: 45, }, + ], + }, + { + code: 'async function f(arg: any) { await ((arg as Promise)); }', + output: 'async function f(arg: any) { await (arg as Promise); }', + errors: [ { messageId: 'unexpected', - line: 12, column: 37, }, + ], + }, + { + code: 'class Foo extends ((Bar as any)) {}', + output: 'class Foo extends (Bar as any) {}', + errors: [ { messageId: 'unexpected', - line: 13, column: 20, }, + ], + }, + { + code: 'class Foo extends (Bar) {}', + output: 'class Foo extends Bar {}', + errors: [ { messageId: 'unexpected', - line: 14, column: 19, }, + ], + }, + { + code: 'const foo = class extends ((Bar as any)) {}', + output: 'const foo = class extends (Bar as any) {}', + errors: [ { messageId: 'unexpected', - line: 15, column: 28, }, + ], + }, + { + code: 'const foo = class extends (Bar) {}', + output: 'const foo = class extends Bar {}', + errors: [ { messageId: 'unexpected', - line: 16, column: 27, }, ], - }), - ...batchedSingleLineTests({ + }, + + { code: ` -const Component = (
) -const Component = (

) + const Component = (
) `, output: ` -const Component =
-const Component =

+ const Component =
`, options: ['all', { ignoreJSX: 'multi-line' }], errors: [ { messageId: 'unexpected', - line: 2, - column: 19, + column: 27, }, + ], + }, + { + code: ` + const Component = (

) + `, + output: ` + const Component =

+ `, + options: ['all', { ignoreJSX: 'multi-line' }], + errors: [ { messageId: 'unexpected', - line: 3, - column: 19, + column: 27, }, ], - }), + }, + { code: ` const Component = ( @@ -420,28 +739,35 @@ const Component =${' '} }, ], }, - ...batchedSingleLineTests({ + { code: ` ((function foo() {}))(); -var y = (function () {return 1;}); `, output: ` (function foo() {})(); -var y = function () {return 1;}; `, options: ['functions'], errors: [ { messageId: 'unexpected', - line: 2, column: 2, }, + ], + }, + { + code: ` +var y = (function () {return 1;}); + `, + output: ` +var y = function () {return 1;}; + `, + options: ['functions'], + errors: [ { messageId: 'unexpected', - line: 3, column: 9, }, ], - }), + }, ], }); diff --git a/packages/eslint-plugin/tests/rules/no-extra-semi.test.ts b/packages/eslint-plugin/tests/rules/no-extra-semi.test.ts index 4d2d870e7e5..897d38ece0c 100644 --- a/packages/eslint-plugin/tests/rules/no-extra-semi.test.ts +++ b/packages/eslint-plugin/tests/rules/no-extra-semi.test.ts @@ -3,8 +3,9 @@ /* eslint "@typescript-eslint/internal/plugin-test-formatting": ["error", { formatWithPrettier: false }] */ /* eslint-enable eslint-comments/no-use */ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/no-extra-semi'; -import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/no-extraneous-class.test.ts b/packages/eslint-plugin/tests/rules/no-extraneous-class.test.ts index ca8cad2b4d1..cb40f6900cc 100644 --- a/packages/eslint-plugin/tests/rules/no-extraneous-class.test.ts +++ b/packages/eslint-plugin/tests/rules/no-extraneous-class.test.ts @@ -1,7 +1,7 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; import rule from '../../src/rules/no-extraneous-class'; -import { RuleTester } from '../RuleTester'; const empty = { messageId: 'empty' as const, diff --git a/packages/eslint-plugin/tests/rules/no-floating-promises.test.ts b/packages/eslint-plugin/tests/rules/no-floating-promises.test.ts index 070cef91e9a..8ddf9aef5b9 100644 --- a/packages/eslint-plugin/tests/rules/no-floating-promises.test.ts +++ b/packages/eslint-plugin/tests/rules/no-floating-promises.test.ts @@ -1,5 +1,7 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/no-floating-promises'; -import { getFixturesRootDir, RuleTester } from '../RuleTester'; +import { getFixturesRootDir } from '../RuleTester'; const rootDir = getFixturesRootDir(); diff --git a/packages/eslint-plugin/tests/rules/no-for-in-array.test.ts b/packages/eslint-plugin/tests/rules/no-for-in-array.test.ts index 396a12d36f9..cb0fff64e36 100644 --- a/packages/eslint-plugin/tests/rules/no-for-in-array.test.ts +++ b/packages/eslint-plugin/tests/rules/no-for-in-array.test.ts @@ -1,7 +1,8 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; import rule from '../../src/rules/no-for-in-array'; -import { getFixturesRootDir, RuleTester } from '../RuleTester'; +import { getFixturesRootDir } from '../RuleTester'; const rootDir = getFixturesRootDir(); const ruleTester = new RuleTester({ diff --git a/packages/eslint-plugin/tests/rules/no-implied-eval.test.ts b/packages/eslint-plugin/tests/rules/no-implied-eval.test.ts index af15aa75851..3b6c11c025d 100644 --- a/packages/eslint-plugin/tests/rules/no-implied-eval.test.ts +++ b/packages/eslint-plugin/tests/rules/no-implied-eval.test.ts @@ -1,5 +1,7 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/no-implied-eval'; -import { getFixturesRootDir, RuleTester } from '../RuleTester'; +import { getFixturesRootDir } from '../RuleTester'; const rootDir = getFixturesRootDir(); const ruleTester = new RuleTester({ diff --git a/packages/eslint-plugin/tests/rules/no-import-type-side-effects.test.ts b/packages/eslint-plugin/tests/rules/no-import-type-side-effects.test.ts index 98d7923e4b4..f638d22fafa 100644 --- a/packages/eslint-plugin/tests/rules/no-import-type-side-effects.test.ts +++ b/packages/eslint-plugin/tests/rules/no-import-type-side-effects.test.ts @@ -1,5 +1,6 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/no-import-type-side-effects'; -import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/no-inferrable-types.test.ts b/packages/eslint-plugin/tests/rules/no-inferrable-types.test.ts index 5a085044685..ce1b5deb277 100644 --- a/packages/eslint-plugin/tests/rules/no-inferrable-types.test.ts +++ b/packages/eslint-plugin/tests/rules/no-inferrable-types.test.ts @@ -1,3 +1,4 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; import type { TSESLint } from '@typescript-eslint/utils'; import rule from '../../src/rules/no-inferrable-types'; @@ -5,7 +6,6 @@ import type { InferMessageIdsTypeFromRule, InferOptionsTypeFromRule, } from '../../src/util'; -import { RuleTester } from '../RuleTester'; type MessageIds = InferMessageIdsTypeFromRule; type Options = InferOptionsTypeFromRule; diff --git a/packages/eslint-plugin/tests/rules/no-invalid-this.test.ts b/packages/eslint-plugin/tests/rules/no-invalid-this.test.ts index a50c01e743d..463f4f3ce9b 100644 --- a/packages/eslint-plugin/tests/rules/no-invalid-this.test.ts +++ b/packages/eslint-plugin/tests/rules/no-invalid-this.test.ts @@ -1,5 +1,6 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/no-invalid-this'; -import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/no-invalid-void-type.test.ts b/packages/eslint-plugin/tests/rules/no-invalid-void-type.test.ts index 1a972b665be..00ba6e4a51f 100644 --- a/packages/eslint-plugin/tests/rules/no-invalid-void-type.test.ts +++ b/packages/eslint-plugin/tests/rules/no-invalid-void-type.test.ts @@ -1,5 +1,6 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/no-invalid-void-type'; -import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/no-loop-func.test.ts b/packages/eslint-plugin/tests/rules/no-loop-func.test.ts index 37be3ec45d6..29ccaa62b1f 100644 --- a/packages/eslint-plugin/tests/rules/no-loop-func.test.ts +++ b/packages/eslint-plugin/tests/rules/no-loop-func.test.ts @@ -1,7 +1,7 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; import rule from '../../src/rules/no-loop-func'; -import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/no-loss-of-precision.test.ts b/packages/eslint-plugin/tests/rules/no-loss-of-precision.test.ts index cd783915b4d..9ccfa68ca4c 100644 --- a/packages/eslint-plugin/tests/rules/no-loss-of-precision.test.ts +++ b/packages/eslint-plugin/tests/rules/no-loss-of-precision.test.ts @@ -1,5 +1,6 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/no-loss-of-precision'; -import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/no-magic-numbers.test.ts b/packages/eslint-plugin/tests/rules/no-magic-numbers.test.ts index d6aa21a799e..10a4c04b42f 100644 --- a/packages/eslint-plugin/tests/rules/no-magic-numbers.test.ts +++ b/packages/eslint-plugin/tests/rules/no-magic-numbers.test.ts @@ -1,5 +1,6 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/no-magic-numbers'; -import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/no-meaningless-void-operator.test.ts b/packages/eslint-plugin/tests/rules/no-meaningless-void-operator.test.ts index 0cd71da26cb..8c961a7e4e4 100644 --- a/packages/eslint-plugin/tests/rules/no-meaningless-void-operator.test.ts +++ b/packages/eslint-plugin/tests/rules/no-meaningless-void-operator.test.ts @@ -1,5 +1,7 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/no-meaningless-void-operator'; -import { getFixturesRootDir, RuleTester } from '../RuleTester'; +import { getFixturesRootDir } from '../RuleTester'; const rootDir = getFixturesRootDir(); diff --git a/packages/eslint-plugin/tests/rules/no-misused-new.test.ts b/packages/eslint-plugin/tests/rules/no-misused-new.test.ts index 527d5d46671..4e251d7f047 100644 --- a/packages/eslint-plugin/tests/rules/no-misused-new.test.ts +++ b/packages/eslint-plugin/tests/rules/no-misused-new.test.ts @@ -1,5 +1,6 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/no-misused-new'; -import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/no-misused-promises.test.ts b/packages/eslint-plugin/tests/rules/no-misused-promises.test.ts index 3d63e093532..a6d6f1db5ad 100644 --- a/packages/eslint-plugin/tests/rules/no-misused-promises.test.ts +++ b/packages/eslint-plugin/tests/rules/no-misused-promises.test.ts @@ -1,5 +1,7 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/no-misused-promises'; -import { getFixturesRootDir, RuleTester } from '../RuleTester'; +import { getFixturesRootDir } from '../RuleTester'; const rootDir = getFixturesRootDir(); @@ -243,14 +245,22 @@ type O = { const Component = (obj: O) => null; 10} />; `, - filename: 'react.tsx', + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + }, }, { code: ` const Component: any = () => null; 10} />; `, - filename: 'react.tsx', + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + }, }, { code: ` @@ -314,7 +324,11 @@ declare function Component(props: Props): any; const _ = {}} />; `, - filename: 'react.tsx', + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + }, }, ` console.log({ ...(await Promise.resolve({ key: 42 })) }); @@ -474,7 +488,11 @@ restTuple('Hello'); ; `, - filename: 'react.tsx', + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + }, options: [{ checksVoidReturn: { attributes: true } }], }, ], @@ -931,7 +949,11 @@ type O = { const Component = (obj: O) => null; 0} />; `, - filename: 'react.tsx', + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + }, errors: [ { line: 6, @@ -947,7 +969,11 @@ type O = { const Component = (obj: O) => null; 0} />; `, - filename: 'react.tsx', + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + }, errors: [ { line: 6, @@ -965,7 +991,11 @@ const g = async () => 'foo'; const Component = (obj: O) => null; ; `, - filename: 'react.tsx', + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + }, errors: [ { line: 7, diff --git a/packages/eslint-plugin/tests/rules/no-mixed-enums.test.ts b/packages/eslint-plugin/tests/rules/no-mixed-enums.test.ts index b3aace8cc81..23ffc3568c5 100644 --- a/packages/eslint-plugin/tests/rules/no-mixed-enums.test.ts +++ b/packages/eslint-plugin/tests/rules/no-mixed-enums.test.ts @@ -1,5 +1,7 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/no-mixed-enums'; -import { getFixturesRootDir, RuleTester } from '../RuleTester'; +import { getFixturesRootDir } from '../RuleTester'; const rootDir = getFixturesRootDir(); const ruleTester = new RuleTester({ diff --git a/packages/eslint-plugin/tests/rules/no-namespace.test.ts b/packages/eslint-plugin/tests/rules/no-namespace.test.ts index 11d9d1a6fca..a981ca59b3c 100644 --- a/packages/eslint-plugin/tests/rules/no-namespace.test.ts +++ b/packages/eslint-plugin/tests/rules/no-namespace.test.ts @@ -1,5 +1,6 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/no-namespace'; -import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/no-non-null-asserted-nullish-coalescing.test.ts b/packages/eslint-plugin/tests/rules/no-non-null-asserted-nullish-coalescing.test.ts index f197593f59d..789fd1a8727 100644 --- a/packages/eslint-plugin/tests/rules/no-non-null-asserted-nullish-coalescing.test.ts +++ b/packages/eslint-plugin/tests/rules/no-non-null-asserted-nullish-coalescing.test.ts @@ -1,5 +1,6 @@ +import { noFormat, RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/no-non-null-asserted-nullish-coalescing'; -import { noFormat, RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/no-non-null-asserted-optional-chain.test.ts b/packages/eslint-plugin/tests/rules/no-non-null-asserted-optional-chain.test.ts index 399c6b73488..a9fda0210fd 100644 --- a/packages/eslint-plugin/tests/rules/no-non-null-asserted-optional-chain.test.ts +++ b/packages/eslint-plugin/tests/rules/no-non-null-asserted-optional-chain.test.ts @@ -1,5 +1,6 @@ +import { noFormat, RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/no-non-null-asserted-optional-chain'; -import { noFormat, RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/no-non-null-assertion.test.ts b/packages/eslint-plugin/tests/rules/no-non-null-assertion.test.ts index e9fae587f55..10dbb0d09c3 100644 --- a/packages/eslint-plugin/tests/rules/no-non-null-assertion.test.ts +++ b/packages/eslint-plugin/tests/rules/no-non-null-assertion.test.ts @@ -1,5 +1,6 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/no-non-null-assertion'; -import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/no-redeclare.test.ts b/packages/eslint-plugin/tests/rules/no-redeclare.test.ts index fcaf99e409d..d53c023c435 100644 --- a/packages/eslint-plugin/tests/rules/no-redeclare.test.ts +++ b/packages/eslint-plugin/tests/rules/no-redeclare.test.ts @@ -1,7 +1,7 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; import { AST_NODE_TYPES, AST_TOKEN_TYPES } from '@typescript-eslint/utils'; import rule from '../../src/rules/no-redeclare'; -import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parserOptions: { diff --git a/packages/eslint-plugin/tests/rules/no-redundant-type-constituents.test.ts b/packages/eslint-plugin/tests/rules/no-redundant-type-constituents.test.ts index 29259f4b3f0..04ee15735c4 100644 --- a/packages/eslint-plugin/tests/rules/no-redundant-type-constituents.test.ts +++ b/packages/eslint-plugin/tests/rules/no-redundant-type-constituents.test.ts @@ -1,5 +1,7 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/no-redundant-type-constituents'; -import { getFixturesRootDir, RuleTester } from '../RuleTester'; +import { getFixturesRootDir } from '../RuleTester'; const rootDir = getFixturesRootDir(); const ruleTester = new RuleTester({ diff --git a/packages/eslint-plugin/tests/rules/no-require-imports.test.ts b/packages/eslint-plugin/tests/rules/no-require-imports.test.ts index d884c77a6d6..ff6cbd2a603 100644 --- a/packages/eslint-plugin/tests/rules/no-require-imports.test.ts +++ b/packages/eslint-plugin/tests/rules/no-require-imports.test.ts @@ -1,5 +1,6 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/no-require-imports'; -import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parserOptions: { diff --git a/packages/eslint-plugin/tests/rules/no-restricted-imports.test.ts b/packages/eslint-plugin/tests/rules/no-restricted-imports.test.ts index b93c8d7e41b..1f3e4748b11 100644 --- a/packages/eslint-plugin/tests/rules/no-restricted-imports.test.ts +++ b/packages/eslint-plugin/tests/rules/no-restricted-imports.test.ts @@ -1,7 +1,7 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; import rule from '../../src/rules/no-restricted-imports'; -import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/no-shadow/no-shadow-eslint.test.ts b/packages/eslint-plugin/tests/rules/no-shadow/no-shadow-eslint.test.ts index bd4f9bfdee6..1b81df4435a 100644 --- a/packages/eslint-plugin/tests/rules/no-shadow/no-shadow-eslint.test.ts +++ b/packages/eslint-plugin/tests/rules/no-shadow/no-shadow-eslint.test.ts @@ -2,12 +2,10 @@ // Original Code: https://github.com/t-mangoe/eslint/blob/c4a70499720f48e27734068074fbeee4f48fb460/tests/lib/rules/no-shadow.js // License : https://github.com/eslint/eslint/blob/c4a70499720f48e27734068074fbeee4f48fb460/LICENSE -'use strict'; - +import { RuleTester } from '@typescript-eslint/rule-tester'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; import rule from '../../../src/rules/no-shadow'; -import { RuleTester } from '../../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/no-shadow/no-shadow.test.ts b/packages/eslint-plugin/tests/rules/no-shadow/no-shadow.test.ts index 854154ff096..ae00139d982 100644 --- a/packages/eslint-plugin/tests/rules/no-shadow/no-shadow.test.ts +++ b/packages/eslint-plugin/tests/rules/no-shadow/no-shadow.test.ts @@ -1,7 +1,7 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; import rule from '../../../src/rules/no-shadow'; -import { RuleTester } from '../../RuleTester'; const ruleTester = new RuleTester({ parserOptions: { diff --git a/packages/eslint-plugin/tests/rules/no-this-alias.test.ts b/packages/eslint-plugin/tests/rules/no-this-alias.test.ts index 942fcf810ff..6df8dbb38c7 100644 --- a/packages/eslint-plugin/tests/rules/no-this-alias.test.ts +++ b/packages/eslint-plugin/tests/rules/no-this-alias.test.ts @@ -1,7 +1,7 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; import rule from '../../src/rules/no-this-alias'; -import { RuleTester } from '../RuleTester'; const idError = { messageId: 'thisAssignment' as const, diff --git a/packages/eslint-plugin/tests/rules/no-throw-literal.test.ts b/packages/eslint-plugin/tests/rules/no-throw-literal.test.ts index a85614327cf..12373d220bc 100644 --- a/packages/eslint-plugin/tests/rules/no-throw-literal.test.ts +++ b/packages/eslint-plugin/tests/rules/no-throw-literal.test.ts @@ -1,5 +1,7 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/no-throw-literal'; -import { getFixturesRootDir, RuleTester } from '../RuleTester'; +import { getFixturesRootDir } from '../RuleTester'; const ruleTester = new RuleTester({ parserOptions: { diff --git a/packages/eslint-plugin/tests/rules/no-type-alias.test.ts b/packages/eslint-plugin/tests/rules/no-type-alias.test.ts index ed2c00c9991..12acba6dd3f 100644 --- a/packages/eslint-plugin/tests/rules/no-type-alias.test.ts +++ b/packages/eslint-plugin/tests/rules/no-type-alias.test.ts @@ -1,5 +1,6 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/no-type-alias'; -import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/no-unnecessary-boolean-literal-compare.test.ts b/packages/eslint-plugin/tests/rules/no-unnecessary-boolean-literal-compare.test.ts index 7c22e7d8d15..897f616fc57 100644 --- a/packages/eslint-plugin/tests/rules/no-unnecessary-boolean-literal-compare.test.ts +++ b/packages/eslint-plugin/tests/rules/no-unnecessary-boolean-literal-compare.test.ts @@ -1,5 +1,7 @@ +import { noFormat, RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/no-unnecessary-boolean-literal-compare'; -import { getFixturesRootDir, noFormat, RuleTester } from '../RuleTester'; +import { getFixturesRootDir } from '../RuleTester'; const rootDir = getFixturesRootDir(); const ruleTester = new RuleTester({ diff --git a/packages/eslint-plugin/tests/rules/no-unnecessary-condition.test.ts b/packages/eslint-plugin/tests/rules/no-unnecessary-condition.test.ts index 785ae3e8c1a..397d4b507cc 100644 --- a/packages/eslint-plugin/tests/rules/no-unnecessary-condition.test.ts +++ b/packages/eslint-plugin/tests/rules/no-unnecessary-condition.test.ts @@ -1,3 +1,4 @@ +import { noFormat, RuleTester } from '@typescript-eslint/rule-tester'; import type { InvalidTestCase, TestCaseError, @@ -9,7 +10,7 @@ import type { Options, } from '../../src/rules/no-unnecessary-condition'; import rule from '../../src/rules/no-unnecessary-condition'; -import { getFixturesRootDir, noFormat, RuleTester } from '../RuleTester'; +import { getFixturesRootDir } from '../RuleTester'; const rootPath = getFixturesRootDir(); diff --git a/packages/eslint-plugin/tests/rules/no-unnecessary-qualifier.test.ts b/packages/eslint-plugin/tests/rules/no-unnecessary-qualifier.test.ts index 391f84ac5da..e31a8a99ecd 100644 --- a/packages/eslint-plugin/tests/rules/no-unnecessary-qualifier.test.ts +++ b/packages/eslint-plugin/tests/rules/no-unnecessary-qualifier.test.ts @@ -1,7 +1,8 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; import rule from '../../src/rules/no-unnecessary-qualifier'; -import { getFixturesRootDir, RuleTester } from '../RuleTester'; +import { getFixturesRootDir } from '../RuleTester'; const rootPath = getFixturesRootDir(); diff --git a/packages/eslint-plugin/tests/rules/no-unnecessary-type-arguments.test.ts b/packages/eslint-plugin/tests/rules/no-unnecessary-type-arguments.test.ts index abedc24d274..162877446c6 100644 --- a/packages/eslint-plugin/tests/rules/no-unnecessary-type-arguments.test.ts +++ b/packages/eslint-plugin/tests/rules/no-unnecessary-type-arguments.test.ts @@ -1,5 +1,7 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/no-unnecessary-type-arguments'; -import { getFixturesRootDir, RuleTester } from '../RuleTester'; +import { getFixturesRootDir } from '../RuleTester'; const rootPath = getFixturesRootDir(); diff --git a/packages/eslint-plugin/tests/rules/no-unnecessary-type-assertion.test.ts b/packages/eslint-plugin/tests/rules/no-unnecessary-type-assertion.test.ts index 8b5bec5f592..8cf362938ba 100644 --- a/packages/eslint-plugin/tests/rules/no-unnecessary-type-assertion.test.ts +++ b/packages/eslint-plugin/tests/rules/no-unnecessary-type-assertion.test.ts @@ -1,7 +1,7 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; import path from 'path'; import rule from '../../src/rules/no-unnecessary-type-assertion'; -import { RuleTester } from '../RuleTester'; const rootDir = path.resolve(__dirname, '../fixtures/'); const ruleTester = new RuleTester({ @@ -153,7 +153,11 @@ function Test(props: { id?: null | string | number }) { return
; } `, - filename: 'react.tsx', + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + }, }, { code: ` @@ -488,7 +492,11 @@ function Test(props: { id?: string | number }) { line: 9, }, ], - filename: 'react.tsx', + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + }, }, { code: ` diff --git a/packages/eslint-plugin/tests/rules/no-unnecessary-type-constraint.test.ts b/packages/eslint-plugin/tests/rules/no-unnecessary-type-constraint.test.ts index 72bde5788ca..d96da6e779f 100644 --- a/packages/eslint-plugin/tests/rules/no-unnecessary-type-constraint.test.ts +++ b/packages/eslint-plugin/tests/rules/no-unnecessary-type-constraint.test.ts @@ -1,5 +1,6 @@ +import { noFormat, RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/no-unnecessary-type-constraint'; -import { noFormat, RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parserOptions: { @@ -121,7 +122,11 @@ function data() {} ], }, ], - filename: 'react.tsx', + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + }, }, { code: noFormat`const data = () => {};`, @@ -141,7 +146,11 @@ function data() {} ], }, ], - filename: 'react.tsx', + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + }, }, { code: noFormat`const data = () => {};`, @@ -161,7 +170,11 @@ function data() {} ], }, ], - filename: 'react.tsx', + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + }, }, { code: noFormat`const data = () => {};`, @@ -181,7 +194,11 @@ function data() {} ], }, ], - filename: 'react.tsx', + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + }, }, { code: noFormat`const data = () => {};`, @@ -201,7 +218,11 @@ function data() {} ], }, ], - filename: 'react.tsx', + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + }, }, { code: 'const data = () => {};', @@ -221,7 +242,11 @@ function data() {} ], }, ], - filename: 'react.tsx', + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + }, }, { code: 'const data = () => {};', @@ -255,7 +280,11 @@ function data() {} ], }, ], - filename: 'react.tsx', + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + }, }, { code: 'function data() {}', diff --git a/packages/eslint-plugin/tests/rules/no-unsafe-argument.test.ts b/packages/eslint-plugin/tests/rules/no-unsafe-argument.test.ts index 77058a563a9..3b17a756c42 100644 --- a/packages/eslint-plugin/tests/rules/no-unsafe-argument.test.ts +++ b/packages/eslint-plugin/tests/rules/no-unsafe-argument.test.ts @@ -1,5 +1,7 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/no-unsafe-argument'; -import { getFixturesRootDir, RuleTester } from '../RuleTester'; +import { getFixturesRootDir } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/no-unsafe-assignment.test.ts b/packages/eslint-plugin/tests/rules/no-unsafe-assignment.test.ts index f0d32d2ed47..27028234b31 100644 --- a/packages/eslint-plugin/tests/rules/no-unsafe-assignment.test.ts +++ b/packages/eslint-plugin/tests/rules/no-unsafe-assignment.test.ts @@ -1,3 +1,4 @@ +import { noFormat, RuleTester } from '@typescript-eslint/rule-tester'; import type { TSESLint } from '@typescript-eslint/utils'; import rule from '../../src/rules/no-unsafe-assignment'; @@ -5,12 +6,7 @@ import type { InferMessageIdsTypeFromRule, InferOptionsTypeFromRule, } from '../../src/util'; -import { - batchedSingleLineTests, - getFixturesRootDir, - noFormat, - RuleTester, -} from '../RuleTester'; +import { getFixturesRootDir } from '../RuleTester'; type Options = InferOptionsTypeFromRule; type MessageIds = InferMessageIdsTypeFromRule; @@ -123,21 +119,33 @@ type Props = { a: string }; declare function Foo(props: Props): never; ; `, - filename: 'react.tsx', + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + }, }, { code: ` declare function Foo(props: { a: string }): never; ; `, - filename: 'react.tsx', + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + }, }, { code: ` declare function Foo(props: { a: string }): never; ; `, - filename: 'react.tsx', + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + }, }, 'const x: unknown = y as any;', 'const x: unknown[] = y as any[];', @@ -146,74 +154,53 @@ declare function Foo(props: { a: string }): never; 'const x: Map = new Map();', ], invalid: [ - ...batchedSingleLineTests({ - code: noFormat` -const x = (1 as any); -const x = (1 as any), y = 1; -function foo(a = (1 as any)) {} -class Foo { constructor(private a = (1 as any)) {} } -class Foo { private a = (1 as any) } + { + code: 'const x = 1 as any;', + errors: [{ messageId: 'anyAssignment' }], + }, + { + code: ` +const x = 1 as any, + y = 1; `, - errors: [ - { - messageId: 'anyAssignment', - line: 2, - column: 7, - endColumn: 21, - }, - { - messageId: 'anyAssignment', - line: 3, - column: 7, - endColumn: 21, - }, - { - messageId: 'anyAssignment', - line: 4, - column: 14, - endColumn: 28, - }, - { - messageId: 'anyAssignment', - line: 5, - column: 33, - endColumn: 47, - }, - { - messageId: 'anyAssignment', - line: 6, - column: 13, - endColumn: 35, - }, - ], - }), - ...batchedSingleLineTests({ + errors: [{ messageId: 'anyAssignment' }], + }, + { + code: 'function foo(a = 1 as any) {}', + errors: [{ messageId: 'anyAssignment' }], + }, + { + code: ` +class Foo { + constructor(private a = 1 as any) {} +} + `, + errors: [{ messageId: 'anyAssignment' }], + }, + { + code: ` +class Foo { + private a = 1 as any; +} + `, + errors: [{ messageId: 'anyAssignment' }], + }, + + { code: ` const [x] = 1 as any; -const [x] = [] as any[]; `, - errors: [ - { - messageId: 'anyAssignment', - line: 2, - column: 7, - endColumn: 21, - }, - { - messageId: 'unsafeArrayPattern', - line: 3, - column: 7, - endColumn: 10, - }, - ], - }), - ...batchedSingleLineTests({ - code: noFormat` -const x: Set = new Set(); -const x: Map = new Map(); -const x: Set = new Set(); -const x: Set>> = new Set>>(); + errors: [{ messageId: 'anyAssignment' }], + }, + { + code: ` +const [x] = [] as any[]; `, + errors: [{ messageId: 'unsafeArrayPattern' }], + }, + + { + code: 'const x: Set = new Set();', errors: [ { messageId: 'unsafeAssignment', @@ -221,34 +208,46 @@ const x: Set>> = new Set>>(); sender: 'Set', receiver: 'Set', }, - line: 2, }, + ], + }, + { + code: 'const x: Map = new Map();', + errors: [ { messageId: 'unsafeAssignment', data: { sender: 'Map', receiver: 'Map', }, - line: 3, }, + ], + }, + { + code: 'const x: Set = new Set();', + errors: [ { messageId: 'unsafeAssignment', data: { sender: 'Set', receiver: 'Set', }, - line: 4, }, + ], + }, + { + code: 'const x: Set>> = new Set>>();', + errors: [ { messageId: 'unsafeAssignment', data: { sender: 'Set>>', receiver: 'Set>>', }, - line: 5, }, ], - }), + }, + ...assignmentTest([ ['[x] = [1] as [any]', 2, 3], ['[[[[x]]]] = [[[[1 as any]]]]', 5, 6], @@ -269,55 +268,52 @@ const x: Set>> = new Set>>(); }, ], }, - ...batchedSingleLineTests({ + + { code: ` const x = [...(1 as any)]; + `, + errors: [{ messageId: 'unsafeArraySpread' }], + }, + { + code: ` const x = [...([] as any[])]; `, - errors: [ - { - messageId: 'unsafeArraySpread', - line: 2, - column: 12, - endColumn: 25, - }, - { - messageId: 'unsafeArraySpread', - line: 3, - column: 12, - endColumn: 28, - }, - ], - }), + errors: [{ messageId: 'unsafeArraySpread' }], + }, + ...assignmentTest([ ['{x} = {x: 1} as {x: any}', 2, 3], ['{x: y} = {x: 1} as {x: any}', 5, 6], ['{x: {y}} = {x: {y: 1}} as {x: {y: any}}', 6, 7], ['{x: [y]} = {x: {y: 1}} as {x: [any]}', 6, 7], ]), - ...batchedSingleLineTests({ - code: ` -const x = { y: 1 as any }; -const x = { y: { z: 1 as any } }; -const x: { y: Set>> } = { y: new Set>>() }; -const x = { ...(1 as any) }; - `, + + { + code: 'const x = { y: 1 as any };', errors: [ { messageId: 'anyAssignment', - line: 2, column: 13, endColumn: 24, }, + ], + }, + { + code: 'const x = { y: { z: 1 as any } };', + errors: [ { messageId: 'anyAssignment', - line: 3, column: 18, endColumn: 29, }, + ], + }, + { + code: 'const x: { y: Set>> } = { y: new Set>>() };', + errors: [ { messageId: 'unsafeAssignment', - line: 4, column: 43, endColumn: 70, data: { @@ -325,22 +321,31 @@ const x = { ...(1 as any) }; receiver: 'Set>>', }, }, + ], + }, + { + code: 'const x = { ...(1 as any) };', + errors: [ { // spreading an any widens the object type to any messageId: 'anyAssignment', - line: 5, column: 7, endColumn: 28, }, ], - }), + }, + { code: ` type Props = { a: string }; declare function Foo(props: Props): never; ; `, - filename: 'react.tsx', + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + }, errors: [ { messageId: 'anyAssignment', diff --git a/packages/eslint-plugin/tests/rules/no-unsafe-call.test.ts b/packages/eslint-plugin/tests/rules/no-unsafe-call.test.ts index db71189a697..b91b2ec6273 100644 --- a/packages/eslint-plugin/tests/rules/no-unsafe-call.test.ts +++ b/packages/eslint-plugin/tests/rules/no-unsafe-call.test.ts @@ -1,10 +1,7 @@ +import { noFormat, RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/no-unsafe-call'; -import { - batchedSingleLineTests, - getFixturesRootDir, - noFormat, - RuleTester, -} from '../RuleTester'; +import { getFixturesRootDir } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', @@ -47,107 +44,95 @@ function foo(x: { a?: () => void }) { `, ], invalid: [ - ...batchedSingleLineTests({ - code: noFormat` -function foo(x: any) { x() } -function foo(x: any) { x?.() } -function foo(x: any) { x.a.b.c.d.e.f.g() } -function foo(x: any) { x.a.b.c.d.e.f.g?.() } + { + code: ` +function foo(x: any) { + x(); +} `, - errors: [ - { - messageId: 'unsafeCall', - line: 2, - column: 24, - endColumn: 25, - }, - { - messageId: 'unsafeCall', - line: 3, - column: 24, - endColumn: 25, - }, - { - messageId: 'unsafeCall', - line: 4, - column: 24, - endColumn: 39, - }, - { - messageId: 'unsafeCall', - line: 5, - column: 24, - endColumn: 39, - }, - ], - }), - ...batchedSingleLineTests({ - code: noFormat` -function foo(x: { a: any }) { x.a() } -function foo(x: { a: any }) { x?.a() } -function foo(x: { a: any }) { x.a?.() } + errors: [{ messageId: 'unsafeCall' }], + }, + { + code: ` +function foo(x: any) { + x?.(); +} `, - errors: [ - { - messageId: 'unsafeCall', - line: 2, - column: 31, - endColumn: 34, - }, - { - messageId: 'unsafeCall', - line: 3, - column: 31, - endColumn: 35, - }, - { - messageId: 'unsafeCall', - line: 4, - column: 31, - endColumn: 34, - }, - ], - }), - ...batchedSingleLineTests({ - code: noFormat` -function foo(x: any) { new x() } -function foo(x: { a: any }) { new x.a() } + errors: [{ messageId: 'unsafeCall' }], + }, + { + code: ` +function foo(x: any) { + x.a.b.c.d.e.f.g(); +} `, - errors: [ - { - messageId: 'unsafeNew', - line: 2, - column: 24, - endColumn: 31, - }, - { - messageId: 'unsafeNew', - line: 3, - column: 31, - endColumn: 40, - }, - ], - }), - ...batchedSingleLineTests({ - code: noFormat` -function foo(x: any) { x\`foo\` } -function foo(x: { tag: any }) { x.tag\`foo\` } + errors: [{ messageId: 'unsafeCall' }], + }, + { + code: ` +function foo(x: any) { + x.a.b.c.d.e.f.g?.(); +} `, - errors: [ - { - messageId: 'unsafeTemplateTag', - line: 2, - column: 24, - endColumn: 25, - }, - { - messageId: 'unsafeTemplateTag', - line: 3, - column: 33, - endColumn: 38, - }, - ], - }), + errors: [{ messageId: 'unsafeCall' }], + }, + { + code: ` +function foo(x: { a: any }) { + x.a(); +} + `, + errors: [{ messageId: 'unsafeCall' }], + }, + { + code: ` +function foo(x: { a: any }) { + x?.a(); +} + `, + errors: [{ messageId: 'unsafeCall' }], + }, + { + code: ` +function foo(x: { a: any }) { + x.a?.(); +} + `, + errors: [{ messageId: 'unsafeCall' }], + }, + { + code: ` +function foo(x: any) { + new x(); +} + `, + errors: [{ messageId: 'unsafeNew' }], + }, + { + code: ` +function foo(x: { a: any }) { + new x.a(); +} + `, + errors: [{ messageId: 'unsafeNew' }], + }, + { + code: ` +function foo(x: any) { + x\`foo\`; +} + `, + errors: [{ messageId: 'unsafeTemplateTag' }], + }, + { + code: ` +function foo(x: { tag: any }) { + x.tag\`foo\`; +} + `, + errors: [{ messageId: 'unsafeTemplateTag' }], + }, + { code: noFormat` const methods = { diff --git a/packages/eslint-plugin/tests/rules/no-unsafe-declaration-merging.test.ts b/packages/eslint-plugin/tests/rules/no-unsafe-declaration-merging.test.ts index 1feabbe8158..82be9996f20 100644 --- a/packages/eslint-plugin/tests/rules/no-unsafe-declaration-merging.test.ts +++ b/packages/eslint-plugin/tests/rules/no-unsafe-declaration-merging.test.ts @@ -1,5 +1,7 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/no-unsafe-declaration-merging'; -import { getFixturesRootDir, RuleTester } from '../RuleTester'; +import { getFixturesRootDir } from '../RuleTester'; const rootPath = getFixturesRootDir(); diff --git a/packages/eslint-plugin/tests/rules/no-unsafe-enum-comparison.test.ts b/packages/eslint-plugin/tests/rules/no-unsafe-enum-comparison.test.ts index 5e84c983076..adb3630354e 100644 --- a/packages/eslint-plugin/tests/rules/no-unsafe-enum-comparison.test.ts +++ b/packages/eslint-plugin/tests/rules/no-unsafe-enum-comparison.test.ts @@ -1,5 +1,7 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/no-unsafe-enum-comparison'; -import { getFixturesRootDir, RuleTester } from '../RuleTester'; +import { getFixturesRootDir } from '../RuleTester'; const rootDir = getFixturesRootDir(); diff --git a/packages/eslint-plugin/tests/rules/no-unsafe-member-access.test.ts b/packages/eslint-plugin/tests/rules/no-unsafe-member-access.test.ts index 5ab598c3a5a..b66b96d4663 100644 --- a/packages/eslint-plugin/tests/rules/no-unsafe-member-access.test.ts +++ b/packages/eslint-plugin/tests/rules/no-unsafe-member-access.test.ts @@ -1,10 +1,7 @@ +import { noFormat, RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/no-unsafe-member-access'; -import { - batchedSingleLineTests, - getFixturesRootDir, - noFormat, - RuleTester, -} from '../RuleTester'; +import { getFixturesRootDir } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', @@ -74,11 +71,11 @@ interface B extends FG.A {} `, ], invalid: [ - ...batchedSingleLineTests({ - code: noFormat` -function foo(x: any) { x.a } -function foo(x: any) { x.a.b.c.d.e.f.g } -function foo(x: { a: any }) { x.a.b.c.d.e.f.g } + { + code: ` +function foo(x: any) { + x.a; +} `, errors: [ { @@ -86,34 +83,44 @@ function foo(x: { a: any }) { x.a.b.c.d.e.f.g } data: { property: '.a', }, - line: 2, - column: 24, - endColumn: 27, }, + ], + }, + { + code: ` +function foo(x: any) { + x.a.b.c.d.e.f.g; +} + `, + errors: [ { messageId: 'unsafeMemberExpression', data: { property: '.a', }, - line: 3, - column: 24, - endColumn: 27, }, + ], + }, + { + code: ` +function foo(x: { a: any }) { + x.a.b.c.d.e.f.g; +} + `, + errors: [ { messageId: 'unsafeMemberExpression', data: { property: '.b', }, - line: 4, - column: 31, - endColumn: 36, }, ], - }), - ...batchedSingleLineTests({ - code: noFormat` -function foo(x: any) { x['a'] } -function foo(x: any) { x['a']['b']['c'] } + }, + { + code: ` +function foo(x: any) { + x['a']; +} `, errors: [ { @@ -121,29 +128,29 @@ function foo(x: any) { x['a']['b']['c'] } data: { property: "['a']", }, - line: 2, - column: 24, - endColumn: 30, }, + ], + }, + { + code: ` +function foo(x: any) { + x['a']['b']['c']; +} + `, + errors: [ { messageId: 'unsafeMemberExpression', data: { property: "['a']", }, - line: 3, - column: 24, - endColumn: 30, }, ], - }), - ...batchedSingleLineTests({ - code: noFormat` -function foo(x: { a: number }, y: any) { x[y] } -function foo(x?: { a: number }, y: any) { x?.[y] } -function foo(x: { a: number }, y: any) { x[y += 1] } -function foo(x: { a: number }, y: any) { x[1 as any] } -function foo(x: { a: number }, y: any) { x[y()] } -function foo(x: string[], y: any) { x[y] } + }, + { + code: ` +function foo(x: { a: number }, y: any) { + x[y]; +} `, errors: [ { @@ -151,57 +158,85 @@ function foo(x: string[], y: any) { x[y] } data: { property: '[y]', }, - line: 2, - column: 44, - endColumn: 45, }, + ], + }, + { + code: ` +function foo(x?: { a: number }, y: any) { + x?.[y]; +} + `, + errors: [ { messageId: 'unsafeComputedMemberAccess', data: { property: '[y]', }, - line: 3, - column: 47, - endColumn: 48, }, + ], + }, + { + code: ` +function foo(x: { a: number }, y: any) { + x[(y += 1)]; +} + `, + errors: [ { messageId: 'unsafeComputedMemberAccess', data: { property: '[y += 1]', }, - line: 4, - column: 44, - endColumn: 50, }, + ], + }, + { + code: ` +function foo(x: { a: number }, y: any) { + x[1 as any]; +} + `, + errors: [ { messageId: 'unsafeComputedMemberAccess', data: { property: '[1 as any]', }, - line: 5, - column: 44, - endColumn: 52, }, + ], + }, + { + code: ` +function foo(x: { a: number }, y: any) { + x[y()]; +} + `, + errors: [ { messageId: 'unsafeComputedMemberAccess', data: { property: '[y()]', }, - line: 6, - column: 44, - endColumn: 47, }, + ], + }, + { + code: ` +function foo(x: string[], y: any) { + x[y]; +} + `, + errors: [ { messageId: 'unsafeComputedMemberAccess', data: { property: '[y]', }, - line: 7, - column: 39, - endColumn: 40, }, ], - }), + }, + { code: noFormat` const methods = { diff --git a/packages/eslint-plugin/tests/rules/no-unsafe-return.test.ts b/packages/eslint-plugin/tests/rules/no-unsafe-return.test.ts index 47ec9701a77..f0cbd8b2535 100644 --- a/packages/eslint-plugin/tests/rules/no-unsafe-return.test.ts +++ b/packages/eslint-plugin/tests/rules/no-unsafe-return.test.ts @@ -1,10 +1,7 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/no-unsafe-return'; -import { - batchedSingleLineTests, - getFixturesRootDir, - noFormat, - RuleTester, -} from '../RuleTester'; +import { getFixturesRootDir } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', @@ -112,12 +109,11 @@ function foo(): Set { `, ], invalid: [ - ...batchedSingleLineTests({ - code: noFormat` -function foo() { return (1 as any); } -function foo() { return Object.create(null); } -const foo = () => { return (1 as any) }; -const foo = () => Object.create(null); + { + code: ` +function foo() { + return 1 as any; +} `, errors: [ { @@ -125,43 +121,55 @@ const foo = () => Object.create(null); data: { type: 'any', }, - line: 2, - column: 18, }, + ], + }, + { + code: ` +function foo() { + return Object.create(null); +} + `, + errors: [ { messageId: 'unsafeReturn', data: { type: 'any', }, - line: 3, - column: 18, }, + ], + }, + { + code: ` +const foo = () => { + return 1 as any; +}; + `, + errors: [ { messageId: 'unsafeReturn', data: { type: 'any', }, - line: 4, - column: 21, }, + ], + }, + { + code: 'const foo = () => Object.create(null);', + errors: [ { messageId: 'unsafeReturn', data: { type: 'any', }, - line: 5, - column: 19, }, ], - }), - ...batchedSingleLineTests({ - code: noFormat` -function foo() { return ([] as any[]); } -function foo() { return ([] as Array); } -function foo() { return ([] as readonly any[]); } -function foo() { return ([] as Readonly); } -const foo = () => { return ([] as any[]) }; -const foo = () => ([] as any[]); + }, + { + code: ` +function foo() { + return [] as any[]; +} `, errors: [ { @@ -169,57 +177,85 @@ const foo = () => ([] as any[]); data: { type: 'any[]', }, - line: 2, - column: 18, }, + ], + }, + { + code: ` +function foo() { + return [] as Array; +} + `, + errors: [ { messageId: 'unsafeReturn', data: { type: 'any[]', }, - line: 3, - column: 18, }, + ], + }, + { + code: ` +function foo() { + return [] as readonly any[]; +} + `, + errors: [ { messageId: 'unsafeReturn', data: { type: 'any[]', }, - line: 4, - column: 18, }, + ], + }, + { + code: ` +function foo() { + return [] as Readonly; +} + `, + errors: [ { messageId: 'unsafeReturn', data: { type: 'any[]', }, - line: 5, - column: 18, }, + ], + }, + { + code: ` +const foo = () => { + return [] as any[]; +}; + `, + errors: [ { messageId: 'unsafeReturn', data: { type: 'any[]', }, - line: 6, - column: 21, }, + ], + }, + { + code: 'const foo = () => [] as any[];', + errors: [ { messageId: 'unsafeReturn', data: { type: 'any[]', }, - line: 7, - column: 20, }, ], - }), - ...batchedSingleLineTests({ - code: noFormat` -function foo(): Set { return new Set(); } -function foo(): Map { return new Map(); } -function foo(): Set { return new Set(); } -function foo(): Set>> { return new Set>>(); } + }, + { + code: ` +function foo(): Set { + return new Set(); +} `, errors: [ { @@ -228,34 +264,58 @@ function foo(): Set>> { return new Set>>(); } sender: 'Set', receiver: 'Set', }, - line: 2, }, + ], + }, + { + code: ` +function foo(): Map { + return new Map(); +} + `, + errors: [ { messageId: 'unsafeReturnAssignment', data: { sender: 'Map', receiver: 'Map', }, - line: 3, }, + ], + }, + { + code: ` +function foo(): Set { + return new Set(); +} + `, + errors: [ { messageId: 'unsafeReturnAssignment', data: { sender: 'Set', receiver: 'Set', }, - line: 4, }, + ], + }, + { + code: ` +function foo(): Set>> { + return new Set>>(); +} + `, + errors: [ { messageId: 'unsafeReturnAssignment', data: { sender: 'Set>>', receiver: 'Set>>', }, - line: 5, }, ], - }), + }, + { code: ` type Fn = () => Set; diff --git a/packages/eslint-plugin/tests/rules/no-unused-expressions.test.ts b/packages/eslint-plugin/tests/rules/no-unused-expressions.test.ts index 36a0adda0dc..1160917f6ed 100644 --- a/packages/eslint-plugin/tests/rules/no-unused-expressions.test.ts +++ b/packages/eslint-plugin/tests/rules/no-unused-expressions.test.ts @@ -1,7 +1,7 @@ +import { noFormat, RuleTester } from '@typescript-eslint/rule-tester'; import type { TSESLint } from '@typescript-eslint/utils'; import rule from '../../src/rules/no-unused-expressions'; -import { noFormat, RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parserOptions: { diff --git a/packages/eslint-plugin/tests/rules/no-unused-vars/no-unused-vars-eslint.test.ts b/packages/eslint-plugin/tests/rules/no-unused-vars/no-unused-vars-eslint.test.ts index 38438bceb6f..06300a7821c 100644 --- a/packages/eslint-plugin/tests/rules/no-unused-vars/no-unused-vars-eslint.test.ts +++ b/packages/eslint-plugin/tests/rules/no-unused-vars/no-unused-vars-eslint.test.ts @@ -2,14 +2,12 @@ // Original Code: https://github.com/eslint/eslint/blob/0cb81a9b90dd6b92bac383022f886e501bd2cb31/tests/lib/rules/no-unused-vars.js // License : https://github.com/eslint/eslint/blob/0cb81a9b90dd6b92bac383022f886e501bd2cb31/LICENSE -'use strict'; - +import { RuleTester } from '@typescript-eslint/rule-tester'; import type { TSESLint } from '@typescript-eslint/utils'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; import type { MessageIds } from '../../../src/rules/no-unused-vars'; import rule from '../../../src/rules/no-unused-vars'; -import { RuleTester } from '../../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/no-unused-vars/no-unused-vars.test.ts b/packages/eslint-plugin/tests/rules/no-unused-vars/no-unused-vars.test.ts index ee2191a3f4c..22a03ae8489 100644 --- a/packages/eslint-plugin/tests/rules/no-unused-vars/no-unused-vars.test.ts +++ b/packages/eslint-plugin/tests/rules/no-unused-vars/no-unused-vars.test.ts @@ -1,6 +1,8 @@ +import { noFormat, RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../../src/rules/no-unused-vars'; import { collectUnusedVariables } from '../../../src/util'; -import { getFixturesRootDir, noFormat, RuleTester } from '../../RuleTester'; +import { getFixturesRootDir } from '../../RuleTester'; const ruleTester = new RuleTester({ parserOptions: { @@ -587,7 +589,6 @@ export interface Bar extends foo.i18n {} `, { // https://github.com/typescript-eslint/typescript-eslint/issues/141 - filename: 'test.tsx', code: ` import { TypeA } from './interface'; export const a = />; @@ -600,7 +601,6 @@ export const a = />; }, { // https://github.com/typescript-eslint/typescript-eslint/issues/160 - filename: 'test.tsx', code: ` const text = 'text'; export function Foo() { @@ -611,6 +611,11 @@ export function Foo() { ); } `, + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + }, }, // https://github.com/eslint/typescript-eslint-parser/issues/535 ` diff --git a/packages/eslint-plugin/tests/rules/no-use-before-define.test.ts b/packages/eslint-plugin/tests/rules/no-use-before-define.test.ts index 465cf69168e..44ce43101e7 100644 --- a/packages/eslint-plugin/tests/rules/no-use-before-define.test.ts +++ b/packages/eslint-plugin/tests/rules/no-use-before-define.test.ts @@ -1,7 +1,7 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; import rule from '../../src/rules/no-use-before-define'; -import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/no-useless-constructor.test.ts b/packages/eslint-plugin/tests/rules/no-useless-constructor.test.ts index 5301a2e930e..a68ee56fb8f 100644 --- a/packages/eslint-plugin/tests/rules/no-useless-constructor.test.ts +++ b/packages/eslint-plugin/tests/rules/no-useless-constructor.test.ts @@ -1,7 +1,7 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; import rule from '../../src/rules/no-useless-constructor'; -import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parserOptions: { diff --git a/packages/eslint-plugin/tests/rules/no-useless-empty-export.test.ts b/packages/eslint-plugin/tests/rules/no-useless-empty-export.test.ts index ea13395ec9e..6ed201033bb 100644 --- a/packages/eslint-plugin/tests/rules/no-useless-empty-export.test.ts +++ b/packages/eslint-plugin/tests/rules/no-useless-empty-export.test.ts @@ -2,8 +2,9 @@ // this rule tests the spacing, which prettier will want to fix and break the tests /* eslint "@typescript-eslint/internal/plugin-test-formatting": ["error", { formatWithPrettier: false }] */ /* eslint-enable eslint-comments/no-use */ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/no-useless-empty-export'; -import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parserOptions: { diff --git a/packages/eslint-plugin/tests/rules/no-var-requires.test.ts b/packages/eslint-plugin/tests/rules/no-var-requires.test.ts index 1e38c482218..14ce5110994 100644 --- a/packages/eslint-plugin/tests/rules/no-var-requires.test.ts +++ b/packages/eslint-plugin/tests/rules/no-var-requires.test.ts @@ -1,5 +1,6 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/no-var-requires'; -import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/non-nullable-type-assertion-style.test.ts b/packages/eslint-plugin/tests/rules/non-nullable-type-assertion-style.test.ts index 6826230b4fd..2f5d7163de3 100644 --- a/packages/eslint-plugin/tests/rules/non-nullable-type-assertion-style.test.ts +++ b/packages/eslint-plugin/tests/rules/non-nullable-type-assertion-style.test.ts @@ -1,5 +1,7 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/non-nullable-type-assertion-style'; -import { getFixturesRootDir, RuleTester } from '../RuleTester'; +import { getFixturesRootDir } from '../RuleTester'; const ruleTester = new RuleTester({ parserOptions: { diff --git a/packages/eslint-plugin/tests/rules/object-curly-spacing.test.ts b/packages/eslint-plugin/tests/rules/object-curly-spacing.test.ts index 49861e5229a..df37213121c 100644 --- a/packages/eslint-plugin/tests/rules/object-curly-spacing.test.ts +++ b/packages/eslint-plugin/tests/rules/object-curly-spacing.test.ts @@ -3,10 +3,10 @@ /* eslint "@typescript-eslint/internal/plugin-test-formatting": ["error", { formatWithPrettier: false }] */ /* eslint-enable eslint-comments/no-use */ +import { RuleTester } from '@typescript-eslint/rule-tester'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; import rule from '../../src/rules/object-curly-spacing'; -import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/padding-line-between-statements.test.ts b/packages/eslint-plugin/tests/rules/padding-line-between-statements.test.ts index 93b01ce6f33..335abb3710b 100644 --- a/packages/eslint-plugin/tests/rules/padding-line-between-statements.test.ts +++ b/packages/eslint-plugin/tests/rules/padding-line-between-statements.test.ts @@ -3,8 +3,9 @@ /* eslint "@typescript-eslint/internal/plugin-test-formatting": ["error", { formatWithPrettier: false }] */ /* eslint-enable eslint-comments/no-use */ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/padding-line-between-statements'; -import { RuleTester } from '../RuleTester'; //------------------------------------------------------------------------------ // Tests diff --git a/packages/eslint-plugin/tests/rules/parameter-properties.test.ts b/packages/eslint-plugin/tests/rules/parameter-properties.test.ts index 237f277a31e..6a60e06ee89 100644 --- a/packages/eslint-plugin/tests/rules/parameter-properties.test.ts +++ b/packages/eslint-plugin/tests/rules/parameter-properties.test.ts @@ -1,5 +1,6 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/parameter-properties'; -import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/prefer-as-const.test.ts b/packages/eslint-plugin/tests/rules/prefer-as-const.test.ts index f4e2f46d998..19058d692b4 100644 --- a/packages/eslint-plugin/tests/rules/prefer-as-const.test.ts +++ b/packages/eslint-plugin/tests/rules/prefer-as-const.test.ts @@ -1,5 +1,6 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/prefer-as-const'; -import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/prefer-enum-initializers.test.ts b/packages/eslint-plugin/tests/rules/prefer-enum-initializers.test.ts index adfdd065bb8..7e64015641f 100644 --- a/packages/eslint-plugin/tests/rules/prefer-enum-initializers.test.ts +++ b/packages/eslint-plugin/tests/rules/prefer-enum-initializers.test.ts @@ -1,5 +1,6 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/prefer-enum-initializers'; -import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/prefer-for-of.test.ts b/packages/eslint-plugin/tests/rules/prefer-for-of.test.ts index 8e59de6bce9..a370ee57a78 100644 --- a/packages/eslint-plugin/tests/rules/prefer-for-of.test.ts +++ b/packages/eslint-plugin/tests/rules/prefer-for-of.test.ts @@ -1,5 +1,6 @@ +import { noFormat, RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/prefer-for-of'; -import { noFormat, RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/prefer-function-type.test.ts b/packages/eslint-plugin/tests/rules/prefer-function-type.test.ts index 5c65dfc4d2b..0788f415cda 100644 --- a/packages/eslint-plugin/tests/rules/prefer-function-type.test.ts +++ b/packages/eslint-plugin/tests/rules/prefer-function-type.test.ts @@ -1,7 +1,7 @@ +import { noFormat, RuleTester } from '@typescript-eslint/rule-tester'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; import rule, { phrases } from '../../src/rules/prefer-function-type'; -import { noFormat, RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parserOptions: { diff --git a/packages/eslint-plugin/tests/rules/prefer-includes.test.ts b/packages/eslint-plugin/tests/rules/prefer-includes.test.ts index 6b37be5c59f..432bea9ce34 100644 --- a/packages/eslint-plugin/tests/rules/prefer-includes.test.ts +++ b/packages/eslint-plugin/tests/rules/prefer-includes.test.ts @@ -1,5 +1,7 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/prefer-includes'; -import { getFixturesRootDir, RuleTester } from '../RuleTester'; +import { getFixturesRootDir } from '../RuleTester'; const rootPath = getFixturesRootDir(); diff --git a/packages/eslint-plugin/tests/rules/prefer-literal-enum-member.test.ts b/packages/eslint-plugin/tests/rules/prefer-literal-enum-member.test.ts index c0e3aec4e8e..4b1f1e49f2c 100644 --- a/packages/eslint-plugin/tests/rules/prefer-literal-enum-member.test.ts +++ b/packages/eslint-plugin/tests/rules/prefer-literal-enum-member.test.ts @@ -1,5 +1,6 @@ +import { noFormat, RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/prefer-literal-enum-member'; -import { noFormat, RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/prefer-namespace-keyword.test.ts b/packages/eslint-plugin/tests/rules/prefer-namespace-keyword.test.ts index b512cea6757..34fc80b2ef7 100644 --- a/packages/eslint-plugin/tests/rules/prefer-namespace-keyword.test.ts +++ b/packages/eslint-plugin/tests/rules/prefer-namespace-keyword.test.ts @@ -1,5 +1,6 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/prefer-namespace-keyword'; -import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/prefer-nullish-coalescing.test.ts b/packages/eslint-plugin/tests/rules/prefer-nullish-coalescing.test.ts index 1ec4ec762d4..f75d958468e 100644 --- a/packages/eslint-plugin/tests/rules/prefer-nullish-coalescing.test.ts +++ b/packages/eslint-plugin/tests/rules/prefer-nullish-coalescing.test.ts @@ -1,3 +1,4 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; import type { TSESLint } from '@typescript-eslint/utils'; import * as path from 'path'; @@ -6,7 +7,7 @@ import type { Options, } from '../../src/rules/prefer-nullish-coalescing'; import rule from '../../src/rules/prefer-nullish-coalescing'; -import { getFixturesRootDir, RuleTester } from '../RuleTester'; +import { getFixturesRootDir } from '../RuleTester'; const rootPath = getFixturesRootDir(); diff --git a/packages/eslint-plugin/tests/rules/prefer-optional-chain/prefer-optional-chain.test.ts b/packages/eslint-plugin/tests/rules/prefer-optional-chain/prefer-optional-chain.test.ts index a18de12bf7b..3a2c6cd8d45 100644 --- a/packages/eslint-plugin/tests/rules/prefer-optional-chain/prefer-optional-chain.test.ts +++ b/packages/eslint-plugin/tests/rules/prefer-optional-chain/prefer-optional-chain.test.ts @@ -1,5 +1,6 @@ +import { noFormat, RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../../src/rules/prefer-optional-chain'; -import { noFormat, RuleTester } from '../../RuleTester'; import * as BaseCases from './base-cases'; const ruleTester = new RuleTester({ diff --git a/packages/eslint-plugin/tests/rules/prefer-readonly-parameter-types.test.ts b/packages/eslint-plugin/tests/rules/prefer-readonly-parameter-types.test.ts index 6d6a353c623..d392a5232fd 100644 --- a/packages/eslint-plugin/tests/rules/prefer-readonly-parameter-types.test.ts +++ b/packages/eslint-plugin/tests/rules/prefer-readonly-parameter-types.test.ts @@ -1,3 +1,4 @@ +import { noFormat, RuleTester } from '@typescript-eslint/rule-tester'; import type { TSESLint } from '@typescript-eslint/utils'; import rule from '../../src/rules/prefer-readonly-parameter-types'; @@ -6,7 +7,7 @@ import type { InferOptionsTypeFromRule, } from '../../src/util'; import { readonlynessOptionsDefaults } from '../../src/util'; -import { getFixturesRootDir, noFormat, RuleTester } from '../RuleTester'; +import { getFixturesRootDir } from '../RuleTester'; type MessageIds = InferMessageIdsTypeFromRule; type Options = InferOptionsTypeFromRule; diff --git a/packages/eslint-plugin/tests/rules/prefer-readonly.test.ts b/packages/eslint-plugin/tests/rules/prefer-readonly.test.ts index 10f2e3d1e07..f1b57419adc 100644 --- a/packages/eslint-plugin/tests/rules/prefer-readonly.test.ts +++ b/packages/eslint-plugin/tests/rules/prefer-readonly.test.ts @@ -1,5 +1,7 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/prefer-readonly'; -import { getFixturesRootDir, RuleTester } from '../RuleTester'; +import { getFixturesRootDir } from '../RuleTester'; const rootDir = getFixturesRootDir(); const ruleTester = new RuleTester({ diff --git a/packages/eslint-plugin/tests/rules/prefer-reduce-type-parameter.test.ts b/packages/eslint-plugin/tests/rules/prefer-reduce-type-parameter.test.ts index 5e7fae0bfea..43aadcec074 100644 --- a/packages/eslint-plugin/tests/rules/prefer-reduce-type-parameter.test.ts +++ b/packages/eslint-plugin/tests/rules/prefer-reduce-type-parameter.test.ts @@ -1,5 +1,7 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/prefer-reduce-type-parameter'; -import { getFixturesRootDir, RuleTester } from '../RuleTester'; +import { getFixturesRootDir } from '../RuleTester'; const rootPath = getFixturesRootDir(); diff --git a/packages/eslint-plugin/tests/rules/prefer-regexp-exec.test.ts b/packages/eslint-plugin/tests/rules/prefer-regexp-exec.test.ts index 46f192ab0ca..dca08379827 100644 --- a/packages/eslint-plugin/tests/rules/prefer-regexp-exec.test.ts +++ b/packages/eslint-plugin/tests/rules/prefer-regexp-exec.test.ts @@ -1,5 +1,7 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/prefer-regexp-exec'; -import { getFixturesRootDir, RuleTester } from '../RuleTester'; +import { getFixturesRootDir } from '../RuleTester'; const rootPath = getFixturesRootDir(); diff --git a/packages/eslint-plugin/tests/rules/prefer-return-this-type.test.ts b/packages/eslint-plugin/tests/rules/prefer-return-this-type.test.ts index a93590dfec0..bc571b26cc2 100644 --- a/packages/eslint-plugin/tests/rules/prefer-return-this-type.test.ts +++ b/packages/eslint-plugin/tests/rules/prefer-return-this-type.test.ts @@ -1,5 +1,7 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/prefer-return-this-type'; -import { getFixturesRootDir, RuleTester } from '../RuleTester'; +import { getFixturesRootDir } from '../RuleTester'; const rootPath = getFixturesRootDir(); diff --git a/packages/eslint-plugin/tests/rules/prefer-string-starts-ends-with.test.ts b/packages/eslint-plugin/tests/rules/prefer-string-starts-ends-with.test.ts index c9fe331c99d..1440a6521fd 100644 --- a/packages/eslint-plugin/tests/rules/prefer-string-starts-ends-with.test.ts +++ b/packages/eslint-plugin/tests/rules/prefer-string-starts-ends-with.test.ts @@ -1,7 +1,8 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; import type { TSESLint } from '@typescript-eslint/utils'; import rule from '../../src/rules/prefer-string-starts-ends-with'; -import { getFixturesRootDir, RuleTester } from '../RuleTester'; +import { getFixturesRootDir } from '../RuleTester'; const rootPath = getFixturesRootDir(); diff --git a/packages/eslint-plugin/tests/rules/prefer-ts-expect-error.test.ts b/packages/eslint-plugin/tests/rules/prefer-ts-expect-error.test.ts index ccc510187d9..7937dc3fc6e 100644 --- a/packages/eslint-plugin/tests/rules/prefer-ts-expect-error.test.ts +++ b/packages/eslint-plugin/tests/rules/prefer-ts-expect-error.test.ts @@ -1,5 +1,6 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/prefer-ts-expect-error'; -import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/promise-function-async.test.ts b/packages/eslint-plugin/tests/rules/promise-function-async.test.ts index 0f084d5d78f..83f0bf6107a 100644 --- a/packages/eslint-plugin/tests/rules/promise-function-async.test.ts +++ b/packages/eslint-plugin/tests/rules/promise-function-async.test.ts @@ -1,5 +1,7 @@ +import { noFormat, RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/promise-function-async'; -import { getFixturesRootDir, noFormat, RuleTester } from '../RuleTester'; +import { getFixturesRootDir } from '../RuleTester'; const rootDir = getFixturesRootDir(); const messageId = 'missingAsync'; diff --git a/packages/eslint-plugin/tests/rules/quotes.test.ts b/packages/eslint-plugin/tests/rules/quotes.test.ts index 003d4fd19d7..9d32ad3cd8c 100644 --- a/packages/eslint-plugin/tests/rules/quotes.test.ts +++ b/packages/eslint-plugin/tests/rules/quotes.test.ts @@ -3,8 +3,9 @@ /* eslint "@typescript-eslint/internal/plugin-test-formatting": ["error", { formatWithPrettier: false }] */ /* eslint-enable eslint-comments/no-use */ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/quotes'; -import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/require-array-sort-compare.test.ts b/packages/eslint-plugin/tests/rules/require-array-sort-compare.test.ts index 672ff4e7c10..99326816468 100644 --- a/packages/eslint-plugin/tests/rules/require-array-sort-compare.test.ts +++ b/packages/eslint-plugin/tests/rules/require-array-sort-compare.test.ts @@ -1,5 +1,7 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/require-array-sort-compare'; -import { getFixturesRootDir, RuleTester } from '../RuleTester'; +import { getFixturesRootDir } from '../RuleTester'; const rootPath = getFixturesRootDir(); diff --git a/packages/eslint-plugin/tests/rules/require-await.test.ts b/packages/eslint-plugin/tests/rules/require-await.test.ts index 6cd40be6deb..6e36dcf10c2 100644 --- a/packages/eslint-plugin/tests/rules/require-await.test.ts +++ b/packages/eslint-plugin/tests/rules/require-await.test.ts @@ -1,5 +1,7 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/require-await'; -import { getFixturesRootDir, RuleTester } from '../RuleTester'; +import { getFixturesRootDir } from '../RuleTester'; const rootDir = getFixturesRootDir(); diff --git a/packages/eslint-plugin/tests/rules/restrict-plus-operands.test.ts b/packages/eslint-plugin/tests/rules/restrict-plus-operands.test.ts index 59215883758..8ccb8bdb5fe 100644 --- a/packages/eslint-plugin/tests/rules/restrict-plus-operands.test.ts +++ b/packages/eslint-plugin/tests/rules/restrict-plus-operands.test.ts @@ -1,5 +1,7 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/restrict-plus-operands'; -import { getFixturesRootDir, RuleTester } from '../RuleTester'; +import { getFixturesRootDir } from '../RuleTester'; const rootPath = getFixturesRootDir(); diff --git a/packages/eslint-plugin/tests/rules/restrict-template-expressions.test.ts b/packages/eslint-plugin/tests/rules/restrict-template-expressions.test.ts index b58305051fa..7e3a4858f3a 100644 --- a/packages/eslint-plugin/tests/rules/restrict-template-expressions.test.ts +++ b/packages/eslint-plugin/tests/rules/restrict-template-expressions.test.ts @@ -1,5 +1,7 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/restrict-template-expressions'; -import { getFixturesRootDir, RuleTester } from '../RuleTester'; +import { getFixturesRootDir } from '../RuleTester'; const rootPath = getFixturesRootDir(); diff --git a/packages/eslint-plugin/tests/rules/return-await.test.ts b/packages/eslint-plugin/tests/rules/return-await.test.ts index 6a19ba3c223..ef6c3044c81 100644 --- a/packages/eslint-plugin/tests/rules/return-await.test.ts +++ b/packages/eslint-plugin/tests/rules/return-await.test.ts @@ -1,5 +1,7 @@ +import { noFormat, RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/return-await'; -import { getFixturesRootDir, noFormat, RuleTester } from '../RuleTester'; +import { getFixturesRootDir } from '../RuleTester'; const rootDir = getFixturesRootDir(); diff --git a/packages/eslint-plugin/tests/rules/semi.test.ts b/packages/eslint-plugin/tests/rules/semi.test.ts index f0a856d68dd..e1f53043a9c 100644 --- a/packages/eslint-plugin/tests/rules/semi.test.ts +++ b/packages/eslint-plugin/tests/rules/semi.test.ts @@ -3,11 +3,11 @@ /* eslint "@typescript-eslint/internal/plugin-test-formatting": ["error", { formatWithPrettier: false }] */ /* eslint-enable eslint-comments/no-use */ +import { RuleTester } from '@typescript-eslint/rule-tester'; import type { TSESLint } from '@typescript-eslint/utils'; import type { MessageIds, Options } from '../../src/rules/semi'; import rule from '../../src/rules/semi'; -import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/sort-type-constituents.test.ts b/packages/eslint-plugin/tests/rules/sort-type-constituents.test.ts index 42f9ab8153a..81a0754f73e 100644 --- a/packages/eslint-plugin/tests/rules/sort-type-constituents.test.ts +++ b/packages/eslint-plugin/tests/rules/sort-type-constituents.test.ts @@ -1,3 +1,4 @@ +import { noFormat, RuleTester } from '@typescript-eslint/rule-tester'; import type { TSESLint } from '@typescript-eslint/utils'; import type { @@ -5,7 +6,6 @@ import type { Options, } from '../../src/rules/sort-type-constituents'; import rule from '../../src/rules/sort-type-constituents'; -import { noFormat, RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/space-before-blocks.test.ts b/packages/eslint-plugin/tests/rules/space-before-blocks.test.ts index 7e1338c6fc5..193dc06b505 100644 --- a/packages/eslint-plugin/tests/rules/space-before-blocks.test.ts +++ b/packages/eslint-plugin/tests/rules/space-before-blocks.test.ts @@ -3,8 +3,9 @@ /* eslint "@typescript-eslint/internal/plugin-test-formatting": ["error", { formatWithPrettier: false }] */ /* eslint-enable eslint-comments/no-use */ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/space-before-blocks'; -import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/space-before-function-paren.test.ts b/packages/eslint-plugin/tests/rules/space-before-function-paren.test.ts index 065b36b0c09..35b19dfa2be 100644 --- a/packages/eslint-plugin/tests/rules/space-before-function-paren.test.ts +++ b/packages/eslint-plugin/tests/rules/space-before-function-paren.test.ts @@ -3,10 +3,10 @@ /* eslint "@typescript-eslint/internal/plugin-test-formatting": ["error", { formatWithPrettier: false }] */ /* eslint-enable eslint-comments/no-use */ +import { RuleTester } from '@typescript-eslint/rule-tester'; import { AST_NODE_TYPES } from '@typescript-eslint/utils'; import rule from '../../src/rules/space-before-function-paren'; -import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/space-infix-ops.test.ts b/packages/eslint-plugin/tests/rules/space-infix-ops.test.ts index 37060fab745..61bb6b08c1f 100644 --- a/packages/eslint-plugin/tests/rules/space-infix-ops.test.ts +++ b/packages/eslint-plugin/tests/rules/space-infix-ops.test.ts @@ -3,8 +3,9 @@ /* eslint "@typescript-eslint/internal/plugin-test-formatting": ["error", { formatWithPrettier: false }] */ /* eslint-enable eslint-comments/no-use */ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/space-infix-ops'; -import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/tests/rules/strict-boolean-expressions.test.ts b/packages/eslint-plugin/tests/rules/strict-boolean-expressions.test.ts index 3994fc77313..65878e2d17f 100644 --- a/packages/eslint-plugin/tests/rules/strict-boolean-expressions.test.ts +++ b/packages/eslint-plugin/tests/rules/strict-boolean-expressions.test.ts @@ -1,3 +1,6 @@ +/* eslint-disable deprecation/deprecation -- TODO - migrate this test away from `batchedSingleLineTests` */ + +import { noFormat, RuleTester } from '@typescript-eslint/rule-tester'; import * as path from 'path'; import type { @@ -5,12 +8,7 @@ import type { Options, } from '../../src/rules/strict-boolean-expressions'; import rule from '../../src/rules/strict-boolean-expressions'; -import { - batchedSingleLineTests, - getFixturesRootDir, - noFormat, - RuleTester, -} from '../RuleTester'; +import { batchedSingleLineTests, getFixturesRootDir } from '../RuleTester'; const rootPath = getFixturesRootDir(); const ruleTester = new RuleTester({ @@ -24,114 +22,200 @@ const ruleTester = new RuleTester({ ruleTester.run('strict-boolean-expressions', rule, { valid: [ // boolean in boolean context - ...batchedSingleLineTests({ - code: noFormat` - true ? "a" : "b"; - if (false) {} - while (true) {} - for (; false;) {} - !true; - false || 123; - true && "foo"; - !(false || true); - true && false ? true : false; - false && true || false; - false && true || []; - (false && 1) || (true && 2); - declare const x: boolean; if (x) {} - (x: boolean) => !x; - (x: T) => x ? 1 : 0; - declare const x: never; if (x) {} - `, - }), + "true ? 'a' : 'b';", + ` +if (false) { +} + `, + 'while (true) {}', + 'for (; false; ) {}', + '!true;', + 'false || 123;', + "true && 'foo';", + '!(false || true);', + 'true && false ? true : false;', + '(false && true) || false;', + '(false && true) || [];', + '(false && 1) || (true && 2);', + ` +declare const x: boolean; +if (x) { +} + `, + '(x: boolean) => !x;', + '(x: T) => (x ? 1 : 0);', + ` +declare const x: never; +if (x) { +} + `, // string in boolean context - ...batchedSingleLineTests({ - code: noFormat` - if ("") {} - while ("x") {} - for (; "";) {} - "" && "1" || x; - declare const x: string; if (x) {} - (x: string) => !x; - (x: T) => x ? 1 : 0; - `, - }), + ` +if ('') { +} + `, + "while ('x') {}", + "for (; ''; ) {}", + "('' && '1') || x;", + ` +declare const x: string; +if (x) { +} + `, + '(x: string) => !x;', + '(x: T) => (x ? 1 : 0);', // number in boolean context - ...batchedSingleLineTests({ - code: noFormat` - if (0) {} - while (1n) {} - for (; Infinity;) {} - 0 / 0 && 1 + 2 || x; - declare const x: number; if (x) {} - (x: bigint) => !x; - (x: T) => x ? 1 : 0; - `, - }), + ` +if (0) { +} + `, + 'while (1n) {}', + 'for (; Infinity; ) {}', + '(0 / 0 && 1 + 2) || x;', + ` +declare const x: number; +if (x) { +} + `, + '(x: bigint) => !x;', + '(x: T) => (x ? 1 : 0);', // nullable object in boolean context - ...batchedSingleLineTests({ - code: noFormat` - declare const x: null | object; if (x) {} - (x?: { a: any }) => !x; - (x: T) => x ? 1 : 0; - `, - }), + ` +declare const x: null | object; +if (x) { +} + `, + '(x?: { a: any }) => !x;', + '(x: T) => (x ? 1 : 0);', // nullable boolean in boolean context - ...batchedSingleLineTests({ + { options: [{ allowNullableBoolean: true }], - code: noFormat` - declare const x: boolean | null; if (x) {} + code: ` + declare const x: boolean | null; + if (x) { + } + `, + }, + { + options: [{ allowNullableBoolean: true }], + code: ` (x?: boolean) => !x; - (x: T) => x ? 1 : 0; `, - }), + }, + { + options: [{ allowNullableBoolean: true }], + code: ` + (x: T) => (x ? 1 : 0); + `, + }, // nullable string in boolean context - ...batchedSingleLineTests({ + { options: [{ allowNullableString: true }], - code: noFormat` - declare const x: string | null; if (x) {} + code: ` + declare const x: string | null; + if (x) { + } + `, + }, + { + options: [{ allowNullableString: true }], + code: ` (x?: string) => !x; - (x: T) => x ? 1 : 0; `, - }), + }, + { + options: [{ allowNullableString: true }], + code: ` + (x: T) => (x ? 1 : 0); + `, + }, // nullable number in boolean context - ...batchedSingleLineTests({ + { options: [{ allowNullableNumber: true }], - code: noFormat` - declare const x: number | null; if (x) {} + code: ` + declare const x: number | null; + if (x) { + } + `, + }, + { + options: [{ allowNullableNumber: true }], + code: ` (x?: number) => !x; - (x: T) => x ? 1 : 0; `, - }), + }, + { + options: [{ allowNullableNumber: true }], + code: ` + (x: T) => (x ? 1 : 0); + `, + }, // any in boolean context - ...batchedSingleLineTests({ + { options: [{ allowAny: true }], - code: noFormat` - declare const x: any; if (x) {} - (x) => !x; - (x: T) => x ? 1 : 0; + code: ` + declare const x: any; + if (x) { + } `, - }), + }, + { + options: [{ allowAny: true }], + code: ` + x => !x; + `, + }, + { + options: [{ allowAny: true }], + code: ` + (x: T) => (x ? 1 : 0); + `, + }, // logical operator - ...batchedSingleLineTests({ + { options: [{ allowString: true, allowNumber: true }], code: ` 1 && true && 'x' && {}; + `, + }, + { + options: [{ allowString: true, allowNumber: true }], + code: ` let x = 0 || false || '' || null; + `, + }, + { + options: [{ allowString: true, allowNumber: true }], + code: ` if (1 && true && 'x') void 0; + `, + }, + { + options: [{ allowString: true, allowNumber: true }], + code: ` if (0 || false || '') void 0; + `, + }, + { + options: [{ allowString: true, allowNumber: true }], + code: ` 1 && true && 'x' ? {} : null; + `, + }, + { + options: [{ allowString: true, allowNumber: true }], + code: ` 0 || false || '' ? null : {}; `, - }), + }, // nullable enum in boolean context { diff --git a/packages/eslint-plugin/tests/rules/switch-exhaustiveness-check.test.ts b/packages/eslint-plugin/tests/rules/switch-exhaustiveness-check.test.ts index 747323bd486..b250a09e2bb 100644 --- a/packages/eslint-plugin/tests/rules/switch-exhaustiveness-check.test.ts +++ b/packages/eslint-plugin/tests/rules/switch-exhaustiveness-check.test.ts @@ -1,7 +1,7 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; import path from 'path'; import switchExhaustivenessCheck from '../../src/rules/switch-exhaustiveness-check'; -import { RuleTester } from '../RuleTester'; const rootPath = path.join(process.cwd(), 'tests/fixtures/'); diff --git a/packages/eslint-plugin/tests/rules/triple-slash-reference.test.ts b/packages/eslint-plugin/tests/rules/triple-slash-reference.test.ts index 8dd71212fbb..5c0c7d482cc 100644 --- a/packages/eslint-plugin/tests/rules/triple-slash-reference.test.ts +++ b/packages/eslint-plugin/tests/rules/triple-slash-reference.test.ts @@ -1,5 +1,6 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/triple-slash-reference'; -import { RuleTester } from '../RuleTester'; const ruleTester = new RuleTester({ parserOptions: { diff --git a/packages/eslint-plugin/tests/rules/type-annotation-spacing.test.ts b/packages/eslint-plugin/tests/rules/type-annotation-spacing.test.ts index 17fb23c7771..ff745515c4b 100644 --- a/packages/eslint-plugin/tests/rules/type-annotation-spacing.test.ts +++ b/packages/eslint-plugin/tests/rules/type-annotation-spacing.test.ts @@ -3,6 +3,7 @@ /* eslint "@typescript-eslint/internal/plugin-test-formatting": ["error", { formatWithPrettier: false }] */ /* eslint-enable eslint-comments/no-use */ +import { RuleTester } from '@typescript-eslint/rule-tester'; import type { TSESLint } from '@typescript-eslint/utils'; import rule from '../../src/rules/type-annotation-spacing'; @@ -10,7 +11,6 @@ import type { InferMessageIdsTypeFromRule, InferOptionsTypeFromRule, } from '../../src/util'; -import { RuleTester } from '../RuleTester'; type MessageIds = InferMessageIdsTypeFromRule; type Options = InferOptionsTypeFromRule; diff --git a/packages/eslint-plugin/tests/rules/typedef.test.ts b/packages/eslint-plugin/tests/rules/typedef.test.ts index 3a58eb1387a..79dcaa9b193 100644 --- a/packages/eslint-plugin/tests/rules/typedef.test.ts +++ b/packages/eslint-plugin/tests/rules/typedef.test.ts @@ -1,5 +1,7 @@ +import { noFormat, RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/typedef'; -import { getFixturesRootDir, noFormat, RuleTester } from '../RuleTester'; +import { getFixturesRootDir } from '../RuleTester'; const rootDir = getFixturesRootDir(); const ruleTester = new RuleTester({ diff --git a/packages/eslint-plugin/tests/rules/unbound-method.test.ts b/packages/eslint-plugin/tests/rules/unbound-method.test.ts index 49b06a4ac50..9eb2b73b22c 100644 --- a/packages/eslint-plugin/tests/rules/unbound-method.test.ts +++ b/packages/eslint-plugin/tests/rules/unbound-method.test.ts @@ -1,8 +1,9 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; import type { TSESLint } from '@typescript-eslint/utils'; import type { MessageIds, Options } from '../../src/rules/unbound-method'; import rule from '../../src/rules/unbound-method'; -import { getFixturesRootDir, RuleTester } from '../RuleTester'; +import { getFixturesRootDir } from '../RuleTester'; const rootPath = getFixturesRootDir(); diff --git a/packages/eslint-plugin/tests/rules/unified-signatures.test.ts b/packages/eslint-plugin/tests/rules/unified-signatures.test.ts index c01749e14b1..dcc16c7a196 100644 --- a/packages/eslint-plugin/tests/rules/unified-signatures.test.ts +++ b/packages/eslint-plugin/tests/rules/unified-signatures.test.ts @@ -1,5 +1,6 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; + import rule from '../../src/rules/unified-signatures'; -import { RuleTester } from '../RuleTester'; //------------------------------------------------------------------------------ // Tests diff --git a/packages/eslint-plugin/tests/util/getWrappingFixer.test.ts b/packages/eslint-plugin/tests/util/getWrappingFixer.test.ts index 9b4c070ec61..52b0231420c 100644 --- a/packages/eslint-plugin/tests/util/getWrappingFixer.test.ts +++ b/packages/eslint-plugin/tests/util/getWrappingFixer.test.ts @@ -1,7 +1,8 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; import type { TSESTree } from '@typescript-eslint/utils'; import { createRule, getWrappingFixer } from '../../src/util'; -import { getFixturesRootDir, RuleTester } from '../RuleTester'; +import { getFixturesRootDir } from '../RuleTester'; const rule = createRule({ name: 'void-everything', diff --git a/packages/eslint-plugin/tests/util/isNodeEqual.test.ts b/packages/eslint-plugin/tests/util/isNodeEqual.test.ts index 5e273bb1c7b..a2473fb88db 100644 --- a/packages/eslint-plugin/tests/util/isNodeEqual.test.ts +++ b/packages/eslint-plugin/tests/util/isNodeEqual.test.ts @@ -1,7 +1,8 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; import type { TSESLint, TSESTree } from '@typescript-eslint/utils'; import { createRule, isNodeEqual } from '../../src/util'; -import { getFixturesRootDir, RuleTester } from '../RuleTester'; +import { getFixturesRootDir } from '../RuleTester'; const rule = createRule({ name: 'no-useless-expression', diff --git a/packages/eslint-plugin/tools/generate-configs.ts b/packages/eslint-plugin/tools/generate-configs.ts index e9e1f3a7047..1ddf337d8cf 100644 --- a/packages/eslint-plugin/tools/generate-configs.ts +++ b/packages/eslint-plugin/tools/generate-configs.ts @@ -78,7 +78,7 @@ async function main(): Promise { type RuleEntry = [ string, - TSESLint.RuleModule, + TSESLint.RuleModule, ]; const allRuleEntries: RuleEntry[] = Object.entries(rules).sort((a, b) => @@ -95,14 +95,11 @@ async function main(): Promise { /** * Helper function reduces records to key - value pairs. */ - function reducer( + function reducer( config: LinterConfigRules, - entry: [string, TSESLint.RuleModule], + [key, value]: RuleEntry, settings: RuleFilter = {}, ): LinterConfigRules { - const key = entry[0]; - const value = entry[1]; - if (settings.deprecated && value.meta.deprecated) { return config; } @@ -168,10 +165,10 @@ async function main(): Promise { } interface ExtendedConfigSettings { - extraExtends?: string[]; + extraExtends?: readonly string[]; name: string; filters?: RuleFilter; - ruleEntries: RuleEntry[]; + ruleEntries: readonly RuleEntry[]; } function writeExtendedConfig({ diff --git a/packages/utils/src/eslint-utils/batchedSingleLineTests.ts b/packages/utils/src/eslint-utils/batchedSingleLineTests.ts deleted file mode 100644 index fcd15210e48..00000000000 --- a/packages/utils/src/eslint-utils/batchedSingleLineTests.ts +++ /dev/null @@ -1,73 +0,0 @@ -import type { - InvalidTestCase, - ValidTestCase, -} from '../eslint-utils/rule-tester/RuleTester'; - -/** - * Converts a batch of single line tests into a number of separate test cases. - * This makes it easier to write tests which use the same options. - * - * Why wouldn't you just leave them as one test? - * Because it makes the test error messages harder to decipher. - * This way each line will fail separately, instead of them all failing together. - */ -function batchedSingleLineTests>( - test: ValidTestCase, -): ValidTestCase[]; -/** - * Converts a batch of single line tests into a number of separate test cases. - * This makes it easier to write tests which use the same options. - * - * Why wouldn't you just leave them as one test? - * Because it makes the test error messages harder to decipher. - * This way each line will fail separately, instead of them all failing together. - * - * Make sure you have your line numbers correct for error reporting, as it will match - * the line numbers up with the split tests! - */ -function batchedSingleLineTests< - TMessageIds extends string, - TOptions extends Readonly, ->( - test: InvalidTestCase, -): InvalidTestCase[]; -function batchedSingleLineTests< - TMessageIds extends string, - TOptions extends Readonly, ->( - options: ValidTestCase | InvalidTestCase, -): (ValidTestCase | InvalidTestCase)[] { - // -- eslint counts lines from 1 - const lineOffset = options.code.startsWith('\n') ? 2 : 1; - const output = - 'output' in options && options.output - ? options.output.trim().split('\n') - : null; - return options.code - .trim() - .split('\n') - .map((code, i) => { - const lineNum = i + lineOffset; - const errors = - 'errors' in options - ? options.errors.filter(e => e.line === lineNum) - : []; - const returnVal = { - ...options, - code, - errors: errors.map(e => ({ - ...e, - line: 1, - })), - }; - if (output?.[i]) { - return { - ...returnVal, - output: output[i], - }; - } - return returnVal; - }); -} - -export { batchedSingleLineTests }; diff --git a/packages/utils/src/eslint-utils/index.ts b/packages/utils/src/eslint-utils/index.ts index a3d0cb75245..baf3e82bc65 100644 --- a/packages/utils/src/eslint-utils/index.ts +++ b/packages/utils/src/eslint-utils/index.ts @@ -1,8 +1,6 @@ export * from './applyDefault'; -export * from './batchedSingleLineTests'; export * from './getParserServices'; export * from './InferTypesFromRule'; export * from './RuleCreator'; -export * from './rule-tester/RuleTester'; export * from './deepMerge'; export * from './nullThrows'; diff --git a/packages/utils/src/eslint-utils/rule-tester/RuleTester.ts b/packages/utils/src/eslint-utils/rule-tester/RuleTester.ts deleted file mode 100644 index 44a503b7d83..00000000000 --- a/packages/utils/src/eslint-utils/rule-tester/RuleTester.ts +++ /dev/null @@ -1,314 +0,0 @@ -import type * as TSESTreeType from '@typescript-eslint/typescript-estree'; -import assert from 'assert'; -import { version as eslintVersion } from 'eslint/package.json'; -import * as path from 'path'; -import * as semver from 'semver'; - -import type { ParserOptions } from '../../ts-eslint/ParserOptions'; -import type { RuleModule } from '../../ts-eslint/Rule'; -import type { RuleTesterTestFrameworkFunction } from '../../ts-eslint/RuleTester'; -import * as BaseRuleTester from '../../ts-eslint/RuleTester'; -import { deepMerge } from '../deepMerge'; -import type { DependencyConstraint } from './dependencyConstraints'; -import { satisfiesAllDependencyConstraints } from './dependencyConstraints'; - -const TS_ESLINT_PARSER = '@typescript-eslint/parser'; -const ERROR_MESSAGE = `Do not set the parser at the test level unless you want to use a parser other than ${TS_ESLINT_PARSER}`; - -type RuleTesterConfig = Omit & { - parser: typeof TS_ESLINT_PARSER; - /** - * Constraints that must pass in the current environment for any tests to run - */ - dependencyConstraints?: DependencyConstraint; -}; - -interface InvalidTestCase< - TMessageIds extends string, - TOptions extends Readonly, -> extends BaseRuleTester.InvalidTestCase { - /** - * Constraints that must pass in the current environment for the test to run - */ - dependencyConstraints?: DependencyConstraint; -} -interface ValidTestCase> - extends BaseRuleTester.ValidTestCase { - /** - * Constraints that must pass in the current environment for the test to run - */ - dependencyConstraints?: DependencyConstraint; -} -interface RunTests< - TMessageIds extends string, - TOptions extends Readonly, -> { - // RuleTester.run also accepts strings for valid cases - readonly valid: readonly (ValidTestCase | string)[]; - readonly invalid: readonly InvalidTestCase[]; -} - -type AfterAll = (fn: () => void) => void; - -function isDescribeWithSkip( - value: unknown, -): value is RuleTesterTestFrameworkFunction & { - skip: RuleTesterTestFrameworkFunction; -} { - return ( - typeof value === 'object' && - value != null && - 'skip' in value && - typeof (value as Record).skip === 'function' - ); -} - -class RuleTester extends BaseRuleTester.RuleTester { - readonly #baseOptions: RuleTesterConfig; - - static #afterAll: AfterAll | undefined; - /** - * If you supply a value to this property, the rule tester will call this instead of using the version defined on - * the global namespace. - */ - static get afterAll(): AfterAll { - return ( - this.#afterAll ?? - (typeof afterAll === 'function' ? afterAll : (): void => {}) - ); - } - static set afterAll(value: AfterAll | undefined) { - this.#afterAll = value; - } - - private get staticThis(): typeof RuleTester { - // the cast here is due to https://github.com/microsoft/TypeScript/issues/3841 - return this.constructor as typeof RuleTester; - } - - constructor(baseOptions: RuleTesterConfig) { - // eslint will hard-error if you include non-standard top-level properties - const { dependencyConstraints: _, ...baseOptionsSafeForESLint } = - baseOptions; - super({ - ...baseOptionsSafeForESLint, - parserOptions: { - ...baseOptions.parserOptions, - warnOnUnsupportedTypeScriptVersion: - baseOptions.parserOptions?.warnOnUnsupportedTypeScriptVersion ?? - false, - }, - // as of eslint 6 you have to provide an absolute path to the parser - // but that's not as clean to type, this saves us trying to manually enforce - // that contributors require.resolve everything - parser: require.resolve(baseOptions.parser), - }); - - this.#baseOptions = baseOptions; - - // make sure that the parser doesn't hold onto file handles between tests - // on linux (i.e. our CI env), there can be very a limited number of watch handles available - this.staticThis.afterAll(() => { - try { - // instead of creating a hard dependency, just use a soft require - // a bit weird, but if they're using this tooling, it'll be installed - const parser = require(TS_ESLINT_PARSER) as typeof TSESTreeType; - parser.clearCaches(); - } catch { - // ignored on purpose - } - }); - } - private getFilename(testOptions?: ParserOptions): string { - const resolvedOptions = deepMerge( - this.#baseOptions.parserOptions, - testOptions, - ) as ParserOptions; - const filename = `file.ts${resolvedOptions.ecmaFeatures?.jsx ? 'x' : ''}`; - if (resolvedOptions.project) { - return path.join( - resolvedOptions.tsconfigRootDir != null - ? resolvedOptions.tsconfigRootDir - : process.cwd(), - filename, - ); - } - return filename; - } - - // as of eslint 6 you have to provide an absolute path to the parser - // If you don't do that at the test level, the test will fail somewhat cryptically... - // This is a lot more explicit - run>( - name: string, - rule: RuleModule, - testsReadonly: RunTests, - ): void { - if ( - this.#baseOptions.dependencyConstraints && - !satisfiesAllDependencyConstraints( - this.#baseOptions.dependencyConstraints, - ) - ) { - if (isDescribeWithSkip(this.staticThis.describe)) { - // for frameworks like mocha or jest that have a "skip" version of their function - // we can provide a nice skipped test! - this.staticThis.describe.skip(name, () => { - this.staticThis.it( - 'All tests skipped due to unsatisfied constructor dependency constraints', - () => {}, - ); - }); - } else { - // otherwise just declare an empty test - this.staticThis.describe(name, () => { - this.staticThis.it( - 'All tests skipped due to unsatisfied constructor dependency constraints', - () => { - // some frameworks error if there are no assertions - assert.equal(true, true); - }, - ); - }); - } - - // don't run any tests because we don't match the base constraint - return; - } - - const tests = { - // standardize the valid tests as objects - valid: testsReadonly.valid.map(test => { - if (typeof test === 'string') { - return { - code: test, - }; - } - return test; - }), - invalid: testsReadonly.invalid, - }; - - // convenience iterator to make it easy to loop all tests without a concat - const allTestsIterator = { - *[Symbol.iterator](): Generator, void, unknown> { - for (const test of tests.valid) { - yield test; - } - for (const test of tests.invalid) { - yield test; - } - }, - }; - - /* - Automatically add a filename to the tests to enable type-aware tests to "just work". - This saves users having to verbosely and manually add the filename to every - single test case. - Hugely helps with the string-based valid test cases as it means they don't - need to be made objects! - Also removes dependencyConstraints, which we support but ESLint core doesn't. - */ - const normalizeTest = < - T extends - | ValidTestCase - | InvalidTestCase, - >({ - dependencyConstraints: _, - ...test - }: T): Omit => { - if (test.parser === TS_ESLINT_PARSER) { - throw new Error(ERROR_MESSAGE); - } - if (!test.filename) { - return { - ...test, - filename: this.getFilename(test.parserOptions), - }; - } - return test; - }; - tests.valid = tests.valid.map(normalizeTest); - tests.invalid = tests.invalid.map(normalizeTest); - - const hasOnly = ((): boolean => { - for (const test of allTestsIterator) { - if (test.only) { - return true; - } - } - return false; - })(); - // if there is an `only: true` - don't apply constraints - assume that - // we are in "local development" mode rather than "CI validation" mode - if (!hasOnly) { - /* - Automatically skip tests that don't satisfy the dependency constraints. - */ - const hasConstraints = ((): boolean => { - for (const test of allTestsIterator) { - if ( - test.dependencyConstraints && - Object.keys(test.dependencyConstraints).length > 0 - ) { - return true; - } - } - return false; - })(); - if (hasConstraints) { - // The `only: boolean` test property was only added in ESLint v7.29.0. - if (semver.satisfies(eslintVersion, '>=7.29.0')) { - /* - Mark all satisfactory tests as `only: true`, and all other tests as - `only: false`. - When multiple tests are marked as "only", test frameworks like jest and mocha - will run all of those tests and will just skip the other tests. - - We do this instead of just omitting the tests entirely because it gives the - test framework the opportunity to log the test as skipped rather than the test - just disappearing. - */ - const maybeMarkAsOnly = < - T extends - | ValidTestCase - | InvalidTestCase, - >( - test: T, - ): T => { - return { - ...test, - only: satisfiesAllDependencyConstraints( - test.dependencyConstraints, - ), - }; - }; - - tests.valid = tests.valid.map(maybeMarkAsOnly); - tests.invalid = tests.invalid.map(maybeMarkAsOnly); - } else { - // On older versions we just fallback to raw array filtering like SAVAGES - tests.valid = tests.valid.filter(test => - satisfiesAllDependencyConstraints(test.dependencyConstraints), - ); - tests.invalid = tests.invalid.filter(test => - satisfiesAllDependencyConstraints(test.dependencyConstraints), - ); - } - } - } - - super.run(name, rule, tests); - } -} - -/** - * Simple no-op tag to mark code samples as "should not format with prettier" - * for the internal/plugin-test-formatting lint rule - */ -function noFormat(raw: TemplateStringsArray, ...keys: string[]): string { - return String.raw({ raw }, ...keys); -} - -export { noFormat, RuleTester }; -export type { InvalidTestCase, ValidTestCase, RunTests }; diff --git a/packages/utils/src/eslint-utils/rule-tester/dependencyConstraints.ts b/packages/utils/src/eslint-utils/rule-tester/dependencyConstraints.ts deleted file mode 100644 index 0bc1f5fc5ce..00000000000 --- a/packages/utils/src/eslint-utils/rule-tester/dependencyConstraints.ts +++ /dev/null @@ -1,63 +0,0 @@ -import * as semver from 'semver'; - -interface SemverVersionConstraint { - readonly range: string; - readonly options?: Parameters[2]; -} -type AtLeastVersionConstraint = - | `${number}` - | `${number}.${number}` - | `${number}.${number}.${number}` - | `${number}.${number}.${number}-${string}`; -type VersionConstraint = SemverVersionConstraint | AtLeastVersionConstraint; -interface DependencyConstraint { - /** - * Passing a string for the value is shorthand for a '>=' constraint - */ - readonly [packageName: string]: VersionConstraint; -} - -const BASE_SATISFIES_OPTIONS: semver.RangeOptions = { - includePrerelease: true, -}; - -function satisfiesDependencyConstraint( - packageName: string, - constraintIn: DependencyConstraint[string], -): boolean { - const constraint: SemverVersionConstraint = - typeof constraintIn === 'string' - ? { - range: `>=${constraintIn}`, - } - : constraintIn; - - return semver.satisfies( - (require(`${packageName}/package.json`) as { version: string }).version, - constraint.range, - typeof constraint.options === 'object' - ? { ...BASE_SATISFIES_OPTIONS, ...constraint.options } - : constraint.options, - ); -} - -function satisfiesAllDependencyConstraints( - dependencyConstraints: DependencyConstraint | undefined, -): boolean { - if (dependencyConstraints == null) { - return true; - } - - for (const [packageName, constraint] of Object.entries( - dependencyConstraints, - )) { - if (!satisfiesDependencyConstraint(packageName, constraint)) { - return false; - } - } - - return true; -} - -export { satisfiesAllDependencyConstraints }; -export type { DependencyConstraint }; diff --git a/packages/utils/tests/eslint-utils/batchedSingleLineTests.test.ts b/packages/utils/tests/eslint-utils/batchedSingleLineTests.test.ts deleted file mode 100644 index 596bb480b94..00000000000 --- a/packages/utils/tests/eslint-utils/batchedSingleLineTests.test.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { ESLintUtils } from '../../src'; - -describe('batchedSingleLineTests', () => { - const FIXTURES = ` -a -b -c - `; - const errors = [ - { messageId: 'someMessage1', line: 2 }, - { messageId: 'someMessage2', line: 3 }, - { messageId: 'someMessage3', line: 4 }, - ]; - const options = [{ optionOne: 'value' }]; - - it('should work without options', () => { - expect( - ESLintUtils.batchedSingleLineTests({ - code: FIXTURES, - }), - ).toEqual([ - { code: 'a', errors: [] }, - { code: 'b', errors: [] }, - { code: 'c', errors: [] }, - ]); - }); - - it('should work with errors', () => { - expect( - ESLintUtils.batchedSingleLineTests({ - code: FIXTURES, - errors, - }), - ).toEqual([ - { code: 'a', errors: [{ messageId: 'someMessage1', line: 1 }] }, - { code: 'b', errors: [{ messageId: 'someMessage2', line: 1 }] }, - { code: 'c', errors: [{ messageId: 'someMessage3', line: 1 }] }, - ]); - }); - - it('should work with all fields', () => { - const filename = 'foo.ts'; - const parser = 'some-parser'; - - expect( - ESLintUtils.batchedSingleLineTests({ - code: FIXTURES, - errors, - options, - parser, - output: FIXTURES, - filename, - }), - ).toEqual([ - { - code: 'a', - output: 'a', - errors: [{ messageId: 'someMessage1', line: 1 }], - parser, - filename, - options, - }, - { - code: 'b', - output: 'b', - errors: [{ messageId: 'someMessage2', line: 1 }], - parser, - filename, - options, - }, - { - code: 'c', - output: 'c', - errors: [{ messageId: 'someMessage3', line: 1 }], - parser, - filename, - options, - }, - ]); - }); -}); diff --git a/packages/utils/tests/eslint-utils/rule-tester/RuleTester.test.ts b/packages/utils/tests/eslint-utils/rule-tester/RuleTester.test.ts deleted file mode 100644 index 57ac48b38c1..00000000000 --- a/packages/utils/tests/eslint-utils/rule-tester/RuleTester.test.ts +++ /dev/null @@ -1,737 +0,0 @@ -import * as parser from '@typescript-eslint/parser'; -import eslintPackageJson from 'eslint/package.json'; - -import * as dependencyConstraintsModule from '../../../src/eslint-utils/rule-tester/dependencyConstraints'; -import { RuleTester } from '../../../src/eslint-utils/rule-tester/RuleTester'; -import type { RuleModule } from '../../../src/ts-eslint'; -import { RuleTester as BaseRuleTester } from '../../../src/ts-eslint'; - -// we can't spy on the exports of an ES module - so we instead have to mock the entire module -jest.mock('../../../src/eslint-utils/rule-tester/dependencyConstraints', () => { - const dependencyConstraints = jest.requireActual< - typeof dependencyConstraintsModule - >('../../../src/eslint-utils/rule-tester/dependencyConstraints'); - - return { - ...dependencyConstraints, - __esModule: true, - satisfiesAllDependencyConstraints: jest.fn( - dependencyConstraints.satisfiesAllDependencyConstraints, - ), - }; -}); -const satisfiesAllDependencyConstraintsMock = jest.mocked( - dependencyConstraintsModule.satisfiesAllDependencyConstraints, -); - -jest.mock( - 'totally-real-dependency/package.json', - () => ({ - version: '10.0.0', - }), - { - // this is not a real module that will exist - virtual: true, - }, -); -jest.mock( - 'totally-real-dependency-prerelease/package.json', - () => ({ - version: '10.0.0-rc.1', - }), - { - // this is not a real module that will exist - virtual: true, - }, -); - -// mock the eslint package.json so that we can manipulate the version in the test -jest.mock('eslint/package.json', () => { - return { - // make the version a getter so we can spy on it and change the return value - get version(): string { - // fix the version so the test is stable on older ESLint versions - return '8.0.0'; - }, - }; -}); - -jest.mock('@typescript-eslint/parser', () => { - return { - __esModule: true, - clearCaches: jest.fn(), - }; -}); - -/* eslint-disable jest/prefer-spy-on -- - need to specifically assign to the properties or else it will use the - global value */ -RuleTester.afterAll = jest.fn(); -RuleTester.describe = jest.fn(); -RuleTester.it = jest.fn(); -RuleTester.itOnly = jest.fn(); -/* eslint-enable jest/prefer-spy-on */ - -const mockedAfterAll = jest.mocked(RuleTester.afterAll); -const mockedDescribe = jest.mocked(RuleTester.describe); -const mockedIt = jest.mocked(RuleTester.it); -const _mockedItOnly = jest.mocked(RuleTester.itOnly); -const runSpy = jest.spyOn(BaseRuleTester.prototype, 'run'); -const mockedParserClearCaches = jest.mocked(parser.clearCaches); - -const eslintVersionSpy = jest.spyOn(eslintPackageJson, 'version', 'get'); - -beforeEach(() => { - jest.clearAllMocks(); -}); - -const NOOP_RULE: RuleModule<'error', []> = { - meta: { - messages: { - error: 'error', - }, - type: 'problem', - schema: {}, - }, - defaultOptions: [], - create() { - return {}; - }, -}; - -describe('RuleTester', () => { - it('automatically sets the filename for tests', () => { - const ruleTester = new RuleTester({ - parser: '@typescript-eslint/parser', - parserOptions: { - project: 'tsconfig.json', - tsconfigRootDir: '/some/path/that/totally/exists/', - }, - }); - - ruleTester.run('my-rule', NOOP_RULE, { - invalid: [ - { - code: 'invalid tests should work as well', - errors: [], - }, - ], - valid: [ - 'string based valid test', - { - code: 'object based valid test', - }, - { - code: "explicit filename shouldn't be overwritten", - filename: '/set/in/the/test.ts', - }, - { - code: 'jsx should have the correct filename', - parserOptions: { - ecmaFeatures: { - jsx: true, - }, - }, - }, - { - code: 'type-aware parser options should override the constructor config', - parserOptions: { - project: 'tsconfig.test-specific.json', - tsconfigRootDir: '/set/in/the/test/', - }, - }, - ], - }); - - expect(runSpy.mock.lastCall?.[2]).toMatchInlineSnapshot(` - { - "invalid": [ - { - "code": "invalid tests should work as well", - "errors": [], - "filename": "/some/path/that/totally/exists/file.ts", - }, - ], - "valid": [ - { - "code": "string based valid test", - "filename": "/some/path/that/totally/exists/file.ts", - }, - { - "code": "object based valid test", - "filename": "/some/path/that/totally/exists/file.ts", - }, - { - "code": "explicit filename shouldn't be overwritten", - "filename": "/set/in/the/test.ts", - }, - { - "code": "jsx should have the correct filename", - "filename": "/some/path/that/totally/exists/file.tsx", - "parserOptions": { - "ecmaFeatures": { - "jsx": true, - }, - }, - }, - { - "code": "type-aware parser options should override the constructor config", - "filename": "/set/in/the/test/file.ts", - "parserOptions": { - "project": "tsconfig.test-specific.json", - "tsconfigRootDir": "/set/in/the/test/", - }, - }, - ], - } - `); - }); - - it('schedules the parser caches to be cleared afterAll', () => { - // it should schedule the afterAll - expect(mockedAfterAll).toHaveBeenCalledTimes(0); - const _ruleTester = new RuleTester({ - parser: '@typescript-eslint/parser', - parserOptions: { - project: 'tsconfig.json', - tsconfigRootDir: '/some/path/that/totally/exists/', - }, - }); - expect(mockedAfterAll).toHaveBeenCalledTimes(1); - - // the provided callback should clear the caches - const callback = mockedAfterAll.mock.calls[0][0]; - expect(typeof callback).toBe('function'); - expect(mockedParserClearCaches).not.toHaveBeenCalled(); - callback(); - expect(mockedParserClearCaches).toHaveBeenCalledTimes(1); - }); - - it('throws an error if you attempt to set the parser to ts-eslint at the test level', () => { - const ruleTester = new RuleTester({ - parser: '@typescript-eslint/parser', - parserOptions: { - project: 'tsconfig.json', - tsconfigRootDir: '/some/path/that/totally/exists/', - }, - }); - - expect(() => - ruleTester.run('my-rule', NOOP_RULE, { - valid: [ - { - code: 'object based valid test', - parser: '@typescript-eslint/parser', - }, - ], - - invalid: [], - }), - ).toThrowErrorMatchingInlineSnapshot( - `"Do not set the parser at the test level unless you want to use a parser other than @typescript-eslint/parser"`, - ); - }); - - describe('checks dependencies as specified', () => { - it('does not check dependencies if there are no dependency constraints', () => { - const ruleTester = new RuleTester({ - parser: '@typescript-eslint/parser', - }); - - ruleTester.run('my-rule', NOOP_RULE, { - valid: [ - 'const x = 1;', - { code: 'const x = 2;' }, - // empty object is ignored - { code: 'const x = 3;', dependencyConstraints: {} }, - ], - invalid: [], - }); - - expect(satisfiesAllDependencyConstraintsMock).not.toHaveBeenCalled(); - }); - - describe('does not check dependencies if is an "only" manually set', () => { - it('in the valid section', () => { - const ruleTester = new RuleTester({ - parser: '@typescript-eslint/parser', - }); - - ruleTester.run('my-rule', NOOP_RULE, { - valid: [ - 'const x = 1;', - { code: 'const x = 2;' }, - { - code: 'const x = 3;', - // eslint-disable-next-line eslint-plugin/no-only-tests -- intentional only for test purposes - only: true, - }, - { - code: 'const x = 4;', - dependencyConstraints: { - 'totally-real-dependency': '999', - }, - }, - ], - invalid: [], - }); - - expect(satisfiesAllDependencyConstraintsMock).not.toHaveBeenCalled(); - }); - - it('in the invalid section', () => { - const ruleTester = new RuleTester({ - parser: '@typescript-eslint/parser', - }); - - ruleTester.run('my-rule', NOOP_RULE, { - valid: [ - 'const x = 1;', - { code: 'const x = 2;' }, - { - code: 'const x = 4;', - dependencyConstraints: { - 'totally-real-dependency': '999', - }, - }, - ], - invalid: [ - { - code: 'const x = 3;', - errors: [], - // eslint-disable-next-line eslint-plugin/no-only-tests -- intentional only for test purposes - only: true, - }, - ], - }); - - expect(satisfiesAllDependencyConstraintsMock).not.toHaveBeenCalled(); - }); - }); - - it('correctly handles string-based at-least', () => { - const ruleTester = new RuleTester({ - parser: '@typescript-eslint/parser', - }); - - ruleTester.run('my-rule', NOOP_RULE, { - invalid: [ - { - code: 'failing - major', - errors: [], - dependencyConstraints: { - 'totally-real-dependency': '999', - }, - }, - { - code: 'failing - major.minor', - errors: [], - dependencyConstraints: { - 'totally-real-dependency': '999.0', - }, - }, - { - code: 'failing - major.minor.patch', - errors: [], - dependencyConstraints: { - 'totally-real-dependency': '999.0.0', - }, - }, - ], - valid: [ - { - code: 'passing - major', - dependencyConstraints: { - 'totally-real-dependency': '10', - }, - }, - { - code: 'passing - major.minor', - dependencyConstraints: { - 'totally-real-dependency': '10.0', - }, - }, - { - code: 'passing - major.minor.patch', - dependencyConstraints: { - 'totally-real-dependency': '10.0.0', - }, - }, - ], - }); - - expect(runSpy.mock.lastCall?.[2]).toMatchInlineSnapshot(` - { - "invalid": [ - { - "code": "failing - major", - "errors": [], - "filename": "file.ts", - }, - { - "code": "failing - major.minor", - "errors": [], - "filename": "file.ts", - }, - { - "code": "failing - major.minor.patch", - "errors": [], - "filename": "file.ts", - }, - ], - "valid": [ - { - "code": "passing - major", - "filename": "file.ts", - }, - { - "code": "passing - major.minor", - "filename": "file.ts", - }, - { - "code": "passing - major.minor.patch", - "filename": "file.ts", - }, - ], - } - `); - }); - - it('correctly handles object-based semver', () => { - const ruleTester = new RuleTester({ - parser: '@typescript-eslint/parser', - }); - - ruleTester.run('my-rule', NOOP_RULE, { - invalid: [ - { - code: 'failing - major', - errors: [], - dependencyConstraints: { - 'totally-real-dependency': { - range: '^999', - }, - }, - }, - { - code: 'failing - major.minor', - errors: [], - dependencyConstraints: { - 'totally-real-dependency': { - range: '>=999.0', - }, - }, - }, - - { - code: 'failing with options', - errors: [], - dependencyConstraints: { - 'totally-real-dependency-prerelease': { - range: '^10', - options: { - includePrerelease: false, - }, - }, - }, - }, - ], - valid: [ - { - code: 'passing - major', - dependencyConstraints: { - 'totally-real-dependency': { - range: '^10', - }, - }, - }, - { - code: 'passing - major.minor', - dependencyConstraints: { - 'totally-real-dependency': { - range: '<999', - }, - }, - }, - ], - }); - - expect(runSpy.mock.lastCall?.[2]).toMatchInlineSnapshot(` - { - "invalid": [ - { - "code": "failing - major", - "errors": [], - "filename": "file.ts", - }, - { - "code": "failing - major.minor", - "errors": [], - "filename": "file.ts", - }, - { - "code": "failing with options", - "errors": [], - "filename": "file.ts", - }, - ], - "valid": [ - { - "code": "passing - major", - "filename": "file.ts", - }, - { - "code": "passing - major.minor", - "filename": "file.ts", - }, - ], - } - `); - }); - - it('tests without versions should always be run', () => { - const ruleTester = new RuleTester({ - parser: '@typescript-eslint/parser', - }); - - ruleTester.run('my-rule', NOOP_RULE, { - invalid: [ - { - code: 'no constraints is always run', - errors: [], - }, - { - code: 'empty object is always run', - errors: [], - dependencyConstraints: {}, - }, - { - code: 'failing constraint', - errors: [], - dependencyConstraints: { - 'totally-real-dependency': '99999', - }, - }, - ], - valid: [ - 'string based is always run', - { - code: 'no constraints is always run', - }, - { - code: 'empty object is always run', - dependencyConstraints: {}, - }, - { - code: 'passing constraint', - dependencyConstraints: { - 'totally-real-dependency': '10', - }, - }, - ], - }); - - expect(runSpy.mock.lastCall?.[2]).toMatchInlineSnapshot(` - { - "invalid": [ - { - "code": "no constraints is always run", - "errors": [], - "filename": "file.ts", - }, - { - "code": "empty object is always run", - "errors": [], - "filename": "file.ts", - }, - { - "code": "failing constraint", - "errors": [], - "filename": "file.ts", - }, - ], - "valid": [ - { - "code": "string based is always run", - "filename": "file.ts", - }, - { - "code": "no constraints is always run", - "filename": "file.ts", - }, - { - "code": "empty object is always run", - "filename": "file.ts", - }, - { - "code": "passing constraint", - "filename": "file.ts", - }, - ], - } - `); - }); - - it('uses filter instead of "only" for old ESLint versions', () => { - // need it twice because ESLint internally fetches this value once :( - eslintVersionSpy.mockReturnValueOnce('1.0.0'); - eslintVersionSpy.mockReturnValueOnce('1.0.0'); - - const ruleTester = new RuleTester({ - parser: '@typescript-eslint/parser', - }); - - ruleTester.run('my-rule', NOOP_RULE, { - invalid: [ - { - code: 'failing', - errors: [], - dependencyConstraints: { - 'totally-real-dependency': '999', - }, - }, - { - code: 'passing', - errors: [], - dependencyConstraints: { - 'totally-real-dependency': '10', - }, - }, - ], - valid: [ - 'always passing string test', - { - code: 'failing', - dependencyConstraints: { - 'totally-real-dependency': '999', - }, - }, - { - code: 'passing', - dependencyConstraints: { - 'totally-real-dependency': '10', - }, - }, - ], - }); - - expect(runSpy.mock.lastCall?.[2]).toMatchInlineSnapshot(` - { - "invalid": [ - { - "code": "failing", - "errors": [], - "filename": "file.ts", - }, - { - "code": "passing", - "errors": [], - "filename": "file.ts", - }, - ], - "valid": [ - { - "code": "always passing string test", - "filename": "file.ts", - }, - { - "code": "failing", - "filename": "file.ts", - }, - { - "code": "passing", - "filename": "file.ts", - }, - ], - } - `); - }); - - describe('constructor constraints', () => { - it('skips all tests if a constructor constraint is not satisifed', () => { - const ruleTester = new RuleTester({ - parser: '@typescript-eslint/parser', - dependencyConstraints: { - 'totally-real-dependency': '999', - }, - }); - - ruleTester.run('my-rule', NOOP_RULE, { - invalid: [ - { - code: 'failing - major', - errors: [], - }, - ], - valid: [ - { - code: 'passing - major', - }, - ], - }); - - // trigger the describe block - expect(mockedDescribe.mock.calls.length).toBeGreaterThanOrEqual(1); - mockedDescribe.mock.lastCall?.[1](); - expect(mockedDescribe.mock.calls).toMatchInlineSnapshot(` - [ - [ - "my-rule", - [Function], - ], - ] - `); - expect(mockedIt.mock.lastCall).toMatchInlineSnapshot(` - [ - "All tests skipped due to unsatisfied constructor dependency constraints", - [Function], - ] - `); - }); - - it('does not skip all tests if a constructor constraint is satisifed', () => { - const ruleTester = new RuleTester({ - parser: '@typescript-eslint/parser', - dependencyConstraints: { - 'totally-real-dependency': '10', - }, - }); - - ruleTester.run('my-rule', NOOP_RULE, { - invalid: [ - { - code: 'valid', - errors: [], - }, - ], - valid: [ - { - code: 'valid', - }, - ], - }); - - // trigger the describe block - expect(mockedDescribe.mock.calls.length).toBeGreaterThanOrEqual(1); - mockedDescribe.mock.lastCall?.[1](); - expect(mockedDescribe.mock.calls).toMatchInlineSnapshot(` - [ - [ - "my-rule", - [Function], - ], - [ - "valid", - [Function], - ], - [ - "invalid", - [Function], - ], - ] - `); - // expect(mockedIt.mock.lastCall).toMatchInlineSnapshot(`undefined`); - }); - }); - }); -}); diff --git a/packages/website/blog/2023-03-13-announcing-typescript-eslint-v6-beta.md b/packages/website/blog/2023-03-13-announcing-typescript-eslint-v6-beta.md index df9d101c516..d2236bc9e84 100644 --- a/packages/website/blog/2023-03-13-announcing-typescript-eslint-v6-beta.md +++ b/packages/website/blog/2023-03-13-announcing-typescript-eslint-v6-beta.md @@ -244,6 +244,7 @@ If you author any ESLint rules that refer to the syntax mentioned by them, these - `TSIndexSignature`, `TSMethodSignature`, and `TSPropertySignatureBase` no longer have an `export` property. - `TSPropertySignatureBase` no longer has an `initializer` property. - [fix(typescript-estree): account for namespace nesting in AST conversion](https://github.com/typescript-eslint/typescript-eslint/pull/6272): Namespaces with qualified names like `Abc.Def` now use a `TSQualifiedName` node, instead of a nested body structure. +- [feat: remove semantically invalid properties from TSEnumDeclaration, TSInterfaceDeclaration and TSModuleDeclaration](https://github.com/typescript-eslint/typescript-eslint/pull/4863): Removes some properties from those AST node types that should generally not have existed to begin with. ### Errors on Invalid AST Parsing @@ -275,9 +276,47 @@ For more information, see: - The backing issue: [Parsing: strictly enforce the produced AST matches the spec and enforce most "error recovery" parsing errors](https://github.com/typescript-eslint/typescript-eslint/issues/1852) - The implementing pull request: [feat(typescript-estree): added allowInvalidAST option to throw on invalid tokens](https://github.com/typescript-eslint/typescript-eslint/pull/6247) +### Standalone `RuleTester` package + +Previously we provided a version of ESLint's `RuleTester` class from `@typescript-eslint/utils/eslint-utils`. This version was a sub-class of the original version and was implemented in a very fragile way that made it hard to test, maintain and build new features into. + +This was also reasonably cumbersome for users to access as users had to do deep imports in order to access the class without a namespace. + +In v6 we have extracted this into its own package - `@typescript-eslint/rule-tester`. Additionally instead of being a hacky subclass it's now a complete fork of the original tooling. For the most part you should be able to update your tests as follows: + +```ts +// Remove this line +import { TSESLint } from '@typescript-eslint/utils'; +// Add this line +import { RuleTester } from '@typescript-eslint/rule-tester'; + +import rule from '../src/rules/my-rule'; + +// Remove this line +const ruleTester = new TSESLint.RuleTester({ +// Add this line +const ruleTester = new RuleTester({ + parser: '@typescript-eslint/parser', +}); + +ruleTester.run('my-rule', rule, { /* ... */ }); +``` + +Breaking changes: + +- Previously if you set `parserOptions.ecmaFeatures.jsx = true` the rule tester would attempt to look for a fixture named `file.tsx`. Now instead the rule tester will look for a file named `react.tsx`. + - The previous behavior was incorrect because it would encourage you to have both `file.ts` and `file.tsx` and TypeScript would ignore one of those files, causing weird breakages in tests. + - You can control the default filenames by passing `defaultFilenames` to the `RuleTester` constructor. + +New features: + +- `skip: boolean` - the inverse option of `only: boolean`. When `true` we will use your test framework's test skip functionality (`it.skip`) to mark the test as skipped. This is useful during development as it enables you to control which tests run without needing to comment blocks out. +- Dependency version filtering. It's useful to test your rule against multiple versions of your dependencies to ensure it doesn't break on older versions. However in some cases certain tests will not work on older versions of some dependencies due to features that didn't exist until recently - for example a test might use newer syntax that didn't exist in an older version of TypeScript. Our rule tester includes options that allow you to declare the allowed version ranges for a test so that it is automatically skipped when necessary. + +For more information on the package, [see the `rule-tester` package documentation](/architecture/rule-tester). + ### Other Developer-Facing Breaking Changes -- [feat: remove semantically invalid properties from TSEnumDeclaration, TSInterfaceDeclaration and TSModuleDeclaration](https://github.com/typescript-eslint/typescript-eslint/pull/4863): Removes some properties from those AST node types that should generally not have existed to begin with. - [fix(utils): removed TRuleListener generic from the createRule](https://github.com/typescript-eslint/typescript-eslint/pull/5036): Makes `createRule`-created rules more portable in the type system. - [feat(utils): remove (ts-)eslint-scope types](https://github.com/typescript-eslint/typescript-eslint/pull/5256): Removes no-longer-useful `TSESLintScope` types from the `@typescript-eslint/utils` package. Use `@typescript-eslint/scope-manager` directly instead. - [fix: rename typeParameters to typeArguments where needed](https://github.com/typescript-eslint/typescript-eslint/pull/5384): corrects the names of AST properties that were called _parameters_ instead of _arguments_. @@ -287,8 +326,8 @@ For more information, see: - [Enhancement: Add test-only console warnings to deprecated AST properties](https://github.com/typescript-eslint/typescript-eslint/issues/6469): The properties will include a `console.log` that triggers only in test environments, to encourage developers to move off of them. - [feat(scope-manager): ignore ECMA version](https://github.com/typescript-eslint/typescript-eslint/pull/5889): `@typescript-eslint/scope-manager` no longer includes properties referring to `ecmaVersion`, `isES6`, or other ECMA versioning options. It instead now always assumes ESNext. - [feat: remove partial type-information program](https://github.com/typescript-eslint/typescript-eslint/pull/6066): When user configurations don't provide a `parserOptions.project`, parser services will no longer include a `program` with incomplete type information. `program` will be `null` instead. -- [feat: remove experimental-utils](https://github.com/typescript-eslint/typescript-eslint/pull/6468): The `@typescript-eslint/experimental-utils` package has since been renamed to `@typescript-eslint/utils`. - As a result, the `errorOnTypeScriptSyntacticAndSemanticIssues` option will no longer be allowed if `parserOptions.project` is not provided. +- [feat: remove experimental-utils](https://github.com/typescript-eslint/typescript-eslint/pull/6468): The `@typescript-eslint/experimental-utils` package has since been renamed to `@typescript-eslint/utils`. - [feat(typescript-estree): remove optionality from AST boolean properties](https://github.com/typescript-eslint/typescript-eslint/pull/6274): Switches most AST properties marked as `?: boolean` to `: boolean`, as well as some properties marked as `?:` optional to `| undefined`. This results in more predictable AST node object shapes. - [chore(typescript-estree): remove visitor-keys backwards compat export](https://github.com/typescript-eslint/typescript-eslint/pull/6242): `visitorKeys` can now only be imported from `@typescript-eslint/visitor-keys`. Previously it was also re-exported by `@typescript-eslint/utils`. - [feat: add package.json exports for public packages](https://github.com/typescript-eslint/typescript-eslint/pull/6458): `@typescript-eslint/*` packages now use `exports` to prevent importing internal file paths.