From 85e3f6915153fcca1b220acf337a5319e41a9927 Mon Sep 17 00:00:00 2001 From: Vincent Langlet Date: Tue, 29 Jan 2019 10:04:07 +0100 Subject: [PATCH 1/5] Handle I18n case --- src/rules/interfaceNameRule.ts | 8 ++++++-- test/rules/interface-name/never-prefix/test.ts.lint | 3 +++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/rules/interfaceNameRule.ts b/src/rules/interfaceNameRule.ts index b33281c4dbe..5809268e1a9 100644 --- a/src/rules/interfaceNameRule.ts +++ b/src/rules/interfaceNameRule.ts @@ -74,6 +74,10 @@ function walk(ctx: Lint.WalkContext<{ never: boolean }>): void { } function hasPrefixI(name: string): boolean { - // Allow IndexedDB interfaces - return name.length >= 2 && name[0] === "I" && isUpperCase(name[1]) && !name.startsWith("IDB"); + return name.length >= 2 && name[0] === "I" && isUpperCase(name[1]) && !isSpecialCase(name); +} + +function isSpecialCase(name: string): boolean { + // Allow IndexedDB and I18n interfaces + return name.startsWith("IDB") || name.startsWith("I18n"); } diff --git a/test/rules/interface-name/never-prefix/test.ts.lint b/test/rules/interface-name/never-prefix/test.ts.lint index 84d59f63b1f..00a98bc4ce0 100644 --- a/test/rules/interface-name/never-prefix/test.ts.lint +++ b/test/rules/interface-name/never-prefix/test.ts.lint @@ -8,6 +8,9 @@ interface I { interface IDBFactory { } +interface I18nFactory { +} + interface ABC { } From da6c8f1e4cf6b29a62a9a5bf7a3f85ccfc3ff6cf Mon Sep 17 00:00:00 2001 From: Vincent Langlet Date: Mon, 4 Feb 2019 10:17:58 +0100 Subject: [PATCH 2/5] Handle all numeric --- src/rules/interfaceNameRule.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/rules/interfaceNameRule.ts b/src/rules/interfaceNameRule.ts index 5809268e1a9..5a40f5c82f4 100644 --- a/src/rules/interfaceNameRule.ts +++ b/src/rules/interfaceNameRule.ts @@ -19,7 +19,7 @@ import * as utils from "tsutils"; import * as ts from "typescript"; import * as Lint from "../index"; -import { isUpperCase } from "../utils"; +import { isLowerCase } from "../utils"; const OPTION_ALWAYS = "always-prefix"; const OPTION_NEVER = "never-prefix"; @@ -74,10 +74,10 @@ function walk(ctx: Lint.WalkContext<{ never: boolean }>): void { } function hasPrefixI(name: string): boolean { - return name.length >= 2 && name[0] === "I" && isUpperCase(name[1]) && !isSpecialCase(name); + return name.length >= 2 && name[0] === "I" && !isLowerCase(name[1]) && !isSpecialCase(name); } function isSpecialCase(name: string): boolean { - // Allow IndexedDB and I18n interfaces - return name.startsWith("IDB") || name.startsWith("I18n"); + // Allow IndexedDB + return name.startsWith("IDB"); } From 540220b855583fc5560b4440d8e2a39070c5b35c Mon Sep 17 00:00:00 2001 From: Vincent Langlet Date: Mon, 4 Feb 2019 10:54:53 +0100 Subject: [PATCH 3/5] Improve --- src/rules/interfaceNameRule.ts | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/rules/interfaceNameRule.ts b/src/rules/interfaceNameRule.ts index 5a40f5c82f4..5a7641b093f 100644 --- a/src/rules/interfaceNameRule.ts +++ b/src/rules/interfaceNameRule.ts @@ -19,7 +19,7 @@ import * as utils from "tsutils"; import * as ts from "typescript"; import * as Lint from "../index"; -import { isLowerCase } from "../utils"; +import { isLowerCase, isUpperCase } from "../utils"; const OPTION_ALWAYS = "always-prefix"; const OPTION_NEVER = "never-prefix"; @@ -74,10 +74,5 @@ function walk(ctx: Lint.WalkContext<{ never: boolean }>): void { } function hasPrefixI(name: string): boolean { - return name.length >= 2 && name[0] === "I" && !isLowerCase(name[1]) && !isSpecialCase(name); -} - -function isSpecialCase(name: string): boolean { - // Allow IndexedDB - return name.startsWith("IDB"); + return name.length >= 3 && name[0] === "I" && !isLowerCase(name[1]) && !isUpperCase(name[2]); } From 96f85fb72caab16e7dfa1cdac4893bc3d18082e4 Mon Sep 17 00:00:00 2001 From: Vincent Langlet Date: Fri, 15 Feb 2019 02:28:06 +0100 Subject: [PATCH 4/5] Update interfaceNameRule.ts --- src/rules/interfaceNameRule.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/rules/interfaceNameRule.ts b/src/rules/interfaceNameRule.ts index 5a7641b093f..119ccee182f 100644 --- a/src/rules/interfaceNameRule.ts +++ b/src/rules/interfaceNameRule.ts @@ -64,7 +64,7 @@ function walk(ctx: Lint.WalkContext<{ never: boolean }>): void { const { name } = node; if (never && hasPrefixI(name.text)) { ctx.addFailureAtNode(name, Rule.FAILURE_STRING_NO_PREFIX); - } else if (!never && name.text[0] !== "I") { + } else if (!never && !hasPrefixI(name.text) && !isEdgeCase(name.text)) { ctx.addFailureAtNode(name, Rule.FAILURE_STRING); } } else { @@ -76,3 +76,7 @@ function walk(ctx: Lint.WalkContext<{ never: boolean }>): void { function hasPrefixI(name: string): boolean { return name.length >= 3 && name[0] === "I" && !isLowerCase(name[1]) && !isUpperCase(name[2]); } + +function isEdgeCase(name: string): boolean { + return name.length === 2 && name[0] === "I" && !isLowerCase(name[1]); +} From 6a15011994858b4da48b017ececdb78159a3077c Mon Sep 17 00:00:00 2001 From: Vincent Langlet Date: Sat, 23 Feb 2019 18:02:53 +0100 Subject: [PATCH 5/5] Fix edge case --- src/rules/interfaceNameRule.ts | 17 +++++++++++------ .../interface-name/always-prefix/test.ts.lint | 13 +++++++++++++ .../interface-name/never-prefix/test.ts.lint | 6 ++++++ 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/rules/interfaceNameRule.ts b/src/rules/interfaceNameRule.ts index 119ccee182f..32f169f5e2c 100644 --- a/src/rules/interfaceNameRule.ts +++ b/src/rules/interfaceNameRule.ts @@ -62,10 +62,12 @@ function walk(ctx: Lint.WalkContext<{ never: boolean }>): void { return ts.forEachChild(ctx.sourceFile, function cb(node: ts.Node): void { if (utils.isInterfaceDeclaration(node)) { const { name } = node; - if (never && hasPrefixI(name.text)) { - ctx.addFailureAtNode(name, Rule.FAILURE_STRING_NO_PREFIX); - } else if (!never && !hasPrefixI(name.text) && !isEdgeCase(name.text)) { - ctx.addFailureAtNode(name, Rule.FAILURE_STRING); + if (!cantDecide(name.text)) { + if (never && hasPrefixI(name.text)) { + ctx.addFailureAtNode(name, Rule.FAILURE_STRING_NO_PREFIX); + } else if (!never && !hasPrefixI(name.text)) { + ctx.addFailureAtNode(name, Rule.FAILURE_STRING); + } } } else { return ts.forEachChild(node, cb); @@ -77,6 +79,9 @@ function hasPrefixI(name: string): boolean { return name.length >= 3 && name[0] === "I" && !isLowerCase(name[1]) && !isUpperCase(name[2]); } -function isEdgeCase(name: string): boolean { - return name.length === 2 && name[0] === "I" && !isLowerCase(name[1]); +function cantDecide(name: string): boolean { + return ( + (name.length === 2 && name[0] === "I" && !isLowerCase(name[1])) || + (name.length >= 2 && name[0] === "I" && !isLowerCase(name[1]) && !isLowerCase(name[2])) + ); } diff --git a/test/rules/interface-name/always-prefix/test.ts.lint b/test/rules/interface-name/always-prefix/test.ts.lint index df81902d1d8..7dda122e691 100644 --- a/test/rules/interface-name/always-prefix/test.ts.lint +++ b/test/rules/interface-name/always-prefix/test.ts.lint @@ -2,7 +2,20 @@ interface IOptions { } +interface ID { +} + +interface IABC { +} + +interface IDBFactory { +} + // invalid code interface Options { ~~~~~~~ [interface name must start with a capitalized I] } + +interface Incomplete { + ~~~~~~~~~~ [interface name must start with a capitalized I] +} diff --git a/test/rules/interface-name/never-prefix/test.ts.lint b/test/rules/interface-name/never-prefix/test.ts.lint index 00a98bc4ce0..f6afc38f412 100644 --- a/test/rules/interface-name/never-prefix/test.ts.lint +++ b/test/rules/interface-name/never-prefix/test.ts.lint @@ -5,6 +5,12 @@ interface Index { interface I { } +interface ID { +} + +interface IABC { +} + interface IDBFactory { }