@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,384 @@
1
+ import { describe, test } from "bun:test";
2
+ import { getCommandRegistry } from "../fixtures/CommandRegistry.ts";
3
+ import {
4
+ getGlobalCommand,
5
+ getGlobalModifierCommand,
6
+ getSubCommandWithOption,
7
+ getSubCommandWithPositional,
8
+ } from "../fixtures/Command.ts";
9
+ import { getContext } from "../fixtures/Context.ts";
10
+ import {
11
+ expectStringIncludes,
12
+ expectStringNotIncludes,
13
+ } from "../fixtures/util.ts";
14
+ import { ArgumentValueTypeName } from "../../src/api/argument/ArgumentValueTypes.ts";
15
+ import { SingleCommandCliHelpGlobalCommand } from "../../src/command/SingleCommandCliHelpCommand.ts";
16
+ import type SubCommand from "../../src/api/command/SubCommand.ts";
17
+ import StreamString from "../fixtures/StreamString.ts";
18
+
19
+ describe("SingleCommandCliHelpCommand Tests", () => {
20
+ test("Ensure single command CLI with simple default command help is rendered correctly: simple default command", async () => {
21
+ const streamString = new StreamString();
22
+ const context = getContext(streamString);
23
+ const help = new SingleCommandCliHelpGlobalCommand(
24
+ true,
25
+ getSubCommandWithOption("command_a", true, true, true),
26
+ getCommandRegistry(),
27
+ );
28
+
29
+ await help.execute(context);
30
+ expectStringIncludes(streamString.getString(), "--foo");
31
+ });
32
+
33
+ test("Ensure single command CLI aggregates all non-default command arguments", async () => {
34
+ const streamString = new StreamString();
35
+ const context = getContext(streamString);
36
+ const commandRegistry = getCommandRegistry([
37
+ getGlobalCommand("global1", true, true),
38
+ getGlobalCommand("global2", true),
39
+ getSubCommandWithOption(
40
+ "command_a",
41
+ true,
42
+ true,
43
+ true,
44
+ ArgumentValueTypeName.BOOLEAN,
45
+ ),
46
+ getSubCommandWithOption("command_b", true),
47
+ {
48
+ name: "topic",
49
+ helpTopic: "topic",
50
+ options: [],
51
+ positionals: [],
52
+ execute: async (): Promise<void> => {},
53
+ } as SubCommand,
54
+ ]);
55
+ const help = new SingleCommandCliHelpGlobalCommand(
56
+ true,
57
+ getSubCommandWithOption("command_a", true, true, true),
58
+ commandRegistry,
59
+ );
60
+
61
+ await help.execute(context);
62
+ expectStringNotIncludes(streamString.getString(), "Global");
63
+ expectStringNotIncludes(streamString.getString(), "Topic");
64
+ expectStringIncludes(streamString.getString(), "Command Arguments");
65
+ expectStringIncludes(streamString.getString(), "Other Arguments");
66
+ });
67
+
68
+ test("Ensure single command CLI with default and globals help is rendered correctly: default and global modifier", async () => {
69
+ const streamString = new StreamString();
70
+ const context = getContext(streamString);
71
+ const commandRegistry = getCommandRegistry([
72
+ getGlobalModifierCommand("modifier1", "m", true, true),
73
+ ]);
74
+ const help = new SingleCommandCliHelpGlobalCommand(
75
+ true,
76
+ getSubCommandWithOption("command_a", true, true, true),
77
+ commandRegistry,
78
+ );
79
+
80
+ await help.execute(context);
81
+ expectStringIncludes(streamString.getString(), "Other Arguments");
82
+ });
83
+
84
+ test("Ensure single command CLI with default and globals help is rendered correctly: default, global modifier and global", async () => {
85
+ const streamString = new StreamString();
86
+ const context = getContext(streamString);
87
+ const commandRegistry = getCommandRegistry([
88
+ getGlobalModifierCommand("modifier1"),
89
+ getGlobalCommand("global1"),
90
+ ]);
91
+ const help = new SingleCommandCliHelpGlobalCommand(
92
+ true,
93
+ getSubCommandWithOption("command_a", true, true, true),
94
+ commandRegistry,
95
+ );
96
+ await help.execute(context);
97
+ expectStringIncludes(streamString.getString(), "Other Arguments");
98
+ });
99
+
100
+ test("Ensure single command CLI usage syntax is rendered correctly: simple default command", async () => {
101
+ const streamString = new StreamString();
102
+ const context = getContext(streamString);
103
+ const help = new SingleCommandCliHelpGlobalCommand(
104
+ true,
105
+ getSubCommandWithOption("command_a", true, true, true),
106
+ getCommandRegistry(),
107
+ );
108
+
109
+ await help.execute(context);
110
+ expectStringIncludes(
111
+ streamString.getString(),
112
+ "foo --foo <string_value>...",
113
+ );
114
+ });
115
+
116
+ test("Ensure single command CLI usage syntax is rendered correctly: simple default command with non-multiple arg", async () => {
117
+ const streamString = new StreamString();
118
+ const context = getContext(streamString);
119
+ const commandRegistry = getCommandRegistry();
120
+ const help = new SingleCommandCliHelpGlobalCommand(
121
+ true,
122
+ getSubCommandWithOption("command_a", true, true),
123
+ commandRegistry,
124
+ );
125
+
126
+ await help.execute(context);
127
+ expectStringIncludes(
128
+ streamString.getString(),
129
+ "foo --foo <string_value>",
130
+ );
131
+ });
132
+
133
+ test("Ensure single command CLI usage syntax is rendered correctly: simple default command with optional arg", async () => {
134
+ const streamString = new StreamString();
135
+ const context = getContext(streamString);
136
+ const commandRegistry = getCommandRegistry();
137
+ const help = new SingleCommandCliHelpGlobalCommand(
138
+ true,
139
+ getSubCommandWithOption("command_a", true),
140
+ commandRegistry,
141
+ );
142
+
143
+ await help.execute(context);
144
+ expectStringIncludes(
145
+ streamString.getString(),
146
+ "foo [--foo <string_value>]",
147
+ );
148
+ });
149
+
150
+ test("Ensure single command CLI usage syntax is rendered correctly: with mandatory arg global modifier", async () => {
151
+ const streamString = new StreamString();
152
+ const context = getContext(streamString);
153
+ const commandRegistry = getCommandRegistry([
154
+ getGlobalModifierCommand("modifier1", "m", true, true),
155
+ ]);
156
+ const help = new SingleCommandCliHelpGlobalCommand(
157
+ true,
158
+ getSubCommandWithOption("command_a", true, true, true),
159
+ commandRegistry,
160
+ );
161
+
162
+ await help.execute(context);
163
+ expectStringIncludes(
164
+ streamString.getString(),
165
+ "foo --foo <string_value>...",
166
+ );
167
+ });
168
+
169
+ test("Ensure single command CLI usage syntax is rendered correctly: with global modifier with no arg", async () => {
170
+ const streamString = new StreamString();
171
+ const context = getContext(streamString);
172
+ const commandRegistry = getCommandRegistry([
173
+ getGlobalModifierCommand("modifier1"),
174
+ ]);
175
+ const help = new SingleCommandCliHelpGlobalCommand(
176
+ true,
177
+ getSubCommandWithOption("command_a", true, true, true),
178
+ commandRegistry,
179
+ );
180
+
181
+ await help.execute(context);
182
+ expectStringIncludes(
183
+ streamString.getString(),
184
+ "foo --foo <string_value>...",
185
+ );
186
+ });
187
+
188
+ test("Ensure single command CLI usage syntax is rendered correctly: with singular optional arg and global modifier", async () => {
189
+ const streamString = new StreamString();
190
+ const context = getContext(streamString);
191
+ const commandRegistry = getCommandRegistry([
192
+ getGlobalModifierCommand("modifier1"),
193
+ ]);
194
+ const help = new SingleCommandCliHelpGlobalCommand(
195
+ true,
196
+ getSubCommandWithOption("command_a", true),
197
+ commandRegistry,
198
+ );
199
+
200
+ await help.execute(context);
201
+ expectStringIncludes(
202
+ streamString.getString(),
203
+ "foo [--foo <string_value>]",
204
+ );
205
+ });
206
+
207
+ test("Ensure single command CLI usage syntax is rendered correctly: with multiple optional arg and multiple global modifiers and multiple global commands", async () => {
208
+ const streamString = new StreamString();
209
+ const context = getContext(streamString);
210
+ const commandRegistry = getCommandRegistry([
211
+ getGlobalModifierCommand("modifier1"),
212
+ getGlobalModifierCommand("modifier2", "m", true, true),
213
+ getGlobalCommand("global1", true, true),
214
+ getGlobalCommand("global2", true, true),
215
+ ]);
216
+ const help = new SingleCommandCliHelpGlobalCommand(
217
+ true,
218
+ getSubCommandWithOption("command_a", true, false, true),
219
+ commandRegistry,
220
+ );
221
+
222
+ await help.execute(context);
223
+ expectStringIncludes(
224
+ streamString.getString(),
225
+ "foo [--foo <string_value>]...",
226
+ );
227
+ });
228
+
229
+ test("Ensure single command CLI usage syntax is rendered correctly: with optional arg, multiple global modifiers, multiple global commands, multiple sub-commands", async () => {
230
+ const streamString = new StreamString();
231
+ const context = getContext(streamString);
232
+ const commandRegistry = getCommandRegistry([
233
+ getGlobalModifierCommand("modifier1"),
234
+ getGlobalModifierCommand("modifier2", "m", true, true),
235
+ getGlobalCommand("global1", true, true),
236
+ getGlobalCommand("global2", true, true),
237
+ getSubCommandWithOption("sub1", true, true),
238
+ ]);
239
+ const help = new SingleCommandCliHelpGlobalCommand(
240
+ true,
241
+ getSubCommandWithOption("command_a", true, false, true),
242
+ commandRegistry,
243
+ );
244
+
245
+ await help.execute(context);
246
+ expectStringIncludes(
247
+ streamString.getString(),
248
+ "foo [--foo <string_value>]...",
249
+ );
250
+ });
251
+
252
+ test("Ensure single command CLI usage syntax is rendered correctly: also with boolean args", async () => {
253
+ const streamString = new StreamString();
254
+ const context = getContext(streamString);
255
+ const commandRegistry = getCommandRegistry([
256
+ getGlobalModifierCommand("modifier1"),
257
+ getGlobalModifierCommand("modifier2", "m", true, true),
258
+ getGlobalCommand("global1", true, true),
259
+ getGlobalCommand("global2", true, true),
260
+ getSubCommandWithOption(
261
+ "sub1",
262
+ true,
263
+ true,
264
+ false,
265
+ ArgumentValueTypeName.BOOLEAN,
266
+ ),
267
+ ]);
268
+ const help = new SingleCommandCliHelpGlobalCommand(
269
+ true,
270
+ getSubCommandWithOption(
271
+ "command_a",
272
+ true,
273
+ false,
274
+ true,
275
+ ArgumentValueTypeName.BOOLEAN,
276
+ ),
277
+ commandRegistry,
278
+ );
279
+
280
+ await help.execute(context);
281
+ expectStringIncludes(
282
+ streamString.getString(),
283
+ "foo [--foo [true|false]]...",
284
+ );
285
+ });
286
+
287
+ test("Ensure single command CLI usage syntax is rendered correctly: also with default value", async () => {
288
+ const streamString = new StreamString();
289
+ const context = getContext(streamString);
290
+ const commandRegistry = getCommandRegistry();
291
+ const help = new SingleCommandCliHelpGlobalCommand(
292
+ true,
293
+ getSubCommandWithOption(
294
+ "command_a",
295
+ true,
296
+ false,
297
+ true,
298
+ ArgumentValueTypeName.STRING,
299
+ "foo",
300
+ ),
301
+ commandRegistry,
302
+ );
303
+
304
+ await help.execute(context);
305
+ expectStringIncludes(
306
+ streamString.getString(),
307
+ "foo [--foo <string_value>]...",
308
+ );
309
+ });
310
+
311
+ test("Ensure single command CLI usage syntax is rendered correctly: with positionals", async () => {
312
+ const streamString = new StreamString();
313
+ const context = getContext(streamString);
314
+ const commandRegistry = getCommandRegistry();
315
+ let help = new SingleCommandCliHelpGlobalCommand(
316
+ true,
317
+ getSubCommandWithPositional("command_a"),
318
+ commandRegistry,
319
+ );
320
+
321
+ await help.execute(context);
322
+ expectStringIncludes(streamString.getString(), "foo <foo>");
323
+
324
+ help = new SingleCommandCliHelpGlobalCommand(
325
+ true,
326
+ getSubCommandWithPositional("command_a", true, true),
327
+ commandRegistry,
328
+ );
329
+ await help.execute(context);
330
+ expectStringIncludes(streamString.getString(), "foo [<foo>]...");
331
+
332
+ help = new SingleCommandCliHelpGlobalCommand(
333
+ true,
334
+ getSubCommandWithPositional(
335
+ "command_a",
336
+ true,
337
+ true,
338
+ ArgumentValueTypeName.BOOLEAN,
339
+ ),
340
+ commandRegistry,
341
+ );
342
+ await help.execute(context);
343
+ expectStringIncludes(streamString.getString(), "foo [<foo>]...");
344
+
345
+ help = new SingleCommandCliHelpGlobalCommand(
346
+ true,
347
+ getSubCommandWithPositional(
348
+ "command_a",
349
+ true,
350
+ true,
351
+ ArgumentValueTypeName.STRING,
352
+ ),
353
+ commandRegistry,
354
+ );
355
+ await help.execute(context);
356
+ expectStringIncludes(streamString.getString(), "foo [<foo>]...");
357
+
358
+ help = new SingleCommandCliHelpGlobalCommand(
359
+ true,
360
+ getSubCommandWithPositional(
361
+ "command_a",
362
+ false,
363
+ false,
364
+ ArgumentValueTypeName.STRING,
365
+ ),
366
+ commandRegistry,
367
+ );
368
+ await help.execute(context);
369
+ expectStringIncludes(streamString.getString(), "foo <foo>");
370
+
371
+ help = new SingleCommandCliHelpGlobalCommand(
372
+ true,
373
+ getSubCommandWithPositional(
374
+ "command_a",
375
+ false,
376
+ true,
377
+ ArgumentValueTypeName.BOOLEAN,
378
+ ),
379
+ commandRegistry,
380
+ );
381
+ await help.execute(context);
382
+ expectStringIncludes(streamString.getString(), "foo <foo>...");
383
+ });
384
+ });
@@ -0,0 +1,53 @@
1
+ import { describe, test } from "bun:test";
2
+ import DefaultContext from "../../src/runtime/DefaultContext.ts";
3
+ import UsageCommand from "../../src/command/UsageCommand.ts";
4
+ import { getCLIConfig } from "../fixtures/CLIConfig.ts";
5
+ import { PRINTER_SERVICE_ID } from "../../src/api/service/core/PrinterService.ts";
6
+ import DefaultPrinterService from "../../src/service/printer/DefaultPrinterService.ts";
7
+ import type { ArgumentValues } from "../../src/api/argument/ArgumentValueTypes.ts";
8
+ import type Context from "../../src/api/Context.ts";
9
+ import type Command from "../../src/api/command/Command.ts";
10
+ import StreamString from "../fixtures/StreamString.ts";
11
+ import { expectStringEquals } from "../fixtures/util.ts";
12
+ import TtyTerminal from "../../src/service/printer/terminal/TtyTerminal.ts";
13
+ import TtyStyler from "../../src/service/printer/terminal/TtyStyler.ts";
14
+
15
+ describe("UsageCommand Tests", () => {
16
+ test("Usage works", async () => {
17
+ const dummyStdout = new StreamString();
18
+ const dummyStderr = new StreamString();
19
+ const printer = new DefaultPrinterService(
20
+ dummyStdout.writableStream,
21
+ dummyStderr.writableStream,
22
+ true,
23
+ true,
24
+ new TtyTerminal(dummyStderr.writeStream),
25
+ new TtyStyler(3),
26
+ );
27
+ printer.colorEnabled = false;
28
+
29
+ const context = new DefaultContext(getCLIConfig());
30
+
31
+ context.addServiceInstance(PRINTER_SERVICE_ID, printer);
32
+
33
+ const usageCommand = new UsageCommand(
34
+ new class implements Command {
35
+ readonly name = "help";
36
+
37
+ execute(
38
+ _argumentValues: ArgumentValues,
39
+ _context: Context,
40
+ ): Promise<void> {
41
+ return Promise.resolve(undefined);
42
+ }
43
+ }(),
44
+ );
45
+
46
+ await usageCommand.execute(context);
47
+
48
+ expectStringEquals(
49
+ dummyStdout.getString(),
50
+ "Try running:\n\n foo --help\n\n",
51
+ );
52
+ });
53
+ });
@@ -0,0 +1,36 @@
1
+ import { describe, test } from "bun:test";
2
+ import DefaultContext from "../../src/runtime/DefaultContext.ts";
3
+ import VersionCommand from "../../src/command/VersionCommand.ts";
4
+ import { getCLIConfig } from "../fixtures/CLIConfig.ts";
5
+ import { PRINTER_SERVICE_ID } from "../../src/api/service/core/PrinterService.ts";
6
+ import DefaultPrinterService from "../../src/service/printer/DefaultPrinterService.ts";
7
+ import StreamString from "../fixtures/StreamString.ts";
8
+ import { expectStringEquals } from "../fixtures/util.ts";
9
+ import TtyTerminal from "../../src/service/printer/terminal/TtyTerminal.ts";
10
+ import TtyStyler from "../../src/service/printer/terminal/TtyStyler.ts";
11
+
12
+ describe("VersionCommand Tests", () => {
13
+ test("Version works", async () => {
14
+ const dummyStdout = new StreamString();
15
+ const dummyStderr = new StreamString();
16
+ const printer = new DefaultPrinterService(
17
+ dummyStdout.writableStream,
18
+ dummyStderr.writableStream,
19
+ true,
20
+ true,
21
+ new TtyTerminal(dummyStderr.writeStream),
22
+ new TtyStyler(3),
23
+ );
24
+ printer.colorEnabled = false;
25
+
26
+ const context = new DefaultContext(getCLIConfig());
27
+
28
+ context.addServiceInstance(PRINTER_SERVICE_ID, printer);
29
+
30
+ const versionCommand = new VersionCommand();
31
+
32
+ await versionCommand.execute(context);
33
+
34
+ expectStringEquals(dummyStdout.getString(), "foobar\n");
35
+ });
36
+ });
@@ -0,0 +1,9 @@
1
+ import type CLIConfig from "../../src/api/CLIConfig.ts";
2
+
3
+ export function getCLIConfig(name = "foo"): CLIConfig {
4
+ return {
5
+ name,
6
+ description: "bar",
7
+ version: "foobar",
8
+ };
9
+ }