From 06b1c7960069cc5bce09dab29261749d3281552e Mon Sep 17 00:00:00 2001 From: Kristiyan Nikolov Date: Wed, 6 Oct 2021 13:00:37 +0300 Subject: [PATCH 1/2] feat: Prompt Bypass supports Object choice values --- src/prompt-bypass.js | 30 ++++++------- tests/prompt-bypass-list.ava.js | 76 +++++++++++++++++---------------- 2 files changed, 55 insertions(+), 51 deletions(-) diff --git a/src/prompt-bypass.js b/src/prompt-bypass.js index a84cb5a..6f99540 100644 --- a/src/prompt-bypass.js +++ b/src/prompt-bypass.js @@ -19,23 +19,23 @@ const getChoiceValue = (choice) => { return choice; }; +// check if the choice value matches the bypass value +function checkChoiceValue(choiceValue, value) { + return typeof choiceValue === 'string' + && choiceValue.toLowerCase() === value.toLowerCase(); +} + // check if a bypass value matches some aspect of // a particular choice option (index, value, key, etc) -const choiceMatchesValue = (choice, choiceIdx, value) => { - const choiceValue = getChoiceValue(choice); - - const valueMatchesChoice = choiceValue && choiceValue.toLowerCase() === value.toLowerCase(); - const valueMatchesChoiceKey = typeof choice.key === 'string' && choice.key.toLowerCase() === value.toLowerCase(); - const valueMatchesChoiceName = typeof choice.name === 'string' && choice.name.toLowerCase() === value.toLowerCase(); - const valueMatchesChoiceIndex = choiceIdx.toString() === value; - - return ( - valueMatchesChoice - || valueMatchesChoiceKey - || valueMatchesChoiceName - || valueMatchesChoiceIndex - ); -}; +function choiceMatchesValue (choice, choiceIdx, value) { + return [ + choice, + choice.value, + choice.key, + choice.name, + choiceIdx.toString() + ].some(choiceValue => checkChoiceValue(choiceValue, value)); +} // check if a value matches a particular set of flagged input options const isFlag = (list, v) => list.includes(v.toLowerCase()); diff --git a/tests/prompt-bypass-list.ava.js b/tests/prompt-bypass-list.ava.js index 8260f8a..06c112e 100644 --- a/tests/prompt-bypass-list.ava.js +++ b/tests/prompt-bypass-list.ava.js @@ -6,52 +6,56 @@ const plop = nodePlop(); const prompts = [{ type:'list', - name:'list', message:'listMsg', + name:'list', + message:'listMsg', choices: [ 'eh', {key: 'b', value:'bee'}, {name: 'c', value: 'see'}, {value: 'd'}, - {name: 'e'} + {name: 'e'}, + {key: 'f', name: 'ff', value: { prop: 'value'}} ] }]; test('verify good bypass input', function (t) { - const [, byValue] = promptBypass(prompts, ['eh'], plop); - t.is(byValue.list, 'eh'); - - const [, byKey] = promptBypass(prompts, ['b'], plop); - t.is(byKey.list, 'bee'); - - const [, byName] = promptBypass(prompts, ['c'], plop); - t.is(byName.list, 'see'); - - const [, byValueProp] = promptBypass(prompts, ['d'], plop); - t.is(byValueProp.list, 'd'); - - const [, byNameNoValue] = promptBypass(prompts, ['e'], plop); - t.is(byNameNoValue.list, 'e'); - - const [, byIndexValue] = promptBypass(prompts, ['0'], plop); - t.is(byIndexValue.list, 'eh'); - - const [, byIndexKey] = promptBypass(prompts, ['1'], plop); - t.is(byIndexKey.list, 'bee'); - - const [, byIndexName] = promptBypass(prompts, ['2'], plop); - t.is(byIndexName.list, 'see'); - - const [, byIndexValueProp] = promptBypass(prompts, ['3'], plop); - t.is(byIndexValueProp.list, 'd'); - - const [, byIndexNameNoValue] = promptBypass(prompts, ['4'], plop); - t.is(byIndexNameNoValue.list, 'e'); - - const [, byIndexNumber] = promptBypass(prompts, [4], plop); - t.is(byIndexNumber.list, 'e'); + // answer is string + [ + { bypassValue: 'eh', expectedAnswer: 'eh' }, // by value + { bypassValue: 'b', expectedAnswer: 'bee' }, // by key + { bypassValue: 'c', expectedAnswer: 'see' }, // by name + { bypassValue: 'd', expectedAnswer: 'd' }, // by value prop + { bypassValue: 'e', expectedAnswer: 'e' }, // by name, no value + { bypassValue: '0', expectedAnswer: 'eh' }, // by index - value + { bypassValue: '1', expectedAnswer: 'bee' }, // by index - key + { bypassValue: '2', expectedAnswer: 'see' }, // by index - name + { bypassValue: '3', expectedAnswer: 'd' }, // by index - value prop + { bypassValue: '4', expectedAnswer: 'e' }, // by index - name, no value + { bypassValue: 4, expectedAnswer: 'e' }, // by index number + ].forEach(testCase => { + const [, value] = promptBypass(prompts, [testCase.bypassValue], plop); + t.is(value.list, testCase.expectedAnswer); + }); + + // answer is object + const objValue = { prop: 'value' }; + [ + { bypassValue: 'f', expectedAnswer: objValue }, // by key + { bypassValue: 'ff', expectedAnswer: objValue }, // by name + { bypassValue: '5', expectedAnswer: objValue }, // by index + { bypassValue: 5, expectedAnswer: objValue }, // by index number + ].forEach(testCase => { + const [, value] = promptBypass(prompts, [testCase.bypassValue], plop); + t.deepEqual(value.list, testCase.expectedAnswer); + }); }); test('verify bad bypass input', function (t) { - t.throws(() => promptBypass(prompts, ['asdf'], plop)); - t.throws(() => promptBypass(prompts, ['5'], plop)); + [ + 'asdf', + '6', + 6, + ].forEach(bypassValue => { + t.throws(() => promptBypass(prompts, [bypassValue], plop)); + }); }); From f41e79878882894936a6fb9e5575696c8263aed4 Mon Sep 17 00:00:00 2001 From: Kristiyan Nikolov Date: Thu, 7 Oct 2021 10:11:54 +0300 Subject: [PATCH 2/2] simplify code and tests as per PR comments --- src/prompt-bypass.js | 12 +++-- tests/prompt-bypass-list.ava.js | 80 ++++++++++++++++++--------------- 2 files changed, 49 insertions(+), 43 deletions(-) diff --git a/src/prompt-bypass.js b/src/prompt-bypass.js index 6f99540..e86fe21 100644 --- a/src/prompt-bypass.js +++ b/src/prompt-bypass.js @@ -28,13 +28,11 @@ function checkChoiceValue(choiceValue, value) { // check if a bypass value matches some aspect of // a particular choice option (index, value, key, etc) function choiceMatchesValue (choice, choiceIdx, value) { - return [ - choice, - choice.value, - choice.key, - choice.name, - choiceIdx.toString() - ].some(choiceValue => checkChoiceValue(choiceValue, value)); + return checkChoiceValue(choice, value) + || checkChoiceValue(choice.value, value) + || checkChoiceValue(choice.key, value) + || checkChoiceValue(choice.name, value) + || checkChoiceValue(choiceIdx.toString(), value); } // check if a value matches a particular set of flagged input options diff --git a/tests/prompt-bypass-list.ava.js b/tests/prompt-bypass-list.ava.js index 06c112e..0b4cf43 100644 --- a/tests/prompt-bypass-list.ava.js +++ b/tests/prompt-bypass-list.ava.js @@ -19,43 +19,51 @@ const prompts = [{ }]; test('verify good bypass input', function (t) { - // answer is string - [ - { bypassValue: 'eh', expectedAnswer: 'eh' }, // by value - { bypassValue: 'b', expectedAnswer: 'bee' }, // by key - { bypassValue: 'c', expectedAnswer: 'see' }, // by name - { bypassValue: 'd', expectedAnswer: 'd' }, // by value prop - { bypassValue: 'e', expectedAnswer: 'e' }, // by name, no value - { bypassValue: '0', expectedAnswer: 'eh' }, // by index - value - { bypassValue: '1', expectedAnswer: 'bee' }, // by index - key - { bypassValue: '2', expectedAnswer: 'see' }, // by index - name - { bypassValue: '3', expectedAnswer: 'd' }, // by index - value prop - { bypassValue: '4', expectedAnswer: 'e' }, // by index - name, no value - { bypassValue: 4, expectedAnswer: 'e' }, // by index number - ].forEach(testCase => { - const [, value] = promptBypass(prompts, [testCase.bypassValue], plop); - t.is(value.list, testCase.expectedAnswer); - }); - - // answer is object - const objValue = { prop: 'value' }; - [ - { bypassValue: 'f', expectedAnswer: objValue }, // by key - { bypassValue: 'ff', expectedAnswer: objValue }, // by name - { bypassValue: '5', expectedAnswer: objValue }, // by index - { bypassValue: 5, expectedAnswer: objValue }, // by index number - ].forEach(testCase => { - const [, value] = promptBypass(prompts, [testCase.bypassValue], plop); - t.deepEqual(value.list, testCase.expectedAnswer); - }); + const [, byValue] = promptBypass(prompts, ['eh'], plop); + t.is(byValue.list, 'eh'); + + const [, byKey] = promptBypass(prompts, ['b'], plop); + t.is(byKey.list, 'bee'); + + const [, byName] = promptBypass(prompts, ['c'], plop); + t.is(byName.list, 'see'); + + const [, byValueProp] = promptBypass(prompts, ['d'], plop); + t.is(byValueProp.list, 'd'); + + const [, byNameNoValue] = promptBypass(prompts, ['e'], plop); + t.is(byNameNoValue.list, 'e'); + + const [, byIndexValue] = promptBypass(prompts, ['0'], plop); + t.is(byIndexValue.list, 'eh'); + + const [, byIndexKey] = promptBypass(prompts, ['1'], plop); + t.is(byIndexKey.list, 'bee'); + + const [, byIndexName] = promptBypass(prompts, ['2'], plop); + t.is(byIndexName.list, 'see'); + + const [, byIndexValueProp] = promptBypass(prompts, ['3'], plop); + t.is(byIndexValueProp.list, 'd'); + + const [, byIndexNameNoValue] = promptBypass(prompts, ['4'], plop); + t.is(byIndexNameNoValue.list, 'e'); + + const [, byIndexNumber] = promptBypass(prompts, [4], plop); + t.is(byIndexNumber.list, 'e'); + + const [, byIndexNumberObject] = promptBypass(prompts, [5], plop); + t.deepEqual(byIndexNumberObject.list, { prop: 'value' }); + + const [, byKeyObject] = promptBypass(prompts, 'f', plop); + t.deepEqual(byKeyObject.list, { prop: 'value' }); + + const [, byNameObject] = promptBypass(prompts, 'ff', plop); + t.deepEqual(byNameObject.list, { prop: 'value' }); }); test('verify bad bypass input', function (t) { - [ - 'asdf', - '6', - 6, - ].forEach(bypassValue => { - t.throws(() => promptBypass(prompts, [bypassValue], plop)); - }); + t.throws(() => promptBypass(prompts, ['asdf'], plop)); + t.throws(() => promptBypass(prompts, ['6'], plop)); + t.throws(() => promptBypass(prompts, [6], plop)); });