From 88cb735e96f05ad3a998356c95eb00527e54bb9f Mon Sep 17 00:00:00 2001 From: weixin wu Date: Sun, 5 May 2024 23:30:18 -0400 Subject: [PATCH 1/2] fix(prompt): prompt does not respect [body-leading-blank] setting --- @commitlint/prompt/src/inquirer/InputCustomPrompt.ts | 2 ++ @commitlint/prompt/src/inquirer/inquirer.d.ts | 1 + @commitlint/prompt/src/library/get-prompt.ts | 1 + 3 files changed, 4 insertions(+) diff --git a/@commitlint/prompt/src/inquirer/InputCustomPrompt.ts b/@commitlint/prompt/src/inquirer/InputCustomPrompt.ts index 3ec1b0988f..6e7824dcdd 100644 --- a/@commitlint/prompt/src/inquirer/InputCustomPrompt.ts +++ b/@commitlint/prompt/src/inquirer/InputCustomPrompt.ts @@ -46,6 +46,8 @@ export default class InputCustomPrompt< onEnd(state: SuccessfulPromptStateData): void { this.lineSubscription.unsubscribe(); + // Add or remove leading blank if rule is active. + state.value = this.opt.forceLeadingBlankFn(state.value); super.onEnd(state); } diff --git a/@commitlint/prompt/src/inquirer/inquirer.d.ts b/@commitlint/prompt/src/inquirer/inquirer.d.ts index 06d2304ab2..98af94d2a7 100644 --- a/@commitlint/prompt/src/inquirer/inquirer.d.ts +++ b/@commitlint/prompt/src/inquirer/inquirer.d.ts @@ -15,6 +15,7 @@ declare module 'inquirer' { log?(answers?: T): string; tabCompletion?: InputCustomCompletionOption[]; maxLength(answers?: T): number; + forceLeadingBlankFn(input: string): string; } interface QuestionMap { diff --git a/@commitlint/prompt/src/library/get-prompt.ts b/@commitlint/prompt/src/library/get-prompt.ts index 9ab0550288..4e57f035c9 100644 --- a/@commitlint/prompt/src/library/get-prompt.ts +++ b/@commitlint/prompt/src/library/get-prompt.ts @@ -119,5 +119,6 @@ export default function getPrompt( transformer(value: string) { return forceCaseFn(value); }, + forceLeadingBlankFn, }; } From e14d99f1a9ebfea26a3b2891123641273d271624 Mon Sep 17 00:00:00 2001 From: weixin wu Date: Wed, 8 May 2024 21:52:08 -0400 Subject: [PATCH 2/2] test(prompt): add unit tests --- @commitlint/prompt/src/input.test.ts | 48 ++++++++++++++++++++++++---- 1 file changed, 42 insertions(+), 6 deletions(-) diff --git a/@commitlint/prompt/src/input.test.ts b/@commitlint/prompt/src/input.test.ts index f15c39424a..7b9cb5dfe6 100644 --- a/@commitlint/prompt/src/input.test.ts +++ b/@commitlint/prompt/src/input.test.ts @@ -1,18 +1,46 @@ /// -import {test, expect, vi} from 'vitest'; +import {expect, test, vi} from 'vitest'; // @ts-expect-error -- no typings import config from '@commitlint/config-angular'; import chalk from 'chalk'; -import {Answers, DistinctQuestion, PromptModule} from 'inquirer'; +import { + Answers, + DistinctQuestion, + InputCustomOptions, + PromptModule, +} from 'inquirer'; import {input} from './input.js'; +const testConfig = { + parserPreset: config.parserPreset, + rules: { + ...config.rules, + }, +}; + vi.mock('@commitlint/load', () => ({ - default: () => config, + default: () => testConfig, })); test('should work with all fields filled', async () => { + const prompt = stub({ + 'input-custom': { + type: 'fix', + scope: 'test', + subject: 'subject', + body: 'body', + footer: 'footer', + }, + }); + const message = await input(prompt); + expect(message).toEqual('fix(test): subject\n' + '\nbody\n' + '\nfooter'); +}); + +test('should not add leading blank line to body and footer if rules are disabled', async () => { + testConfig.rules['body-leading-blank'] = ['1', 'never']; + testConfig.rules['footer-leading-blank'] = ['1', 'never']; const prompt = stub({ 'input-custom': { type: 'fix', @@ -24,6 +52,10 @@ test('should work with all fields filled', async () => { }); const message = await input(prompt); expect(message).toEqual('fix(test): subject\n' + 'body\n' + 'footer'); + // reset config mock + testConfig.rules['body-leading-blank'] = config.rules['body-leading-blank']; + testConfig.rules['footer-leading-blank'] = + config.rules['footer-leading-blank']; }); test('should work without scope', async () => { @@ -37,7 +69,7 @@ test('should work without scope', async () => { }, }); const message = await input(prompt); - expect(message).toEqual('fix: subject\n' + 'body\n' + 'footer'); + expect(message).toEqual('fix: subject\n' + '\nbody\n' + '\nfooter'); }); test('should fail without type', async () => { @@ -72,7 +104,7 @@ function stub(config: Record>): PromptModule { if (!questions) { throw new Error(`Unexpected config type: ${configType}`); } - const answer = questions[promptConfig.name!]; + let answer = questions[promptConfig.name!]; if (answer == null) { throw new Error(`Unexpected config name: ${promptConfig.name}`); } @@ -83,7 +115,11 @@ function stub(config: Record>): PromptModule { throw new Error(validationResult || undefined); } } - + const forceLeadingBlankFn = (promptConfig as InputCustomOptions) + .forceLeadingBlankFn; + if (forceLeadingBlankFn) { + answer = forceLeadingBlankFn(answer as string); + } result[promptConfig.name!] = answer; } return result;