From 734bb709b30175e88b78411f81e1c5082e5ef5df Mon Sep 17 00:00:00 2001 From: Marcelo Shima Date: Tue, 10 Mar 2020 02:51:41 -0300 Subject: [PATCH] Add support to pre-filed answers. (#901) * Remove callback parameter that doesn't exists on prompt * Remove node 8 test from travis * Allow answer to be pre-filed. * Implement askAnswered option Co-authored-by: Simon Boudrias --- README.md | 1 + packages/inquirer/lib/inquirer.js | 4 +- packages/inquirer/lib/ui/prompt.js | 18 ++++-- packages/inquirer/test/specs/inquirer.js | 77 ++++++++++++++++++++++-- 4 files changed, 87 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index a4b604299..7fa511995 100644 --- a/README.md +++ b/README.md @@ -136,6 +136,7 @@ A question object is a `hash` containing question related values: - **pageSize**: (Number) Change the number of lines that will be rendered when using `list`, `rawList`, `expand` or `checkbox`. - **prefix**: (String) Change the default _prefix_ message. - **suffix**: (String) Change the default _suffix_ message. +- **askAnswered**: (Boolean) Force to prompt the question if the answer already exists. `default`, `choices`(if defined as functions), `validate`, `filter` and `when` functions can be called asynchronously. Either return a promise or use `this.async()` to get a callback you'll call with the final value. diff --git a/packages/inquirer/lib/inquirer.js b/packages/inquirer/lib/inquirer.js index ab66e80ae..aa8b2a17e 100644 --- a/packages/inquirer/lib/inquirer.js +++ b/packages/inquirer/lib/inquirer.js @@ -23,14 +23,14 @@ inquirer.ui = { * Create a new self-contained prompt module. */ inquirer.createPromptModule = function(opt) { - var promptModule = function(questions) { + var promptModule = function(questions, answers) { var ui; try { ui = new inquirer.ui.Prompt(promptModule.prompts, opt); } catch (error) { return Promise.reject(error); } - var promise = ui.run(questions); + var promise = ui.run(questions, answers); // Monkey patch the UI on the promise object so // that it remains publicly accessible. diff --git a/packages/inquirer/lib/ui/prompt.js b/packages/inquirer/lib/ui/prompt.js index bc1ee9eb8..9735c999f 100644 --- a/packages/inquirer/lib/ui/prompt.js +++ b/packages/inquirer/lib/ui/prompt.js @@ -16,9 +16,13 @@ class PromptUI extends Base { this.prompts = prompts; } - run(questions) { + run(questions, answers) { // Keep global reference to the answers - this.answers = {}; + if (_.isPlainObject(answers)) { + this.answers = _.clone(answers); + } else { + this.answers = {}; + } // Make sure questions is an array. if (_.isPlainObject(questions)) { @@ -40,9 +44,9 @@ class PromptUI extends Base { return this.process .pipe( reduce((answers, answer) => { - _.set(this.answers, answer.name, answer.answer); - return this.answers; - }, {}) + _.set(answers, answer.name, answer.answer); + return answers; + }, this.answers) ) .toPromise(Promise) .then(this.onCompletion.bind(this)); @@ -100,6 +104,10 @@ class PromptUI extends Base { } filterIfRunnable(question) { + if (question.askAnswered !== true && this.answers[question.name] !== undefined) { + return empty(); + } + if (question.when === false) { return empty(); } diff --git a/packages/inquirer/test/specs/inquirer.js b/packages/inquirer/test/specs/inquirer.js index 179e2ffbc..b4ec53ffc 100644 --- a/packages/inquirer/test/specs/inquirer.js +++ b/packages/inquirer/test/specs/inquirer.js @@ -197,7 +197,7 @@ describe('inquirer.prompt', function() { } ]; - var promise = this.prompt(prompts, function() {}); + var promise = this.prompt(prompts); promise.ui.rl.emit('line'); }); @@ -232,7 +232,7 @@ describe('inquirer.prompt', function() { } ]; - var promise = this.prompt(prompts, function() {}); + var promise = this.prompt(prompts); promise.ui.rl.emit('line'); }); @@ -330,7 +330,7 @@ describe('inquirer.prompt', function() { } ]; - var promise = this.prompt(prompts, function() {}); + var promise = this.prompt(prompts); promise.ui.rl.emit('line'); }); @@ -383,7 +383,7 @@ describe('inquirer.prompt', function() { }); it('should expose the UI', function(done) { - var promise = this.prompt([], function() {}); + var promise = this.prompt([]); expect(promise.ui.answers).to.be.an('object'); done(); }); @@ -417,6 +417,25 @@ describe('inquirer.prompt', function() { }); }); + it('should take a prompts array and answers and return answers', function() { + var prompts = [ + { + type: 'confirm', + name: 'q1', + message: 'message' + } + ]; + + var answers = { prefiled: true }; + var promise = this.prompt(prompts, answers); + autosubmit(promise.ui); + + return promise.then(answers => { + expect(answers.prefiled).to.equal(true); + expect(answers.q1).to.equal(true); + }); + }); + describe('hierarchical mode (`when`)', function() { it('should pass current answers to `when`', function() { var prompts = [ @@ -616,6 +635,52 @@ describe('inquirer.prompt', function() { expect(answers.q).to.equal('foo'); }); }); + + it('should not run prompt if answer exists for question', function() { + var throwFunc = function(step) { + throw new Error(`askAnswered Error ${step}`); + }; + var prompts = [ + { + type: 'input', + name: 'prefiled', + when: throwFunc.bind(undefined, 'when'), + validate: throwFunc.bind(undefined, 'validate'), + transformer: throwFunc.bind(undefined, 'transformer'), + filter: throwFunc.bind(undefined, 'filter'), + message: 'message', + default: 'newValue' + } + ]; + + var answers = { prefiled: 'prefiled' }; + var promise = this.prompt(prompts, answers); + autosubmit(promise.ui); + + return promise.then(answers => { + expect(answers.prefiled).to.equal('prefiled'); + }); + }); + + it('should run prompt if answer exists for question and askAnswered is set', function() { + var prompts = [ + { + askAnswered: true, + type: 'input', + name: 'prefiled', + message: 'message', + default: 'newValue' + } + ]; + + var answers = { prefiled: 'prefiled' }; + var promise = this.prompt(prompts, answers); + autosubmit(promise.ui); + + return promise.then(answers => { + expect(answers.prefiled).to.equal('newValue'); + }); + }); }); describe('#registerPrompt()', function() { @@ -628,7 +693,7 @@ describe('inquirer.prompt', function() { done(); }); - inquirer.prompt(questions, _.noop); + inquirer.prompt(questions); }); it('overwrite default prompt types', function(done) { @@ -638,7 +703,7 @@ describe('inquirer.prompt', function() { done(); }); - inquirer.prompt(questions, _.noop); + inquirer.prompt(questions); inquirer.restoreDefaultPrompts(); }); });