-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Allow readonly array as parameter of .choices() (#1667)
* Allow readonly array as parameter of .choices() Without `readonly`, readonly arrays cannot be passed as parameters. Example: https://www.typescriptlang.org/play?#code/GYVwdgxgLglg9mABMAjACgIYCcsC5EDOUWMYA5gNoC6AlIgN4C+AUKJLAsgEyY75YBTDABMEAGwCehYqUq0GLZhARFE2LCkQBeRBQDkGPVQDcSlVDU4u23QaNqCiZWCKnW6dShqngPT9-deLC4A3yCQ4yA * Add tests for .choices() typings * Take a defensive copy of .choices argument to make sure it's readonly * Expand choices tests to cover readonly contract (#1) * Use the defensive copy of the parameter of .choices() in parseArg Co-authored-by: John Gee <[email protected]>
- Loading branch information
1 parent
10b673f
commit ad640de
Showing
8 changed files
with
126 additions
and
30 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
const commander = require('../'); | ||
|
||
test('when command argument in choices then argument set', () => { | ||
const program = new commander.Command(); | ||
let shade; | ||
program | ||
.exitOverride() | ||
.addArgument(new commander.Argument('<shade>').choices(['red', 'blue'])) | ||
.action((shadeParam) => { shade = shadeParam; }); | ||
program.parse(['red'], { from: 'user' }); | ||
expect(shade).toBe('red'); | ||
}); | ||
|
||
test('when command argument is not in choices then error', () => { | ||
// Lightweight check, more detailed testing of behaviour in command.exitOverride.test.js | ||
const program = new commander.Command(); | ||
program | ||
.exitOverride() | ||
.configureOutput({ | ||
writeErr: () => {} | ||
}) | ||
.addArgument(new commander.Argument('<shade>').choices(['red', 'blue'])); | ||
expect(() => { | ||
program.parse(['orange'], { from: 'user' }); | ||
}).toThrow(); | ||
}); | ||
|
||
describe('choices parameter is treated as readonly, per TypeScript declaration', () => { | ||
test('when choices called then parameter does not change', () => { | ||
// Unlikely this could break, but check the API we are declaring in TypeScript. | ||
const original = ['red', 'blue', 'green']; | ||
const param = original.slice(); | ||
new commander.Argument('<shade>').choices(param); | ||
expect(param).toEqual(original); | ||
}); | ||
|
||
test('when choices called and argChoices later changed then parameter does not change', () => { | ||
const original = ['red', 'blue', 'green']; | ||
const param = original.slice(); | ||
const argument = new commander.Argument('<shade>').choices(param); | ||
argument.argChoices.push('purple'); | ||
expect(param).toEqual(original); | ||
}); | ||
|
||
test('when choices called and parameter changed the choices does not change', () => { | ||
const program = new commander.Command(); | ||
const param = ['red', 'blue']; | ||
program | ||
.exitOverride() | ||
.configureOutput({ | ||
writeErr: () => {} | ||
}) | ||
.addArgument(new commander.Argument('<shade>').choices(param)); | ||
param.push('orange'); | ||
expect(() => { | ||
program.parse(['orange'], { from: 'user' }); | ||
}).toThrow(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
const commander = require('../'); | ||
|
||
test('when option argument in choices then option set', () => { | ||
const program = new commander.Command(); | ||
program | ||
.exitOverride() | ||
.addOption(new commander.Option('--colour <shade>').choices(['red', 'blue'])); | ||
program.parse(['--colour', 'red'], { from: 'user' }); | ||
expect(program.opts().colour).toBe('red'); | ||
}); | ||
|
||
test('when option argument is not in choices then error', () => { | ||
// Lightweight check, more detailed testing of behaviour in command.exitOverride.test.js | ||
const program = new commander.Command(); | ||
program | ||
.exitOverride() | ||
.configureOutput({ | ||
writeErr: () => {} | ||
}) | ||
.addOption(new commander.Option('--colour <shade>').choices(['red', 'blue'])); | ||
expect(() => { | ||
program.parse(['--colour', 'orange'], { from: 'user' }); | ||
}).toThrow(); | ||
}); | ||
|
||
describe('choices parameter is treated as readonly, per TypeScript declaration', () => { | ||
test('when choices called then parameter does not change', () => { | ||
// Unlikely this could break, but check the API we are declaring in TypeScript. | ||
const original = ['red', 'blue', 'green']; | ||
const param = original.slice(); | ||
new commander.Option('--colour <shade>').choices(param); | ||
expect(param).toEqual(original); | ||
}); | ||
|
||
test('when choices called and argChoices later changed then parameter does not change', () => { | ||
const original = ['red', 'blue', 'green']; | ||
const param = original.slice(); | ||
const option = new commander.Option('--colour <shade>').choices(param); | ||
option.argChoices.push('purple'); | ||
expect(param).toEqual(original); | ||
}); | ||
|
||
test('when choices called and parameter changed the choices does not change', () => { | ||
const program = new commander.Command(); | ||
const param = ['red', 'blue']; | ||
program | ||
.exitOverride() | ||
.configureOutput({ | ||
writeErr: () => {} | ||
}) | ||
.addOption(new commander.Option('--colour <shade>').choices(param)); | ||
param.push('orange'); | ||
expect(() => { | ||
program.parse(['--colour', 'orange'], { from: 'user' }); | ||
}).toThrow(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters