/
argument.custom-processing.test.js
207 lines (187 loc) · 6.84 KB
/
argument.custom-processing.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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
const commander = require('../');
// Testing default value and custom processing behaviours.
// Some double assertions in tests to check action argument and .processedArg
test('when argument not specified then callback not called', () => {
const mockCoercion = jest.fn();
const program = new commander.Command();
program
.argument('[n]', 'number', mockCoercion)
.action(() => {});
program.parse([], { from: 'user' });
expect(mockCoercion).not.toHaveBeenCalled();
});
test('when argument not specified then action argument undefined', () => {
let actionValue = 'foo';
const program = new commander.Command();
program
.argument('[n]', 'number', parseFloat)
.action((arg) => {
actionValue = arg;
});
program.parse([], { from: 'user' });
expect(actionValue).toBeUndefined();
});
test('when custom with starting value and argument not specified then callback not called', () => {
const mockCoercion = jest.fn();
const program = new commander.Command();
program
.argument('[n]', 'number', parseFloat, 1)
.action(() => {});
program.parse([], { from: 'user' });
expect(mockCoercion).not.toHaveBeenCalled();
});
test('when custom with starting value and argument not specified with action handler then action argument is starting value', () => {
const startingValue = 1;
let actionValue;
const program = new commander.Command();
program
.argument('[n]', 'number', parseFloat, startingValue)
.action((arg) => {
actionValue = arg;
});
program.parse([], { from: 'user' });
expect(actionValue).toEqual(startingValue);
expect(program.processedArgs).toEqual([startingValue]);
});
test('when custom with starting value and argument not specified without action handler then .processedArgs has starting value', () => {
const startingValue = 1;
const program = new commander.Command();
program
.argument('[n]', 'number', parseFloat, startingValue);
program.parse([], { from: 'user' });
expect(program.processedArgs).toEqual([startingValue]);
});
test('when default value is defined (without custom processing) and argument not specified with action handler then action argument is default value', () => {
const defaultValue = 1;
let actionValue;
const program = new commander.Command();
program
.argument('[n]', 'number', defaultValue)
.action((arg) => {
actionValue = arg;
});
program.parse([], { from: 'user' });
expect(actionValue).toEqual(defaultValue);
expect(program.processedArgs).toEqual([defaultValue]);
});
test('when default value is defined (without custom processing) and argument not specified without action handler then .processedArgs is default value', () => {
const defaultValue = 1;
const program = new commander.Command();
program
.argument('[n]', 'number', defaultValue);
program.parse([], { from: 'user' });
expect(program.processedArgs).toEqual([defaultValue]);
});
test('when argument specified then callback called with value', () => {
const mockCoercion = jest.fn();
const value = '1';
const program = new commander.Command();
program
.argument('[n]', 'number', mockCoercion)
.action(() => {});
program.parse([value], { from: 'user' });
expect(mockCoercion).toHaveBeenCalledWith(value, undefined);
});
test('when argument specified with action handler then action value is as returned from callback', () => {
const callbackResult = 2;
let actionValue;
const program = new commander.Command();
program
.argument('[n]', 'number', () => {
return callbackResult;
})
.action((arg) => {
actionValue = arg;
});
program.parse(['node', 'test', 'alpha']);
expect(actionValue).toEqual(callbackResult);
expect(program.processedArgs).toEqual([callbackResult]);
});
test('when argument specified without action handler then .processedArgs is as returned from callback', () => {
const callbackResult = 2;
const program = new commander.Command();
program
.argument('[n]', 'number', () => {
return callbackResult;
});
program.parse(['node', 'test', 'alpha']);
expect(program.processedArgs).toEqual([callbackResult]);
});
test('when argument specified then program.args has original rather than custom', () => {
// This is as intended, so check behaviour.
const callbackResult = 2;
const program = new commander.Command();
program
.argument('[n]', 'number', () => {
return callbackResult;
})
.action(() => {});
program.parse(['node', 'test', 'alpha']);
expect(program.args).toEqual(['alpha']);
});
test('when custom with starting value and argument specified then callback called with value and starting value', () => {
const mockCoercion = jest.fn();
const startingValue = 1;
const value = '2';
const program = new commander.Command()
.argument('[n]', 'number', mockCoercion, startingValue)
.action(() => {});
program.parse(['node', 'test', value]);
expect(mockCoercion).toHaveBeenCalledWith(value, startingValue);
});
test('when variadic argument specified multiple times then callback called with value and previousValue', () => {
const mockCoercion = jest.fn().mockImplementation(() => {
return 'callback';
});
const program = new commander.Command();
program
.argument('<n...>', 'number', mockCoercion)
.action(() => {});
program.parse(['1', '2'], { from: 'user' });
expect(mockCoercion).toHaveBeenCalledTimes(2);
expect(mockCoercion).toHaveBeenNthCalledWith(1, '1', undefined);
expect(mockCoercion).toHaveBeenNthCalledWith(2, '2', 'callback');
});
test('when variadic argument without action handler then .processedArg has array', () => {
const program = new commander.Command();
program
.argument('<n...>', 'number');
program.parse(['1', '2'], { from: 'user' });
expect(program.processedArgs).toEqual([['1', '2']]);
});
test('when parseFloat "1e2" then action argument is 100', () => {
let actionValue;
const program = new commander.Command();
program
.argument('<number>', 'float argument', parseFloat)
.action((arg) => {
actionValue = arg;
});
program.parse(['1e2'], { from: 'user' });
expect(actionValue).toEqual(100);
expect(program.processedArgs).toEqual([actionValue]);
});
test('when defined default value for required argument then throw', () => {
const program = new commander.Command();
expect(() => {
program.argument('<number>', 'float argument', 4);
}).toThrow();
});
test('when custom processing for argument throws plain error then not CommanderError caught', () => {
function justSayNo(value) {
throw new Error('no no no');
}
const program = new commander.Command();
program
.exitOverride()
.argument('[n]', 'number', justSayNo)
.action(() => {});
let caughtErr;
try {
program.parse(['green'], { from: 'user' });
} catch (err) {
caughtErr = err;
}
expect(caughtErr).toBeInstanceOf(Error);
expect(caughtErr).not.toBeInstanceOf(commander.CommanderError);
});