From b2f6a44bebde2c7db6ca8bf3ebd2b9915e04e7d6 Mon Sep 17 00:00:00 2001 From: Manuel Spigolon Date: Fri, 7 Oct 2022 21:13:30 +0200 Subject: [PATCH] chore: update after merge into node.js core --- README.md | 4 +- index.js | 22 +++++---- test/default-values.js | 101 ++++++++++++++++++++--------------------- utils.js | 2 +- 4 files changed, 65 insertions(+), 64 deletions(-) diff --git a/README.md b/README.md index 3dfcf71..0a04192 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,9 @@ changes: times. If `true`, all values will be collected in an array. If `false`, values for the option are last-wins. **Default:** `false`. * `short` {string} A single character alias for the option. - * `default` {string | boolean | string[] | boolean[]} The default option value when it is not set by args. + * `default` {string | boolean | string\[] | boolean\[]} The default option + value when it is not set by args. It must be of the same type as the + the `type` property. When `multiple` is `true`, it must be an array. * `strict` {boolean} Should an error be thrown when unknown arguments are encountered, or when arguments are passed that do not match the `type` configured in `options`. diff --git a/index.js b/index.js index 2a5657d..b1004c7 100644 --- a/index.js +++ b/index.js @@ -331,17 +331,19 @@ const parseArgs = (config = kEmptyObject) => { validateBoolean(multipleOption, `options.${longOption}.multiple`); } - if (ObjectHasOwn(optionConfig, 'default')) { - const defaultValue = objectGetOwn(optionConfig, 'default'); - if (optionType === 'string' && !multipleOption) { - validateString(defaultValue, `options.${longOption}.default`); - } else if (optionType === 'string' && multipleOption) { - validateStringArray(defaultValue, `options.${longOption}.default`); - } else if (optionType === 'boolean' && !multipleOption) { - validateBoolean(defaultValue, `options.${longOption}.default`); - } else if (optionType === 'boolean' && multipleOption) { - validateBooleanArray(defaultValue, `options.${longOption}.default`); + const defaultValue = objectGetOwn(optionConfig, 'default'); + if (defaultValue !== undefined) { + let validator; + switch (optionType) { + case 'string': + validator = multipleOption ? validateStringArray : validateString; + break; + + case 'boolean': + validator = multipleOption ? validateBooleanArray : validateBoolean; + break; } + validator(defaultValue, `options.${longOption}.default`); } } ); diff --git a/test/default-values.js b/test/default-values.js index 8182865..ad0bea0 100644 --- a/test/default-values.js +++ b/test/default-values.js @@ -1,71 +1,78 @@ -'use strict'; - +/* global assert */ /* eslint max-len: 0 */ +'use strict'; -const test = require('tape'); +const { test } = require('./utils'); const { parseArgs } = require('../index.js'); -test('default must be a boolean when option type is boolean', (t) => { +test('default must be a boolean when option type is boolean', () => { const args = []; const options = { alpha: { type: 'boolean', default: 'not a boolean' } }; - t.throws(() => { + assert.throws(() => { parseArgs({ args, options }); - }, /alpha\.default must be Boolean/ + }, /options\.alpha\.default must be Boolean/ ); - t.end(); }); -test('default must be a boolean array when option type is boolean and multiple', (t) => { +test('default must accept undefined value', () => { + const args = []; + const options = { alpha: { type: 'boolean', default: undefined } }; + const result = parseArgs({ args, options }); + const expected = { + values: { + __proto__: null, + }, + positionals: [] + }; + assert.deepStrictEqual(result, expected); +}); + +test('default must be a boolean array when option type is boolean and multiple', () => { const args = []; const options = { alpha: { type: 'boolean', multiple: true, default: 'not an array' } }; - t.throws(() => { + assert.throws(() => { parseArgs({ args, options }); - }, /alpha\.default must be Array/ + }, /options\.alpha\.default must be Array/ ); - t.end(); }); -test('default must be a boolean array when option type is string and multiple is true', (t) => { +test('default must be a boolean array when option type is string and multiple is true', () => { const args = []; const options = { alpha: { type: 'boolean', multiple: true, default: [true, true, 42] } }; - t.throws(() => { + assert.throws(() => { parseArgs({ args, options }); - }, /alpha\.default\[2\] must be Boolean/ + }, /options\.alpha\.default\[2\] must be Boolean/ ); - t.end(); }); -test('default must be a string when option type is string', (t) => { +test('default must be a string when option type is string', () => { const args = []; const options = { alpha: { type: 'string', default: true } }; - t.throws(() => { + assert.throws(() => { parseArgs({ args, options }); - }, /alpha\.default must be String/ + }, /options\.alpha\.default must be String/ ); - t.end(); }); -test('default must be an array when option type is string and multiple is true', (t) => { +test('default must be an array when option type is string and multiple is true', () => { const args = []; const options = { alpha: { type: 'string', multiple: true, default: 'not an array' } }; - t.throws(() => { + assert.throws(() => { parseArgs({ args, options }); - }, /alpha\.default must be Array/ + }, /options\.alpha\.default must be Array/ ); - t.end(); }); -test('default must be a string array when option type is string and multiple is true', (t) => { +test('default must be a string array when option type is string and multiple is true', () => { const args = []; const options = { alpha: { type: 'string', multiple: true, default: ['str', 42] } }; - t.throws(() => { + assert.throws(() => { parseArgs({ args, options }); - }, /alpha\.default\[1\] must be String/ + }, /options\.alpha\.default\[1\] must be String/ ); - t.end(); }); -test('default accepted input when multiple is true', (t) => { +test('default accepted input when multiple is true', () => { const args = ['--inputStringArr', 'c', '--inputStringArr', 'd', '--inputBoolArr', '--inputBoolArr']; const options = { inputStringArr: { type: 'string', multiple: true, default: ['a', 'b'] }, @@ -84,11 +91,10 @@ test('default accepted input when multiple is true', (t) => { fullBoolArr: [false, true, false] }, positionals: [] }; const result = parseArgs({ args, options }); - t.deepEqual(result, expected); - t.end(); + assert.deepStrictEqual(result, expected); }); -test('when default is set, the option must be added as result', (t) => { +test('when default is set, the option must be added as result', () => { const args = []; const options = { a: { type: 'string', default: 'HELLO' }, @@ -98,12 +104,10 @@ test('when default is set, the option must be added as result', (t) => { const expected = { values: { __proto__: null, a: 'HELLO', b: false, c: true }, positionals: [] }; const result = parseArgs({ args, options }); - - t.deepEqual(result, expected); - t.end(); + assert.deepStrictEqual(result, expected); }); -test('when default is set, the args value takes precedence', (t) => { +test('when default is set, the args value takes precedence', () => { const args = ['--a', 'WORLD', '--b', '-c']; const options = { a: { type: 'string', default: 'HELLO' }, @@ -113,12 +117,10 @@ test('when default is set, the args value takes precedence', (t) => { const expected = { values: { __proto__: null, a: 'WORLD', b: true, c: true }, positionals: [] }; const result = parseArgs({ args, options }); - - t.deepEqual(result, expected); - t.end(); + assert.deepStrictEqual(result, expected); }); -test('tokens should not include the default options', (t) => { +test('tokens should not include the default options', () => { const args = []; const options = { a: { type: 'string', default: 'HELLO' }, @@ -129,11 +131,10 @@ test('tokens should not include the default options', (t) => { const expectedTokens = []; const { tokens } = parseArgs({ args, options, tokens: true }); - t.deepEqual(tokens, expectedTokens); - t.end(); + assert.deepStrictEqual(tokens, expectedTokens); }); -test('tokens:true should not include the default options after the args input', (t) => { +test('tokens:true should not include the default options after the args input', () => { const args = ['--z', 'zero', 'positional-item']; const options = { z: { type: 'string' }, @@ -148,11 +149,10 @@ test('tokens:true should not include the default options after the args input', ]; const { tokens } = parseArgs({ args, options, tokens: true, allowPositionals: true }); - t.deepEqual(tokens, expectedTokens); - t.end(); + assert.deepStrictEqual(tokens, expectedTokens); }); -test('proto as default value must be ignored', (t) => { +test('proto as default value must be ignored', () => { const args = []; const options = Object.create(null); @@ -161,17 +161,14 @@ test('proto as default value must be ignored', (t) => { const result = parseArgs({ args, options, allowPositionals: true }); const expected = { values: { __proto__: null }, positionals: [] }; - t.deepEqual(result, expected); - t.end(); + assert.deepStrictEqual(result, expected); }); -test('multiple as false should expect a String', (t) => { +test('multiple as false should expect a String', () => { const args = []; const options = { alpha: { type: 'string', multiple: false, default: ['array'] } }; - t.throws(() => { + assert.throws(() => { parseArgs({ args, options }); - }, /alpha\.default must be String/ - ); - t.end(); + }, / must be String got array/); }); diff --git a/utils.js b/utils.js index 1434724..d7f420a 100644 --- a/utils.js +++ b/utils.js @@ -180,7 +180,7 @@ function findLongOptionForShort(shortOption, options) { */ function useDefaultValueOption(longOption, optionConfig, values) { return objectGetOwn(optionConfig, 'default') !== undefined && - values[longOption] === undefined; + values[longOption] === undefined; } module.exports = {