cli-kiss 0.2.4 → 0.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,197 @@
1
+ import { it } from "@jest/globals";
2
+ import {
3
+ command,
4
+ operation,
5
+ optionRepeatable,
6
+ positionalVariadics,
7
+ runAndExit,
8
+ type,
9
+ TypoSupport,
10
+ usageToStyledLines,
11
+ } from "../src";
12
+
13
+ const cliName = "my-cli";
14
+
15
+ it("run", async function () {
16
+ const usage = {
17
+ segments: [{ positional: "[string]..." }],
18
+ information: { description: "Description" },
19
+ subcommands: [],
20
+ options: [{ long: "option", label: "<string>", annotation: " [*]" }],
21
+ positionals: [{ label: "[string]...", description: "Variadics" }],
22
+ };
23
+ const usageNone = usageToStyledLines({
24
+ cliName,
25
+ usage,
26
+ typoSupport: TypoSupport.none(),
27
+ }).join("\n");
28
+ const usageMock = usageToStyledLines({
29
+ cliName,
30
+ usage,
31
+ typoSupport: TypoSupport.mock(),
32
+ }).join("\n");
33
+ const usageTty = usageToStyledLines({
34
+ cliName,
35
+ usage,
36
+ typoSupport: TypoSupport.tty(),
37
+ }).join("\n");
38
+
39
+ await testCase("flag", ["--color=auto", "--help"], [usageTty], [], 0);
40
+ await testCase("flag", ["--color=always", "--help"], [usageTty], [], 0);
41
+ await testCase("flag", ["--color=never", "--help"], [usageNone], [], 0);
42
+ await testCase("flag", ["--color=mock", "--help"], [usageMock], [], 0);
43
+ await testCase("flag", ["--help"], [usageTty], [], 0);
44
+ await testCase("env", ["--help"], [usageTty], [], 0);
45
+ await testCase("always", ["--help"], [usageTty], [], 0);
46
+ await testCase("never", ["--help"], [usageNone], [], 0);
47
+ await testCase("mock", ["--help"], [usageMock], [], 0);
48
+
49
+ process.env["NO_COLOR"] = "";
50
+ await testCase("flag", ["--color=auto", "--help"], [usageNone], [], 0);
51
+ await testCase("flag", ["--color=always", "--help"], [usageTty], [], 0);
52
+ await testCase("flag", ["--color=never", "--help"], [usageNone], [], 0);
53
+ await testCase("flag", ["--color=mock", "--help"], [usageMock], [], 0);
54
+ await testCase("flag", ["--help"], [usageNone], [], 0);
55
+ await testCase("env", ["--help"], [usageNone], [], 0);
56
+ await testCase("always", ["--help"], [usageTty], [], 0);
57
+ await testCase("never", ["--help"], [usageNone], [], 0);
58
+ await testCase("mock", ["--help"], [usageMock], [], 0);
59
+ delete process.env["NO_COLOR"];
60
+
61
+ process.env["FORCE_COLOR"] = "";
62
+ await testCase("flag", ["--color=auto", "--help"], [usageTty], [], 0);
63
+ await testCase("flag", ["--color=always", "--help"], [usageTty], [], 0);
64
+ await testCase("flag", ["--color=never", "--help"], [usageNone], [], 0);
65
+ await testCase("flag", ["--color=mock", "--help"], [usageMock], [], 0);
66
+ await testCase("flag", ["--help"], [usageTty], [], 0);
67
+ await testCase("env", ["--help"], [usageTty], [], 0);
68
+ await testCase("always", ["--help"], [usageTty], [], 0);
69
+ await testCase("never", ["--help"], [usageNone], [], 0);
70
+ await testCase("mock", ["--help"], [usageMock], [], 0);
71
+ delete process.env["FORCE_COLOR"];
72
+
73
+ process.env["FORCE_COLOR"] = "0";
74
+ await testCase("flag", ["--color=auto", "--help"], [usageNone], [], 0);
75
+ await testCase("flag", ["--color=always", "--help"], [usageTty], [], 0);
76
+ await testCase("flag", ["--color=never", "--help"], [usageNone], [], 0);
77
+ await testCase("flag", ["--color=mock", "--help"], [usageMock], [], 0);
78
+ await testCase("flag", ["--help"], [usageNone], [], 0);
79
+ await testCase("env", ["--help"], [usageNone], [], 0);
80
+ await testCase("always", ["--help"], [usageTty], [], 0);
81
+ await testCase("never", ["--help"], [usageNone], [], 0);
82
+ await testCase("mock", ["--help"], [usageMock], [], 0);
83
+ delete process.env["FORCE_COLOR"];
84
+
85
+ process.env["MOCK_COLOR"] = "";
86
+ await testCase("flag", ["--color=auto", "--help"], [usageMock], [], 0);
87
+ await testCase("flag", ["--color=always", "--help"], [usageTty], [], 0);
88
+ await testCase("flag", ["--color=never", "--help"], [usageNone], [], 0);
89
+ await testCase("flag", ["--color=mock", "--help"], [usageMock], [], 0);
90
+ await testCase("flag", ["--help"], [usageMock], [], 0);
91
+ await testCase("env", ["--help"], [usageMock], [], 0);
92
+ await testCase("always", ["--help"], [usageTty], [], 0);
93
+ await testCase("never", ["--help"], [usageNone], [], 0);
94
+ await testCase("mock", ["--help"], [usageMock], [], 0);
95
+ delete process.env["MOCK_COLOR"];
96
+
97
+ process.env["MOCK_COLOR"] = "";
98
+ await testCase(
99
+ "flag",
100
+ ["--color=42"],
101
+ [],
102
+ [
103
+ usageMock,
104
+ '{{Error:}@darkRed}+ {{--color}@darkCyan}+: {{<color-mode>}@darkBlue}+: Invalid value: {{"42"}@darkYellow}+ (expected one of: {{"auto"}@darkYellow}+ | {{"always"}@darkYellow}+ | {{"never"}@darkYellow}+...)',
105
+ ],
106
+ 1,
107
+ );
108
+ delete process.env["MOCK_COLOR"];
109
+
110
+ const unexpected1 = "Error: Unexpected unknown option: --color";
111
+ await testCase("never", ["--color=auto"], [], [usageNone, unexpected1], 1);
112
+ await testCase("never", ["--color=always"], [], [usageNone, unexpected1], 1);
113
+ await testCase("never", ["--color=never"], [], [usageNone, unexpected1], 1);
114
+ await testCase("never", ["--color=mock"], [], [usageNone, unexpected1], 1);
115
+ process.env["FORCE_COLOR"] = "0";
116
+ await testCase("env", ["--color=auto"], [], [usageNone, unexpected1], 1);
117
+ await testCase("env", ["--color=always"], [], [usageNone, unexpected1], 1);
118
+ await testCase("env", ["--color=never"], [], [usageNone, unexpected1], 1);
119
+ await testCase("env", ["--color=mock"], [], [usageNone, unexpected1], 1);
120
+ delete process.env["FORCE_COLOR"];
121
+
122
+ const unexpected2 =
123
+ "{{Error:}@darkRed}+ Unexpected unknown option: {{--color}@darkYellow}+";
124
+ await testCase("mock", ["--color=auto"], [], [usageMock, unexpected2], 1);
125
+ await testCase("mock", ["--color=always"], [], [usageMock, unexpected2], 1);
126
+ await testCase("mock", ["--color=never"], [], [usageMock, unexpected2], 1);
127
+ await testCase("mock", ["--color=mock"], [], [usageMock, unexpected2], 1);
128
+ });
129
+
130
+ async function testCase(
131
+ colorSetup: "flag" | "env" | "always" | "never" | "mock",
132
+ cliArgs: Array<string>,
133
+ expectStdOut: Array<string>,
134
+ expectStdErr: Array<string>,
135
+ expectExit: number,
136
+ ) {
137
+ const onLogStdOut = makeMocked<string, void>([
138
+ null as unknown as void,
139
+ null as unknown as void,
140
+ ]);
141
+ const onLogStdErr = makeMocked<string, void>([
142
+ null as unknown as void,
143
+ null as unknown as void,
144
+ ]);
145
+ const onExit = makeMocked<number, never>([null as never]);
146
+ const cmd = command<null, void>(
147
+ { description: "Description" },
148
+ operation(
149
+ {
150
+ options: {
151
+ value: optionRepeatable({ long: "option", type: type() }),
152
+ },
153
+ positionals: [
154
+ positionalVariadics({ type: type(), description: "Variadics" }),
155
+ ],
156
+ },
157
+ async function (_, { options: { value }, positionals: [rest] }) {
158
+ console.log(
159
+ `Has executed: ${JSON.stringify(value)}, ${JSON.stringify(rest)}`,
160
+ );
161
+ },
162
+ ),
163
+ );
164
+ console.log = onLogStdOut.call;
165
+ console.error = onLogStdErr.call;
166
+ await runAndExit(cliName, cliArgs, null, cmd, {
167
+ buildVersion: "1.0.0",
168
+ onExit: onExit.call,
169
+ colorSetup,
170
+ });
171
+ expect({
172
+ stdOut: onLogStdOut.history,
173
+ stdErr: onLogStdErr.history,
174
+ }).toEqual({
175
+ stdOut: expectStdOut,
176
+ stdErr: expectStdErr,
177
+ });
178
+ expect(onExit.history).toEqual([expectExit]);
179
+ }
180
+
181
+ function makeMocked<P, R>(returns: Array<R>) {
182
+ const history = new Array<P>();
183
+ return {
184
+ history,
185
+ call(p: P) {
186
+ history.push(p);
187
+ if (history.length > returns.length) {
188
+ throw new Error(
189
+ `Mocked function called more times than expected. History: ${JSON.stringify(
190
+ history,
191
+ )}, returns: ${JSON.stringify(returns)}`,
192
+ );
193
+ }
194
+ return returns[history.length - 1]!;
195
+ },
196
+ };
197
+ }
@@ -10,46 +10,46 @@ import {
10
10
  positionalRequired,
11
11
  positionalVariadics,
12
12
  runAndExit,
13
- typeMapped,
14
- typeOneOf,
15
- typeString,
13
+ type,
14
+ typeChoice,
15
+ typeConverted,
16
16
  typeUrl,
17
17
  } from "../src";
