Skip to content

Commit

Permalink
fix: do not mutate process.argv (#36)
Browse files Browse the repository at this point in the history
* (fix): don't mutate process.argv with arr.splice

- 1.7.1 introduced some arr.splice's into the code, which caused
  mutations in process.argv, affecting downstream code

- set arr to a clone of process.argv instead so it can be freely
  mutated after
- explicitly call the parameter processArgv so code is written more
  carefully when dealing with it
- add a test to ensure process.argv is not mutated

* chore: truncate

* chore: add & improve tests

Co-authored-by: Luke Edwards <[email protected]>
  • Loading branch information
agilgur5 and lukeed authored Feb 16, 2020
1 parent ff2ed46 commit 9d3fdca
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 0 deletions.
1 change: 1 addition & 0 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ class Sade {
}

parse(arr, opts={}) {
arr = arr.slice(); // copy
let offset=2, tmp, idx, isVoid, cmd;
let alias = { h:'help', v:'version' };
let argv = mri(arr.slice(offset), { alias });
Expand Down
64 changes: 64 additions & 0 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,70 @@ test('prog.action (multi optional)', t => {
(c=true) && run(); // +4 tests
});

test('prog.parse :: safe :: default', t => {
let ctx = sade('foo').command('build', '', { default: true });

let argv1 = ['', '', 'build'];
let foo = ctx.parse(argv1, { lazy: true });
t.deepEqual(argv1, ['', '', 'build'], '~> argv unchanged');
t.deepEqual(foo.args, [{ _: [] }], '~> args correct');

let argv2 = ['', ''];
let bar = ctx.parse(argv2, { lazy: true });
t.deepEqual(argv2, ['', ''], '~> argv unchanged');
t.deepEqual(bar.args, [{ _: [] }], '~> args correct');

t.end();
});

test('prog.parse :: safe :: alias', t => {
let ctx = sade('foo').command('build').alias('b');

let argv1 = ['', '', 'build'];
let foo = ctx.parse(argv1, { lazy: true });
t.deepEqual(argv1, ['', '', 'build'], '~> argv unchanged');
t.deepEqual(foo.args, [{ _: [] }], '~> args correct');

let argv2 = ['', '', 'b'];
let bar = ctx.parse(argv2, { lazy: true });
t.deepEqual(argv2, ['', '', 'b'], '~> argv unchanged');
t.deepEqual(bar.args, [{ _: [] }], '~> args correct');

t.end();
});

test('prog.parse :: safe :: default :: flags', t => {
let ctx = sade('foo').command('build <dir>', '', { default: true });

let argv1 = ['', '', '-r', 'dotenv', 'build', 'public', '--fresh'];
let foo = ctx.parse(argv1, { lazy: true });
t.deepEqual(argv1, ['', '', '-r', 'dotenv', 'build', 'public', '--fresh'], '~> argv unchanged');
t.deepEqual(foo.args, ['public', { _: [], r: 'dotenv', fresh: true }], '~> args correct');

let argv2 = ['', '', '-r', 'dotenv', 'public', '--fresh'];
let bar = ctx.parse(argv2, { lazy: true });
t.deepEqual(argv2, ['', '', '-r', 'dotenv', 'public', '--fresh'], '~> argv unchanged');
t.deepEqual(bar.args, ['public', { _: [], r: 'dotenv', fresh: true }], '~> args correct');

t.end();
});

test('prog.parse :: safe :: alias :: flags', t => {
let ctx = sade('foo').command('build <dir>').alias('b');

let argv1 = ['', '', '-r', 'dotenv', 'build', 'public', '--fresh'];
let foo = ctx.parse(argv1, { lazy: true });
t.deepEqual(argv1, ['', '', '-r', 'dotenv', 'build', 'public', '--fresh'], '~> argv unchanged');
t.deepEqual(foo.args, ['public', { _: [], r: 'dotenv', fresh: true }], '~> args correct');

let argv2 = ['', '', '-r', 'dotenv', 'b', 'public', '--fresh'];
let bar = ctx.parse(argv2, { lazy: true });
t.deepEqual(argv2, ['', '', '-r', 'dotenv', 'b', 'public', '--fresh'], '~> argv unchanged');
t.deepEqual(bar.args, ['public', { _: [], r: 'dotenv', fresh: true }], '~> args correct');

t.end();
});

test('prog.parse :: lazy', t => {
t.plan(14);

Expand Down

0 comments on commit 9d3fdca

Please sign in to comment.