@flowscripter/dynamic-cli-framework 1.0.0

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.
Files changed (133) hide show
  1. package/.github/workflows/check-bun-dependencies.yml +9 -0
  2. package/.github/workflows/lint-pr-message.yml +11 -0
  3. package/.github/workflows/release-bun-library.yml +8 -0
  4. package/.github/workflows/validate-bun-library-pr.yml +8 -0
  5. package/LICENSE +21 -0
  6. package/README.md +1475 -0
  7. package/bun.lock +63 -0
  8. package/index.ts +89 -0
  9. package/package.json +23 -0
  10. package/src/api/CLI.ts +17 -0
  11. package/src/api/CLIConfig.ts +19 -0
  12. package/src/api/Context.ts +25 -0
  13. package/src/api/RunResult.ts +142 -0
  14. package/src/api/argument/Argument.ts +36 -0
  15. package/src/api/argument/ArgumentValueTypes.ts +87 -0
  16. package/src/api/argument/ComplexOption.ts +31 -0
  17. package/src/api/argument/GlobalCommandArgument.ts +17 -0
  18. package/src/api/argument/Option.ts +32 -0
  19. package/src/api/argument/Positional.ts +27 -0
  20. package/src/api/argument/SubCommandArgument.ts +20 -0
  21. package/src/api/command/Command.ts +22 -0
  22. package/src/api/command/GlobalCommand.ts +33 -0
  23. package/src/api/command/GlobalModifierCommand.ts +12 -0
  24. package/src/api/command/GroupCommand.ts +20 -0
  25. package/src/api/command/SubCommand.ts +41 -0
  26. package/src/api/command/UsageExample.ts +21 -0
  27. package/src/api/service/ServiceProvider.ts +52 -0
  28. package/src/api/service/core/AsciiBannerGeneratorService.ts +35 -0
  29. package/src/api/service/core/KeyValueService.ts +28 -0
  30. package/src/api/service/core/PrinterService.ts +266 -0
  31. package/src/api/service/core/ShutdownService.ts +12 -0
  32. package/src/api/service/core/SyntaxHighlighterService.ts +42 -0
  33. package/src/cli/BaseCLI.ts +312 -0
  34. package/src/cli/DefaultRuntimeCLI.ts +54 -0
  35. package/src/command/MultiCommandCliHelpCommand.ts +394 -0
  36. package/src/command/SingleCommandCliHelpCommand.ts +183 -0
  37. package/src/command/UsageCommand.ts +35 -0
  38. package/src/command/VersionCommand.ts +22 -0
  39. package/src/launcher.ts +127 -0
  40. package/src/runtime/DefaultContext.ts +32 -0
  41. package/src/runtime/argument/ArgumentTypeGuards.ts +8 -0
  42. package/src/runtime/command/CommandTypeGuards.ts +30 -0
  43. package/src/runtime/command/CommandValidator.ts +549 -0
  44. package/src/runtime/parser.ts +219 -0
  45. package/src/runtime/registry/CommandRegistry.ts +121 -0
  46. package/src/runtime/registry/DefaultCommandRegistry.ts +318 -0
  47. package/src/runtime/registry/DefaultServiceProviderRegistry.ts +26 -0
  48. package/src/runtime/registry/ServiceProviderRegistry.ts +11 -0
  49. package/src/runtime/runner.ts +697 -0
  50. package/src/runtime/scanner.ts +417 -0
  51. package/src/runtime/values/ValuePopulationResult.ts +41 -0
  52. package/src/runtime/values/argumentValueMerge.ts +201 -0
  53. package/src/runtime/values/argumentValueValidation.ts +610 -0
  54. package/src/runtime/values/globalCommandValuePopulation.ts +96 -0
  55. package/src/runtime/values/subCommandValuePopulation.ts +680 -0
  56. package/src/service/asciiBannerGenerator/AsciiBannerGeneratorServiceProvider.ts +45 -0
  57. package/src/service/asciiBannerGenerator/DefaultAsciiBannerGeneratorService.ts +38 -0
  58. package/src/service/asciiBannerGenerator/standard.flf.json +3 -0
  59. package/src/service/banner/BannerServiceProvider.ts +99 -0
  60. package/src/service/banner/command/NoBannerCommand.ts +42 -0
  61. package/src/service/configuration/ConfigurationServiceProvider.ts +571 -0
  62. package/src/service/configuration/DefaultKeyValueService.ts +60 -0
  63. package/src/service/configuration/command/ConfigCommand.ts +43 -0
  64. package/src/service/configuration/command/DumpConfigCommand.ts +47 -0
  65. package/src/service/printer/DefaultPrinterService.ts +256 -0
  66. package/src/service/printer/PrinterServiceProvider.ts +61 -0
  67. package/src/service/printer/command/DarkModeCommand.ts +43 -0
  68. package/src/service/printer/command/LogLevelCommand.ts +68 -0
  69. package/src/service/printer/command/NoColorCommand.ts +43 -0
  70. package/src/service/printer/terminal/Ansi.ts +10 -0
  71. package/src/service/printer/terminal/Color.ts +14 -0
  72. package/src/service/printer/terminal/Progress.ts +373 -0
  73. package/src/service/printer/terminal/Spinner.ts +100 -0
  74. package/src/service/printer/terminal/Styler.ts +5 -0
  75. package/src/service/printer/terminal/Terminal.ts +8 -0
  76. package/src/service/printer/terminal/Theme.ts +34 -0
  77. package/src/service/printer/terminal/TtyStyler.ts +39 -0
  78. package/src/service/printer/terminal/TtyTerminal.ts +65 -0
  79. package/src/service/shutdown/DefaultShutdownService.ts +9 -0
  80. package/src/service/shutdown/ShutdownServiceProvider.ts +55 -0
  81. package/src/service/syntaxHighlighter/DefaultSyntaxHighlighterService.ts +52 -0
  82. package/src/service/syntaxHighlighter/SyntaxHighlighterServiceProvider.ts +51 -0
  83. package/src/util/configHelper.ts +95 -0
  84. package/src/util/envVarHelper.ts +338 -0
  85. package/src/util/helpHelper.ts +751 -0
  86. package/src/util/logger.ts +84 -0
  87. package/src/util/runnerHelper.ts +112 -0
  88. package/tests/cli/BaseCLI.test.ts +344 -0
  89. package/tests/command/MultiCommandCliHelpCommand.test.ts +650 -0
  90. package/tests/command/SingleCommandCliHelpCommand.test.ts +384 -0
  91. package/tests/command/UsageCommand.test.ts +53 -0
  92. package/tests/command/VersionCommand.test.ts +36 -0
  93. package/tests/fixtures/CLIConfig.ts +9 -0
  94. package/tests/fixtures/Command.ts +229 -0
  95. package/tests/fixtures/CommandRegistry.ts +8 -0
  96. package/tests/fixtures/ConfigurationServiceProvider.ts +28 -0
  97. package/tests/fixtures/Context.ts +33 -0
  98. package/tests/fixtures/ServiceProviderRegistry.ts +16 -0
  99. package/tests/fixtures/StreamString.ts +37 -0
  100. package/tests/fixtures/util.ts +41 -0
  101. package/tests/runtime/DefaultContext.test.ts +20 -0
  102. package/tests/runtime/argument/ArgumentTypeGuards.test.ts +49 -0
  103. package/tests/runtime/command/CommandTypeGuards.test.ts +43 -0
  104. package/tests/runtime/command/CommandValidator.test.ts +816 -0
  105. package/tests/runtime/parser.test.ts +766 -0
  106. package/tests/runtime/registry/DefaultCommandRegistry.test.ts +166 -0
  107. package/tests/runtime/registry/DefaultServiceProviderRegistry.test.ts +42 -0
  108. package/tests/runtime/runner.test.ts +1298 -0
  109. package/tests/runtime/scanner.test.ts +1113 -0
  110. package/tests/runtime/values/argumentValueMerge.test.ts +314 -0
  111. package/tests/runtime/values/argumentValueValidation.test.ts +1020 -0
  112. package/tests/runtime/values/globalCommandValuePopulation.test.ts +662 -0
  113. package/tests/runtime/values/subCommandValuePopulation.test.ts +2658 -0
  114. package/tests/service/asciiBannerGenerator/AsciiBannerGeneratorServiceProvider.test.ts +22 -0
  115. package/tests/service/asciiBannerGenerator/DefaultAsciiBannerGeneratorService.test.ts +70 -0
  116. package/tests/service/asciiBannerGenerator/__snapshots__/DefaultAsciiBannerGeneratorService.test.ts.snap +22 -0
  117. package/tests/service/asciiBannerGenerator/small.flf.json +3 -0
  118. package/tests/service/configuration/ConfigurationServiceProvider.test.ts +249 -0
  119. package/tests/service/configuration/DefaultKeyValueService.test.ts +65 -0
  120. package/tests/service/launchBanner/BannerServiceProvider.test.ts +49 -0
  121. package/tests/service/launchBanner/__snapshots__/BannerServiceProvider.test.ts.snap +3 -0
  122. package/tests/service/launchBanner/command/NoBannerCommand.test.ts +21 -0
  123. package/tests/service/printer/DefaultPrinterService.test.ts +409 -0
  124. package/tests/service/printer/PrinterServiceProvider.test.ts +29 -0
  125. package/tests/service/printer/command/LogLevelCommand.test.ts +58 -0
  126. package/tests/service/printer/terminal/Progress.test.ts +40 -0
  127. package/tests/service/printer/terminal/Spinner.test.ts +57 -0
  128. package/tests/service/shutdown/ShutdownServiceProvider.test.ts +13 -0
  129. package/tests/service/syntaxHighlighter/DefaultSyntaxHighlighterService.test.ts +123 -0
  130. package/tests/service/syntaxHighlighter/SyntaxHighlighterServiceProvider.test.ts +41 -0
  131. package/tests/util/configHelper.test.ts +275 -0
  132. package/tests/util/envVarHelper.test.ts +318 -0
  133. package/tests/util/logger.test.ts +10 -0