18
18
 
19
19
  it("run", async function () {
20
20
  const rootUsage = [
21
- "Usage: my-cli <REQUIRED1> <SUBCOMMAND>",
21
+ "Usage: my-cli <required1> <subcommand>",
22
22
  "",
23
23
  "Root Description",
24
24
  "",
25
25
  "Positionals:",
26
- " <REQUIRED1> Required1 positional description",
26
+ " <required1> Required1 positional description",
27
27
  "",
28
28
  "Subcommands:",
29
29
  " subcommand Subcommand Description",
30
30
  "",
31
31
  "Options:",
32
- " --flag[=no] Option flag description",
33
- " --repeatable <STRING> [*] Option repeatable description",
34
- " --single-value <NUMBER-ENUM> Option single value description",
32
+ " --flag[=no] Option flag description",
33
+ " --repeatable <string> [*] Option repeatable description",
34
+ " --single-value <enum(number)> Option single value description",
35
35
  "",
36
36
  ].join("\n");
37
37
  const subcommandUsage = [
38
- "Usage: my-cli <REQUIRED1> subcommand <REQUIRED2> [OPTIONAL] [VARIADICS]...",
38
+ "Usage: my-cli <required1> subcommand <required2> [optional] [variadic]...",
39
39
  "",
40
40
  "Subcommand Description",
41
41
  "",
42
42
  "Positionals:",
43
- " <REQUIRED1> Required1 positional description",
44
- " <REQUIRED2> Required2 positional description",
45
- " [OPTIONAL] Optional positional description",
46
- " [VARIADICS]... Variadics positional description",
43
+ " <required1> Required1 positional description",
44
+ " <required2> Required2 positional description",
45
+ " [optional] Optional positional description",
46
+ " [variadic]... Variadics positional description",
47
47
  "",
48
48
  "Options:",
49
- " --flag[=no] Option flag description",
50
- " --repeatable <STRING> [*] Option repeatable description",
51
- " --single-value <NUMBER-ENUM> Option single value description",
52
- " --url <URL> [*] Option url description",
49
+ " --flag[=no] Option flag description",
50
+ " --repeatable <string> [*] Option repeatable description",
51
+ " --single-value <enum(number)> Option single value description",
52
+ " --url <url> [*] Option url description",
53
53
  "",
54
54
  ].join("\n");
55
55
 
@@ -97,6 +97,20 @@ it("run", async function () {
97
97
  await testCase(["--version", "--help"], [rootUsage], [], 0);
98
98
  await testCase(["--help", "--version"], [rootUsage], [], 0);
99
99
 
100
+ // Weird help/version values inputs
101
+ await testCase(
102
+ ["--help=invalid"],
103
+ [],
104
+ [rootUsage, `Error: --help: value: Not a boolean: "invalid"`],
105
+ 1,
106
+ );
107
+ await testCase(
108
+ ["--version=invalid"],
109
+ [],
110
+ [rootUsage, `Error: --version: value: Not a boolean: "invalid"`],
111
+ 1,
112
+ );
113
+
100
114
  // Test multiple errors at once (first one should show only)
101
115
  await testCase(
102
116
  ["--invalid1", "--invalid2", "required1", "--invalid3"],
@@ -107,7 +121,7 @@ it("run", async function () {
107
121
  await testCase(
108
122
  ["required1", "unknown", "-wut", "--flag", "--single-value"],
109
123
  [],
110
- [rootUsage, 'Error: <SUBCOMMAND>: Invalid value: "unknown"'],
124
+ [rootUsage, 'Error: <subcommand>: Invalid value: "unknown"'],
111
125
  1,
112
126
  );
113
127
 
@@ -115,19 +129,19 @@ it("run", async function () {
115
129
  await testCase(
116
130
  [],
117
131
  [],
118
- [rootUsage, "Error: <REQUIRED1>: Is required, but was not provided"],
132
+ [rootUsage, "Error: <required1>: Is required, but was not provided"],
119
133
  1,
120
134
  );
121
135
  await testCase(
122
136
  ["required1"],
123
137
  [],
124
- [rootUsage, "Error: <SUBCOMMAND>: Is required, but was not provided"],
138
+ [rootUsage, "Error: <subcommand>: Is required, but was not provided"],
125
139
  1,
126
140
  );
127
141
  await testCase(
128
142
  ["required1", "subcommand"],
129
143
  [],
130
- [subcommandUsage, "Error: <REQUIRED2>: Is required, but was not provided"],
144
+ [subcommandUsage, "Error: <required2>: Is required, but was not provided"],
131
145
  1,
132
146
  );
133
147
 
@@ -147,7 +161,7 @@ it("run", async function () {
147
161
  await testCase(
148
162
  ["required1", "subcommand", "--url", "https://example.com"],
149
163
  [],
150
- [subcommandUsage, "Error: <REQUIRED2>: Is required, but was not provided"],
164
+ [subcommandUsage, "Error: <required2>: Is required, but was not provided"],
151
165
  1,
152
166
  );
153
167
  await testCase(
@@ -167,7 +181,7 @@ it("run", async function () {
167
181
  await testCase(
168
182
  ["--flag=42", "required1", "subcommand", "required2"],
169
183
  [],
170
- [subcommandUsage, 'Error: --flag: <BOOLEAN>: Boolean: Invalid value: "42"'],
184
+ [subcommandUsage, 'Error: --flag: value: Not a boolean: "42"'],
171
185
  1,
172
186
  );
173
187
  await testCase(
@@ -182,6 +196,12 @@ it("run", async function () {
182
196
  [],
183
197
  0,
184
198
  );
199
+ await testCase(
200
+ ["--flag", "required1", "subcommand", "required2"],
201
+ ["Has executed root command", "Has executed subcommand"],
202
+ [],
203
+ 0,
204
+ );
185
205
 
186
206
  // Test option parsing errors
187
207
  await testCase(
@@ -219,7 +239,7 @@ it("run", async function () {
219
239
  await testCase(
220
240
  ["invalid"],
221
241
  [],
222
- [rootUsage, "Error: <SUBCOMMAND>: Is required, but was not provided"],
242
+ [rootUsage, "Error: <subcommand>: Is required, but was not provided"],
223
243
  1,
224
244
  );
225
245
  await testCase(
@@ -227,7 +247,7 @@ it("run", async function () {
227
247
  [],
228
248
  [
229
249
  subcommandUsage,
230
- 'Error: <REQUIRED1>: STRING-ENUM: Invalid value: "invalid" (expected one of: "required1" | "required1-bis")',
250
+ 'Error: <required1>: Invalid value: "invalid" (expected one of: "required1" | "required1-bis")',
231
251
  ],
232
252
  1,
233
253
  );
@@ -236,7 +256,7 @@ it("run", async function () {
236
256
  [],
237
257
  [
238
258
  subcommandUsage,
239
- 'Error: <REQUIRED1>: STRING-ENUM: Invalid value: "invalid" (expected one of: "required1" | "required1-bis")',
259
+ 'Error: <required1>: Invalid value: "invalid" (expected one of: "required1" | "required1-bis")',
240
260
  ],
241
261
  1,
242
262
  );
@@ -245,7 +265,7 @@ it("run", async function () {
245
265
  [],
246
266
  [
247
267
  subcommandUsage,
248
- 'Error: <REQUIRED2>: STRING-ENUM: Invalid value: "invalid" (expected one of: "required2" | "required2-bis")',
268
+ 'Error: <required2>: Invalid value: "invalid" (expected one of: "required2" | "required2-bis")',
249
269
  ],
250
270
  1,
251
271
  );
@@ -254,7 +274,7 @@ it("run", async function () {
254
274
  [],
255
275
  [
256
276
  subcommandUsage,
257
- 'Error: <REQUIRED1>: STRING-ENUM: Invalid value: "invalid" (expected one of: "required1" | "required1-bis")',
277
+ 'Error: <required1>: Invalid value: "invalid" (expected one of: "required1" | "required1-bis")',
258
278
  ],
259
279
  1,
260
280
  );
@@ -265,7 +285,7 @@ it("run", async function () {
265
285
  [],
266
286
  [
267
287
  subcommandUsage,
268
- 'Error: --single-value: <NUMBER-ENUM>: NUMBER-ENUM: from: STRING-ENUM: Invalid value: "dodo" (expected one of: "42" | "43")',
288
+ 'Error: --single-value: <enum(number)>: from: enum(string): Invalid value: "dodo" (expected one of: "42" | "43")',
269
289
  ],
270
290
  1,
271
291
  );
@@ -274,7 +294,7 @@ it("run", async function () {
274
294
  [],
275
295
  [
276
296
  subcommandUsage,
277
- 'Error: --single-value: <NUMBER-ENUM>: NUMBER-ENUM: from: STRING-ENUM: Invalid value: "44" (expected one of: "42" | "43")',
297
+ 'Error: --single-value: <enum(number)>: from: enum(string): Invalid value: "44" (expected one of: "42" | "43")',
278
298
  ],
279
299
  1,
280
300
  );
@@ -289,7 +309,7 @@ it("run", async function () {
289
309
  await testCase(
290
310
  ["required1", "subcommand", "required2", "--url", "not-a-url"],
291
311
  [],
292
- [subcommandUsage, 'Error: --url: <URL>: Url: Unable to parse: "not-a-url"'],
312
+ [subcommandUsage, 'Error: --url: <url>: Not an URL: "not-a-url"'],
293
313
  1,
294
314
  );
295
315
 
@@ -317,10 +337,7 @@ it("run", async function () {
317
337
  "43",
318
338
  ],
319
339
  [],
320
- [
321
- subcommandUsage,
322
- "Error: --single-value: Requires a single value, but got multiple",
323
- ],
340
+ [subcommandUsage, "Error: --single-value: Must not be set multiple times"],
324
341
  1,
325
342
  );
326
343
  });
@@ -351,29 +368,29 @@ async function testCase(
351
368
  }),
352
369
  optionRepeatable: optionRepeatable({
353
370
  long: "repeatable",
354
- type: typeString,
371
+ type: type(),
355
372
  description: "Option repeatable description",
356
373
  }),
357
374
  optionSingleValue: optionSingleValue({
358
375
  long: "single-value",
359
- type: typeMapped(typeOneOf("STRING-ENUM", ["42", "43"]), {
360
- content: "NUMBER-ENUM",
361
- decoder: (value) => Number(value),
362
- }),
376
+ type: typeConverted(
377
+ "enum(number)",
378
+ typeChoice("enum(string)", ["42", "43"]),
379
+ (value) => Number(value),
380
+ ),
363
381
  description: "Option single value description",
364
- default: () => 42,
382
+ defaultWhenNotDefined: () => 42,
365
383
  }),
366
384
  },
367
385
  positionals: [
368
386
  positionalRequired({
369
- type: typeOneOf("STRING-ENUM", ["required1", "required1-bis"]),
370
- label: "REQUIRED1",
387
+ type: typeChoice("required1", ["required1", "required1-bis"]),
371
388
  description: "Required1 positional description",
372
389
  }),
373
390
  ],
374
391
  },
375
- async function () {
376
- console.log("Has executed root command");
392
+ async function (_, _inputs) {
393
+ console.log(`Has executed root command`);
377
394
  },
378
395
  ),
379
396
  {
@@ -385,30 +402,27 @@ async function testCase(
385
402
  optionExtra: optionRepeatable({
386
403
  long: "url",
387
404
  description: "Option url description",
388
- type: typeUrl,
405
+ type: typeUrl("url"),
389
406
  }),
390
407
  },
391
408
  positionals: [
392
409
  positionalRequired({
393
- type: typeOneOf("STRING-ENUM", ["required2", "required2-bis"]),
394
- label: "REQUIRED2",
410
+ type: typeChoice("required2", ["required2", "required2-bis"]),
395
411
  description: "Required2 positional description",
396
412
  }),
397
413
  positionalOptional({
398
- label: "OPTIONAL",
399
- type: typeString,
414
+ type: type("optional"),
400
415
  description: "Optional positional description",
401
416
  default: () => "world !",
402
417
  }),
403
418
  positionalVariadics({
404
- label: "VARIADICS",
405
- type: typeString,
419
+ type: type("variadic"),
406
420
  description: "Variadics positional description",
407
421
  }),
408
422
  ],
409
423
  },
410
- async function () {
411
- console.log("Has executed subcommand");
424
+ async function (_, _inputs) {
425
+ console.log(`Has executed subcommand`);
412
426
  },
413
427
  ),
414
428
  ),
@@ -418,8 +432,8 @@ async function testCase(
418
432
  console.error = onLogStdErr.call;
419
433
  await runAndExit("my-cli", args, null, cmd, {
420
434
  buildVersion: "1.0.0",
421
- useTtyColors: false,
422
435
  onExit: onExit.call,
436
+ colorSetup: "never",
423
437
  });
424
438
  expect({
425
439
  stdOut: onLogStdOut.history,
@@ -24,28 +24,24 @@ it("run", async function () {
24
24
  "{{Error:}@darkRed}+ {{--flag}@darkCyan}+: Must not be set multiple times",
25
25
  );
26
26
  await testCase(
27
- ["--flag", "--no-flag"],
28
- "{{Error:}@darkRed}+ {{--flag}@darkCyan}+: Must not be set in combination with: {{--no-flag}@darkCyan}+",
29
- );
30
- await testCase(
31
- ["--no-flag", "--no-flag"],
32
- "{{Error:}@darkRed}+ {{--no-flag}@darkCyan}+: Must not be set multiple times",
27
+ ["--flag=invalid"],
28
+ '{{Error:}@darkRed}+ {{--flag}@darkCyan}+: {{value}@darkMagenta}+: Not a boolean: {{"invalid"}@darkYellow}+',
33
29
  );
34
30
  await testCase(
35
31
  ["--single-value=a", "--single-value=b"],
36
- "{{Error:}@darkRed}+ {{--single-value}@darkCyan}+: Requires a single value, but got multiple",
32
+ "{{Error:}@darkRed}+ {{--single-value}@darkCyan}+: Must not be set multiple times",
37
33
  );
38
34
  await testCase(
39
- ["--flag=invalid"],
40
- '{{Error:}@darkRed}+ {{--flag}@darkCyan}+: {{<BOOLEAN>}@darkBlue}+: {{Boolean}@darkMagenta}+: Invalid value: {{"invalid"}@darkYellow}+',
35
+ ["--single-value"],
36
+ "{{Error:}@darkRed}+ {{--single-value}@darkCyan}+: Requires a value, but got end of input",
41
37
  );
42
38
  await testCase(
43
39
  ["--single-value=invalid"],
44
- '{{Error:}@darkRed}+ {{--single-value}@darkCyan}+: {{<LOCATION>}@darkBlue}+: {{Url}@darkMagenta}+: Unable to parse: {{"invalid"}@darkYellow}+',
40
+ '{{Error:}@darkRed}+ {{--single-value}@darkCyan}+: {{<location>}@darkBlue}+: Not an URL: {{"invalid"}@darkYellow}+',
45
41
  );
46
42
  await testCase(
47
43
  ["--repeatable=invalid"],
48
- '{{Error:}@darkRed}+ {{--repeatable}@darkCyan}+: {{<INDEX>}@darkBlue}+: {{Number}@darkMagenta}+: Unable to parse: {{"invalid"}@darkYellow}+',
44
+ '{{Error:}@darkRed}+ {{--repeatable}@darkCyan}+: {{<index>}@darkBlue}+: Not a number: {{"invalid"}@darkYellow}+',
49
45
  );
50
46
  });
51
47
 
@@ -58,19 +54,15 @@ async function testCase(args: Array<string>, error: string) {
58
54
  operation(
59
55
  {
60
56
  options: {
61
- optionFlag: optionFlag({
62
- long: "flag",
63
- }),
57
+ optionFlag: optionFlag({ long: "flag" }),
64
58
  optionSingleValue: optionSingleValue({
65
- label: "LOCATION",
66
59
  long: "single-value",
67
- type: typeUrl,
68
- default: () => undefined,
60
+ type: typeUrl("location"),
61
+ defaultWhenNotDefined: () => undefined,
69
62
  }),
70
63
  optionRepeatable: optionRepeatable({
71
- label: "INDEX",
72
64
  long: "repeatable",
73
- type: typeNumber,
65
+ type: typeNumber("index"),
74
66
  }),
75
67
  },
76
68
  positionals: [],
@@ -83,7 +75,7 @@ async function testCase(args: Array<string>, error: string) {
83
75
  await runAndExit("my-cli", args, null, rootCommand, {
84
76
  buildVersion: "1.0.0",
85
77
  usageOnError: false,
86
- useTtyColors: "mock",
78
+ colorSetup: "mock",
87
79
  onExit: onExit.call,
88
80
  });
89
81
  expect(onLogStdOut.history).toEqual([]);