From f0e2bd6aaa0ed7b47843482046d4c443db5643c7 Mon Sep 17 00:00:00 2001 From: Nik Date: Sun, 16 Jun 2019 04:31:00 +1200 Subject: [PATCH] :sparkles: Add --yes flag (#45) --- src/cli.js | 30 +++++++++++-- src/cli.spec.js | 112 ++++++++++++++++++++++++++++++++++++++++++------ src/index.js | 3 ++ 3 files changed, 129 insertions(+), 16 deletions(-) diff --git a/src/cli.js b/src/cli.js index 8cbf234..6b22354 100644 --- a/src/cli.js +++ b/src/cli.js @@ -11,7 +11,7 @@ const utils = require('./utils') * * @param {Object} projectInfos */ -const askQuestions = async projectInfos => { +const askQuestions = async (projectInfos, skipQuestions) => { let answersContext = { isGithubRepos: projectInfos.isGithubRepos, repositoryUrl: projectInfos.repositoryUrl, @@ -22,7 +22,10 @@ const askQuestions = async projectInfos => { const question = questionBuilder(projectInfos, answersContext) if (!isNil(question)) { - const currentAnswerContext = await inquirer.prompt([question]) + const currentAnswerContext = skipQuestions + ? { [question.name]: getDefaultAnswer(question) } + : await inquirer.prompt([question]) + answersContext = { ...answersContext, ...currentAnswerContext @@ -33,6 +36,24 @@ const askQuestions = async projectInfos => { return answersContext } +/** + * Get the default answer depending on the question type + * + * @param {Object} question + */ +const getDefaultAnswer = question => { + switch (question.type) { + case 'input': + return question.default || '' + case 'checkbox': + return question.choices + .filter(choice => choice.checked) + .map(choice => choice.value) + default: + return undefined + } +} + /** * Main process: * 1) Gather project infos @@ -42,9 +63,9 @@ const askQuestions = async projectInfos => { * * @param {Object} args */ -const mainProcess = async ({ template }) => { +const mainProcess = async ({ template, yes }) => { const projectInformations = await projectInfos.getProjectInfos() - const answersContext = await cli.askQuestions(projectInformations) + const answersContext = await cli.askQuestions(projectInformations, yes) const readmeContent = await readme.buildReadmeContent( answersContext, template @@ -57,6 +78,7 @@ const mainProcess = async ({ template }) => { const cli = { mainProcess, + getDefaultAnswer, askQuestions } diff --git a/src/cli.spec.js b/src/cli.spec.js index 7e9e3ae..70146d5 100644 --- a/src/cli.spec.js +++ b/src/cli.spec.js @@ -12,12 +12,30 @@ inquirer.prompt = jest.fn(([question]) => ) jest.mock('./questions', () => ({ - askProjectName: jest.fn(() => ({ name: 'askProjectName' })), - askProjectVersion: jest.fn(() => ({ name: 'askProjectVersion' })), - askProjectDescription: jest.fn(() => ({ name: 'askProjectDescription' })) + askProjectName: jest.fn(() => ({ + name: 'projectName', + type: 'input', + default: 'defaultProjectName' + })), + askProjectVersion: jest.fn(() => ({ + name: 'projectVersion', + type: 'input' + })), + askProjectDescription: jest.fn(() => ({ + name: 'projectDescription', + type: 'checkbox', + choices: [ + { value: { name: 'choiceOne', value: 1 }, checked: true }, + { value: { name: 'choiceTwo', value: 2 }, checked: false } + ] + })) })) describe('cli', () => { + beforeEach(() => { + inquirer.prompt.mockClear() + }) + describe('mainProcess', () => { const answersContext = { projectName: 'readme-md-generator' } @@ -25,6 +43,10 @@ describe('cli', () => { cli.askQuestions = jest.fn(() => Promise.resolve(answersContext)) }) + afterEach(() => { + cli.askQuestions.mockClear() + }) + afterAll(() => { cli.askQuestions = realAskQuestions }) @@ -43,17 +65,67 @@ describe('cli', () => { await cli.mainProcess({ template }) expect(projectInfos.getProjectInfos).toHaveBeenCalledTimes(1) - expect(cli.askQuestions).toHaveBeenCalledTimes(1) - expect(cli.askQuestions).toHaveBeenCalledWith(projectInformations) - expect(readme.buildReadmeContent).toHaveBeenCalledTimes(1) - expect(readme.buildReadmeContent).toHaveBeenCalledWith( + expect(cli.askQuestions).toHaveBeenNthCalledWith( + 1, + projectInformations, + undefined + ) + expect(readme.buildReadmeContent).toHaveBeenNthCalledWith( + 1, answersContext, template ) - expect(readme.writeReadme).toHaveBeenCalledTimes(1) - expect(readme.writeReadme).toHaveBeenCalledWith(readmeContent) + expect(readme.writeReadme).toHaveBeenNthCalledWith(1, readmeContent) expect(utils.showEndMessage).toHaveBeenCalledTimes(1) }) + + it('should forward --yes option to askQuestions', async () => { + const template = 'default' + const projectInformations = { name: 'readme-md-generator' } + const skipQuestions = true + utils.showEndMessage = jest.fn() + + await cli.mainProcess({ template, yes: skipQuestions }) + + expect(cli.askQuestions).toHaveBeenNthCalledWith( + 1, + projectInformations, + skipQuestions + ) + }) + }) + + describe('getDefaultAnswer', () => { + it('should handle input prompts correctly', () => { + const question = { type: 'input', default: 'default' } + const result = cli.getDefaultAnswer(question) + expect(result).toEqual(question.default) + }) + + it('should handle choices prompts correctly', () => { + const value = { name: 'name', value: 'value' } + const question = { + type: 'checkbox', + choices: [{ value, checked: true }, { checked: false }] + } + const result = cli.getDefaultAnswer(question) + + expect(result).toEqual([value]) + }) + + it('should return empty string for non-defaulted fields', () => { + const question = { type: 'input' } + const result = cli.getDefaultAnswer(question) + + expect(result).toEqual('') + }) + + it('should return undefined for invalid types', () => { + const question = { type: 'invalid' } + const result = cli.getDefaultAnswer(question) + + expect(result).toEqual(undefined) + }) }) describe('askQuestions', () => { @@ -67,15 +139,31 @@ describe('cli', () => { expect(questions.askProjectDescription).toHaveBeenCalledTimes(1) }) + it('should use default values with --yes option', async () => { + const projectInfos = { name: 'readme-md-generator' } + + const result = await cli.askQuestions(projectInfos, true) + + expect(inquirer.prompt).not.toHaveBeenCalled() + expect(result).toEqual({ + projectName: 'defaultProjectName', + projectVersion: '', + projectDescription: [{ name: 'choiceOne', value: 1 }], + isGithubRepos: undefined, + repositoryUrl: undefined, + projectPrerequisites: undefined + }) + }) + it('should return merged contexts', async () => { const projectInfos = { name: 'readme-md-generator' } const context = await cli.askQuestions(projectInfos) expect(context).toEqual({ - askProjectName: 'value', - askProjectVersion: 'value', - askProjectDescription: 'value', + projectName: 'value', + projectVersion: 'value', + projectDescription: 'value', isGithubRepos: undefined, repositoryUrl: undefined, projectPrerequisites: undefined diff --git a/src/index.js b/src/index.js index 3f9cdcf..8b772e1 100755 --- a/src/index.js +++ b/src/index.js @@ -16,6 +16,9 @@ yargs }), args => mainProcess(args) ) + .boolean('yes') + .alias('y', 'yes') + .describe('yes', 'Use default values for all fields') .help() .epilog( 'for more information, find our manual at https://github.com/kefranabg/readme-md-generator'