diff --git a/index.js b/index.js index 542f6812..a0367bd3 100644 --- a/index.js +++ b/index.js @@ -361,7 +361,10 @@ function parse (args, opts) { // on the nargs option? function eatNargs (i, key, args) { let ii - const toEat = checkAllAliases(key, flags.nargs) + let toEat = checkAllAliases(key, flags.nargs) + // NaN has a special meaning for the array type, indicating that one or + // more values are expected. + toEat = isNaN(toEat) ? 1 : toEat if (toEat === 0) { setArg(key, defaultValue(key)) @@ -397,6 +400,8 @@ function parse (args, opts) { function eatArray (i, key, args) { let argsToSet = [] let next = args[i + 1] + // If both array and nargs are configured, enforce the nargs count: + const nargsCount = checkAllAliases(key, flags.nargs) if (checkAllAliases(key, flags.bools) && !(/^(true|false)$/.test(next))) { argsToSet.push(true) @@ -413,14 +418,16 @@ function parse (args, opts) { if (/^-/.test(next) && !negative.test(next) && !isUnknownOptionAsArg(next)) break i = ii argsToSet.push(processValue(key, next)) - if (!configuration['greedy-arrays']) break + if (!configuration['greedy-arrays'] || + (nargsCount && argsToSet.length >= nargsCount)) break } } // If both array and nargs are configured, create an error if less than - // nargs positionals were found: - const toEat = checkAllAliases(key, flags.nargs) - if (toEat && argsToSet.length < toEat) { + // nargs positionals were found. NaN has special meaning, indicating + // that at least one value is required (more are okay). + if ((nargsCount && argsToSet.length < nargsCount) || + (isNaN(nargsCount) && argsToSet.length === 0)) { error = Error(__('Not enough arguments following: %s', key)) } diff --git a/test/yargs-parser.js b/test/yargs-parser.js index 81605629..4a16cacc 100644 --- a/test/yargs-parser.js +++ b/test/yargs-parser.js @@ -3565,28 +3565,65 @@ describe('yargs-parser', function () { parse.infinite.should.equal(false) }) - // See: https://github.com/yargs/yargs/issues/1098 + // See: https://github.com/yargs/yargs/issues/1098, + // https://github.com/yargs/yargs/issues/1570 describe('array with nargs', () => { it('allows array and nargs to be configured in conjunction, enforcing the nargs value', () => { - var parse = parser(['-a', 'apple', 'banana'], { + var parse = parser.detailed(['-a', 'apple', 'banana'], { array: 'a', narg: { a: 1 } }) - parse.a.should.eql(['apple', 'banana']) + expect(parse.error).to.be.null // eslint-disable-line + parse.argv.a.should.eql(['apple']) + parse.argv._.should.eql(['banana']) }) - it('returns an error if not enough positionals were provided for nargs', () => { + // see; https://github.com/yargs/yargs/issues/1098 + it('allows special NaN count to be provided to narg, to indicate one or more array values', () => { + var parse = parser.detailed(['-a', 'apple', 'banana'], { + array: 'a', + narg: { + a: NaN + } + }) + expect(parse.error).to.be.null // eslint-disable-line + parse.argv.a.should.eql(['apple', 'banana']) + }) + + it('throws error if at least one value not provided for NaN', () => { var parse = parser.detailed(['-a'], { array: 'a', narg: { - a: 1 + a: NaN + } + }) + parse.error.message.should.match(/Not enough arguments/) + }) + + it('returns an error if not enough positionals were provided for nargs', () => { + var parse = parser.detailed(['-a', '33'], { + array: 'a', + narg: { + a: 2 } }) - parse.argv.a.should.eql([]) + parse.argv.a.should.eql([33]) parse.error.message.should.equal('Not enough arguments following: a') }) + + it('does not raise error if no arguments are provided for boolean option', () => { + var parse = parser.detailed(['-a'], { + array: 'a', + boolean: 'a', + narg: { + a: NaN + } + }) + expect(parse.error).to.be.null // eslint-disable-line + parse.argv.a.should.eql([true]) + }) }) describe('greedy-arrays=false', () => {