forked from tj/commander.js
/
command.asterisk.test.js
164 lines (152 loc) · 5.51 KB
/
command.asterisk.test.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
const commander = require('../');
// .command('*') is the old main/default command handler. It adds a listener
// for 'command:*'. It has been somewhat replaced by the program action handler,
// so most uses are probably old code. Current plan is keep the code backwards compatible
// and put work in elsewhere for new code (e.g. evolving behaviour for program action handler).
//
// The event 'command:*' is also listened for directly for testing for unknown commands
// due to an example in the README.
//
// Historical: the event 'command:*' used to also be shared by the action handler on the program.
describe(".command('*')", () => {
test('when no arguments then asterisk action not called', () => {
const writeMock = jest.spyOn(process.stderr, 'write').mockImplementation(() => { });
const mockAction = jest.fn();
const program = new commander.Command();
program
.exitOverride() // to catch help
.command('*')
.action(mockAction);
try {
program.parse(['node', 'test']);
} catch (err) {
;
}
expect(mockAction).not.toHaveBeenCalled();
writeMock.mockRestore();
});
test('when unrecognised argument then asterisk action called', () => {
const mockAction = jest.fn();
const program = new commander.Command();
program
.command('*')
.arguments('[args...]')
.action(mockAction);
program.parse(['node', 'test', 'unrecognised-command']);
expect(mockAction).toHaveBeenCalled();
});
test('when recognised command then asterisk action not called', () => {
const mockAction = jest.fn();
const program = new commander.Command();
program
.command('install')
.action(() => { });
program
.command('*')
.action(mockAction);
program.parse(['node', 'test', 'install']);
expect(mockAction).not.toHaveBeenCalled();
});
test('when unrecognised command/argument then asterisk action called', () => {
const mockAction = jest.fn();
const program = new commander.Command();
program
.command('install');
program
.command('*')
.arguments('[args...]')
.action(mockAction);
program.parse(['node', 'test', 'unrecognised-command']);
expect(mockAction).toHaveBeenCalled();
});
test('when unrecognised argument and known option then asterisk action called', () => {
// This tests for a regression between v4 and v5. Known default option should not be rejected by program.
const mockAction = jest.fn();
const program = new commander.Command();
program
.command('install');
const star = program
.command('*')
.arguments('[args...]')
.option('-d, --debug')
.action(mockAction);
program.parse(['node', 'test', 'unrecognised-command', '--debug']);
expect(mockAction).toHaveBeenCalled();
expect(star.opts().debug).toEqual(true);
});
test('when non-command argument and unknown option then error for unknown option', () => {
// This is a change in behaviour from v2 which did not error, but is consistent with modern better detection of invalid options
const mockAction = jest.fn();
const program = new commander.Command();
program
.exitOverride()
.configureOutput({
writeErr: () => {}
})
.command('install');
program
.command('*')
.arguments('[args...]')
.action(mockAction);
let caughtErr;
try {
program.parse(['node', 'test', 'some-argument', '--unknown']);
} catch (err) {
caughtErr = err;
}
expect(caughtErr.code).toEqual('commander.unknownOption');
});
});
// Test .on explicitly rather than assuming covered by .command
describe(".on('command:*')", () => {
test('when no arguments then listener not called', () => {
const mockAction = jest.fn();
const program = new commander.Command();
program
.on('command:*', mockAction);
program.parse(['node', 'test']);
expect(mockAction).not.toHaveBeenCalled();
});
test('when unrecognised argument then listener called', () => {
const mockAction = jest.fn();
const program = new commander.Command();
program
.on('command:*', mockAction);
program.parse(['node', 'test', 'unrecognised-command']);
expect(mockAction).toHaveBeenCalled();
});
test('when recognised command then listener not called', () => {
const mockAction = jest.fn();
const program = new commander.Command();
program
.command('install')
.action(() => { });
program
.on('command:*', mockAction);
program.parse(['node', 'test', 'install']);
expect(mockAction).not.toHaveBeenCalled();
});
test('when unrecognised command/argument then listener called', () => {
const mockAction = jest.fn();
const program = new commander.Command();
program
.command('install');
program
.on('command:*', mockAction);
program.parse(['node', 'test', 'unrecognised-command']);
expect(mockAction).toHaveBeenCalled();
});
test('when unrecognised command/argument and unknown option then listener called', () => {
// Give listener a chance to make a suggestion for misspelled command. The option
// could only be unknown because the command is not correct.
// Regression identified in https://github.com/tj/commander.js/issues/1460#issuecomment-772313494
const mockAction = jest.fn();
const program = new commander.Command();
program
.command('install');
program
.on('command:*', mockAction);
program.parse(['node', 'test', 'intsall', '--unknown']);
expect(mockAction).toHaveBeenCalled();
});
});