From aae214284da8a5128093f0391d044fd90df27e07 Mon Sep 17 00:00:00 2001 From: Alexander T Date: Wed, 18 Dec 2019 18:21:11 +0200 Subject: [PATCH 1/2] fix(eslint-plugin): [quotes] ignore backticks for Enum members --- packages/eslint-plugin/src/rules/quotes.ts | 3 +- .../eslint-plugin/tests/rules/quotes.test.ts | 69 +++++++++++++++++++ 2 files changed, 71 insertions(+), 1 deletion(-) diff --git a/packages/eslint-plugin/src/rules/quotes.ts b/packages/eslint-plugin/src/rules/quotes.ts index 25a9d3b4c9e..6f576bde36c 100644 --- a/packages/eslint-plugin/src/rules/quotes.ts +++ b/packages/eslint-plugin/src/rules/quotes.ts @@ -36,7 +36,8 @@ export default util.createRule({ option === 'backtick' && (parent?.type === AST_NODE_TYPES.TSModuleDeclaration || parent?.type === AST_NODE_TYPES.TSLiteralType || - parent?.type === AST_NODE_TYPES.TSPropertySignature) + parent?.type === AST_NODE_TYPES.TSPropertySignature || + parent?.type === AST_NODE_TYPES.TSEnumMember) ) { return; } diff --git a/packages/eslint-plugin/tests/rules/quotes.test.ts b/packages/eslint-plugin/tests/rules/quotes.test.ts index feb312deb99..e931e52ce06 100644 --- a/packages/eslint-plugin/tests/rules/quotes.test.ts +++ b/packages/eslint-plugin/tests/rules/quotes.test.ts @@ -353,6 +353,32 @@ interface Foo { b: string; 'a-b': boolean; 'a-b-c': boolean; +} + `, + options: ['backtick'], + }, + { + code: ` +enum Foo { + A = 1, + "A-B" = 2 +} + `, + }, + { + code: ` +enum Foo { + A = 1, + 'A-B' = 2 +} + `, + options: ['single'], + }, + { + code: ` +enum Foo { + A = 1, + 'A-B' = 2 } `, options: ['backtick'], @@ -684,5 +710,48 @@ interface Foo { ], options: ['single'], }, + { + code: ` +enum Foo { + A = 1, + 'A-B' = 2 +} + `, + output: ` +enum Foo { + A = 1, + "A-B" = 2 +} + `, + errors: [ + { + ...useDoubleQuote, + line: 4, + column: 3, + }, + ], + }, + { + code: ` +enum Foo { + A = 1, + "A-B" = 2 +} + `, + output: ` +enum Foo { + A = 1, + 'A-B' = 2 +} + `, + errors: [ + { + ...useSingleQuote, + line: 4, + column: 3, + }, + ], + options: ['single'], + }, ], }); From 98f7b4513b55b2a7dbc6617d57169db3f2543633 Mon Sep 17 00:00:00 2001 From: Alexander T Date: Thu, 19 Dec 2019 17:22:58 +0200 Subject: [PATCH 2/2] feat(eslint-plugin): [quotes] handle more TypeScript node types --- packages/eslint-plugin/src/rules/quotes.ts | 37 +- .../eslint-plugin/tests/rules/quotes.test.ts | 421 +++++++++++++++++- 2 files changed, 447 insertions(+), 11 deletions(-) diff --git a/packages/eslint-plugin/src/rules/quotes.ts b/packages/eslint-plugin/src/rules/quotes.ts index 6f576bde36c..6a8e91814c1 100644 --- a/packages/eslint-plugin/src/rules/quotes.ts +++ b/packages/eslint-plugin/src/rules/quotes.ts @@ -1,4 +1,7 @@ -import { AST_NODE_TYPES } from '@typescript-eslint/experimental-utils'; +import { + AST_NODE_TYPES, + TSESTree, +} from '@typescript-eslint/experimental-utils'; import baseRule from 'eslint/lib/rules/quotes'; import * as util from '../util'; @@ -29,16 +32,32 @@ export default util.createRule({ create(context, [option]) { const rules = baseRule.create(context); + function isAllowedAsNonBacktick(node: TSESTree.Literal): boolean { + const parent = node.parent; + + switch (parent?.type) { + case AST_NODE_TYPES.TSAbstractMethodDefinition: + case AST_NODE_TYPES.TSMethodSignature: + case AST_NODE_TYPES.TSPropertySignature: + case AST_NODE_TYPES.TSModuleDeclaration: + case AST_NODE_TYPES.TSLiteralType: + return true; + + case AST_NODE_TYPES.TSEnumMember: + return node === parent.id; + + case AST_NODE_TYPES.TSAbstractClassProperty: + case AST_NODE_TYPES.ClassProperty: + return node === parent.key; + + default: + return false; + } + } + return { Literal(node): void { - const parent = node.parent; - if ( - option === 'backtick' && - (parent?.type === AST_NODE_TYPES.TSModuleDeclaration || - parent?.type === AST_NODE_TYPES.TSLiteralType || - parent?.type === AST_NODE_TYPES.TSPropertySignature || - parent?.type === AST_NODE_TYPES.TSEnumMember) - ) { + if (option === 'backtick' && isAllowedAsNonBacktick(node)) { return; } diff --git a/packages/eslint-plugin/tests/rules/quotes.test.ts b/packages/eslint-plugin/tests/rules/quotes.test.ts index e931e52ce06..c6bf01f3e77 100644 --- a/packages/eslint-plugin/tests/rules/quotes.test.ts +++ b/packages/eslint-plugin/tests/rules/quotes.test.ts @@ -357,6 +357,8 @@ interface Foo { `, options: ['backtick'], }, + + // TSEnumMember { code: ` enum Foo { @@ -377,8 +379,120 @@ enum Foo { { code: ` enum Foo { - A = 1, - 'A-B' = 2 + A = \`A\`, + 'A-B' = \`A-B\` +} + `, + options: ['backtick'], + }, + + // TSMethodSignature + { + code: ` +interface Foo { + a(): void; + "a-b"(): void; +} + `, + }, + { + code: ` +interface Foo { + a(): void; + 'a-b'(): void; +} + `, + options: ['single'], + }, + { + code: ` +interface Foo { + a(): void; + 'a-b'(): void; +} + `, + options: ['backtick'], + }, + + // ClassProperty + { + code: ` +class Foo { + public a = ""; + public "a-b" = ""; +} + `, + }, + { + code: ` +class Foo { + public a = ''; + public 'a-b' = ''; +} + `, + options: ['single'], + }, + { + code: ` +class Foo { + public a = \`\`; + public 'a-b' = \`\`; +} + `, + options: ['backtick'], + }, + + // TSAbstractClassProperty + { + code: ` +abstract class Foo { + public abstract a = ""; + public abstract "a-b" = ""; +} + `, + }, + { + code: ` +abstract class Foo { + public abstract a = ''; + public abstract 'a-b' = ''; +} + `, + options: ['single'], + }, + { + code: ` +abstract class Foo { + public abstract a = \`\`; + public abstract 'a-b' = \`\`; +} + `, + options: ['backtick'], + }, + + // TSAbstractMethodDefinition + { + code: ` +abstract class Foo { + public abstract a(): void; + public abstract "a-b"(): void; +} + `, + }, + { + code: ` +abstract class Foo { + public abstract a(): void; + public abstract 'a-b'(): void; +} + `, + options: ['single'], + }, + { + code: ` +abstract class Foo { + public abstract a(): void; + public abstract 'a-b'(): void; } `, options: ['backtick'], @@ -710,6 +824,8 @@ interface Foo { ], options: ['single'], }, + + // Enums { code: ` enum Foo { @@ -753,5 +869,306 @@ enum Foo { ], options: ['single'], }, + { + code: ` +enum Foo { + A = 'A', + 'A-B' = 'A-B' +} + `, + output: ` +enum Foo { + A = \`A\`, + 'A-B' = \`A-B\` +} + `, + errors: [ + { + ...useBacktick, + line: 3, + column: 7, + }, + { + ...useBacktick, + line: 4, + column: 11, + }, + ], + options: ['backtick'], + }, + + // TSMethodSignature + { + code: ` +interface Foo { + a(): void; + 'a-b'(): void; +} + `, + output: ` +interface Foo { + a(): void; + "a-b"(): void; +} + `, + errors: [ + { + ...useDoubleQuote, + line: 4, + column: 3, + }, + ], + }, + { + code: ` +interface Foo { + a(): void; + "a-b"(): void; +} + `, + output: ` +interface Foo { + a(): void; + 'a-b'(): void; +} + `, + errors: [ + { + ...useSingleQuote, + line: 4, + column: 3, + }, + ], + options: ['single'], + }, + + // ClassProperty + { + code: ` +class Foo { + public a = ''; + public 'a-b' = ''; +} + `, + output: ` +class Foo { + public a = ""; + public "a-b" = ""; +} + `, + errors: [ + { + ...useDoubleQuote, + line: 3, + column: 14, + }, + { + ...useDoubleQuote, + line: 4, + column: 10, + }, + { + ...useDoubleQuote, + line: 4, + column: 18, + }, + ], + }, + { + code: ` +class Foo { + public a = ""; + public "a-b" = ""; +} + `, + output: ` +class Foo { + public a = ''; + public 'a-b' = ''; +} + `, + errors: [ + { + ...useSingleQuote, + line: 3, + column: 14, + }, + { + ...useSingleQuote, + line: 4, + column: 10, + }, + { + ...useSingleQuote, + line: 4, + column: 18, + }, + ], + options: ['single'], + }, + { + code: ` +class Foo { + public a = ""; + public "a-b" = ""; +} + `, + output: ` +class Foo { + public a = \`\`; + public "a-b" = \`\`; +} + `, + errors: [ + { + ...useBacktick, + line: 3, + column: 14, + }, + { + ...useBacktick, + line: 4, + column: 18, + }, + ], + options: ['backtick'], + }, + + // TSAbstractClassProperty + { + code: ` +abstract class Foo { + public abstract a = ''; + public abstract 'a-b' = ''; +} + `, + output: ` +abstract class Foo { + public abstract a = ""; + public abstract "a-b" = ""; +} + `, + errors: [ + { + ...useDoubleQuote, + line: 3, + column: 23, + }, + { + ...useDoubleQuote, + line: 4, + column: 19, + }, + { + ...useDoubleQuote, + line: 4, + column: 27, + }, + ], + }, + { + code: ` +abstract class Foo { + public abstract a = ""; + public abstract "a-b" = ""; +} + `, + output: ` +abstract class Foo { + public abstract a = ''; + public abstract 'a-b' = ''; +} + `, + errors: [ + { + ...useSingleQuote, + line: 3, + column: 23, + }, + { + ...useSingleQuote, + line: 4, + column: 19, + }, + { + ...useSingleQuote, + line: 4, + column: 27, + }, + ], + options: ['single'], + }, + { + code: ` +abstract class Foo { + public abstract a = ""; + public abstract "a-b" = ""; +} + `, + output: ` +abstract class Foo { + public abstract a = \`\`; + public abstract "a-b" = \`\`; +} + `, + errors: [ + { + ...useBacktick, + line: 3, + column: 23, + }, + { + ...useBacktick, + line: 4, + column: 27, + }, + ], + options: ['backtick'], + }, + + // TSAbstractMethodDefinition + { + code: ` +abstract class Foo { + public abstract a(): void; + public abstract 'a-b'(): void; +} + `, + output: ` +abstract class Foo { + public abstract a(): void; + public abstract "a-b"(): void; +} + `, + errors: [ + { + ...useDoubleQuote, + line: 4, + column: 19, + }, + ], + }, + { + code: ` +abstract class Foo { + public abstract a(): void; + public abstract "a-b"(): void; +} + `, + output: ` +abstract class Foo { + public abstract a(): void; + public abstract 'a-b'(): void; +} + `, + errors: [ + { + ...useSingleQuote, + line: 4, + column: 19, + }, + ], + options: ['single'], + }, ], });