From 09dfb6741f4374ae9bcce7fa7b0e7276ba6ffb8c Mon Sep 17 00:00:00 2001 From: John Gee Date: Sun, 31 Jan 2021 17:42:04 +1300 Subject: [PATCH] Add support for variadic to choices (#1454) --- index.js | 23 +++++++++++++++++------ tests/options.variadic.test.js | 18 ++++++++++++++++++ 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/index.js b/index.js index b53035c78..641946960 100644 --- a/index.js +++ b/index.js @@ -425,6 +425,18 @@ class Option { return this; }; + /** + * @api private + */ + + _concatValue(value, previous) { + if (previous === this.defaultValue || !Array.isArray(previous)) { + return [value]; + } + + return previous.concat(value); + } + /** * Only allow option value to be one of choices. * @@ -434,10 +446,13 @@ class Option { choices(values) { this.argChoices = values; - this.parseArg = (arg) => { + this.parseArg = (arg, previous) => { if (!values.includes(arg)) { throw new InvalidOptionArgumentError(`Allowed choices are ${values.join(', ')}.`); } + if (this.variadic) { + return this._concatValue(arg, previous); + } return arg; }; return this; @@ -976,11 +991,7 @@ class Command extends EventEmitter { throw err; } } else if (val !== null && option.variadic) { - if (oldValue === defaultValue || !Array.isArray(oldValue)) { - val = [val]; - } else { - val = oldValue.concat(val); - } + val = option._concatValue(val, oldValue); } // unassigned or boolean value diff --git a/tests/options.variadic.test.js b/tests/options.variadic.test.js index 1c32e21cc..870797448 100644 --- a/tests/options.variadic.test.js +++ b/tests/options.variadic.test.js @@ -40,6 +40,24 @@ describe('variadic option with required value', () => { expect(program.opts().required).toEqual(['one', 'two']); }); + test('when variadic used with choices and one value then set in array', () => { + const program = new commander.Command(); + program + .addOption(new commander.Option('-r,--required ').choices(['one', 'two'])); + + program.parse(['--required', 'one'], { from: 'user' }); + expect(program.opts().required).toEqual(['one']); + }); + + test('when variadic used with choices and two values then set in array', () => { + const program = new commander.Command(); + program + .addOption(new commander.Option('-r,--required ').choices(['one', 'two'])); + + program.parse(['--required', 'one', 'two'], { from: 'user' }); + expect(program.opts().required).toEqual(['one', 'two']); + }); + test('when variadic with short combined argument then not variadic', () => { const program = new commander.Command(); program