diff --git a/@commitlint/rules/src/type-empty.test.ts b/@commitlint/rules/src/type-empty.test.ts index a1c6f4ab86..c9be284a1d 100644 --- a/@commitlint/rules/src/type-empty.test.ts +++ b/@commitlint/rules/src/type-empty.test.ts @@ -4,11 +4,17 @@ import {typeEmpty} from './type-empty'; const messages = { empty: '(scope):', filled: 'type: subject', + fullyFilled: 'type(scope): subject', + subjectOnly: 'subject', + separator: ': subject', }; const parsed = { empty: parse(messages.empty), filled: parse(messages.filled), + fullyFilled: parse(messages.fullyFilled), + subjectOnly: parse(messages.subjectOnly), + separator: parse(messages.separator), }; test('without type should succeed for empty keyword', async () => { @@ -46,3 +52,57 @@ test('with type fail for "always"', async () => { const expected = false; expect(actual).toEqual(expected); }); + +test('with title, scope and subject should fail for empty keyword', async () => { + const [actual] = typeEmpty(await parsed.fullyFilled); + const expected = false; + expect(actual).toEqual(expected); +}); + +test('with title, scope and subject should succeed for "never"', async () => { + const [actual] = typeEmpty(await parsed.fullyFilled, 'never'); + const expected = true; + expect(actual).toEqual(expected); +}); + +test('with title, scope and subject should fail for "always"', async () => { + const [actual] = typeEmpty(await parsed.fullyFilled, 'always'); + const expected = false; + expect(actual).toEqual(expected); +}); + +test('with only subject should succeed for empty keyword', async () => { + const [actual] = typeEmpty(await parsed.subjectOnly); + const expected = true; + expect(actual).toEqual(expected); +}); + +test('with only subject should fail for "never"', async () => { + const [actual] = typeEmpty(await parsed.subjectOnly, 'never'); + const expected = false; + expect(actual).toEqual(expected); +}); + +test('with only subject should succeed for "always"', async () => { + const [actual] = typeEmpty(await parsed.subjectOnly, 'always'); + const expected = true; + expect(actual).toEqual(expected); +}); + +test('without type but with a separator should fail for empty keyword', async () => { + const [actual] = typeEmpty(await parsed.separator); + const expected = false; + expect(actual).toEqual(expected); +}); + +test('without type but with a separator should succeed for "never"', async () => { + const [actual] = typeEmpty(await parsed.separator, 'never'); + const expected = true; + expect(actual).toEqual(expected); +}); + +test('without type but with a separator should fail for "always"', async () => { + const [actual] = typeEmpty(await parsed.separator, 'always'); + const expected = false; + expect(actual).toEqual(expected); +}); diff --git a/@commitlint/rules/src/type-empty.ts b/@commitlint/rules/src/type-empty.ts index 8802e00d77..e4ee393a6b 100644 --- a/@commitlint/rules/src/type-empty.ts +++ b/@commitlint/rules/src/type-empty.ts @@ -4,7 +4,14 @@ import {SyncRule} from '@commitlint/types'; export const typeEmpty: SyncRule = (parsed, when = 'always') => { const negated = when === 'never'; - const notEmpty = ensure.notEmpty(parsed.type || ''); + const notEmptyType = ensure.notEmpty(parsed.type || ''); + let notEmpty = notEmptyType; + if ( + !notEmptyType && + parsed.subject !== parsed.header && + parsed.header.substring(0, 1) === ':' + ) + notEmpty = true; return [ negated ? notEmpty : !notEmpty, message(['type', negated ? 'may not' : 'must', 'be empty']),