diff --git a/tests/command.alias.test.js b/tests/command.alias.test.js index 73a9b8f29..30882de19 100644 --- a/tests/command.alias.test.js +++ b/tests/command.alias.test.js @@ -96,3 +96,29 @@ test('when set alias on executable then can get alias', () => { .alias(alias); expect(program.commands[0].alias()).toEqual(alias); }); + +describe('aliases parameter is treated as readonly, per TypeScript declaration', () => { + test('when aliases called then parameter does not change', () => { + // Unlikely this could break, but check the API we are declaring in TypeScript. + const original = ['b', 'bld']; + const param = original.slice(); + new commander.Command('build').aliases(param); + expect(param).toEqual(original); + }); + + test('when aliases called and aliases later changed then parameter does not change', () => { + const original = ['b', 'bld']; + const param = original.slice(); + const cmd = new commander.Command('build').aliases(param); + cmd.alias('BBB'); + expect(param).toEqual(original); + }); + + test('when aliases called and parameter later changed then aliases does not change', () => { + const original = ['b', 'bld']; + const param = original.slice(); + const cmd = new commander.Command('build').aliases(param); + param.length = 0; + expect(cmd.aliases()).toEqual(original); + }); +}); diff --git a/tests/command.parse.test.js b/tests/command.parse.test.js index 796c3b67d..b9903725f 100644 --- a/tests/command.parse.test.js +++ b/tests/command.parse.test.js @@ -96,3 +96,71 @@ test('when parse strings instead of array then throw', () => { program.parse('node', 'test'); }).toThrow(); }); + +describe('parse parameter is treated as readonly, per TypeScript declaration', () => { + test('when parse called then parameter does not change', () => { + const program = new commander.Command(); + program.option('--debug'); + const original = ['node', '--debug', 'arg']; + const param = original.slice(); + program.parse(param); + expect(param).toEqual(original); + }); + + test('when parse called and parsed args later changed then parameter does not change', () => { + const program = new commander.Command(); + program.option('--debug'); + const original = ['node', '--debug', 'arg']; + const param = original.slice(); + program.parse(param); + program.args.length = 0; + program.rawArgs.length = 0; + expect(param).toEqual(original); + }); + + test('when parse called and param later changed then parsed args do not change', () => { + const program = new commander.Command(); + program.option('--debug'); + const param = ['node', '--debug', 'arg']; + program.parse(param); + const oldArgs = program.args.slice(); + const oldRawArgs = program.rawArgs.slice(); + param.length = 0; + expect(program.args).toEqual(oldArgs); + expect(program.rawArgs).toEqual(oldRawArgs); + }); +}); + +describe('parseAsync parameter is treated as readonly, per TypeScript declaration', () => { + test('when parse called then parameter does not change', async() => { + const program = new commander.Command(); + program.option('--debug'); + const original = ['node', '--debug', 'arg']; + const param = original.slice(); + await program.parseAsync(param); + expect(param).toEqual(original); + }); + + test('when parseAsync called and parsed args later changed then parameter does not change', async() => { + const program = new commander.Command(); + program.option('--debug'); + const original = ['node', '--debug', 'arg']; + const param = original.slice(); + await program.parseAsync(param); + program.args.length = 0; + program.rawArgs.length = 0; + expect(param).toEqual(original); + }); + + test('when parseAsync called and param later changed then parsed args do not change', async() => { + const program = new commander.Command(); + program.option('--debug'); + const param = ['node', '--debug', 'arg']; + await program.parseAsync(param); + const oldArgs = program.args.slice(); + const oldRawArgs = program.rawArgs.slice(); + param.length = 0; + expect(program.args).toEqual(oldArgs); + expect(program.rawArgs).toEqual(oldRawArgs); + }); +}); diff --git a/typings/index.d.ts b/typings/index.d.ts index 81d6f5a53..9c40882e9 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -626,7 +626,7 @@ export class Command { * * @returns `this` command for chaining */ - parse(argv?: string[], options?: ParseOptions): this; + parse(argv?: readonly string[], options?: ParseOptions): this; /** * Parse `argv`, setting options and invoking commands when defined. @@ -645,7 +645,7 @@ export class Command { * * @returns Promise */ - parseAsync(argv?: string[], options?: ParseOptions): Promise; + parseAsync(argv?: readonly string[], options?: ParseOptions): Promise; /** * Parse options from `argv` removing known options, @@ -698,7 +698,7 @@ export class Command { * * @returns `this` command for chaining */ - aliases(aliases: string[]): this; + aliases(aliases: readonly string[]): this; /** * Get aliases for the command. */ diff --git a/typings/index.test-d.ts b/typings/index.test-d.ts index 9e86405ff..ca5802690 100644 --- a/typings/index.test-d.ts +++ b/typings/index.test-d.ts @@ -187,6 +187,7 @@ expectType(program.parse(process.argv)); expectType(program.parse(['node', 'script.js'], { from: 'node' })); expectType(program.parse(['node', 'script.js'], { from: 'electron' })); expectType(program.parse(['--option'], { from: 'user' })); +expectType(program.parse(['node', 'script.js'] as const)); // parseAsync, same tests as parse expectType>(program.parseAsync()); @@ -194,6 +195,7 @@ expectType>(program.parseAsync(process.argv)); expectType>(program.parseAsync(['node', 'script.js'], { from: 'node' })); expectType>(program.parseAsync(['node', 'script.js'], { from: 'electron' })); expectType>(program.parseAsync(['--option'], { from: 'user' })); +expectType>(program.parseAsync(['node', 'script.js'] as const)); // parseOptions (and ParseOptionsResult) expectType<{operands: string[]; unknown: string[]}>(program.parseOptions(['node', 'script.js', 'hello'])); @@ -224,6 +226,7 @@ expectType(program.alias()); // aliases expectType(program.aliases(['first-alias', 'second-alias'])); +expectType(program.aliases(['first-alias', 'second-alias'] as const)); expectType(program.aliases()); // usage