diff --git a/packages/eslint-plugin/src/rules/class-name-casing.ts b/packages/eslint-plugin/src/rules/class-name-casing.ts index b27bf1ebcf14..cbcc805630d4 100644 --- a/packages/eslint-plugin/src/rules/class-name-casing.ts +++ b/packages/eslint-plugin/src/rules/class-name-casing.ts @@ -67,7 +67,13 @@ export default util.createRule({ * @param decl The declaration * @param id The name of the declaration */ - function report(decl: TSESTree.Node, id: TSESTree.Identifier): void { + function report( + decl: + | TSESTree.ClassDeclaration + | TSESTree.TSInterfaceDeclaration + | TSESTree.ClassExpression, + id: TSESTree.Identifier, + ): void { let friendlyName; switch (decl.type) { @@ -78,8 +84,6 @@ export default util.createRule({ case AST_NODE_TYPES.TSInterfaceDeclaration: friendlyName = 'Interface'; break; - default: - friendlyName = decl.type; } context.report({ diff --git a/packages/eslint-plugin/src/rules/explicit-member-accessibility.ts b/packages/eslint-plugin/src/rules/explicit-member-accessibility.ts index fe8c38c03413..ebfbae27329d 100644 --- a/packages/eslint-plugin/src/rules/explicit-member-accessibility.ts +++ b/packages/eslint-plugin/src/rules/explicit-member-accessibility.ts @@ -183,7 +183,7 @@ export default util.createRule({ /** * Checks that the parameter property has the desired accessibility modifiers set. - * @param {TSESTree.TSParameterProperty} node The node representing a Parameter Property + * @param node The node representing a Parameter Property */ function checkParameterPropertyAccessibilityModifier( node: TSESTree.TSParameterProperty, diff --git a/packages/eslint-plugin/src/rules/no-array-constructor.ts b/packages/eslint-plugin/src/rules/no-array-constructor.ts index 749ce2ba7ada..731cb960973c 100644 --- a/packages/eslint-plugin/src/rules/no-array-constructor.ts +++ b/packages/eslint-plugin/src/rules/no-array-constructor.ts @@ -15,7 +15,7 @@ export default util.createRule({ }, fixable: 'code', messages: { - useLiteral: 'The array literal notation [] is preferrable.', + useLiteral: 'The array literal notation [] is preferable.', }, schema: [], }, diff --git a/packages/eslint-plugin/src/rules/no-empty-interface.ts b/packages/eslint-plugin/src/rules/no-empty-interface.ts index cb43721cac45..039415ad68f4 100644 --- a/packages/eslint-plugin/src/rules/no-empty-interface.ts +++ b/packages/eslint-plugin/src/rules/no-empty-interface.ts @@ -49,33 +49,25 @@ export default util.createRule({ return; } - if (!node.extends || node.extends.length === 0) { + const extend = node.extends; + if (!extend || extend.length === 0) { context.report({ node: node.id, messageId: 'noEmpty', }); - } else if (node.extends.length === 1) { + } else if (extend.length === 1) { // interface extends exactly 1 interface --> Report depending on rule setting - if (allowSingleExtends) { - return; - } else { + if (!allowSingleExtends) { context.report({ node: node.id, messageId: 'noEmptyWithSuper', - fix(fixer) { - if (node.extends && node.extends.length) { - return [ - fixer.replaceText( - node, - `type ${sourceCode.getText( - node.id, - )} = ${sourceCode.getText(node.extends[0])}`, - ), - ]; - } - - return null; - }, + fix: fixer => + fixer.replaceText( + node, + `type ${sourceCode.getText(node.id)} = ${sourceCode.getText( + extend[0], + )}`, + ), }); } } diff --git a/packages/eslint-plugin/src/rules/no-misused-new.ts b/packages/eslint-plugin/src/rules/no-misused-new.ts index 67d00b131f0e..d0331e19fa35 100644 --- a/packages/eslint-plugin/src/rules/no-misused-new.ts +++ b/packages/eslint-plugin/src/rules/no-misused-new.ts @@ -22,7 +22,7 @@ export default util.createRule({ defaultOptions: [], create(context) { /** - * @param {ASTNode} node type to be inspected. + * @param node type to be inspected. * @returns name of simple type or null */ function getTypeReferenceName( @@ -48,8 +48,8 @@ export default util.createRule({ } /** - * @param {ASTNode} parent parent node. - * @param {ASTNode} returnType type to be compared + * @param parent parent node. + * @param returnType type to be compared */ function isMatchingParentType( parent: undefined | TSESTree.Node, diff --git a/packages/eslint-plugin/src/rules/no-type-alias.ts b/packages/eslint-plugin/src/rules/no-type-alias.ts index 02aca84e3151..d8e22e9d2196 100644 --- a/packages/eslint-plugin/src/rules/no-type-alias.ts +++ b/packages/eslint-plugin/src/rules/no-type-alias.ts @@ -218,8 +218,7 @@ export default util.createRule({ /** * Validates the node looking for aliases, callbacks and literals. - * @param node the node to be validated. - * @param compositionType the type of composition this alias is part of (null if not + * @param type the type of composition this alias is part of (null if not * part of a composition) * @param isTopLevel a flag indicating this is the top level node. */ diff --git a/packages/eslint-plugin/src/rules/no-unnecessary-type-assertion.ts b/packages/eslint-plugin/src/rules/no-unnecessary-type-assertion.ts index 61cbbcb99b9c..6696b127c10b 100644 --- a/packages/eslint-plugin/src/rules/no-unnecessary-type-assertion.ts +++ b/packages/eslint-plugin/src/rules/no-unnecessary-type-assertion.ts @@ -245,7 +245,7 @@ export default util.createRule({ node: TSESTree.TSTypeAssertion | TSESTree.TSAsExpression, ): void { if ( - options?.typesToIgnore?.includes( + options.typesToIgnore?.includes( sourceCode.getText(node.typeAnnotation), ) ) { diff --git a/packages/eslint-plugin/tests/fixtures/class.ts b/packages/eslint-plugin/tests/fixtures/class.ts new file mode 100644 index 000000000000..9b8aac7d7e38 --- /dev/null +++ b/packages/eslint-plugin/tests/fixtures/class.ts @@ -0,0 +1,2 @@ +// used by no-throw-literal test case to validate custom error +export class Error {} diff --git a/packages/eslint-plugin/tests/rules/array-type.test.ts b/packages/eslint-plugin/tests/rules/array-type.test.ts index 86cb1940826b..b74c06c09fd1 100644 --- a/packages/eslint-plugin/tests/rules/array-type.test.ts +++ b/packages/eslint-plugin/tests/rules/array-type.test.ts @@ -42,15 +42,15 @@ ruleTester.run('array-type', rule, { options: [{ default: 'generic' }], }, { - code: `let fooVar: Array;`, + code: 'let fooVar: Array;', options: [{ default: 'generic' }], }, { - code: `function foo (a: Array): Array {}`, + code: 'function foo (a: Array): Array {}', options: [{ default: 'generic' }], }, { - code: `let yy: number[][] = [[4, 5], [6]];`, + code: 'let yy: number[][] = [[4, 5], [6]];', options: [{ default: 'array-simple' }], }, { @@ -66,15 +66,15 @@ ruleTester.run('array-type', rule, { options: [{ default: 'array-simple' }], }, { - code: `let fooVar: Array<(c: number) => number>;`, + code: 'let fooVar: Array<(c: number) => number>;', options: [{ default: 'array-simple' }], }, { - code: `type fooUnion = Array;`, + code: 'type fooUnion = Array;', options: [{ default: 'array-simple' }], }, { - code: `type fooIntersection = Array;`, + code: 'type fooIntersection = Array;', options: [{ default: 'array-simple' }], }, { @@ -91,11 +91,11 @@ ruleTester.run('array-type', rule, { options: [{ default: 'array-simple' }], }, { - code: `let yy: number[][] = [[4, 5], [6]];`, + code: 'let yy: number[][] = [[4, 5], [6]];', options: [{ default: 'array' }], }, { - code: `let ya = [[1, "2"]] as[number, string][];`, + code: 'let ya = [[1, "2"]] as[number, string][];', options: [{ default: 'array' }], }, { @@ -111,15 +111,15 @@ ruleTester.run('array-type', rule, { options: [{ default: 'array' }], }, { - code: `let barVar: ((c: number) => number)[];`, + code: 'let barVar: ((c: number) => number)[];', options: [{ default: 'array' }], }, { - code: `type barUnion = (string|number|boolean)[];`, + code: 'type barUnion = (string|number|boolean)[];', options: [{ default: 'array' }], }, { - code: `type barIntersection = (string & number)[];`, + code: 'type barIntersection = (string & number)[];', options: [{ default: 'array' }], }, { @@ -134,15 +134,15 @@ ruleTester.run('array-type', rule, { options: [{ default: 'array' }], }, { - code: `let z: Array = [3, "4"];`, + code: 'let z: Array = [3, "4"];', options: [{ default: 'generic' }], }, { - code: `let xx: Array> = [[1, 2], [3]];`, + code: 'let xx: Array> = [[1, 2], [3]];', options: [{ default: 'generic' }], }, { - code: `type Arr = Array;`, + code: 'type Arr = Array;', options: [{ default: 'generic' }], }, { @@ -158,15 +158,15 @@ ruleTester.run('array-type', rule, { options: [{ default: 'generic' }], }, { - code: `let fooVar: Array<(c: number) => number>;`, + code: 'let fooVar: Array<(c: number) => number>;', options: [{ default: 'generic' }], }, { - code: `type fooUnion = Array;`, + code: 'type fooUnion = Array;', options: [{ default: 'generic' }], }, { - code: `type fooIntersection = Array;`, + code: 'type fooIntersection = Array;', options: [{ default: 'generic' }], }, { @@ -189,15 +189,15 @@ ruleTester.run('array-type', rule, { options: [{ default: 'array', readonly: 'generic' }], }, { - code: `let a: Array = []`, + code: 'let a: Array = []', options: [{ default: 'generic', readonly: 'array' }], }, { - code: `let a: readonly number[] = []`, + code: 'let a: readonly number[] = []', options: [{ default: 'generic', readonly: 'array' }], }, { - code: `let a: readonly Array[] = [[]]`, + code: 'let a: readonly Array[] = [[]]', options: [{ default: 'generic', readonly: 'array' }], }, ], @@ -313,8 +313,27 @@ ruleTester.run('array-type', rule, { ], }, { - code: `let x: Array = [undefined] as undefined[];`, - output: `let x: undefined[] = [undefined] as undefined[];`, + code: 'let a: Array<>[] = []', + output: 'let a: any[][] = []', + options: [{ default: 'array-simple' }], + errors: [ + { + messageId: 'errorStringGenericSimple', + data: { type: 'T' }, + line: 1, + column: 8, + }, + { + messageId: 'errorStringArraySimple', + data: { type: 'any' }, + line: 1, + column: 8, + }, + ], + }, + { + code: 'let x: Array = [undefined] as undefined[];', + output: 'let x: undefined[] = [undefined] as undefined[];', options: [{ default: 'array-simple' }], errors: [ { @@ -326,8 +345,8 @@ ruleTester.run('array-type', rule, { ], }, { - code: `let xx: Array = [];`, - output: `let xx: object[] = [];`, + code: 'let xx: Array = [];', + output: 'let xx: object[] = [];', options: [{ default: 'array-simple' }], errors: [ { @@ -339,8 +358,8 @@ ruleTester.run('array-type', rule, { ], }, { - code: `let y: string[] = >["2"];`, - output: `let y: string[] = ["2"];`, + code: 'let y: string[] = >["2"];', + output: 'let y: string[] = ["2"];', options: [{ default: 'array-simple' }], errors: [ { @@ -352,8 +371,8 @@ ruleTester.run('array-type', rule, { ], }, { - code: `let z: Array = [3, "4"];`, - output: `let z: any[] = [3, "4"];`, + code: 'let z: Array = [3, "4"];', + output: 'let z: any[] = [3, "4"];', options: [{ default: 'array-simple' }], errors: [ { @@ -365,8 +384,8 @@ ruleTester.run('array-type', rule, { ], }, { - code: `let ya = [[1, "2"]] as[number, string][];`, - output: `let ya = [[1, "2"]] as Array<[number, string]>;`, + code: 'let ya = [[1, "2"]] as[number, string][];', + output: 'let ya = [[1, "2"]] as Array<[number, string]>;', options: [{ default: 'array-simple' }], errors: [ { @@ -378,8 +397,8 @@ ruleTester.run('array-type', rule, { ], }, { - code: `type Arr = Array;`, - output: `type Arr = T[];`, + code: 'type Arr = Array;', + output: 'type Arr = T[];', options: [{ default: 'array-simple' }], errors: [ { @@ -446,8 +465,8 @@ let yyyy: Arr>>> = [[[["2"]]]];`, ], }, { - code: `let barVar: ((c: number) => number)[];`, - output: `let barVar: Array<(c: number) => number>;`, + code: 'let barVar: ((c: number) => number)[];', + output: 'let barVar: Array<(c: number) => number>;', options: [{ default: 'array-simple' }], errors: [ { @@ -459,8 +478,8 @@ let yyyy: Arr>>> = [[[["2"]]]];`, ], }, { - code: `type barUnion = (string|number|boolean)[];`, - output: `type barUnion = Array;`, + code: 'type barUnion = (string|number|boolean)[];', + output: 'type barUnion = Array;', options: [{ default: 'array-simple' }], errors: [ { @@ -472,8 +491,8 @@ let yyyy: Arr>>> = [[[["2"]]]];`, ], }, { - code: `type barIntersection = (string & number)[];`, - output: `type barIntersection = Array;`, + code: 'type barIntersection = (string & number)[];', + output: 'type barIntersection = Array;', options: [{ default: 'array-simple' }], errors: [ { @@ -485,8 +504,8 @@ let yyyy: Arr>>> = [[[["2"]]]];`, ], }, { - code: `let v: Array = [{ bar: "bar" }];`, - output: `let v: fooName.BarType[] = [{ bar: "bar" }];`, + code: 'let v: Array = [{ bar: "bar" }];', + output: 'let v: fooName.BarType[] = [{ bar: "bar" }];', options: [{ default: 'array-simple' }], errors: [ { @@ -498,8 +517,8 @@ let yyyy: Arr>>> = [[[["2"]]]];`, ], }, { - code: `let w: fooName.BazType[] = [["baz"]];`, - output: `let w: Array> = [["baz"]];`, + code: 'let w: fooName.BazType[] = [["baz"]];', + output: 'let w: Array> = [["baz"]];', options: [{ default: 'array-simple' }], errors: [ { @@ -511,8 +530,8 @@ let yyyy: Arr>>> = [[[["2"]]]];`, ], }, { - code: `let x: Array = [undefined] as undefined[];`, - output: `let x: undefined[] = [undefined] as undefined[];`, + code: 'let x: Array = [undefined] as undefined[];', + output: 'let x: undefined[] = [undefined] as undefined[];', options: [{ default: 'array' }], errors: [ { @@ -524,8 +543,8 @@ let yyyy: Arr>>> = [[[["2"]]]];`, ], }, { - code: `let y: string[] = >["2"];`, - output: `let y: string[] = ["2"];`, + code: 'let y: string[] = >["2"];', + output: 'let y: string[] = ["2"];', options: [{ default: 'array' }], errors: [ { @@ -537,8 +556,8 @@ let yyyy: Arr>>> = [[[["2"]]]];`, ], }, { - code: `let z: Array = [3, "4"];`, - output: `let z: any[] = [3, "4"];`, + code: 'let z: Array = [3, "4"];', + output: 'let z: any[] = [3, "4"];', options: [{ default: 'array' }], errors: [ { @@ -550,8 +569,8 @@ let yyyy: Arr>>> = [[[["2"]]]];`, ], }, { - code: `type Arr = Array;`, - output: `type Arr = T[];`, + code: 'type Arr = Array;', + output: 'type Arr = T[];', options: [{ default: 'array' }], errors: [ { @@ -616,8 +635,8 @@ let yyyy: Arr[][]> = [[[["2"]]]];`, ], }, { - code: `let fooVar: Array<(c: number) => number>;`, - output: `let fooVar: ((c: number) => number)[];`, + code: 'let fooVar: Array<(c: number) => number>;', + output: 'let fooVar: ((c: number) => number)[];', options: [{ default: 'array' }], errors: [ { @@ -629,8 +648,8 @@ let yyyy: Arr[][]> = [[[["2"]]]];`, ], }, { - code: `type fooUnion = Array;`, - output: `type fooUnion = (string|number|boolean)[];`, + code: 'type fooUnion = Array;', + output: 'type fooUnion = (string|number|boolean)[];', options: [{ default: 'array' }], errors: [ { @@ -642,8 +661,8 @@ let yyyy: Arr[][]> = [[[["2"]]]];`, ], }, { - code: `type fooIntersection = Array;`, - output: `type fooIntersection = (string & number)[];`, + code: 'type fooIntersection = Array;', + output: 'type fooIntersection = (string & number)[];', options: [{ default: 'array' }], errors: [ { @@ -655,7 +674,7 @@ let yyyy: Arr[][]> = [[[["2"]]]];`, ], }, { - code: `let fooVar: Array[];`, + code: 'let fooVar: Array[];', options: [{ default: 'array' }], errors: [ { @@ -667,7 +686,7 @@ let yyyy: Arr[][]> = [[[["2"]]]];`, ], }, { - code: `let fooVar: Array[];`, + code: 'let fooVar: Array[];', options: [{ default: 'array-simple' }], errors: [ { @@ -679,8 +698,8 @@ let yyyy: Arr[][]> = [[[["2"]]]];`, ], }, { - code: `let x: Array = [1] as number[];`, - output: `let x: Array = [1] as Array;`, + code: 'let x: Array = [1] as number[];', + output: 'let x: Array = [1] as Array;', options: [{ default: 'generic' }], errors: [ { @@ -692,8 +711,8 @@ let yyyy: Arr[][]> = [[[["2"]]]];`, ], }, { - code: `let y: string[] = >["2"];`, - output: `let y: Array = >["2"];`, + code: 'let y: string[] = >["2"];', + output: 'let y: Array = >["2"];', options: [{ default: 'generic' }], errors: [ { @@ -705,8 +724,8 @@ let yyyy: Arr[][]> = [[[["2"]]]];`, ], }, { - code: `let ya = [[1, "2"]] as[number, string][];`, - output: `let ya = [[1, "2"]] as Array<[number, string]>;`, + code: 'let ya = [[1, "2"]] as[number, string][];', + output: 'let ya = [[1, "2"]] as Array<[number, string]>;', options: [{ default: 'generic' }], errors: [ { @@ -771,8 +790,8 @@ let yyyy: Arr>>> = [[[["2"]]]];`, ], }, { - code: `let barVar: ((c: number) => number)[];`, - output: `let barVar: Array<(c: number) => number>;`, + code: 'let barVar: ((c: number) => number)[];', + output: 'let barVar: Array<(c: number) => number>;', options: [{ default: 'generic' }], errors: [ { @@ -784,8 +803,8 @@ let yyyy: Arr>>> = [[[["2"]]]];`, ], }, { - code: `type barUnion = (string|number|boolean)[];`, - output: `type barUnion = Array;`, + code: 'type barUnion = (string|number|boolean)[];', + output: 'type barUnion = Array;', options: [{ default: 'generic' }], errors: [ { @@ -797,8 +816,8 @@ let yyyy: Arr>>> = [[[["2"]]]];`, ], }, { - code: `type barIntersection = (string & number)[];`, - output: `type barIntersection = Array;`, + code: 'type barIntersection = (string & number)[];', + output: 'type barIntersection = Array;', options: [{ default: 'generic' }], errors: [ { @@ -1001,104 +1020,104 @@ class Foo extends Bar implements Baz { ); testOutput( 'array-simple', - `let xx: Array> = [[1, 2], [3]];`, - `let xx: number[][] = [[1, 2], [3]];`, + 'let xx: Array> = [[1, 2], [3]];', + 'let xx: number[][] = [[1, 2], [3]];', ); testOutput( 'array', - `let xx: Array> = [[1, 2], [3]];`, - `let xx: number[][] = [[1, 2], [3]];`, + 'let xx: Array> = [[1, 2], [3]];', + 'let xx: number[][] = [[1, 2], [3]];', ); testOutput( 'generic', - `let yy: number[][] = [[4, 5], [6]];`, - `let yy: Array> = [[4, 5], [6]];`, + 'let yy: number[][] = [[4, 5], [6]];', + 'let yy: Array> = [[4, 5], [6]];', ); // readonly testOutput( 'generic', - `let x: readonly number[][]`, - `let x: ReadonlyArray>`, + 'let x: readonly number[][]', + 'let x: ReadonlyArray>', ); testOutput( 'generic', - `let x: readonly (readonly number[])[]`, - `let x: ReadonlyArray>`, + 'let x: readonly (readonly number[])[]', + 'let x: ReadonlyArray>', ); testOutput( 'array', - `let x: ReadonlyArray>`, - `let x: readonly number[][]`, + 'let x: ReadonlyArray>', + 'let x: readonly number[][]', ); testOutput( 'array', - `let x: ReadonlyArray>`, - `let x: readonly (readonly number[])[]`, + 'let x: ReadonlyArray>', + 'let x: readonly (readonly number[])[]', ); testOutput( 'array', - `let x: ReadonlyArray`, - `let x: readonly (readonly number[])[]`, + 'let x: ReadonlyArray', + 'let x: readonly (readonly number[])[]', ); testOutput( 'array', - `let x: ReadonlyArray`, - `let x: ReadonlyArray`, + 'let x: ReadonlyArray', + 'let x: ReadonlyArray', 'generic', ); testOutput( 'array', - `let a: string[] = []`, - `let a: string[] = []`, + 'let a: string[] = []', + 'let a: string[] = []', 'generic', ); testOutput( 'array', - `let a: readonly number[][] = []`, - `let a: ReadonlyArray = []`, + 'let a: readonly number[][] = []', + 'let a: ReadonlyArray = []', 'generic', ); testOutput( 'generic', - `let a: string[] = []`, - `let a: Array = []`, + 'let a: string[] = []', + 'let a: Array = []', 'array', ); testOutput( 'generic', - `let a: readonly number[][] = []`, - `let a: readonly Array[] = []`, + 'let a: readonly number[][] = []', + 'let a: readonly Array[] = []', 'array', ); testOutput( 'generic', - `type T = readonly(string)[]`, - `type T = ReadonlyArray`, + 'type T = readonly(string)[]', + 'type T = ReadonlyArray', 'generic', ); testOutput( 'generic', - `let a: readonly(readonly string[])[] = []`, - `let a: ReadonlyArray> = []`, + 'let a: readonly(readonly string[])[] = []', + 'let a: ReadonlyArray> = []', 'generic', ); testOutput( 'generic', - `type T = readonly(readonly string[])[]`, - `type T = ReadonlyArray>`, + 'type T = readonly(readonly string[])[]', + 'type T = ReadonlyArray>', 'generic', ); testOutput( 'generic', - `type T = readonly (readonly string[])[]`, - `type T = ReadonlyArray>`, + 'type T = readonly (readonly string[])[]', + 'type T = ReadonlyArray>', 'generic', ); testOutput( 'generic', - `type T = readonly (readonly string[])[]`, - `type T = ReadonlyArray>`, + 'type T = readonly (readonly string[])[]', + 'type T = ReadonlyArray>', 'generic', ); }); diff --git a/packages/eslint-plugin/tests/rules/class-name-casing.test.ts b/packages/eslint-plugin/tests/rules/class-name-casing.test.ts index 7c89c699d5eb..11f6dc8b8889 100644 --- a/packages/eslint-plugin/tests/rules/class-name-casing.test.ts +++ b/packages/eslint-plugin/tests/rules/class-name-casing.test.ts @@ -34,6 +34,14 @@ ruleTester.run('class-name-casing', rule, { 'class ClassNameWithUnicodeÈ {}', 'class ÈClassNameWithUnicode {}', 'class ClassNameWithæUnicode {}', + // Following test cases are valid, but no one is going to write code like this + 'var { bar } = class { static bar() { return 2 } }', + `var [ bar ] = class { + static [Symbol.iterator]() { + return { next: () => ({ value: 1, done: false}) } + } + } + `, ], invalid: [ @@ -164,7 +172,7 @@ ruleTester.run('class-name-casing', rule, { ], }, { - code: `class æInvalidClassNameWithUnicode {}`, + code: 'class æInvalidClassNameWithUnicode {}', errors: [ { messageId: 'notPascalCased', 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 7eb6bcd076b2..b5477c062a10 100644 --- a/packages/eslint-plugin/tests/rules/explicit-member-accessibility.test.ts +++ b/packages/eslint-plugin/tests/rules/explicit-member-accessibility.test.ts @@ -252,11 +252,7 @@ class Test { constructor(public foo: number){} } `, - options: [ - { - accessibility: 'no-public', - }, - ], + options: [{ accessibility: 'no-public' }], }, { filename: 'test.ts', @@ -267,11 +263,7 @@ class Test { } } `, - options: [ - { - ignoredMethodNames: ['getX'], - }, - ], + options: [{ ignoredMethodNames: ['getX'] }], }, { filename: 'test.ts', @@ -282,11 +274,7 @@ class Test { } } `, - options: [ - { - ignoredMethodNames: ['getX'], - }, - ], + options: [{ ignoredMethodNames: ['getX'] }], }, { filename: 'test.ts', @@ -297,11 +285,7 @@ class Test { } } `, - options: [ - { - ignoredMethodNames: ['getX'], - }, - ], + options: [{ ignoredMethodNames: ['getX'] }], }, { filename: 'test.ts', @@ -312,11 +296,29 @@ class Test { } } `, - options: [ - { - ignoredMethodNames: ['getX'], - }, - ], + options: [{ ignoredMethodNames: ['getX'] }], + }, + { + filename: 'test.ts', + code: 'class Test { x = 2 }', + options: [{ overrides: { properties: 'off' } }], + }, + { + filename: 'test.ts', + code: 'class Test { private x = 2 }', + options: [{ overrides: { properties: 'explicit' } }], + }, + { + filename: 'test.ts', + code: `class Test { + x = 2 + private x = 2 + }`, + options: [{ overrides: { properties: 'no-public' } }], + }, + { + code: 'class Test { constructor(private { x }: any[]) { }}', + options: [{ accessibility: 'no-public' }], }, ], invalid: [ @@ -656,5 +658,53 @@ class Test { }, ], }, + { + filename: 'test.ts', + code: 'class Test { x = 2 }', + options: [ + { + accessibility: 'off', + overrides: { properties: 'explicit' }, + }, + ], + errors: [ + { + messageId: 'missingAccessibility', + line: 1, + column: 14, + }, + ], + }, + { + filename: 'test.ts', + code: `class Test { + public x = 2 + private x = 2 + }`, + options: [ + { + accessibility: 'off', + overrides: { properties: 'no-public' }, + }, + ], + errors: [ + { + messageId: 'unwantedPublicAccessibility', + line: 2, + column: 9, + }, + ], + }, + { + code: 'class Test { constructor(public ...x: any[]) { }}', + options: [{ accessibility: 'explicit' }], + errors: [ + { + messageId: 'missingAccessibility', + line: 1, + column: 14, + }, + ], + }, ], }); 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 2cc784d4e23d..414d86245d5f 100644 --- a/packages/eslint-plugin/tests/rules/no-misused-new.test.ts +++ b/packages/eslint-plugin/tests/rules/no-misused-new.test.ts @@ -14,40 +14,22 @@ declare abstract class C { get new (); bar(); } - `, - ` -class C { - constructor(); -} - `, - ` -class C { - constructor() {} -} - `, + `, + 'class C { constructor(); }', + 'const foo = class { constructor(); }', + 'const foo = class { new(): X }', // OK if there's a body - ` -class C { - new() {} -} - `, + 'class C { new() {} }', + 'class C { constructor() {} }', + 'const foo = class { new() {} }', + 'const foo = class { constructor() {} }', // OK if return type is not the interface. - ` -interface I { - new(): {}; -} - `, + 'interface I { new(): {}; }', // 'new' OK in type literal (we don't know the type name) - ` -type T = { - new(): T; -} - `, - ` -export default class { - constructor(); -} - `, + 'type T = { new(): T; }', + 'export default class { constructor(); }', + 'interface foo { new(): bar; }', + "interface foo { new(): 'x'; }", ], invalid: [ { @@ -128,5 +110,19 @@ declare abstract class C { }, ], }, + { + code: ` +interface I { + constructor(): ''; +} +`, + errors: [ + { + messageId: 'errorMessageInterface', + line: 3, + column: 5, + }, + ], + }, ], }); 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 8cec2d66d9dd..359c2abf3c51 100644 --- a/packages/eslint-plugin/tests/rules/no-throw-literal.test.ts +++ b/packages/eslint-plugin/tests/rules/no-throw-literal.test.ts @@ -4,6 +4,7 @@ import { RuleTester, getFixturesRootDir } from '../RuleTester'; const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 2018, + sourceType: 'module', tsconfigRootDir: getFixturesRootDir(), project: './tsconfig.json', }, @@ -12,117 +13,72 @@ const ruleTester = new RuleTester({ ruleTester.run('no-throw-literal', rule, { valid: [ - { - code: `throw new Error();`, - }, - { - code: `throw new Error('error');`, - }, - { - code: `throw Error('error');`, - }, - { - code: ` + 'throw new Error();', + "throw new Error('error');", + "throw Error('error');", + ` const e = new Error(); throw e; - `, - }, - { - code: ` + `, + ` try { throw new Error(); } catch (e) { throw e; } - `, - }, - { - code: ` + `, + ` function foo() { return new Error(); } - throw foo(); - `, - }, - { - code: ` + `, + ` const foo = { bar: new Error() } - throw foo.bar; - `, - }, - { - code: ` + `, + ` const foo = { bar: new Error() } throw foo['bar']; - `, - }, - { - code: ` + `, + ` const foo = { bar: new Error() } const bar = 'bar'; throw foo[bar]; - `, - }, - { - code: ` + `, + ` class CustomError extends Error {}; throw new CustomError(); - `, - }, - { - code: ` + `, + ` class CustomError1 extends Error {} class CustomError2 extends CustomError1 {} throw new CustomError(); - `, - }, - { - code: `throw foo = new Error();`, - }, - { - code: `throw 1, 2, new Error();`, - }, - { - code: `throw 'literal' && new Error();`, - }, - { - code: `throw new Error() || 'literal'`, - }, - { - code: `throw foo ? new Error() : 'literal';`, - }, - { - code: `throw foo ? 'literal' : new Error();`, - }, - { - code: ` -function* foo() { - let index = 0; - throw yield index++; -} - `, - }, - { - code: ` -async function foo() { - throw await bar; -} - `, - }, + `, + 'throw foo = new Error();', + 'throw 1, 2, new Error();', + "throw 'literal' && new Error();", + "throw new Error() || 'literal'", + "throw foo ? new Error() : 'literal';", + "throw foo ? 'literal' : new Error();", + 'function* foo() { let index = 0; throw yield index++; }', + 'async function foo() { throw await bar; }', + ` +import { Error } from './missing'; +throw Error; + `, ], invalid: [ { - code: `throw undefined;`, + code: 'throw undefined;', errors: [ { messageId: 'undef', @@ -130,7 +86,7 @@ async function foo() { ], }, { - code: `throw new String('');`, + code: "throw new String('');", errors: [ { messageId: 'object', @@ -138,7 +94,7 @@ async function foo() { ], }, { - code: `throw 'error';`, + code: "throw 'error';", errors: [ { messageId: 'object', @@ -146,7 +102,7 @@ async function foo() { ], }, { - code: `throw 0;`, + code: 'throw 0;', errors: [ { messageId: 'object', @@ -154,7 +110,7 @@ async function foo() { ], }, { - code: `throw false;`, + code: 'throw false;', errors: [ { messageId: 'object', @@ -162,7 +118,7 @@ async function foo() { ], }, { - code: `throw null;`, + code: 'throw null;', errors: [ { messageId: 'object', @@ -170,7 +126,7 @@ async function foo() { ], }, { - code: `throw {};`, + code: 'throw {};', errors: [ { messageId: 'object', @@ -178,7 +134,7 @@ async function foo() { ], }, { - code: `throw 'a' + 'b';`, + code: "throw 'a' + 'b';", errors: [ { messageId: 'object', @@ -197,7 +153,7 @@ throw a + 'b'; ], }, { - code: `throw foo = 'error';`, + code: "throw foo = 'error';", errors: [ { messageId: 'object', @@ -205,7 +161,7 @@ throw a + 'b'; ], }, { - code: `throw new Error(), 1, 2, 3;`, + code: 'throw new Error(), 1, 2, 3;', errors: [ { messageId: 'object', @@ -213,7 +169,7 @@ throw a + 'b'; ], }, { - code: `throw 'literal' && 'not an Error';`, + code: "throw 'literal' && 'not an Error';", errors: [ { messageId: 'object', @@ -221,7 +177,7 @@ throw a + 'b'; ], }, { - code: `throw foo ? 'not an Error' : 'literal';`, + code: "throw foo ? 'not an Error' : 'literal';", errors: [ { messageId: 'object', @@ -319,5 +275,18 @@ throw Error; }, ], }, + { + code: ` +import { Error } from './class'; +throw new Error(); + `, + errors: [ + { + messageId: 'object', + line: 3, + column: 7, + }, + ], + }, ], }); 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 be5ca84b9e5b..9d6b0cd0f97f 100644 --- a/packages/eslint-plugin/tests/rules/no-type-alias.test.ts +++ b/packages/eslint-plugin/tests/rules/no-type-alias.test.ts @@ -358,7 +358,8 @@ type Foo = { options: [{ allowMappedTypes: 'in-intersections' }], }, { - code: `export type ClassValue = string | number | ClassDictionary | ClassArray | undefined | null | false;`, + code: + 'export type ClassValue = string | number | ClassDictionary | ClassArray | undefined | null | false;', options: [ { allowAliases: 'in-unions-and-intersections', @@ -2974,7 +2975,7 @@ type Foo = { }, { // https://github.com/typescript-eslint/typescript-eslint/issues/270 - code: `export type ButtonProps = JSX.IntrinsicElements['button'];`, + code: "export type ButtonProps = JSX.IntrinsicElements['button'];", errors: [ { messageId: 'noTypeAlias', @@ -3225,5 +3226,29 @@ type Foo = { }, ], }, + { + // unique symbol is not allowed in this context + code: 'type Foo = keyof [string] | unique symbol;', + errors: [ + { + messageId: 'noCompositionAlias', + data: { + compositionType: 'union', + typeName: 'Tuple Types', + }, + line: 1, + column: 12, + }, + { + messageId: 'noCompositionAlias', + data: { + compositionType: 'union', + typeName: 'Unhandled', + }, + line: 1, + column: 29, + }, + ], + }, ], }); 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 73a8619b6a48..b4f079f39605 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 @@ -30,6 +30,8 @@ const foo = ({ hello: "hello" }) as PossibleTuple;`, ` type PossibleTuple = { 0: "hello", 5: "hello" }; const foo = ({ 0: "hello", 5: "hello" }) as PossibleTuple;`, + `let bar: number | undefined = x; + let foo: number = bar!;`, { code: ` type Foo = number; @@ -37,15 +39,15 @@ const foo = (3 + 5) as Foo;`, options: [{ typesToIgnore: ['Foo'] }], }, { - code: `const foo = (3 + 5) as any;`, + code: 'const foo = (3 + 5) as any;', options: [{ typesToIgnore: ['any'] }], }, { - code: `((Syntax as any).ArrayExpression = 'foo')`, + code: "((Syntax as any).ArrayExpression = 'foo')", options: [{ typesToIgnore: ['any'] }], }, { - code: `const foo = (3 + 5) as string;`, + code: 'const foo = (3 + 5) as string;', options: [{ typesToIgnore: ['string'] }], }, { 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 4eb08c7e9455..0e22722afb43 100644 --- a/packages/eslint-plugin/tests/rules/prefer-for-of.test.ts +++ b/packages/eslint-plugin/tests/rules/prefer-for-of.test.ts @@ -100,6 +100,12 @@ for(let x = 0; x < arr.length(); x++) {} `, ` for(let x = 0; x < arr.length; x+=11) {} +`, + ` +for(let x = arr.length; x > 1; x-=1) {} +`, + ` +for(let x = 0; x < arr.length; x*=2) {} `, ` for(let x = 0; x < arr.length; x=x+11) {} diff --git a/packages/eslint-plugin/tests/rules/prefer-readonly.test.ts b/packages/eslint-plugin/tests/rules/prefer-readonly.test.ts index 8d6ffbf0f7a5..256e38360d9e 100644 --- a/packages/eslint-plugin/tests/rules/prefer-readonly.test.ts +++ b/packages/eslint-plugin/tests/rules/prefer-readonly.test.ts @@ -13,9 +13,9 @@ const ruleTester = new RuleTester({ ruleTester.run('prefer-readonly', rule, { valid: [ - `function ignore() { }`, - `const ignore = function () { }`, - `const ignore = () => { }`, + 'function ignore() { }', + 'const ignore = function () { }', + 'const ignore = () => { }', `const container = { member: true }; container.member;`, `const container = { member: 1 }; @@ -30,7 +30,7 @@ ruleTester.run('prefer-readonly', rule, { --container.member;`, `const container = { member: 1 }; container.member--;`, - `class TestEmpty { }`, + 'class TestEmpty { }', `class TestReadonlyStatic { private static readonly correctlyReadonlyStatic = 7; }`, 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 0785bf7a02ee..690526edf632 100644 --- a/packages/eslint-plugin/tests/rules/triple-slash-reference.test.ts +++ b/packages/eslint-plugin/tests/rules/triple-slash-reference.test.ts @@ -10,6 +10,28 @@ const ruleTester = new RuleTester({ ruleTester.run('triple-slash-reference', rule, { valid: [ + { + code: ` + // + // + // + import * as foo from "foo" + import * as bar from "bar" + import * as baz from "baz" + `, + options: [{ path: 'never', types: 'never', lib: 'never' }], + }, + { + code: ` + // + // + // + import foo = require("foo") + import bar = require("bar") + import baz = require("baz") + `, + options: [{ path: 'never', types: 'never', lib: 'never' }], + }, { code: ` /// @@ -23,26 +45,45 @@ ruleTester.run('triple-slash-reference', rule, { }, { code: ` - import * as foo from "foo" + /// + /// + /// + import foo = require("foo") + import bar = require("bar") + import baz = require("baz") `, + options: [{ path: 'always', types: 'always', lib: 'always' }], + }, + { + code: 'import * as foo from "foo"', options: [{ path: 'never' }], }, { - code: ` - import * as foo from "foo" - `, + code: 'import foo = require("foo");', + options: [{ path: 'never' }], + }, + { + code: 'import * as foo from "foo"', options: [{ types: 'never' }], }, { - code: ` - import * as foo from "foo" - `, + code: 'import foo = require("foo");', + options: [{ types: 'never' }], + }, + { + code: 'import * as foo from "foo"', options: [{ lib: 'never' }], }, { - code: ` - import * as foo from "foo" - `, + code: 'import foo = require("foo");', + options: [{ lib: 'never' }], + }, + { + code: 'import * as foo from "foo"', + options: [{ types: 'prefer-import' }], + }, + { + code: 'import foo = require("foo");', options: [{ types: 'prefer-import' }], }, { @@ -92,7 +133,7 @@ import foo = require("foo"); ], }, { - code: `/// `, + code: '/// ', options: [{ path: 'never' }], errors: [ { @@ -103,7 +144,7 @@ import foo = require("foo"); ], }, { - code: `/// `, + code: '/// ', options: [{ types: 'never' }], errors: [ { @@ -114,7 +155,7 @@ import foo = require("foo"); ], }, { - code: `/// `, + code: '/// ', options: [{ lib: 'never' }], errors: [ {