Skip to content

Commit 68d68a0

Browse files
laggingreflexbcoe
authored andcommitted
fix: flatten/duplicate regression (#75)
1 parent 941d8f3 commit 68d68a0

File tree

2 files changed

+227
-31
lines changed

2 files changed

+227
-31
lines changed

index.js

+44-29
Original file line numberDiff line numberDiff line change
@@ -325,8 +325,10 @@ function parse (args, opts) {
325325
i = ii
326326
argsToSet.push(args[ii])
327327
}
328-
if (multipleArrayFlag && !configuration['flatten-duplicate-arrays']) {
329-
setArg(key, argsToSet)
328+
if (multipleArrayFlag) {
329+
setArg(key, argsToSet.map(function (arg) {
330+
return processValue(key, arg)
331+
}))
330332
} else {
331333
argsToSet.forEach(function (arg) {
332334
setArg(key, arg)
@@ -339,33 +341,13 @@ function parse (args, opts) {
339341
function setArg (key, val) {
340342
unsetDefaulted(key)
341343

342-
// handle parsing boolean arguments --foo=true --bar false.
343-
if (checkAllAliases(key, flags.bools) || checkAllAliases(key, flags.counts)) {
344-
if (typeof val === 'string') val = val === 'true'
345-
}
346-
347344
if (/-/.test(key) && !(flags.aliases[key] && flags.aliases[key].length) && configuration['camel-case-expansion']) {
348345
var c = camelCase(key)
349346
flags.aliases[key] = [c]
350347
newAliases[c] = true
351348
}
352349

353-
var value = val
354-
if (!checkAllAliases(key, flags.strings) && !checkAllAliases(key, flags.coercions)) {
355-
if (isNumber(val)) value = Number(val)
356-
if (!isUndefined(val) && !isNumber(val) && checkAllAliases(key, flags.numbers)) value = NaN
357-
}
358-
359-
// increment a count given as arg (either no value or value parsed as boolean)
360-
if (checkAllAliases(key, flags.counts) && (isUndefined(value) || typeof value === 'boolean')) {
361-
value = increment
362-
}
363-
364-
// Set normalized value when key is in 'normalize' and in 'arrays'
365-
if (checkAllAliases(key, flags.normalize) && checkAllAliases(key, flags.arrays)) {
366-
if (Array.isArray(val)) value = val.map(path.normalize)
367-
else value = path.normalize(val)
368-
}
350+
var value = processValue(key, val)
369351

370352
var splitKey = key.split('.')
371353
setKey(argv, splitKey, value)
@@ -407,6 +389,31 @@ function parse (args, opts) {
407389
}
408390
}
409391

392+
function processValue (key, val) {
393+
// handle parsing boolean arguments --foo=true --bar false.
394+
if (checkAllAliases(key, flags.bools) || checkAllAliases(key, flags.counts)) {
395+
if (typeof val === 'string') val = val === 'true'
396+
}
397+
398+
var value = val
399+
if (!checkAllAliases(key, flags.strings) && !checkAllAliases(key, flags.coercions)) {
400+
if (isNumber(val)) value = Number(val)
401+
if (!isUndefined(val) && !isNumber(val) && checkAllAliases(key, flags.numbers)) value = NaN
402+
}
403+
404+
// increment a count given as arg (either no value or value parsed as boolean)
405+
if (checkAllAliases(key, flags.counts) && (isUndefined(value) || typeof value === 'boolean')) {
406+
value = increment
407+
}
408+
409+
// Set normalized value when key is in 'normalize' and in 'arrays'
410+
if (checkAllAliases(key, flags.normalize) && checkAllAliases(key, flags.arrays)) {
411+
if (Array.isArray(val)) value = val.map(path.normalize)
412+
else value = path.normalize(val)
413+
}
414+
return value
415+
}
416+
410417
// set args from config.json file, this should be
411418
// applied last so that defaults can be applied.
412419
function setConfig (argv) {
@@ -551,15 +558,23 @@ function parse (args, opts) {
551558

552559
var key = keys[keys.length - 1]
553560

561+
var isTypeArray = checkAllAliases(key, flags.arrays)
562+
var isValueArray = Array.isArray(value)
563+
var duplicate = configuration['duplicate-arguments-array']
564+
554565
if (value === increment) {
555566
o[key] = increment(o[key])
556-
} else if (o[key] === undefined && checkAllAliases(key, flags.arrays)) {
557-
o[key] = Array.isArray(value) && configuration['flatten-duplicate-arrays'] ? value : [value]
558-
} else if (o[key] === undefined || checkAllAliases(key, flags.bools) || checkAllAliases(keys.join('.'), flags.bools) || checkAllAliases(key, flags.counts)) {
559-
o[key] = value
560567
} else if (Array.isArray(o[key])) {
561-
o[key].push(value)
562-
} else if (configuration['duplicate-arguments-array']) {
568+
if (duplicate && isTypeArray && isValueArray) {
569+
o[key] = configuration['flatten-duplicate-arrays'] ? o[key].concat(value) : [o[key]].concat([value])
570+
} else if (!duplicate && Boolean(isTypeArray) === Boolean(isValueArray)) {
571+
o[key] = value
572+
} else {
573+
o[key] = o[key].concat([value])
574+
}
575+
} else if (o[key] === undefined && isTypeArray) {
576+
o[key] = isValueArray ? value : [value]
577+
} else if (duplicate && !(o[key] === undefined || checkAllAliases(key, flags.bools) || checkAllAliases(keys.join('.'), flags.bools) || checkAllAliases(key, flags.counts))) {
563578
o[key] = [ o[key], value ]
564579
} else {
565580
o[key] = value

test/yargs-parser.js

+183-2
Original file line numberDiff line numberDiff line change
@@ -1374,11 +1374,16 @@ describe('yargs-parser', function () {
13741374
})
13751375

13761376
describe('array', function () {
1377-
it('should group values into an array if the same option is specified multiple times', function () {
1378-
var parse = parser(['-v', 'a', '-v', 'b', '-v', 'c'])
1377+
it('should group values into an array if the same option is specified multiple times (duplicate-arguments-array=true)', function () {
1378+
var parse = parser(['-v', 'a', '-v', 'b', '-v', 'c'], {configuration: {'duplicate-arguments-array': true}})
13791379
parse.should.have.property('v').and.deep.equal(['a', 'b', 'c'])
13801380
parse.should.have.property('_').with.length(0)
13811381
})
1382+
it('should keep only the last value if the same option is specified multiple times (duplicate-arguments-false)', function () {
1383+
var parse = parser(['-v', 'a', '-v', 'b', '-v', 'c'], {configuration: {'duplicate-arguments-array': false}})
1384+
parse.should.have.property('v').and.equal('c')
1385+
parse.should.have.property('_').with.length(0)
1386+
})
13821387

13831388
it('should default an array to an empty array if passed as first option followed by another', function () {
13841389
var result = parser(['-a', '-b'], {
@@ -2012,6 +2017,182 @@ describe('yargs-parser', function () {
20122017
parsed['x'].should.deep.equal(['a', 'b'])
20132018
})
20142019
})
2020+
2021+
describe('duplicate-arguments-array VS flatten-duplicate-arrays', function () {
2022+
/*
2023+
duplicate=false, flatten=false
2024+
type=array
2025+
[-x 1 2 3] => [1, 2, 3]
2026+
[-x 1 2 3 -x 2 3 4] => [2, 3, 4]
2027+
type=string/number/etc
2028+
[-x 1 -x 2 -x 3] => 3
2029+
2030+
duplicate=false, flatten=true
2031+
type=array
2032+
[-x 1 2 3] => [1, 2, 3]
2033+
[-x 1 2 3 -x 2 3 4] => [2, 3, 4]
2034+
type=string/number/etc
2035+
[-x 1 -x 2 -x 3] => 3
2036+
2037+
duplicate=true, flatten=true
2038+
type=array
2039+
[-x 1 2 3] => [1, 2, 3]
2040+
[-x 1 2 3 -x 2 3 4] => [1, 2, 3, 2, 3, 4]
2041+
type=string/number/etc
2042+
[-x 1 -x 2 -x 3] => [1, 2, 3]
2043+
2044+
duplicate=true, flatten=false
2045+
type=array
2046+
[-x 1 2 3] => [1, 2, 3]
2047+
[-x 1 2 3 -x 2 3 4] => [[1, 2, 3], [2, 3, 4]]
2048+
type=string/number/etc
2049+
[-x 1 -x 2 -x 3] => [1, 2, 3]
2050+
*/
2051+
describe('duplicate=false, flatten=false,', function () {
2052+
describe('type=array', function () {
2053+
it('[-x 1 2 3] => [1, 2, 3]', function () {
2054+
var parsed = parser('-x 1 2 3', {
2055+
array: ['x'],
2056+
configuration: {
2057+
'duplicate-arguments-array': false,
2058+
'flatten-duplicate-arrays': false
2059+
}
2060+
})
2061+
parsed['x'].should.deep.equal([1, 2, 3])
2062+
})
2063+
it('[-x 1 2 3 -x 2 3 4] => [2, 3, 4]', function () {
2064+
var parsed = parser('-x 1 2 3 -x 2 3 4', {
2065+
array: ['x'],
2066+
configuration: {
2067+
'duplicate-arguments-array': false,
2068+
'flatten-duplicate-arrays': false
2069+
}
2070+
})
2071+
parsed['x'].should.deep.equal([2, 3, 4])
2072+
})
2073+
})
2074+
describe('type=number', function () {
2075+
it('[-x 1 -x 2 -x 3] => 3', function () {
2076+
var parsed = parser('-x 1 -x 2 -x 3', {
2077+
number: 'x',
2078+
configuration: {
2079+
'duplicate-arguments-array': false,
2080+
'flatten-duplicate-arrays': false
2081+
}
2082+
})
2083+
parsed['x'].should.deep.equal(3)
2084+
})
2085+
})
2086+
})
2087+
describe('duplicate=false, flatten=true,', function () {
2088+
describe('type=array', function () {
2089+
it('[-x 1 2 3] => [1, 2, 3]', function () {
2090+
var parsed = parser('-x 1 2 3', {
2091+
array: ['x'],
2092+
configuration: {
2093+
'duplicate-arguments-array': false,
2094+
'flatten-duplicate-arrays': true
2095+
}
2096+
})
2097+
parsed['x'].should.deep.equal([1, 2, 3])
2098+
})
2099+
it('[-x 1 2 3 -x 2 3 4] => [2, 3, 4]', function () {
2100+
var parsed = parser('-x 1 2 3 -x 2 3 4', {
2101+
array: ['x'],
2102+
configuration: {
2103+
'duplicate-arguments-array': false,
2104+
'flatten-duplicate-arrays': true
2105+
}
2106+
})
2107+
parsed['x'].should.deep.equal([2, 3, 4])
2108+
})
2109+
})
2110+
describe('type=number', function () {
2111+
it('[-x 1 -x 2 -x 3] => 3', function () {
2112+
var parsed = parser('-x 1 -x 2 -x 3', {
2113+
number: 'x',
2114+
configuration: {
2115+
'duplicate-arguments-array': false,
2116+
'flatten-duplicate-arrays': true
2117+
}
2118+
})
2119+
parsed['x'].should.deep.equal(3)
2120+
})
2121+
})
2122+
})
2123+
describe('duplicate=true, flatten=true,', function () {
2124+
describe('type=array', function () {
2125+
it('[-x 1 2 3] => [1, 2, 3]', function () {
2126+
var parsed = parser('-x 1 2 3', {
2127+
array: ['x'],
2128+
configuration: {
2129+
'duplicate-arguments-array': true,
2130+
'flatten-duplicate-arrays': true
2131+
}
2132+
})
2133+
parsed['x'].should.deep.equal([1, 2, 3])
2134+
})
2135+
it('[-x 1 2 3 -x 2 3 4] => [1, 2, 3, 2, 3, 4]', function () {
2136+
var parsed = parser('-x 1 2 3 -x 2 3 4', {
2137+
array: ['x'],
2138+
configuration: {
2139+
'duplicate-arguments-array': true,
2140+
'flatten-duplicate-arrays': true
2141+
}
2142+
})
2143+
parsed['x'].should.deep.equal([1, 2, 3, 2, 3, 4])
2144+
})
2145+
})
2146+
describe('type=number', function () {
2147+
it('[-x 1 -x 2 -x 3] => [1, 2, 3]', function () {
2148+
var parsed = parser('-x 1 -x 2 -x 3', {
2149+
number: 'x',
2150+
configuration: {
2151+
'duplicate-arguments-array': true,
2152+
'flatten-duplicate-arrays': true
2153+
}
2154+
})
2155+
parsed['x'].should.deep.equal([1, 2, 3])
2156+
})
2157+
})
2158+
})
2159+
describe('duplicate=true, flatten=false,', function () {
2160+
describe('type=array', function () {
2161+
it('[-x 1 -x 2 -x 3] => [1, 2, 3]', function () {
2162+
var parsed = parser('-x 1 -x 2 -x 3', {
2163+
array: ['x'],
2164+
configuration: {
2165+
'duplicate-arguments-array': true,
2166+
'flatten-duplicate-arrays': false
2167+
}
2168+
})
2169+
parsed['x'].should.deep.equal([1, 2, 3])
2170+
})
2171+
it('[-x 1 2 3 -x 2 3 4] => [[1, 2, 3], [ 2, 3, 4]]', function () {
2172+
var parsed = parser('-x 1 2 3 -x 2 3 4', {
2173+
array: ['x'],
2174+
configuration: {
2175+
'duplicate-arguments-array': true,
2176+
'flatten-duplicate-arrays': false
2177+
}
2178+
})
2179+
parsed['x'].should.deep.equal([[1, 2, 3], [2, 3, 4]])
2180+
})
2181+
})
2182+
describe('type=number', function () {
2183+
it('[-x 1 -x 2 -x 3] => [1, 2, 3]', function () {
2184+
var parsed = parser('-x 1 -x 2 -x 3', {
2185+
number: 'x',
2186+
configuration: {
2187+
'duplicate-arguments-array': true,
2188+
'flatten-duplicate-arrays': false
2189+
}
2190+
})
2191+
parsed['x'].should.deep.equal([1, 2, 3])
2192+
})
2193+
})
2194+
})
2195+
})
20152196
})
20162197

20172198
// addresses: https://github.com/yargs/yargs-parser/issues/41

0 commit comments

Comments
 (0)