@@ -0,0 +1,662 @@
1
+ import { describe, expect, test } from "bun:test";
2
+ import type { GlobalCommandValuePopulationResult } from "../../../src/runtime/values/ValuePopulationResult.ts";
3
+ import populateGlobalCommandValue from "../../../src/runtime/values/globalCommandValuePopulation.ts";
4
+ import { InvalidArgumentReason } from "../../../src/api/RunResult.ts";
5
+ import type GlobalCommand from "../../../src/api/command/GlobalCommand.ts";
6
+ import {
7
+ type ArgumentSingleValueType,
8
+ ArgumentValueTypeName,
9
+ } from "../../../src/api/argument/ArgumentValueTypes.ts";
10
+
11
+ function expectExtractResult(
12
+ result: GlobalCommandValuePopulationResult,
13
+ value: ArgumentSingleValueType | undefined,
14
+ unusedArgs: ReadonlyArray<string>,
15
+ ) {
16
+ expect(result.populatedArgumentValue).toEqual(value!);
17
+ expect(result.unusedArgs).toEqual(unusedArgs);
18
+ }
19
+
20
+ describe("globalCommandValuePopulation Tests", () => {
21
+ test("Global command argument", () => {
22
+ const command: GlobalCommand = {
23
+ name: "foo",
24
+ argument: {
25
+ type: ArgumentValueTypeName.STRING,
26
+ },
27
+ execute: async (): Promise<void> => {
28
+ },
29
+ };
30
+
31
+ const result = populateGlobalCommandValue(
32
+ command,
33
+ ["bar"],
34
+ undefined,
35
+ );
36
+ expectExtractResult(result, "bar", []);
37
+ expect(result.invalidArgument).toBeUndefined();
38
+ });
39
+
40
+ test("Global command argument types", () => {
41
+ let command: GlobalCommand = {
42
+ name: "foo",
43
+ argument: {
44
+ type: ArgumentValueTypeName.NUMBER,
45
+ },
46
+ execute: async (): Promise<void> => {
47
+ },
48
+ };
49
+
50
+ let result = populateGlobalCommandValue(
51
+ command,
52
+ ["1.1"],
53
+ undefined,
54
+ );
55
+ expectExtractResult(result, "1.1", []);
56
+ expect(result.invalidArgument).toBeUndefined();
57
+
58
+ command = {
59
+ name: "foo",
60
+ argument: {
61
+ type: ArgumentValueTypeName.INTEGER,
62
+ },
63
+ execute: async (): Promise<void> => {
64
+ },
65
+ };
66
+
67
+ result = populateGlobalCommandValue(
68
+ command,
69
+ ["1"],
70
+ undefined,
71
+ );
72
+ expectExtractResult(result, "1", []);
73
+ expect(result.invalidArgument).toBeUndefined();
74
+
75
+ command = {
76
+ name: "foo",
77
+ argument: {
78
+ type: ArgumentValueTypeName.SECRET,
79
+ },
80
+ execute: async (): Promise<void> => {
81
+ },
82
+ };
83
+
84
+ result = populateGlobalCommandValue(
85
+ command,
86
+ ["xxx"],
87
+ undefined,
88
+ );
89
+ expectExtractResult(result, "xxx", []);
90
+ expect(result.invalidArgument).toBeUndefined();
91
+
92
+ command = {
93
+ name: "foo",
94
+ argument: {
95
+ type: ArgumentValueTypeName.STRING,
96
+ },
97
+ execute: async (): Promise<void> => {
98
+ },
99
+ };
100
+
101
+ result = populateGlobalCommandValue(
102
+ command,
103
+ ["bar"],
104
+ undefined,
105
+ );
106
+ expectExtractResult(result, "bar", []);
107
+ expect(result.invalidArgument).toBeUndefined();
108
+
109
+ command = {
110
+ name: "foo",
111
+ argument: {
112
+ type: ArgumentValueTypeName.BOOLEAN,
113
+ },
114
+ execute: async (): Promise<void> => {
115
+ },
116
+ };
117
+
118
+ result = populateGlobalCommandValue(
119
+ command,
120
+ [],
121
+ undefined,
122
+ );
123
+ expectExtractResult(result, "true", []);
124
+ expect(result.invalidArgument).toBeUndefined();
125
+
126
+ result = populateGlobalCommandValue(
127
+ command,
128
+ ["false"],
129
+ undefined,
130
+ );
131
+ expectExtractResult(result, "false", []);
132
+ expect(result.invalidArgument).toBeUndefined();
133
+ });
134
+
135
+ test("Global command boolean argument with defaults", () => {
136
+ let command: GlobalCommand = {
137
+ name: "foo",
138
+ argument: {
139
+ type: ArgumentValueTypeName.BOOLEAN,
140
+ },
141
+ execute: async (): Promise<void> => {
142
+ },
143
+ };
144
+
145
+ let result = populateGlobalCommandValue(
146
+ command,
147
+ [],
148
+ undefined,
149
+ );
150
+ expectExtractResult(result, "true", []);
151
+ expect(result.invalidArgument).toBeUndefined();
152
+
153
+ command = {
154
+ name: "foo",
155
+ argument: {
156
+ type: ArgumentValueTypeName.BOOLEAN,
157
+ },
158
+ execute: async (): Promise<void> => {
159
+ },
160
+ };
161
+
162
+ result = populateGlobalCommandValue(
163
+ command,
164
+ ["true"],
165
+ undefined,
166
+ );
167
+ expectExtractResult(result, "true", []);
168
+ expect(result.invalidArgument).toBeUndefined();
169
+
170
+ command = {
171
+ name: "foo",
172
+ argument: {
173
+ type: ArgumentValueTypeName.BOOLEAN,
174
+ },
175
+ execute: async (): Promise<void> => {
176
+ },
177
+ };
178
+
179
+ result = populateGlobalCommandValue(
180
+ command,
181
+ ["false"],
182
+ undefined,
183
+ );
184
+ expectExtractResult(result, "false", []);
185
+ expect(result.invalidArgument).toBeUndefined();
186
+
187
+ command = {
188
+ name: "foo",
189
+ argument: {
190
+ type: ArgumentValueTypeName.BOOLEAN,
191
+ defaultValue: true,
192
+ },
193
+ execute: async (): Promise<void> => {
194
+ },
195
+ };
196
+
197
+ result = populateGlobalCommandValue(
198
+ command,
199
+ [],
200
+ undefined,
201
+ );
202
+ expectExtractResult(result, true, []);
203
+ expect(result.invalidArgument).toBeUndefined();
204
+
205
+ command = {
206
+ name: "foo",
207
+ argument: {
208
+ type: ArgumentValueTypeName.BOOLEAN,
209
+ defaultValue: true,
210
+ },
211
+ execute: async (): Promise<void> => {
212
+ },
213
+ };
214
+
215
+ result = populateGlobalCommandValue(
216
+ command,
217
+ ["false"],
218
+ undefined,
219
+ );
220
+ expectExtractResult(result, "false", []);
221
+ expect(result.invalidArgument).toBeUndefined();
222
+
223
+ command = {
224
+ name: "foo",
225
+ argument: {
226
+ type: ArgumentValueTypeName.BOOLEAN,
227
+ defaultValue: false,
228
+ },
229
+ execute: async (): Promise<void> => {
230
+ },
231
+ };
232
+
233
+ result = populateGlobalCommandValue(
234
+ command,
235
+ [],
236
+ undefined,
237
+ );
238
+ expectExtractResult(result, "true", []);
239
+ expect(result.invalidArgument).toBeUndefined();
240
+
241
+ command = {
242
+ name: "foo",
243
+ argument: {
244
+ type: ArgumentValueTypeName.BOOLEAN,
245
+ defaultValue: false,
246
+ },
247
+ execute: async (): Promise<void> => {
248
+ },
249
+ };
250
+
251
+ result = populateGlobalCommandValue(
252
+ command,
253
+ ["false"],
254
+ undefined,
255
+ );
256
+ expectExtractResult(result, "false", []);
257
+ expect(result.invalidArgument).toBeUndefined();
258
+
259
+ command = {
260
+ name: "foo",
261
+ argument: {
262
+ type: ArgumentValueTypeName.BOOLEAN,
263
+ defaultValue: false,
264
+ },
265
+ execute: async (): Promise<void> => {
266
+ },
267
+ };
268
+
269
+ result = populateGlobalCommandValue(
270
+ command,
271
+ ["true"],
272
+ undefined,
273
+ );
274
+ expectExtractResult(result, "true", []);
275
+ expect(result.invalidArgument).toBeUndefined();
276
+ });
277
+
278
+ test("Argument following is not used if not applicable to a boolean", () => {
279
+ const command: GlobalCommand = {
280
+ name: "foo",
281
+ argument: {
282
+ type: ArgumentValueTypeName.BOOLEAN,
283
+ },
284
+ execute: async (): Promise<void> => {
285
+ },
286
+ };
287
+
288
+ let result = populateGlobalCommandValue(
289
+ command,
290
+ ["--bar"],
291
+ undefined,
292
+ );
293
+ expectExtractResult(result, "true", ["--bar"]);
294
+ expect(result.invalidArgument).toBeUndefined();
295
+
296
+ result = populateGlobalCommandValue(
297
+ command,
298
+ ["True"],
299
+ undefined,
300
+ );
301
+ expectExtractResult(result, "True", []);
302
+ expect(result.invalidArgument).toBeUndefined();
303
+
304
+ result = populateGlobalCommandValue(
305
+ command,
306
+ ["FALSE"],
307
+ undefined,
308
+ );
309
+ expectExtractResult(result, "FALSE", []);
310
+ expect(result.invalidArgument).toBeUndefined();
311
+ });
312
+
313
+ test("Missing argument", () => {
314
+ let command: GlobalCommand = {
315
+ name: "foo",
316
+ argument: {
317
+ type: ArgumentValueTypeName.STRING,
318
+ },
319
+ execute: async (): Promise<void> => {
320
+ },
321
+ };
322
+
323
+ let result = populateGlobalCommandValue(
324
+ command,
325
+ [],
326
+ undefined,
327
+ );
328
+ expectExtractResult(result, undefined, []);
329
+ expect(result.invalidArgument).toEqual({
330
+ name: "foo",
331
+ reason: InvalidArgumentReason.MISSING_VALUE,
332
+ });
333
+
334
+ command = {
335
+ name: "foo",
336
+ argument: {
337
+ type: ArgumentValueTypeName.STRING,
338
+ isOptional: true,
339
+ },
340
+ execute: async (): Promise<void> => {
341
+ },
342
+ };
343
+
344
+ result = populateGlobalCommandValue(
345
+ command,
346
+ [],
347
+ undefined,
348
+ );
349
+ expectExtractResult(result, undefined, []);
350
+ expect(result.invalidArgument).toBeUndefined();
351
+
352
+ command = {
353
+ name: "foo",
354
+ argument: {
355
+ type: ArgumentValueTypeName.STRING,
356
+ defaultValue: "bar",
357
+ },
358
+ execute: async (): Promise<void> => {
359
+ },
360
+ };
361
+
362
+ result = populateGlobalCommandValue(
363
+ command,
364
+ [],
365
+ undefined,
366
+ );
367
+ expectExtractResult(result, "bar", []);
368
+ expect(result.invalidArgument).toBeUndefined();
369
+ });
370
+
371
+ test("Unused option after global command argument", () => {
372
+ const command: GlobalCommand = {
373
+ name: "foo",
374
+ argument: {
375
+ type: ArgumentValueTypeName.STRING,
376
+ },
377
+ execute: async (): Promise<void> => {
378
+ },
379
+ };
380
+
381
+ const result = populateGlobalCommandValue(
382
+ command,
383
+ ["bar", "--goo", "gar"],
384
+ undefined,
385
+ );
386
+ expectExtractResult(result, "bar", ["--goo", "gar"]);
387
+ expect(result.invalidArgument).toBeUndefined();
388
+ });
389
+
390
+ test("Unused positional after global command argument", () => {
391
+ const command: GlobalCommand = {
392
+ name: "foo",
393
+ argument: {
394
+ type: ArgumentValueTypeName.STRING,
395
+ },
396
+ execute: async (): Promise<void> => {
397
+ },
398
+ };
399
+
400
+ const result = populateGlobalCommandValue(
401
+ command,
402
+ ["bar", "goo"],
403
+ undefined,
404
+ );
405
+ expectExtractResult(result, "bar", ["goo"]);
406
+ expect(result.invalidArgument).toBeUndefined();
407
+ });
408
+
409
+ test("Global command default value is overridden by arg", () => {
410
+ let command: GlobalCommand = {
411
+ name: "foo",
412
+ argument: {
413
+ type: ArgumentValueTypeName.NUMBER,
414
+ defaultValue: 0,
415
+ },
416
+ execute: async (): Promise<void> => {
417
+ },
418
+ };
419
+ let result = populateGlobalCommandValue(
420
+ command,
421
+ ["1"],
422
+ undefined,
423
+ );
424
+ expectExtractResult(result, "1", []);
425
+ expect(result.invalidArgument).toBeUndefined();
426
+
427
+ command = {
428
+ name: "foo",
429
+ argument: {
430
+ type: ArgumentValueTypeName.STRING,
431
+ defaultValue: "foo",
432
+ },
433
+ execute: async (): Promise<void> => {
434
+ },
435
+ };
436
+
437
+ result = populateGlobalCommandValue(
438
+ command,
439
+ ["bar"],
440
+ undefined,
441
+ );
442
+ expectExtractResult(result, "bar", []);
443
+ expect(result.invalidArgument).toBeUndefined();
444
+
445
+ command = {
446
+ name: "foo",
447
+ argument: {
448
+ type: ArgumentValueTypeName.BOOLEAN,
449
+ defaultValue: false,
450
+ },
451
+ execute: async (): Promise<void> => {
452
+ },
453
+ };
454
+
455
+ result = populateGlobalCommandValue(
456
+ command,
457
+ ["false"],
458
+ undefined,
459
+ );
460
+ expectExtractResult(result, "false", []);
461
+ expect(result.invalidArgument).toBeUndefined();
462
+ });
463
+
464
+ test("Global command configured value is overridden by arg", () => {
465
+ let command: GlobalCommand = {
466
+ name: "foo",
467
+ argument: {
468
+ type: ArgumentValueTypeName.NUMBER,
469
+ },
470
+ execute: async (): Promise<void> => {
471
+ },
472
+ };
473
+
474
+ let result = populateGlobalCommandValue(
475
+ command,
476
+ ["1"],
477
+ 0,
478
+ );
479
+ expectExtractResult(result, "1", []);
480
+ expect(result.invalidArgument).toBeUndefined();
481
+
482
+ command = {
483
+ name: "foo",
484
+ argument: {
485
+ type: ArgumentValueTypeName.STRING,
486
+ },
487
+ execute: async (): Promise<void> => {
488
+ },
489
+ };
490
+
491
+ result = populateGlobalCommandValue(
492
+ command,
493
+ ["bar"],
494
+ "foo",
495
+ );
496
+ expectExtractResult(result, "bar", []);
497
+ expect(result.invalidArgument).toBeUndefined();
498
+
499
+ command = {
500
+ name: "foo",
501
+ argument: {
502
+ type: ArgumentValueTypeName.BOOLEAN,
503
+ },
504
+ execute: async (): Promise<void> => {
505
+ },
506
+ };
507
+
508
+ result = populateGlobalCommandValue(
509
+ command,
510
+ ["true"],
511
+ "false",
512
+ );
513
+ expectExtractResult(result, "true", []);
514
+ expect(result.invalidArgument).toBeUndefined();
515
+
516
+ command = {
517
+ name: "foo",
518
+ argument: {
519
+ type: ArgumentValueTypeName.BOOLEAN,
520
+ },
521
+ execute: async (): Promise<void> => {
522
+ },
523
+ };
524
+
525
+ result = populateGlobalCommandValue(
526
+ command,
527
+ ["false"],
528
+ "true",
529
+ );
530
+ expectExtractResult(result, "false", []);
531
+ expect(result.invalidArgument).toBeUndefined();
532
+ });
533
+
534
+ test("Global command default value is overridden by configured value", () => {
535
+ let command: GlobalCommand = {
536
+ name: "foo",
537
+ argument: {
538
+ type: ArgumentValueTypeName.NUMBER,
539
+ defaultValue: 0,
540
+ },
541
+ execute: async (): Promise<void> => {
542
+ },
543
+ };
544
+
545
+ let result = populateGlobalCommandValue(
546
+ command,
547
+ [],
548
+ 1,
549
+ );
550
+ expectExtractResult(result, 1, []);
551
+ expect(result.invalidArgument).toBeUndefined();
552
+
553
+ command = {
554
+ name: "foo",
555
+ argument: {
556
+ type: ArgumentValueTypeName.STRING,
557
+ defaultValue: "foo",
558
+ },
559
+ execute: async (): Promise<void> => {
560
+ },
561
+ };
562
+
563
+ result = populateGlobalCommandValue(
564
+ command,
565
+ [],
566
+ "bar",
567
+ );
568
+ expectExtractResult(result, "bar", []);
569
+ expect(result.invalidArgument).toBeUndefined();
570
+
571
+ command = {
572
+ name: "foo",
573
+ argument: {
574
+ type: ArgumentValueTypeName.BOOLEAN,
575
+ defaultValue: false,
576
+ },
577
+ execute: async (): Promise<void> => {
578
+ },
579
+ };
580
+
581
+ result = populateGlobalCommandValue(
582
+ command,
583
+ [],
584
+ "true",
585
+ );
586
+ expectExtractResult(result, "true", []);
587
+ expect(result.invalidArgument).toBeUndefined();
588
+
589
+ command = {
590
+ name: "foo",
591
+ argument: {
592
+ type: ArgumentValueTypeName.BOOLEAN,
593
+ defaultValue: true,
594
+ },
595
+ execute: async (): Promise<void> => {
596
+ },
597
+ };
598
+
599
+ result = populateGlobalCommandValue(
600
+ command,
601
+ [],
602
+ "false",
603
+ );
604
+ expectExtractResult(result, "false", []);
605
+ expect(result.invalidArgument).toBeUndefined();
606
+ });
607
+
608
+ test("Missing argument when configured value is provided is not an error", () => {
609
+ let command: GlobalCommand = {
610
+ name: "foo",
611
+ argument: {
612
+ type: ArgumentValueTypeName.STRING,
613
+ },
614
+ execute: async (): Promise<void> => {
615
+ },
616
+ };
617
+
618
+ let result = populateGlobalCommandValue(
619
+ command,
620
+ [],
621
+ 1,
622
+ );
623
+ expectExtractResult(result, 1, []);
624
+ expect(result.invalidArgument).toBeUndefined();
625
+
626
+ command = {
627
+ name: "foo",
628
+ argument: {
629
+ type: ArgumentValueTypeName.STRING,
630
+ isOptional: true,
631
+ },
632
+ execute: async (): Promise<void> => {
633
+ },
634
+ };
635
+
636
+ result = populateGlobalCommandValue(
637
+ command,
638
+ [],
639
+ "foo",
640
+ );
641
+ expectExtractResult(result, "foo", []);
642
+ expect(result.invalidArgument).toBeUndefined();
643
+
644
+ command = {
645
+ name: "foo",
646
+ argument: {
647
+ type: ArgumentValueTypeName.STRING,
648
+ defaultValue: "bar",
649
+ },
650
+ execute: async (): Promise<void> => {
651
+ },
652
+ };
653
+
654
+ result = populateGlobalCommandValue(
655
+ command,
656
+ [],
657
+ "foo",
658
+ );
659
+ expectExtractResult(result, "foo", []);
660
+ expect(result.invalidArgument).toBeUndefined();
661
+ });
662
+ });