From 70a44501ac8459f0c1d2b200608b024585964637 Mon Sep 17 00:00:00 2001 From: Denis Gribov Date: Fri, 14 Apr 2023 13:21:28 +0500 Subject: [PATCH] fix(rules): avoid processing strings with case-less Letter category symbols in `subject-case` (#3586) * feat(rules): expand Latin-only characters limitation for `subject-case` with Unicode support * fix(rules): avoid processing strings with case-less Letter category symbols in `subject-case` Fixes #3585 --- @commitlint/rules/src/subject-case.test.ts | 20 ++++++++++++++++++++ @commitlint/rules/src/subject-case.ts | 10 +++++----- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/@commitlint/rules/src/subject-case.test.ts b/@commitlint/rules/src/subject-case.test.ts index ac4b15d769..d7054f3a0f 100644 --- a/@commitlint/rules/src/subject-case.test.ts +++ b/@commitlint/rules/src/subject-case.test.ts @@ -7,6 +7,7 @@ const messages = { lowercase: 'test: subject', lowercase_unicode: 'test: тема', // Bulgarian for `subject` mixedcase: 'test: sUbJeCt', + caseless: 'test: 这是一次提交', // Chinese for `this is a commit` uppercase: 'test: SUBJECT', uppercase_unicode: 'test: ÛNDERWERP', // Frisian for `SUBJECT` camelcase: 'test: subJect', @@ -29,6 +30,7 @@ const parsed = { lowercase: parse(messages.lowercase), lowercase_unicode: parse(messages.lowercase_unicode), mixedcase: parse(messages.mixedcase), + caseless: parse(messages.caseless), uppercase: parse(messages.uppercase), uppercase_unicode: parse(messages.uppercase_unicode), camelcase: parse(messages.camelcase), @@ -115,6 +117,24 @@ test('with mixedcase subject should fail for "always uppercase"', async () => { expect(actual).toEqual(expected); }); +test('with caseless subject should succeed for "never sentensecase"', async () => { + const [actual] = subjectCase(await parsed.caseless, 'never', 'sentense-case'); + const expected = true; + expect(actual).toEqual(expected); +}); + +test('with caseless subject should succeed for "never uppercase"', async () => { + const [actual] = subjectCase(await parsed.caseless, 'never', 'upper-case'); + const expected = true; + expect(actual).toEqual(expected); +}); + +test('with caseless subject should succeed for "always uppercase"', async () => { + const [actual] = subjectCase(await parsed.caseless, 'always', 'upper-case'); + const expected = true; + expect(actual).toEqual(expected); +}); + test('with uppercase subject should fail for "never uppercase"', async () => { const [actual] = subjectCase(await parsed.uppercase, 'never', 'uppercase'); const expected = false; diff --git a/@commitlint/rules/src/subject-case.ts b/@commitlint/rules/src/subject-case.ts index 1b66bce291..13e7de850a 100644 --- a/@commitlint/rules/src/subject-case.ts +++ b/@commitlint/rules/src/subject-case.ts @@ -4,12 +4,12 @@ import {TargetCaseType, SyncRule} from '@commitlint/types'; /** * Since the rule requires first symbol of a subject to be a letter, use - * combination of Unicode `Cased_Letter` and `Other_Letter` categories now to - * allow non-Latin alphabets as well. + * Unicode `Cased_Letter` category now to allow non-Latin alphabets as well. * * Do not use `Letter` category directly to avoid capturing `Modifier_Letter` - * (which just modifiers letters, so we probably shouldn't anyway) and to stay - * close to previous implementation. + * (which just modifiers letters, so we probably shouldn't anyway) and + * `Other_Letter` (they actually are case-less, so they can't be validated) + * categories, and to stay close to previous implementation. * * Also, typescript does not seem to support almost any longhand category name * (and even short for `Cased_Letter` too) so list all required letter @@ -17,7 +17,7 @@ import {TargetCaseType, SyncRule} from '@commitlint/types'; * * @see [Unicode Categories]{@link https://www.regular-expressions.info/unicode.html} */ -const startsWithLetterRegex = /^[\p{Ll}\p{Lu}\p{Lt}\p{Lo}]/iu; +const startsWithLetterRegex = /^[\p{Ll}\p{Lu}\p{Lt}]/iu; const negated = (when?: string) => when === 'never';