From 3e0f03d15b377a43f91ed59776477b0aa1a3d8dd Mon Sep 17 00:00:00 2001 From: Shelley Vohr Date: Sun, 10 May 2020 21:19:20 -0700 Subject: [PATCH] fix: enforce default for non-confirmation prompts (#415) --- lib/cli.js | 23 +++++++++++++++++++---- test/unit/cli.test.js | 30 ++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/lib/cli.js b/lib/cli.js index c21fa0c6..5589e5b4 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -12,8 +12,15 @@ const SPINNER_STATUS = { WARN: 'warn', INFO: 'info' }; + const { SUCCESS, FAILED, WARN, INFO } = SPINNER_STATUS; +const QUESTION_TYPE = { + INPUT: 'input', + NUMBER: 'number', + CONFIRM: 'confirm' +}; + function head(text, length = 11) { return chalk.bold(text.padEnd(length)); } @@ -23,6 +30,7 @@ class CLI { this.stream = stream || process.stderr; this.spinner = ora({ stream: this.stream }); this.SPINNER_STATUS = SPINNER_STATUS; + this.QUESTION_TYPE = QUESTION_TYPE; this.figureIndent = ' '; this.assumeYes = false; } @@ -44,15 +52,21 @@ class CLI { this.separator(); } - const questionType = opts.questionType || 'confirm'; - const availableTypes = ['input', 'number', 'confirm']; + const questionType = opts.questionType || QUESTION_TYPE.CONFIRM; + const availableTypes = Object.values(QUESTION_TYPE); if (!availableTypes.includes(questionType)) { throw new Error( `${questionType} must be one of ${availableTypes.join(', ')}`); } - const defaultAnswer = - (opts.defaultAnswer !== 'undefined') ? opts.defaultAnswer : true; + const defaultAnswer = (opts.defaultAnswer === undefined) + ? true : opts.defaultAnswer; + if (typeof defaultAnswer === 'boolean' && + questionType !== QUESTION_TYPE.CONFIRM) { + throw new Error( + 'defaultAnswer must be provided for non-confirmation prompts'); + } + if (this.assumeYes) { return defaultAnswer; } @@ -153,5 +167,6 @@ class CLI { }; CLI.SPINNER_STATUS = SPINNER_STATUS; +CLI.QUESTION_TYPE = QUESTION_TYPE; module.exports = CLI; diff --git a/test/unit/cli.test.js b/test/unit/cli.test.js index 8b6a056b..fd867f45 100644 --- a/test/unit/cli.test.js +++ b/test/unit/cli.test.js @@ -173,6 +173,36 @@ describe('cli', () => { cli.setAssumeYes(); }); + it('rejects when no default answer is provided for \'input\' type', () => { + return assert.rejects(async() => { + await cli.prompt('What is your favorite color', { + questionType: cli.QUESTION_TYPE.INPUT + }); + }, /defaultAnswer must be provided for non-confirmation prompts/); + }); + + it('rejects when no default answer is provided for \'number\' type', () => { + return assert.rejects(async() => { + await cli.prompt('Pick a number from 1-10', { + questionType: cli.QUESTION_TYPE.NUMBER + }); + }, /defaultAnswer must be provided for non-confirmation prompts/); + }); + + it('should return the default answer for an \'input\' type', async() => { + assert.strictEqual(await cli.prompt('What is your favorite color', { + defaultAnswer: 'blue', + questionType: cli.QUESTION_TYPE.INPUT + }), 'blue'); + }); + + it('should return the default answer for a \'number\' type', async() => { + assert.strictEqual(await cli.prompt('Pick a number from 1-10', { + defaultAnswer: 10, + questionType: cli.QUESTION_TYPE.NUMBER + }), 10); + }); + it('should return true if no default is given', async() => { assert.strictEqual(await cli.prompt('Question?'), true); });