From 4b1292a159cacde11e88aa6a949de30dd7e3cdcc Mon Sep 17 00:00:00 2001 From: Mohsen Azimi Date: Wed, 20 Feb 2019 09:49:43 -0800 Subject: [PATCH 1/5] Add enum-const-style rule --- .../docs/rules/enum-const-style.md | 61 +++++++++++++++ .../src/rules/enum-const-style.ts | 54 ++++++++++++++ .../tests/rules/enum-const-style.test.ts | 74 +++++++++++++++++++ 3 files changed, 189 insertions(+) create mode 100644 packages/eslint-plugin/docs/rules/enum-const-style.md create mode 100644 packages/eslint-plugin/src/rules/enum-const-style.ts create mode 100644 packages/eslint-plugin/tests/rules/enum-const-style.test.ts diff --git a/packages/eslint-plugin/docs/rules/enum-const-style.md b/packages/eslint-plugin/docs/rules/enum-const-style.md new file mode 100644 index 000000000000..a27ed6c14f87 --- /dev/null +++ b/packages/eslint-plugin/docs/rules/enum-const-style.md @@ -0,0 +1,61 @@ +# Enforce const enum style + +This rule regulate usage of `const enum`. + +## Rule Details + +This rule aims to standardize usage of const enums. + +## Options + +### Default config: `never` + +```JSON +{ + "enum-const-style": ["error", "never"] +} +``` + +Examples of **incorrect** code for this rule with `never` config: + +```ts +enum Foo { + ONE, + TWO, +} +``` + +Examples of **correct** code for this rule with `never` config: + +```ts +const enum Foo { + ONE, + TWO, +} +``` + +### `always` config + +Only const enums are allowed + +Examples of **incorrect** code for this rule with `always` config: + +```ts +enum const Foo { + ONE, + TWO, +} +``` + +Examples of **correct** code for this rule with `always` config: + +```ts +const Foo { + ONE, + TWO, +} +``` + +## When Not To Use It + +If you don't want to regulate usage of `const enum`s. diff --git a/packages/eslint-plugin/src/rules/enum-const-style.ts b/packages/eslint-plugin/src/rules/enum-const-style.ts new file mode 100644 index 000000000000..6248d19fb1bb --- /dev/null +++ b/packages/eslint-plugin/src/rules/enum-const-style.ts @@ -0,0 +1,54 @@ +/** + * @fileoverview Enforce usage of const enum. + */ + +import { TSESTree } from '@typescript-eslint/typescript-estree'; +import * as util from '../util'; + +export default util.createRule({ + name: 'enum-const-style', + meta: { + type: 'problem', + docs: { + description: 'Enforce usage of const enum', + tslintRuleName: 'enum-const-style', + category: 'Stylistic Issues', + recommended: 'error', + }, + messages: { + noNonConstEnums: 'enums are forbidden. Use const enums', + noConstEnums: 'const enums are forbidden. Use enum', + }, + schema: [ + { + enum: ['always', 'never'], + }, + ], + }, + defaultOptions: ['never'], + create(context, [option]) { + return { + TSEnumDeclaration(node: TSESTree.TSEnumDeclaration) { + switch (option) { + default: + case 'never': + if (node.const) { + context.report({ + node, + messageId: 'noConstEnums', + }); + } + break; + case 'always': + if (!node.const) { + context.report({ + node, + messageId: 'noNonConstEnums', + }); + } + break; + } + }, + }; + }, +}); diff --git a/packages/eslint-plugin/tests/rules/enum-const-style.test.ts b/packages/eslint-plugin/tests/rules/enum-const-style.test.ts new file mode 100644 index 000000000000..3863d676df40 --- /dev/null +++ b/packages/eslint-plugin/tests/rules/enum-const-style.test.ts @@ -0,0 +1,74 @@ +import rule from '../../src/rules/enum-const-style'; +import { RuleTester } from '../RuleTester'; + +const ruleTester = new RuleTester({ + parser: '@typescript-eslint/parser', +}); + +ruleTester.run('enum-style', rule, { + valid: [ + 'enum Foo {}', + 'enum Foo { FOO }', + 'enum Foo { FOO = 1, BAR = 2 }', + 'enum Foo { FOO = "FOO", BAR = "BAR" }', + { + code: 'const enum Foo {}', + options: ['always'], + }, + { + code: 'const enum Foo { FOO }', + options: ['always'], + }, + { + code: 'const enum Foo { FOO = 1, BAR = 2 }', + options: ['always'], + }, + { + code: 'const enum Foo { FOO = "FOO", BAR = "BAR" }', + options: ['always'], + }, + ], + invalid: [ + { + code: 'const enum Foo {}', + errors: [ + { + messageId: 'noConstEnums', + data: { + name: 'Object', + }, + line: 1, + column: 1, + }, + ], + }, + { + code: 'const enum Foo {}', + errors: [ + { + messageId: 'noConstEnums', + data: { + name: 'Object', + }, + line: 1, + column: 1, + }, + ], + options: ['never'], + }, + { + code: 'enum Foo {}', + errors: [ + { + messageId: 'noNonConstEnums', + data: { + name: 'Object', + }, + line: 1, + column: 1, + }, + ], + options: ['always'], + }, + ], +}); From 3715b5f03a24137799ee49e9d817f542fe2b23ed Mon Sep 17 00:00:00 2001 From: Mohsen Azimi Date: Fri, 8 Mar 2019 09:30:33 -0500 Subject: [PATCH 2/5] fix(eslint-plugin) fix coverage --- packages/eslint-plugin/tests/rules/enum-const-style.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/eslint-plugin/tests/rules/enum-const-style.test.ts b/packages/eslint-plugin/tests/rules/enum-const-style.test.ts index 3863d676df40..b9cd6578a639 100644 --- a/packages/eslint-plugin/tests/rules/enum-const-style.test.ts +++ b/packages/eslint-plugin/tests/rules/enum-const-style.test.ts @@ -41,6 +41,7 @@ ruleTester.run('enum-style', rule, { column: 1, }, ], + options: [], }, { code: 'const enum Foo {}', From 1b54a47c2707d2bd2b4b5939c442ce72625dbc3c Mon Sep 17 00:00:00 2001 From: Armano Date: Sun, 19 Jan 2020 22:22:25 +0100 Subject: [PATCH 3/5] fix: add rule to docs, and configs --- packages/eslint-plugin/README.md | 1 + .../docs/rules/enum-const-style.md | 6 +-- packages/eslint-plugin/src/configs/all.json | 1 + .../src/rules/enum-const-style.ts | 46 ++++++++----------- packages/eslint-plugin/src/rules/index.ts | 2 + .../tests/rules/enum-const-style.test.ts | 1 - 6 files changed, 25 insertions(+), 32 deletions(-) diff --git a/packages/eslint-plugin/README.md b/packages/eslint-plugin/README.md index f2418485d521..1d63860408f6 100644 --- a/packages/eslint-plugin/README.md +++ b/packages/eslint-plugin/README.md @@ -102,6 +102,7 @@ Pro Tip: For larger codebases you may want to consider splitting our linting int | [`@typescript-eslint/ban-types`](./docs/rules/ban-types.md) | Bans specific types from being used | :heavy_check_mark: | :wrench: | | | [`@typescript-eslint/consistent-type-assertions`](./docs/rules/consistent-type-assertions.md) | Enforces consistent usage of type assertions | :heavy_check_mark: | | | | [`@typescript-eslint/consistent-type-definitions`](./docs/rules/consistent-type-definitions.md) | Consistent with type definition either `interface` or `type` | | :wrench: | | +| [`@typescript-eslint/enum-const-style`](./docs/rules/enum-const-style.md) | Enforce const enum style | | | | | [`@typescript-eslint/explicit-function-return-type`](./docs/rules/explicit-function-return-type.md) | Require explicit return types on functions and class methods | :heavy_check_mark: | | | | [`@typescript-eslint/explicit-member-accessibility`](./docs/rules/explicit-member-accessibility.md) | Require explicit accessibility modifiers on class properties and methods | | | | | [`@typescript-eslint/explicit-module-boundary-types`](./docs/rules/explicit-module-boundary-types.md) | Require explicit return and argument types on exported functions' and classes' public class methods | | | | diff --git a/packages/eslint-plugin/docs/rules/enum-const-style.md b/packages/eslint-plugin/docs/rules/enum-const-style.md index a27ed6c14f87..6db4c987594e 100644 --- a/packages/eslint-plugin/docs/rules/enum-const-style.md +++ b/packages/eslint-plugin/docs/rules/enum-const-style.md @@ -1,6 +1,6 @@ -# Enforce const enum style +# Enforce const enum style (`enum-const-style`) -This rule regulate usage of `const enum`. +This rule enforces consistent usage of `const enum`. ## Rule Details @@ -12,7 +12,7 @@ This rule aims to standardize usage of const enums. ```JSON { - "enum-const-style": ["error", "never"] + "enum-const-style": ["error", "never"] } ``` diff --git a/packages/eslint-plugin/src/configs/all.json b/packages/eslint-plugin/src/configs/all.json index 91380db19320..6e367b8d58be 100644 --- a/packages/eslint-plugin/src/configs/all.json +++ b/packages/eslint-plugin/src/configs/all.json @@ -12,6 +12,7 @@ "@typescript-eslint/consistent-type-definitions": "error", "default-param-last": "off", "@typescript-eslint/default-param-last": "error", + "@typescript-eslint/enum-const-style": "error", "@typescript-eslint/explicit-function-return-type": "error", "@typescript-eslint/explicit-member-accessibility": "error", "@typescript-eslint/explicit-module-boundary-types": "error", diff --git a/packages/eslint-plugin/src/rules/enum-const-style.ts b/packages/eslint-plugin/src/rules/enum-const-style.ts index 6248d19fb1bb..4b4474cf9bfe 100644 --- a/packages/eslint-plugin/src/rules/enum-const-style.ts +++ b/packages/eslint-plugin/src/rules/enum-const-style.ts @@ -1,19 +1,17 @@ -/** - * @fileoverview Enforce usage of const enum. - */ - -import { TSESTree } from '@typescript-eslint/typescript-estree'; +import { TSESTree } from '@typescript-eslint/experimental-utils'; import * as util from '../util'; -export default util.createRule({ +type Messages = 'noNonConstEnums' | 'noConstEnums'; +type Options = ['always' | 'never']; + +export default util.createRule({ name: 'enum-const-style', meta: { type: 'problem', docs: { - description: 'Enforce usage of const enum', - tslintRuleName: 'enum-const-style', + description: 'Enforce const enum style', category: 'Stylistic Issues', - recommended: 'error', + recommended: false, }, messages: { noNonConstEnums: 'enums are forbidden. Use const enums', @@ -26,27 +24,19 @@ export default util.createRule({ ], }, defaultOptions: ['never'], - create(context, [option]) { + create(context, [options]) { return { TSEnumDeclaration(node: TSESTree.TSEnumDeclaration) { - switch (option) { - default: - case 'never': - if (node.const) { - context.report({ - node, - messageId: 'noConstEnums', - }); - } - break; - case 'always': - if (!node.const) { - context.report({ - node, - messageId: 'noNonConstEnums', - }); - } - break; + if (options === 'always' && !node.const) { + context.report({ + node, + messageId: 'noNonConstEnums', + }); + } else if (options === 'never' && node.const) { + context.report({ + node, + messageId: 'noConstEnums', + }); } }, }; diff --git a/packages/eslint-plugin/src/rules/index.ts b/packages/eslint-plugin/src/rules/index.ts index ac12f27e8ba3..cb553aa0da7c 100644 --- a/packages/eslint-plugin/src/rules/index.ts +++ b/packages/eslint-plugin/src/rules/index.ts @@ -9,6 +9,7 @@ import classNameCasing from './class-name-casing'; import consistentTypeAssertions from './consistent-type-assertions'; import consistentTypeDefinitions from './consistent-type-definitions'; import defaultParamLast from './default-param-last'; +import enumConstStyle from './enum-const-style'; import explicitFunctionReturnType from './explicit-function-return-type'; import explicitMemberAccessibility from './explicit-member-accessibility'; import explicitModuleBoundaryTypes from './explicit-module-boundary-types'; @@ -92,6 +93,7 @@ export default { 'consistent-type-assertions': consistentTypeAssertions, 'consistent-type-definitions': consistentTypeDefinitions, 'default-param-last': defaultParamLast, + 'enum-const-style': enumConstStyle, 'explicit-function-return-type': explicitFunctionReturnType, 'explicit-member-accessibility': explicitMemberAccessibility, 'explicit-module-boundary-types': explicitModuleBoundaryTypes, diff --git a/packages/eslint-plugin/tests/rules/enum-const-style.test.ts b/packages/eslint-plugin/tests/rules/enum-const-style.test.ts index b9cd6578a639..3863d676df40 100644 --- a/packages/eslint-plugin/tests/rules/enum-const-style.test.ts +++ b/packages/eslint-plugin/tests/rules/enum-const-style.test.ts @@ -41,7 +41,6 @@ ruleTester.run('enum-style', rule, { column: 1, }, ], - options: [], }, { code: 'const enum Foo {}', From 59874c8fb64f9b7a6687a3556d7c5abf1b0c2d10 Mon Sep 17 00:00:00 2001 From: Armano Date: Sun, 19 Jan 2020 22:25:33 +0100 Subject: [PATCH 4/5] test: add missing test cases --- .../tests/rules/enum-const-style.test.ts | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/packages/eslint-plugin/tests/rules/enum-const-style.test.ts b/packages/eslint-plugin/tests/rules/enum-const-style.test.ts index 3863d676df40..b7c587a09799 100644 --- a/packages/eslint-plugin/tests/rules/enum-const-style.test.ts +++ b/packages/eslint-plugin/tests/rules/enum-const-style.test.ts @@ -27,6 +27,22 @@ ruleTester.run('enum-style', rule, { code: 'const enum Foo { FOO = "FOO", BAR = "BAR" }', options: ['always'], }, + { + code: 'enum Foo {}', + options: ['never'], + }, + { + code: 'enum Foo { FOO }', + options: ['never'], + }, + { + code: 'enum Foo { FOO = 1, BAR = 2 }', + options: ['never'], + }, + { + code: 'enum Foo { FOO = "FOO", BAR = "BAR" }', + options: ['never'], + }, ], invalid: [ { @@ -34,9 +50,6 @@ ruleTester.run('enum-style', rule, { errors: [ { messageId: 'noConstEnums', - data: { - name: 'Object', - }, line: 1, column: 1, }, @@ -47,9 +60,6 @@ ruleTester.run('enum-style', rule, { errors: [ { messageId: 'noConstEnums', - data: { - name: 'Object', - }, line: 1, column: 1, }, @@ -61,9 +71,6 @@ ruleTester.run('enum-style', rule, { errors: [ { messageId: 'noNonConstEnums', - data: { - name: 'Object', - }, line: 1, column: 1, }, From e69261ebf4b7ecedcad41643074f5182f2bcb16a Mon Sep 17 00:00:00 2001 From: Armano Date: Sun, 19 Jan 2020 22:29:49 +0100 Subject: [PATCH 5/5] fix: correct linting issue --- packages/eslint-plugin/src/rules/enum-const-style.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/eslint-plugin/src/rules/enum-const-style.ts b/packages/eslint-plugin/src/rules/enum-const-style.ts index 4b4474cf9bfe..1f77971f7419 100644 --- a/packages/eslint-plugin/src/rules/enum-const-style.ts +++ b/packages/eslint-plugin/src/rules/enum-const-style.ts @@ -26,7 +26,7 @@ export default util.createRule({ defaultOptions: ['never'], create(context, [options]) { return { - TSEnumDeclaration(node: TSESTree.TSEnumDeclaration) { + TSEnumDeclaration(node: TSESTree.TSEnumDeclaration): void { if (options === 'always' && !node.const) { context.report({ node,