From 0e70c411dd767f177860f395eda93b936f6d544c Mon Sep 17 00:00:00 2001 From: Yeliz Henden Date: Fri, 4 Apr 2025 16:01:12 +0100 Subject: [PATCH 1/7] CLOUDP-306582: IPA-126: Top-Level API Names --- .../IPA126TagNamesShouldUseTitleCase.test.js | 169 ++++++++++++++++++ tools/spectral/ipa/ipa-spectral.yaml | 1 + tools/spectral/ipa/rulesets/IPA-126.yaml | 19 ++ tools/spectral/ipa/rulesets/README.md | 16 ++ .../IPA126TagNamesShouldUseTitleCase.js | 30 ++++ 5 files changed, 235 insertions(+) create mode 100644 tools/spectral/ipa/__tests__/IPA126TagNamesShouldUseTitleCase.test.js create mode 100644 tools/spectral/ipa/rulesets/IPA-126.yaml create mode 100644 tools/spectral/ipa/rulesets/functions/IPA126TagNamesShouldUseTitleCase.js diff --git a/tools/spectral/ipa/__tests__/IPA126TagNamesShouldUseTitleCase.test.js b/tools/spectral/ipa/__tests__/IPA126TagNamesShouldUseTitleCase.test.js new file mode 100644 index 0000000000..89a4c40300 --- /dev/null +++ b/tools/spectral/ipa/__tests__/IPA126TagNamesShouldUseTitleCase.test.js @@ -0,0 +1,169 @@ +import testRule from './__helpers__/testRule.js'; +import { DiagnosticSeverity } from '@stoplight/types'; + +testRule('xgen-IPA-126-tag-names-should-use-title-case', [ + { + name: 'valid Title Case tag names', + document: { + tags: [ + { name: 'User Management' }, + { name: 'Resource Groups' }, + { name: 'Atlas' }, + { name: 'User Profiles' }, + { name: 'Api' }, + { name: 'Users' }, + { name: 'Resources' }, + { name: 'Projects' }, + ], + }, + errors: [], + }, + { + name: 'invalid camelCase instead of Title Case', + document: { + tags: [{ name: 'userManagement' }], + }, + errors: [ + { + code: 'xgen-IPA-126-tag-names-should-use-title-case', + message: 'Tag name should use Title Case, found: "userManagement".', + path: ['tags', '0'], + severity: DiagnosticSeverity.Warning, + }, + ], + }, + { + name: 'invalid kebab-case instead of Title Case', + document: { + tags: [{ name: 'user-management' }], + }, + errors: [ + { + code: 'xgen-IPA-126-tag-names-should-use-title-case', + message: 'Tag name should use Title Case, found: "user-management".', + path: ['tags', '0'], + severity: DiagnosticSeverity.Warning, + }, + ], + }, + { + name: 'invalid snake_case instead of Title Case', + document: { + tags: [{ name: 'user_management' }], + }, + errors: [ + { + code: 'xgen-IPA-126-tag-names-should-use-title-case', + message: 'Tag name should use Title Case, found: "user_management".', + path: ['tags', '0'], + severity: DiagnosticSeverity.Warning, + }, + ], + }, + { + name: 'invalid all lowercase instead of Title Case', + document: { + tags: [{ name: 'user management' }], + }, + errors: [ + { + code: 'xgen-IPA-126-tag-names-should-use-title-case', + message: 'Tag name should use Title Case, found: "user management".', + path: ['tags', '0'], + severity: DiagnosticSeverity.Warning, + }, + ], + }, + { + name: 'invalid ALL UPPERCASE instead of Title Case', + document: { + tags: [{ name: 'USER MANAGEMENT' }], + }, + errors: [ + { + code: 'xgen-IPA-126-tag-names-should-use-title-case', + message: 'Tag name should use Title Case, found: "USER MANAGEMENT".', + path: ['tags', '0'], + severity: DiagnosticSeverity.Warning, + }, + ], + }, + { + name: 'mixed cases in multiple tags', + document: { + tags: [{ name: 'User Management' }, { name: 'resourceGroups' }, { name: 'API ENDPOINTS' }], + }, + errors: [ + { + code: 'xgen-IPA-126-tag-names-should-use-title-case', + message: 'Tag name should use Title Case, found: "resourceGroups".', + path: ['tags', '1'], + severity: DiagnosticSeverity.Warning, + }, + { + code: 'xgen-IPA-126-tag-names-should-use-title-case', + message: 'Tag name should use Title Case, found: "API ENDPOINTS".', + path: ['tags', '2'], + severity: DiagnosticSeverity.Warning, + }, + ], + }, + { + name: 'valid with exception', + document: { + tags: [ + { + name: 'legacy_tag', + 'x-xgen-IPA-exception': { + 'xgen-IPA-126-tag-names-should-use-title-case': 'Legacy tag that cannot be changed', + }, + }, + ], + }, + errors: [], + }, + { + name: 'invalid tag names', + document: { + tags: [ + { name: 'Api V1' }, + { name: 'Version 2 Resources' }, + { name: 'Push-Based Log Export' }, + { name: 'AWS Clusters DNS' }, + { name: 'Encryption at Rest using Customer Key Management' }, + ], + }, + errors: [ + { + code: 'xgen-IPA-126-tag-names-should-use-title-case', + message: 'Tag name should use Title Case, found: "Api V1".', + path: ['tags', '0'], + severity: DiagnosticSeverity.Warning, + }, + { + code: 'xgen-IPA-126-tag-names-should-use-title-case', + message: 'Tag name should use Title Case, found: "Version 2 Resources".', + path: ['tags', '1'], + severity: DiagnosticSeverity.Warning, + }, + { + code: 'xgen-IPA-126-tag-names-should-use-title-case', + message: 'Tag name should use Title Case, found: "Push-Based Log Export".', + path: ['tags', '2'], + severity: DiagnosticSeverity.Warning, + }, + { + code: 'xgen-IPA-126-tag-names-should-use-title-case', + message: 'Tag name should use Title Case, found: "AWS Clusters DNS".', + path: ['tags', '3'], + severity: DiagnosticSeverity.Warning, + }, + { + code: 'xgen-IPA-126-tag-names-should-use-title-case', + message: 'Tag name should use Title Case, found: "Encryption at Rest using Customer Key Management".', + path: ['tags', '4'], + severity: DiagnosticSeverity.Warning, + }, + ], + }, +]); diff --git a/tools/spectral/ipa/ipa-spectral.yaml b/tools/spectral/ipa/ipa-spectral.yaml index ea85043bca..c52ef721a8 100644 --- a/tools/spectral/ipa/ipa-spectral.yaml +++ b/tools/spectral/ipa/ipa-spectral.yaml @@ -18,6 +18,7 @@ extends: - ./rulesets/IPA-123.yaml - ./rulesets/IPA-124.yaml - ./rulesets/IPA-125.yaml + - ./rulesets/IPA-126.yaml overrides: - files: diff --git a/tools/spectral/ipa/rulesets/IPA-126.yaml b/tools/spectral/ipa/rulesets/IPA-126.yaml new file mode 100644 index 0000000000..c4bc6bec67 --- /dev/null +++ b/tools/spectral/ipa/rulesets/IPA-126.yaml @@ -0,0 +1,19 @@ +# IPA-126: Top-Level API Names +# http://go/ipa/126 + +functions: + - IPA126TagNamesShouldUseTitleCase +rules: + xgen-IPA-126-tag-names-should-use-title-case: + description: | + Tag names in the OpenAPI specification should use Title Case. + + ##### Implementation details + Rule checks for the following conditions: + - All tag names defined in the OpenAPI tags object should use Title Case + - Title Case means each word starts with an uppercase letter, and the rest are lowercase + message: '{{error}} https://mdb.link/mongodb-atlas-openapi-validation#xgen-IPA-126-tag-names-should-use-title-case' + severity: warn + given: $.tags[*] + then: + function: 'IPA126TagNamesShouldUseTitleCase' diff --git a/tools/spectral/ipa/rulesets/README.md b/tools/spectral/ipa/rulesets/README.md index 27e7c81fa2..b6d06f6a74 100644 --- a/tools/spectral/ipa/rulesets/README.md +++ b/tools/spectral/ipa/rulesets/README.md @@ -920,4 +920,20 @@ object types with clear discriminators. +### IPA-126 + +Rules are based on [http://go/ipa/IPA-126](http://go/ipa/IPA-126). + +#### xgen-IPA-126-tag-names-should-use-title-case + + ![warn](https://img.shields.io/badge/warning-yellow) +Tag names in the OpenAPI specification should use Title Case. + +##### Implementation details +Rule checks for the following conditions: + - All tag names defined in the OpenAPI tags object should use Title Case + - Title Case means each word starts with an uppercase letter, and the rest are lowercase + + + diff --git a/tools/spectral/ipa/rulesets/functions/IPA126TagNamesShouldUseTitleCase.js b/tools/spectral/ipa/rulesets/functions/IPA126TagNamesShouldUseTitleCase.js new file mode 100644 index 0000000000..1b2b41bf6d --- /dev/null +++ b/tools/spectral/ipa/rulesets/functions/IPA126TagNamesShouldUseTitleCase.js @@ -0,0 +1,30 @@ +import { hasException } from './utils/exceptions.js'; +import { collectAdoption, collectAndReturnViolation, collectException } from './utils/collectionUtils.js'; +import { casing } from '@stoplight/spectral-functions'; + +const RULE_NAME = 'xgen-IPA-126-tag-names-should-use-title-case'; + +export default (input, options, { path }) => { + const tagName = input.name; + if (!tagName || tagName.trim().length === 0) { + return; + } + + if (hasException(input, RULE_NAME)) { + collectException(input, RULE_NAME, path); + return; + } + + // Check if the tag name uses Title Case + if (casing(tagName, { type: 'pascal', disallowDigits: true, separator: { char: ' ' } })) { + return collectAndReturnViolation(path, RULE_NAME, [ + { + path, + message: `Tag name should use Title Case, found: "${tagName}".`, + }, + ]); + } + + // Tag name uses Title Case + collectAdoption(path, RULE_NAME); +}; From fc990a0f8b3ccb7d5fa9665f28aa38c27dec45ed Mon Sep 17 00:00:00 2001 From: Yeliz Henden Date: Fri, 4 Apr 2025 16:16:25 +0100 Subject: [PATCH 2/7] address the comments --- tools/spectral/ipa/rulesets/IPA-126.yaml | 2 +- .../rulesets/functions/IPA126TagNamesShouldUseTitleCase.js | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/tools/spectral/ipa/rulesets/IPA-126.yaml b/tools/spectral/ipa/rulesets/IPA-126.yaml index c4bc6bec67..32a6494b4c 100644 --- a/tools/spectral/ipa/rulesets/IPA-126.yaml +++ b/tools/spectral/ipa/rulesets/IPA-126.yaml @@ -14,6 +14,6 @@ rules: - Title Case means each word starts with an uppercase letter, and the rest are lowercase message: '{{error}} https://mdb.link/mongodb-atlas-openapi-validation#xgen-IPA-126-tag-names-should-use-title-case' severity: warn - given: $.tags[*] + given: $.tags[?(@.name && @.name.length > 0)] then: function: 'IPA126TagNamesShouldUseTitleCase' diff --git a/tools/spectral/ipa/rulesets/functions/IPA126TagNamesShouldUseTitleCase.js b/tools/spectral/ipa/rulesets/functions/IPA126TagNamesShouldUseTitleCase.js index 1b2b41bf6d..2f6912e054 100644 --- a/tools/spectral/ipa/rulesets/functions/IPA126TagNamesShouldUseTitleCase.js +++ b/tools/spectral/ipa/rulesets/functions/IPA126TagNamesShouldUseTitleCase.js @@ -6,10 +6,6 @@ const RULE_NAME = 'xgen-IPA-126-tag-names-should-use-title-case'; export default (input, options, { path }) => { const tagName = input.name; - if (!tagName || tagName.trim().length === 0) { - return; - } - if (hasException(input, RULE_NAME)) { collectException(input, RULE_NAME, path); return; From 1217f4ea3379f2004c8b5a7705216d4fa03e8cbd Mon Sep 17 00:00:00 2001 From: Yeliz Henden Date: Fri, 4 Apr 2025 16:47:14 +0100 Subject: [PATCH 3/7] address the comments --- .../IPA126TagNamesShouldUseTitleCase.test.js | 16 ++--------- tools/spectral/ipa/rulesets/IPA-126.yaml | 9 ++++++ .../IPA126TagNamesShouldUseTitleCase.js | 28 +++++++++++++++++-- 3 files changed, 36 insertions(+), 17 deletions(-) diff --git a/tools/spectral/ipa/__tests__/IPA126TagNamesShouldUseTitleCase.test.js b/tools/spectral/ipa/__tests__/IPA126TagNamesShouldUseTitleCase.test.js index 89a4c40300..443421f413 100644 --- a/tools/spectral/ipa/__tests__/IPA126TagNamesShouldUseTitleCase.test.js +++ b/tools/spectral/ipa/__tests__/IPA126TagNamesShouldUseTitleCase.test.js @@ -128,8 +128,8 @@ testRule('xgen-IPA-126-tag-names-should-use-title-case', [ tags: [ { name: 'Api V1' }, { name: 'Version 2 Resources' }, - { name: 'Push-Based Log Export' }, - { name: 'AWS Clusters DNS' }, + { name: 'Push-Based Log Export' }, //valid + { name: 'AWS Clusters DNS' }, // valid { name: 'Encryption at Rest using Customer Key Management' }, ], }, @@ -146,18 +146,6 @@ testRule('xgen-IPA-126-tag-names-should-use-title-case', [ path: ['tags', '1'], severity: DiagnosticSeverity.Warning, }, - { - code: 'xgen-IPA-126-tag-names-should-use-title-case', - message: 'Tag name should use Title Case, found: "Push-Based Log Export".', - path: ['tags', '2'], - severity: DiagnosticSeverity.Warning, - }, - { - code: 'xgen-IPA-126-tag-names-should-use-title-case', - message: 'Tag name should use Title Case, found: "AWS Clusters DNS".', - path: ['tags', '3'], - severity: DiagnosticSeverity.Warning, - }, { code: 'xgen-IPA-126-tag-names-should-use-title-case', message: 'Tag name should use Title Case, found: "Encryption at Rest using Customer Key Management".', diff --git a/tools/spectral/ipa/rulesets/IPA-126.yaml b/tools/spectral/ipa/rulesets/IPA-126.yaml index 32a6494b4c..ae08901116 100644 --- a/tools/spectral/ipa/rulesets/IPA-126.yaml +++ b/tools/spectral/ipa/rulesets/IPA-126.yaml @@ -17,3 +17,12 @@ rules: given: $.tags[?(@.name && @.name.length > 0)] then: function: 'IPA126TagNamesShouldUseTitleCase' + functionOptions: + ignoreList: + - 'AWS' + - 'DNS' + - 'API' + - 'IP' + - 'MongoDB' + - 'LDAP' + - 'GCP' diff --git a/tools/spectral/ipa/rulesets/functions/IPA126TagNamesShouldUseTitleCase.js b/tools/spectral/ipa/rulesets/functions/IPA126TagNamesShouldUseTitleCase.js index 2f6912e054..6e0468b2a9 100644 --- a/tools/spectral/ipa/rulesets/functions/IPA126TagNamesShouldUseTitleCase.js +++ b/tools/spectral/ipa/rulesets/functions/IPA126TagNamesShouldUseTitleCase.js @@ -1,10 +1,9 @@ import { hasException } from './utils/exceptions.js'; import { collectAdoption, collectAndReturnViolation, collectException } from './utils/collectionUtils.js'; -import { casing } from '@stoplight/spectral-functions'; const RULE_NAME = 'xgen-IPA-126-tag-names-should-use-title-case'; -export default (input, options, { path }) => { +export default (input, { ignoreList }, { path }) => { const tagName = input.name; if (hasException(input, RULE_NAME)) { collectException(input, RULE_NAME, path); @@ -12,7 +11,7 @@ export default (input, options, { path }) => { } // Check if the tag name uses Title Case - if (casing(tagName, { type: 'pascal', disallowDigits: true, separator: { char: ' ' } })) { + if (!isTitleCase(tagName, ignoreList)) { return collectAndReturnViolation(path, RULE_NAME, [ { path, @@ -24,3 +23,26 @@ export default (input, options, { path }) => { // Tag name uses Title Case collectAdoption(path, RULE_NAME); }; + +function isTitleCase(str, ignoreList) { + // Split by spaces to check each word/word-group + const words = str.split(' '); + + return words.every((wordGroup) => { + // For hyphenated words, check each part + if (wordGroup.includes('-')) { + const hyphenatedParts = wordGroup.split('-'); + return hyphenatedParts.every((part) => { + if (part === '') return true; // Skip empty parts + if (ignoreList.includes(part)) return true; + // First character should be uppercase, rest lowercase, all alphabetical + return /^[A-Z][a-z]*$/.test(part); + }); + } + + // For regular words + if (wordGroup === '') return true; + if (ignoreList.includes(wordGroup)) return true; + return /^[A-Z][a-z]*$/.test(wordGroup); + }); +} From 73f0be7fde142e7e69ad9b3ba23df650e7d289d8 Mon Sep 17 00:00:00 2001 From: Yeliz Henden Date: Fri, 4 Apr 2025 16:53:02 +0100 Subject: [PATCH 4/7] address the comments --- tools/spectral/ipa/rulesets/IPA-126.yaml | 21 +++++++++++++++++++ tools/spectral/ipa/rulesets/README.md | 7 +++++++ .../IPA126TagNamesShouldUseTitleCase.js | 8 ++++--- 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/tools/spectral/ipa/rulesets/IPA-126.yaml b/tools/spectral/ipa/rulesets/IPA-126.yaml index ae08901116..8691d99959 100644 --- a/tools/spectral/ipa/rulesets/IPA-126.yaml +++ b/tools/spectral/ipa/rulesets/IPA-126.yaml @@ -12,6 +12,13 @@ rules: Rule checks for the following conditions: - All tag names defined in the OpenAPI tags object should use Title Case - Title Case means each word starts with an uppercase letter, and the rest are lowercase + - Certain abbreviations (like "API", "AWS", etc.) in the ignoreList are allowed to maintain their casing + - Grammatical words (like "and", "or", "the", etc.) are allowed to be all lowercase + + ##### Configuration + This rule includes two configuration options: + - `ignoreList`: Words that are allowed to maintain their specific casing (e.g., "API", "AWS", "DNS") + - `grammaticalWords`: Common words that can remain lowercase in titles (e.g., "and", "or", "the") message: '{{error}} https://mdb.link/mongodb-atlas-openapi-validation#xgen-IPA-126-tag-names-should-use-title-case' severity: warn given: $.tags[?(@.name && @.name.length > 0)] @@ -26,3 +33,17 @@ rules: - 'MongoDB' - 'LDAP' - 'GCP' + grammaticalWords: + - 'and' + - 'or' + - 'to' + - 'in' + - 'as' + - 'for' + - 'of' + - 'with' + - 'by' + - 'but' + - 'the' + - 'a' + - 'an' diff --git a/tools/spectral/ipa/rulesets/README.md b/tools/spectral/ipa/rulesets/README.md index b6d06f6a74..68dac890c4 100644 --- a/tools/spectral/ipa/rulesets/README.md +++ b/tools/spectral/ipa/rulesets/README.md @@ -933,6 +933,13 @@ Tag names in the OpenAPI specification should use Title Case. Rule checks for the following conditions: - All tag names defined in the OpenAPI tags object should use Title Case - Title Case means each word starts with an uppercase letter, and the rest are lowercase + - Certain abbreviations (like "API", "AWS", etc.) in the ignoreList are allowed to maintain their casing + - Grammatical words (like "and", "or", "the", etc.) are allowed to be all lowercase + +##### Configuration +This rule includes two configuration options: + - `ignoreList`: Words that are allowed to maintain their specific casing (e.g., "API", "AWS", "DNS") + - `grammaticalWords`: Common words that can remain lowercase in titles (e.g., "and", "or", "the") diff --git a/tools/spectral/ipa/rulesets/functions/IPA126TagNamesShouldUseTitleCase.js b/tools/spectral/ipa/rulesets/functions/IPA126TagNamesShouldUseTitleCase.js index 6e0468b2a9..a84f870598 100644 --- a/tools/spectral/ipa/rulesets/functions/IPA126TagNamesShouldUseTitleCase.js +++ b/tools/spectral/ipa/rulesets/functions/IPA126TagNamesShouldUseTitleCase.js @@ -3,7 +3,7 @@ import { collectAdoption, collectAndReturnViolation, collectException } from './ const RULE_NAME = 'xgen-IPA-126-tag-names-should-use-title-case'; -export default (input, { ignoreList }, { path }) => { +export default (input, { ignoreList, grammaticalWords }, { path }) => { const tagName = input.name; if (hasException(input, RULE_NAME)) { collectException(input, RULE_NAME, path); @@ -11,7 +11,7 @@ export default (input, { ignoreList }, { path }) => { } // Check if the tag name uses Title Case - if (!isTitleCase(tagName, ignoreList)) { + if (!isTitleCase(tagName, ignoreList, grammaticalWords)) { return collectAndReturnViolation(path, RULE_NAME, [ { path, @@ -24,7 +24,7 @@ export default (input, { ignoreList }, { path }) => { collectAdoption(path, RULE_NAME); }; -function isTitleCase(str, ignoreList) { +function isTitleCase(str, ignoreList, grammaticalWords) { // Split by spaces to check each word/word-group const words = str.split(' '); @@ -35,6 +35,7 @@ function isTitleCase(str, ignoreList) { return hyphenatedParts.every((part) => { if (part === '') return true; // Skip empty parts if (ignoreList.includes(part)) return true; + if (grammaticalWords.includes(part)) return true; // First character should be uppercase, rest lowercase, all alphabetical return /^[A-Z][a-z]*$/.test(part); }); @@ -43,6 +44,7 @@ function isTitleCase(str, ignoreList) { // For regular words if (wordGroup === '') return true; if (ignoreList.includes(wordGroup)) return true; + if (grammaticalWords.includes(wordGroup)) return true; return /^[A-Z][a-z]*$/.test(wordGroup); }); } From df4381c1ad220c2fc2b843b5ebc31f50b6165f30 Mon Sep 17 00:00:00 2001 From: Yeliz Henden Date: Fri, 4 Apr 2025 16:59:02 +0100 Subject: [PATCH 5/7] address the comments --- .../IPA126TagNamesShouldUseTitleCase.test.js | 21 +++++++++++++++++++ .../IPA126TagNamesShouldUseTitleCase.js | 2 -- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/tools/spectral/ipa/__tests__/IPA126TagNamesShouldUseTitleCase.test.js b/tools/spectral/ipa/__tests__/IPA126TagNamesShouldUseTitleCase.test.js index 443421f413..9144ff29a3 100644 --- a/tools/spectral/ipa/__tests__/IPA126TagNamesShouldUseTitleCase.test.js +++ b/tools/spectral/ipa/__tests__/IPA126TagNamesShouldUseTitleCase.test.js @@ -131,6 +131,9 @@ testRule('xgen-IPA-126-tag-names-should-use-title-case', [ { name: 'Push-Based Log Export' }, //valid { name: 'AWS Clusters DNS' }, // valid { name: 'Encryption at Rest using Customer Key Management' }, + { name: '-Test Tag' }, + { name: 'Test Tag-' }, + { name: 'Test Tag -Name' }, ], }, errors: [ @@ -152,6 +155,24 @@ testRule('xgen-IPA-126-tag-names-should-use-title-case', [ path: ['tags', '4'], severity: DiagnosticSeverity.Warning, }, + { + code: 'xgen-IPA-126-tag-names-should-use-title-case', + message: 'Tag name should use Title Case, found: "-Test Tag".', + path: ['tags', '5'], + severity: DiagnosticSeverity.Warning, + }, + { + code: 'xgen-IPA-126-tag-names-should-use-title-case', + message: 'Tag name should use Title Case, found: "Test Tag-".', + path: ['tags', '6'], + severity: DiagnosticSeverity.Warning, + }, + { + code: 'xgen-IPA-126-tag-names-should-use-title-case', + message: 'Tag name should use Title Case, found: "Test Tag -Name".', + path: ['tags', '7'], + severity: DiagnosticSeverity.Warning, + }, ], }, ]); diff --git a/tools/spectral/ipa/rulesets/functions/IPA126TagNamesShouldUseTitleCase.js b/tools/spectral/ipa/rulesets/functions/IPA126TagNamesShouldUseTitleCase.js index a84f870598..2f73503da4 100644 --- a/tools/spectral/ipa/rulesets/functions/IPA126TagNamesShouldUseTitleCase.js +++ b/tools/spectral/ipa/rulesets/functions/IPA126TagNamesShouldUseTitleCase.js @@ -33,7 +33,6 @@ function isTitleCase(str, ignoreList, grammaticalWords) { if (wordGroup.includes('-')) { const hyphenatedParts = wordGroup.split('-'); return hyphenatedParts.every((part) => { - if (part === '') return true; // Skip empty parts if (ignoreList.includes(part)) return true; if (grammaticalWords.includes(part)) return true; // First character should be uppercase, rest lowercase, all alphabetical @@ -42,7 +41,6 @@ function isTitleCase(str, ignoreList, grammaticalWords) { } // For regular words - if (wordGroup === '') return true; if (ignoreList.includes(wordGroup)) return true; if (grammaticalWords.includes(wordGroup)) return true; return /^[A-Z][a-z]*$/.test(wordGroup); From c896471a9ff0b9f7b035b26d113ffaba054f6876 Mon Sep 17 00:00:00 2001 From: Yeliz Henden Date: Fri, 4 Apr 2025 17:10:19 +0100 Subject: [PATCH 6/7] address the comments --- .../ipa/__tests__/IPA126TagNamesShouldUseTitleCase.test.js | 7 +++++++ .../rulesets/functions/IPA126TagNamesShouldUseTitleCase.js | 7 +++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/tools/spectral/ipa/__tests__/IPA126TagNamesShouldUseTitleCase.test.js b/tools/spectral/ipa/__tests__/IPA126TagNamesShouldUseTitleCase.test.js index 9144ff29a3..aee77e89fb 100644 --- a/tools/spectral/ipa/__tests__/IPA126TagNamesShouldUseTitleCase.test.js +++ b/tools/spectral/ipa/__tests__/IPA126TagNamesShouldUseTitleCase.test.js @@ -134,6 +134,7 @@ testRule('xgen-IPA-126-tag-names-should-use-title-case', [ { name: '-Test Tag' }, { name: 'Test Tag-' }, { name: 'Test Tag -Name' }, + { name: 'the Test Tag' }, ], }, errors: [ @@ -173,6 +174,12 @@ testRule('xgen-IPA-126-tag-names-should-use-title-case', [ path: ['tags', '7'], severity: DiagnosticSeverity.Warning, }, + { + code: 'xgen-IPA-126-tag-names-should-use-title-case', + message: 'Tag name should use Title Case, found: "the Test Tag".', + path: ['tags', '8'], + severity: DiagnosticSeverity.Warning, + }, ], }, ]); diff --git a/tools/spectral/ipa/rulesets/functions/IPA126TagNamesShouldUseTitleCase.js b/tools/spectral/ipa/rulesets/functions/IPA126TagNamesShouldUseTitleCase.js index 2f73503da4..6b17a9b415 100644 --- a/tools/spectral/ipa/rulesets/functions/IPA126TagNamesShouldUseTitleCase.js +++ b/tools/spectral/ipa/rulesets/functions/IPA126TagNamesShouldUseTitleCase.js @@ -26,23 +26,22 @@ export default (input, { ignoreList, grammaticalWords }, { path }) => { function isTitleCase(str, ignoreList, grammaticalWords) { // Split by spaces to check each word/word-group + // First character should be uppercase, rest lowercase, all alphabetical const words = str.split(' '); - return words.every((wordGroup) => { + return words.every((wordGroup, index) => { // For hyphenated words, check each part if (wordGroup.includes('-')) { const hyphenatedParts = wordGroup.split('-'); return hyphenatedParts.every((part) => { if (ignoreList.includes(part)) return true; - if (grammaticalWords.includes(part)) return true; - // First character should be uppercase, rest lowercase, all alphabetical return /^[A-Z][a-z]*$/.test(part); }); } // For regular words if (ignoreList.includes(wordGroup)) return true; - if (grammaticalWords.includes(wordGroup)) return true; + if (index !== 0 && grammaticalWords.includes(wordGroup)) return true; return /^[A-Z][a-z]*$/.test(wordGroup); }); } From bee67d901cc6589a02b42dc11e5fbb9769efdb98 Mon Sep 17 00:00:00 2001 From: Yeliz Henden Date: Fri, 4 Apr 2025 17:11:17 +0100 Subject: [PATCH 7/7] address the comments --- .../ipa/__tests__/IPA126TagNamesShouldUseTitleCase.test.js | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/spectral/ipa/__tests__/IPA126TagNamesShouldUseTitleCase.test.js b/tools/spectral/ipa/__tests__/IPA126TagNamesShouldUseTitleCase.test.js index aee77e89fb..f2a1073170 100644 --- a/tools/spectral/ipa/__tests__/IPA126TagNamesShouldUseTitleCase.test.js +++ b/tools/spectral/ipa/__tests__/IPA126TagNamesShouldUseTitleCase.test.js @@ -135,6 +135,7 @@ testRule('xgen-IPA-126-tag-names-should-use-title-case', [ { name: 'Test Tag-' }, { name: 'Test Tag -Name' }, { name: 'the Test Tag' }, + { name: 'A Test Tag' }, ], }, errors: [