From a2f36d7da4145af1c92f76806b7fe2baf6beeceb Mon Sep 17 00:00:00 2001 From: John Gee Date: Sat, 5 Feb 2022 10:49:48 +1300 Subject: [PATCH] feat: basic support for shorts (#50) --- index.js | 18 ++++++++++----- test/index.js | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 6 deletions(-) diff --git a/index.js b/index.js index 8e7065b..60e14ec 100644 --- a/index.js +++ b/index.js @@ -113,14 +113,20 @@ const parseArgs = ( ArrayPrototypeSlice(argv, ++pos) ); return result; - } else if ( - StringPrototypeCharAt(arg, 1) !== '-' - ) { // Look for shortcodes: -fXzy - throw new ERR_NOT_IMPLEMENTED('shortcodes'); + } else if (StringPrototypeCharAt(arg, 1) !== '-') { + // Look for shortcodes: -fXzy + if (arg.length > 2) { + throw new ERR_NOT_IMPLEMENTED('short option groups'); + } + + arg = StringPrototypeCharAt(arg, 1); // short + if (options.short && options.short[arg]) + arg = options.short[arg]; // now long! + // ToDo: later code tests for `=` in arg and wrong for shorts + } else { + arg = StringPrototypeSlice(arg, 2); // remove leading -- } - arg = StringPrototypeSlice(arg, 2); // remove leading -- - if (StringPrototypeIncludes(arg, '=')) { // Store option=value same way independent of `withValue` as: // - looks like a value, store as a value diff --git a/test/index.js b/test/index.js index 8972c8b..7a0aafc 100644 --- a/test/index.js +++ b/test/index.js @@ -6,6 +6,70 @@ const { parseArgs } = require('../index.js'); // Test results are as we expect +test('when short option used as flag then stored as flag', function(t) { + const passedArgs = ['-f']; + const expected = { flags: { f: true }, values: { f: undefined }, positionals: [] }; + const args = parseArgs(passedArgs); + + t.deepEqual(args, expected); + + t.end(); +}); + +test('when short option used as flag before positional then stored as flag and positional (and not value)', function(t) { + const passedArgs = ['-f', 'bar']; + const expected = { flags: { f: true }, values: { f: undefined }, positionals: [ 'bar' ] }; + const args = parseArgs(passedArgs); + + t.deepEqual(args, expected); + + t.end(); +}); + +test('when short option withValue used with value then stored as value', function(t) { + const passedArgs = ['-f', 'bar']; + const passedOptions = { withValue: ['f'] }; + const expected = { flags: { f: true }, values: { f: 'bar' }, positionals: [] }; + const args = parseArgs(passedArgs, passedOptions); + + t.deepEqual(args, expected); + + t.end(); +}); + +test('when short option listed in short used as flag then long option stored as flag', function(t) { + const passedArgs = ['-f']; + const passedOptions = { short: { f: 'foo' } }; + const expected = { flags: { foo: true }, values: { foo: undefined }, positionals: [] }; + const args = parseArgs(passedArgs, passedOptions); + + t.deepEqual(args, expected); + + t.end(); +}); + +test('when short option listed in short and long listed in withValue and used with value then long option stored as value', function(t) { + const passedArgs = ['-f', 'bar']; + const passedOptions = { short: { f: 'foo' }, withValue: ['foo'] }; + const expected = { flags: { foo: true }, values: { foo: 'bar' }, positionals: [] }; + const args = parseArgs(passedArgs, passedOptions); + + t.deepEqual(args, expected); + + t.end(); +}); + +test('when short option withValue used without value then stored as flag', function(t) { + const passedArgs = ['-f']; + const passedOptions = { withValue: ['f'] }; + const expected = { flags: { f: true }, values: { f: undefined }, positionals: [] }; + const args = parseArgs(passedArgs, passedOptions); + + t.deepEqual(args, expected); + + t.end(); +}); + test('Everything after a bare `--` is considered a positional argument', function(t) { const passedArgs = ['--', 'barepositionals', 'mopositionals']; const expected = { flags: {}, values: {}, positionals: ['barepositionals', 'mopositionals'] };