From a2ffe5568df0f7224bfe9141d298e538383d5f09 Mon Sep 17 00:00:00 2001 From: Ville Lahdenvuo Date: Tue, 9 Jun 2020 19:35:32 +0200 Subject: [PATCH] feat(eslint-plugin): [naming-convention] better error message and docs for prefix/suffix (#2195) --- .../eslint-plugin/docs/rules/naming-convention.md | 4 ++++ .../eslint-plugin/src/rules/naming-convention.ts | 14 ++++++++++++-- .../tests/rules/naming-convention.test.ts | 6 +++--- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/packages/eslint-plugin/docs/rules/naming-convention.md b/packages/eslint-plugin/docs/rules/naming-convention.md index 43874c6b008..ec21837594f 100644 --- a/packages/eslint-plugin/docs/rules/naming-convention.md +++ b/packages/eslint-plugin/docs/rules/naming-convention.md @@ -150,6 +150,8 @@ The `prefix` / `suffix` options control which prefix/suffix strings must exist f If these are provided, the identifier must start with one of the provided values. For example, if you provide `{ prefix: ['IFace', 'Class', 'Type'] }`, then the following names are valid: `IFaceFoo`, `ClassBar`, `TypeBaz`, but the name `Bang` is not valid, as it contains none of the prefixes. +**Note:** As [documented above](#format-options), the prefix is trimmed before format is validated, therefore PascalCase must be used to allow variables such as `isEnabled` using the prefix `is`. + ### Selector Options - `selector` (see "Allowed Selectors, Modifiers and Types" below). @@ -277,6 +279,8 @@ Group Selectors are provided for convenience, and essentially bundle up sets of ### Enforce that boolean variables are prefixed with an allowed verb +**Note:** As [documented above](#format-options), the prefix is trimmed before format is validated, thus PascalCase must be used to allow variables such as `isEnabled`. + ```json { "@typescript-eslint/naming-convention": [ diff --git a/packages/eslint-plugin/src/rules/naming-convention.ts b/packages/eslint-plugin/src/rules/naming-convention.ts index d5ea49463bd..bdbedc625ea 100644 --- a/packages/eslint-plugin/src/rules/naming-convention.ts +++ b/packages/eslint-plugin/src/rules/naming-convention.ts @@ -12,7 +12,8 @@ type MessageIds = | 'missingUnderscore' | 'missingAffix' | 'satisfyCustom' - | 'doesNotMatchFormat'; + | 'doesNotMatchFormat' + | 'doesNotMatchFormatTrimmed'; // #region Options Type Config @@ -355,6 +356,8 @@ export default util.createRule({ '{{type}} name `{{name}}` must {{regexMatch}} the RegExp: {{regex}}', doesNotMatchFormat: '{{type}} name `{{name}}` must match one of the following formats: {{formats}}', + doesNotMatchFormatTrimmed: + '{{type}} name `{{name}}` trimmed as `{{processedName}}` must match one of the following formats: {{formats}}', }, schema: SCHEMA, }, @@ -869,18 +872,21 @@ function createValidator( affixes, formats, originalName, + processedName, position, custom, }: { affixes?: string[]; formats?: PredefinedFormats[]; originalName: string; + processedName?: string; position?: 'leading' | 'trailing' | 'prefix' | 'suffix'; custom?: NonNullable; }): Record { return { type: selectorTypeToMessageString(type), name: originalName, + processedName, position, affixes: affixes?.join(', '), formats: formats?.map(f => PredefinedFormats[f]).join(', '), @@ -1052,9 +1058,13 @@ function createValidator( context.report({ node, - messageId: 'doesNotMatchFormat', + messageId: + originalName === name + ? 'doesNotMatchFormat' + : 'doesNotMatchFormatTrimmed', data: formatReportData({ originalName, + processedName: name, formats, }), }); diff --git a/packages/eslint-plugin/tests/rules/naming-convention.test.ts b/packages/eslint-plugin/tests/rules/naming-convention.test.ts index 13f67f6c988..e907f26e8a6 100644 --- a/packages/eslint-plugin/tests/rules/naming-convention.test.ts +++ b/packages/eslint-plugin/tests/rules/naming-convention.test.ts @@ -864,7 +864,7 @@ ruleTester.run('naming-convention', rule, { }, ], parserOptions, - errors: Array(16).fill({ messageId: 'doesNotMatchFormat' }), + errors: Array(16).fill({ messageId: 'doesNotMatchFormatTrimmed' }), }, { code: ` @@ -886,7 +886,7 @@ ruleTester.run('naming-convention', rule, { }, ], parserOptions, - errors: Array(4).fill({ messageId: 'doesNotMatchFormat' }), + errors: Array(4).fill({ messageId: 'doesNotMatchFormatTrimmed' }), }, { code: ` @@ -918,7 +918,7 @@ ruleTester.run('naming-convention', rule, { }, ], parserOptions, - errors: Array(8).fill({ messageId: 'doesNotMatchFormat' }), + errors: Array(8).fill({ messageId: 'doesNotMatchFormatTrimmed' }), }, { code: `