effect-start 0.14.0 → 0.15.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 (81) hide show
  1. package/package.json +8 -9
  2. package/src/Commander.test.ts +507 -245
  3. package/src/ContentNegotiation.test.ts +500 -0
  4. package/src/ContentNegotiation.ts +535 -0
  5. package/src/FileRouter.ts +16 -12
  6. package/src/{FileRouterCodegen.test.ts → FileRouterCodegen.todo.ts} +384 -219
  7. package/src/FileRouterCodegen.ts +6 -6
  8. package/src/FileRouterPattern.test.ts +93 -62
  9. package/src/FileRouter_files.test.ts +5 -5
  10. package/src/FileRouter_path.test.ts +121 -69
  11. package/src/FileRouter_tree.test.ts +62 -56
  12. package/src/FileSystemExtra.test.ts +46 -30
  13. package/src/Http.test.ts +24 -0
  14. package/src/Http.ts +25 -0
  15. package/src/HttpAppExtra.test.ts +39 -20
  16. package/src/HttpAppExtra.ts +0 -1
  17. package/src/HttpUtils.test.ts +35 -18
  18. package/src/HttpUtils.ts +2 -0
  19. package/src/PathPattern.test.ts +648 -0
  20. package/src/PathPattern.ts +483 -0
  21. package/src/Route.ts +258 -1073
  22. package/src/RouteBody.test.ts +182 -0
  23. package/src/RouteBody.ts +106 -0
  24. package/src/RouteHook.test.ts +40 -0
  25. package/src/RouteHook.ts +105 -0
  26. package/src/RouteHttp.test.ts +443 -0
  27. package/src/RouteHttp.ts +219 -0
  28. package/src/RouteMount.test.ts +468 -0
  29. package/src/RouteMount.ts +313 -0
  30. package/src/RouteSchema.test.ts +81 -0
  31. package/src/RouteSchema.ts +44 -0
  32. package/src/RouteTree.test.ts +346 -0
  33. package/src/RouteTree.ts +165 -0
  34. package/src/RouteTrie.test.ts +322 -0
  35. package/src/RouteTrie.ts +224 -0
  36. package/src/RouterPattern.test.ts +569 -548
  37. package/src/RouterPattern.ts +7 -7
  38. package/src/Start.ts +3 -3
  39. package/src/TuplePathPattern.ts +64 -0
  40. package/src/Values.ts +16 -0
  41. package/src/bun/BunBundle.test.ts +36 -42
  42. package/src/bun/BunBundle.ts +2 -2
  43. package/src/bun/BunBundle_imports.test.ts +4 -6
  44. package/src/bun/BunHttpServer.test.ts +183 -6
  45. package/src/bun/BunHttpServer.ts +56 -32
  46. package/src/bun/BunHttpServer_web.ts +18 -6
  47. package/src/bun/BunImportTrackerPlugin.test.ts +3 -3
  48. package/src/bun/BunRoute.ts +29 -210
  49. package/src/{BundleHttp.test.ts → bundler/BundleHttp.test.ts} +34 -60
  50. package/src/{BundleHttp.ts → bundler/BundleHttp.ts} +1 -2
  51. package/src/client/index.ts +1 -1
  52. package/src/{Effect_HttpRouter.test.ts → effect/HttpRouter.test.ts} +69 -90
  53. package/src/experimental/EncryptedCookies.test.ts +125 -64
  54. package/src/experimental/SseHttpResponse.ts +0 -1
  55. package/src/hyper/Hyper.ts +89 -0
  56. package/src/{HyperHtml.test.ts → hyper/HyperHtml.test.ts} +13 -13
  57. package/src/{HyperHtml.ts → hyper/HyperHtml.ts} +2 -2
  58. package/src/{jsx.d.ts → hyper/jsx.d.ts} +1 -1
  59. package/src/index.ts +2 -4
  60. package/src/middlewares/BasicAuthMiddleware.test.ts +29 -19
  61. package/src/{NodeFileSystem.ts → node/FileSystem.ts} +6 -2
  62. package/src/testing/TestHttpClient.test.ts +26 -26
  63. package/src/testing/TestLogger.test.ts +27 -11
  64. package/src/x/datastar/Datastar.test.ts +47 -48
  65. package/src/x/datastar/Datastar.ts +1 -1
  66. package/src/x/tailwind/TailwindPlugin.test.ts +56 -58
  67. package/src/x/tailwind/plugin.ts +1 -1
  68. package/src/FileHttpRouter.test.ts +0 -239
  69. package/src/FileHttpRouter.ts +0 -194
  70. package/src/Hyper.ts +0 -194
  71. package/src/Route.test.ts +0 -1370
  72. package/src/RouteRender.ts +0 -40
  73. package/src/Router.test.ts +0 -375
  74. package/src/Router.ts +0 -255
  75. package/src/bun/BunRoute.test.ts +0 -480
  76. package/src/bun/BunRoute_bundles.test.ts +0 -219
  77. /package/src/{Bundle.ts → bundler/Bundle.ts} +0 -0
  78. /package/src/{BundleFiles.ts → bundler/BundleFiles.ts} +0 -0
  79. /package/src/{HyperNode.ts → hyper/HyperNode.ts} +0 -0
  80. /package/src/{jsx-runtime.ts → hyper/jsx-runtime.ts} +0 -0
  81. /package/src/{NodeUtils.ts → node/Utils.ts} +0 -0
@@ -1,22 +1,26 @@
1
- import * as t from "bun:test"
1
+ import * as test from "bun:test"
2
2
  import * as Effect from "effect/Effect"
3
3
  import * as Schema from "effect/Schema"
4
4
  import * as assert from "node:assert"
5
5
  import * as Commander from "./Commander.ts"
6
6
 
7
- t.describe(`${Commander.make.name}`, () => {
8
- t.it("should create a basic command", () => {
7
+ test.describe(`${Commander.make.name}`, () => {
8
+ test.it("should create a basic command", () => {
9
9
  const cmd = Commander.make({
10
10
  name: "test-app",
11
11
  description: "A test application",
12
12
  })
13
- t.expect(cmd.name).toBe("test-app")
14
- t.expect(cmd.description).toBe("A test application")
13
+ test
14
+ .expect(cmd.name)
15
+ .toBe("test-app")
16
+ test
17
+ .expect(cmd.description)
18
+ .toBe("A test application")
15
19
  })
16
20
  })
17
21
 
18
- t.describe(`${Commander.option.name} - nested builder API`, () => {
19
- t.it("should add an option with schema", () => {
22
+ test.describe(`${Commander.option.name} - nested builder API`, () => {
23
+ test.it("should add an option with schema", () => {
20
24
  const cmd = Commander
21
25
  .make({ name: "app" })
22
26
  .option(
@@ -25,12 +29,18 @@ t.describe(`${Commander.option.name} - nested builder API`, () => {
25
29
  .schema(Schema.String),
26
30
  )
27
31
 
28
- t.expect(cmd.options.output).toBeDefined()
29
- t.expect(cmd.options.output.long).toBe("--output")
30
- t.expect(cmd.options.output.short).toBe("o")
32
+ test
33
+ .expect(cmd.options.output)
34
+ .toBeDefined()
35
+ test
36
+ .expect(cmd.options.output.long)
37
+ .toBe("--output")
38
+ test
39
+ .expect(cmd.options.output.short)
40
+ .toBe("o")
31
41
  })
32
42
 
33
- t.it("should add option with description", () => {
43
+ test.it("should add option with description", () => {
34
44
  const cmd = Commander
35
45
  .make({ name: "app" })
36
46
  .option(
@@ -40,10 +50,12 @@ t.describe(`${Commander.option.name} - nested builder API`, () => {
40
50
  .schema(Schema.String),
41
51
  )
42
52
 
43
- t.expect(cmd.options.output.description).toBe("Output file")
53
+ test
54
+ .expect(cmd.options.output.description)
55
+ .toBe("Output file")
44
56
  })
45
57
 
46
- t.it("should add option with default value", () => {
58
+ test.it("should add option with default value", () => {
47
59
  const cmd = Commander
48
60
  .make({ name: "app" })
49
61
  .option(
@@ -53,10 +65,12 @@ t.describe(`${Commander.option.name} - nested builder API`, () => {
53
65
  .schema(Commander.NumberFromString),
54
66
  )
55
67
 
56
- t.expect(cmd.options.count.defaultValue).toBe(10)
68
+ test
69
+ .expect(cmd.options.count.defaultValue)
70
+ .toBe(10)
57
71
  })
58
72
 
59
- t.it("should chain multiple options", () => {
73
+ test.it("should chain multiple options", () => {
60
74
  const cmd = Commander
61
75
  .make({ name: "app" })
62
76
  .option(
@@ -70,15 +84,23 @@ t.describe(`${Commander.option.name} - nested builder API`, () => {
70
84
  .schema(Schema.String),
71
85
  )
72
86
 
73
- t.expect(cmd.options.input).toBeDefined()
74
- t.expect(cmd.options.output).toBeDefined()
75
- t.expect(cmd.options.input.long).toBe("--input")
76
- t.expect(cmd.options.output.long).toBe("--output")
87
+ test
88
+ .expect(cmd.options.input)
89
+ .toBeDefined()
90
+ test
91
+ .expect(cmd.options.output)
92
+ .toBeDefined()
93
+ test
94
+ .expect(cmd.options.input.long)
95
+ .toBe("--input")
96
+ test
97
+ .expect(cmd.options.output.long)
98
+ .toBe("--output")
77
99
  })
78
100
  })
79
101
 
80
- t.describe(`${Commander.parse.name} - kebab-to-camel conversion`, () => {
81
- t.it("should convert kebab-case to camelCase", async () => {
102
+ test.describe(`${Commander.parse.name} - kebab-to-camel conversion`, () => {
103
+ test.it("should convert kebab-case to camelCase", async () => {
82
104
  const cmd = Commander
83
105
  .make({ name: "app" })
84
106
  .option(
@@ -91,10 +113,12 @@ t.describe(`${Commander.parse.name} - kebab-to-camel conversion`, () => {
91
113
  Commander.parse(cmd, ["--input-file", "test.txt"]),
92
114
  )
93
115
 
94
- t.expect(result.inputFile).toBe("test.txt")
116
+ test
117
+ .expect(result.inputFile)
118
+ .toBe("test.txt")
95
119
  })
96
120
 
97
- t.it("should handle single word options", async () => {
121
+ test.it("should handle single word options", async () => {
98
122
  const cmd = Commander
99
123
  .make({ name: "app" })
100
124
  .option(
@@ -107,10 +131,12 @@ t.describe(`${Commander.parse.name} - kebab-to-camel conversion`, () => {
107
131
  Commander.parse(cmd, ["--port", "3000"]),
108
132
  )
109
133
 
110
- t.expect(result.port).toBe(3000)
134
+ test
135
+ .expect(result.port)
136
+ .toBe(3000)
111
137
  })
112
138
 
113
- t.it("should parse short options", async () => {
139
+ test.it("should parse short options", async () => {
114
140
  const cmd = Commander
115
141
  .make({ name: "app" })
116
142
  .option(
@@ -123,10 +149,12 @@ t.describe(`${Commander.parse.name} - kebab-to-camel conversion`, () => {
123
149
  Commander.parse(cmd, ["-p", "8080"]),
124
150
  )
125
151
 
126
- t.expect(result.port).toBe(8080)
152
+ test
153
+ .expect(result.port)
154
+ .toBe(8080)
127
155
  })
128
156
 
129
- t.it("should parse multiple options", async () => {
157
+ test.it("should parse multiple options", async () => {
130
158
  const cmd = Commander
131
159
  .make({ name: "app" })
132
160
  .option(
@@ -144,11 +172,15 @@ t.describe(`${Commander.parse.name} - kebab-to-camel conversion`, () => {
144
172
  Commander.parse(cmd, ["--host", "localhost", "--port", "3000"]),
145
173
  )
146
174
 
147
- t.expect(result.host).toBe("localhost")
148
- t.expect(result.port).toBe(3000)
175
+ test
176
+ .expect(result.host)
177
+ .toBe("localhost")
178
+ test
179
+ .expect(result.port)
180
+ .toBe(3000)
149
181
  })
150
182
 
151
- t.it("should handle options with equals syntax", async () => {
183
+ test.it("should handle options with equals syntax", async () => {
152
184
  const cmd = Commander
153
185
  .make({ name: "app" })
154
186
  .option(
@@ -161,10 +193,12 @@ t.describe(`${Commander.parse.name} - kebab-to-camel conversion`, () => {
161
193
  Commander.parse(cmd, ["--port=3000"]),
162
194
  )
163
195
 
164
- t.expect(result.port).toBe(3000)
196
+ test
197
+ .expect(result.port)
198
+ .toBe(3000)
165
199
  })
166
200
 
167
- t.it("should use default value when option not provided", async () => {
201
+ test.it("should use default value when option not provided", async () => {
168
202
  const cmd = Commander
169
203
  .make({ name: "app" })
170
204
  .option(
@@ -178,10 +212,12 @@ t.describe(`${Commander.parse.name} - kebab-to-camel conversion`, () => {
178
212
  Commander.parse(cmd, []),
179
213
  )
180
214
 
181
- t.expect(result.port).toBe(3000)
215
+ test
216
+ .expect(result.port)
217
+ .toBe(3000)
182
218
  })
183
219
 
184
- t.it("should override default when option specified", async () => {
220
+ test.it("should override default when option specified", async () => {
185
221
  const cmd = Commander
186
222
  .make({ name: "app" })
187
223
  .option(
@@ -195,36 +231,50 @@ t.describe(`${Commander.parse.name} - kebab-to-camel conversion`, () => {
195
231
  Commander.parse(cmd, ["--port", "8080"]),
196
232
  )
197
233
 
198
- t.expect(result.port).toBe(8080)
234
+ test
235
+ .expect(result.port)
236
+ .toBe(8080)
199
237
  })
200
238
  })
201
239
 
202
- t.describe(`${Commander.optionHelp.name}`, () => {
203
- t.it("should add help option", () => {
240
+ test.describe(`${Commander.optionHelp.name}`, () => {
241
+ test.it("should add help option", () => {
204
242
  const cmd = Commander
205
243
  .make({ name: "app" })
206
244
  .optionHelp()
207
245
 
208
- t.expect(cmd.options.help).toBeDefined()
209
- t.expect(cmd.options.help.long).toBe("--help")
210
- t.expect(cmd.options.help.short).toBe("h")
246
+ test
247
+ .expect(cmd.options.help)
248
+ .toBeDefined()
249
+ test
250
+ .expect(cmd.options.help.long)
251
+ .toBe("--help")
252
+ test
253
+ .expect(cmd.options.help.short)
254
+ .toBe("h")
211
255
  })
212
256
  })
213
257
 
214
- t.describe(`${Commander.optionVersion.name}`, () => {
215
- t.it("should add version option", () => {
258
+ test.describe(`${Commander.optionVersion.name}`, () => {
259
+ test.it("should add version option", () => {
216
260
  const cmd = Commander
217
261
  .make({ name: "app", version: "1.0.0" })
218
262
  .optionVersion()
219
263
 
220
- t.expect(cmd.options.version).toBeDefined()
221
- t.expect(cmd.options.version.long).toBe("--version")
222
- t.expect(cmd.options.version.short).toBe("V")
264
+ test
265
+ .expect(cmd.options.version)
266
+ .toBeDefined()
267
+ test
268
+ .expect(cmd.options.version.long)
269
+ .toBe("--version")
270
+ test
271
+ .expect(cmd.options.version.short)
272
+ .toBe("V")
223
273
  })
224
274
  })
225
275
 
226
- t.describe(`${Commander.handle.name}`, () => {
227
- t.it("should mark command as handled", () => {
276
+ test.describe(`${Commander.handle.name}`, () => {
277
+ test.it("should mark command as handled", () => {
228
278
  const handled = Commander
229
279
  .make({ name: "app" })
230
280
  .option(
@@ -242,13 +292,17 @@ t.describe(`${Commander.handle.name}`, () => {
242
292
  .schema(Schema.String),
243
293
  )
244
294
 
245
- t.expect(handled.handler).toBeDefined()
246
- t.expect(unhandled.handler).toBeUndefined()
295
+ test
296
+ .expect(handled.handler)
297
+ .toBeDefined()
298
+ test
299
+ .expect(unhandled.handler)
300
+ .toBeUndefined()
247
301
  })
248
302
  })
249
303
 
250
- t.describe(`${Commander.subcommand.name}`, () => {
251
- t.it("should add subcommand", () => {
304
+ test.describe(`${Commander.subcommand.name}`, () => {
305
+ test.it("should add subcommand", () => {
252
306
  const subCmd = Commander
253
307
  .make({ name: "format" })
254
308
  .option(
@@ -262,13 +316,17 @@ t.describe(`${Commander.subcommand.name}`, () => {
262
316
  .make({ name: "main" })
263
317
  .subcommand(subCmd)
264
318
 
265
- t.expect(main.subcommands.length).toBe(1)
266
- t.expect(main.subcommands[0]!.command.name).toBe("format")
319
+ test
320
+ .expect(main.subcommands.length)
321
+ .toBe(1)
322
+ test
323
+ .expect(main.subcommands[0]!.command.name)
324
+ .toBe("format")
267
325
  })
268
326
  })
269
327
 
270
- t.describe(`${Commander.help.name}`, () => {
271
- t.it("should generate help text", () => {
328
+ test.describe(`${Commander.help.name}`, () => {
329
+ test.it("should generate help text", () => {
272
330
  const cmd = Commander
273
331
  .make({
274
332
  name: "myapp",
@@ -285,33 +343,49 @@ t.describe(`${Commander.help.name}`, () => {
285
343
 
286
344
  const helpText = Commander.help(cmd)
287
345
 
288
- t.expect(helpText).toContain("My awesome application")
289
- t.expect(helpText).toContain("Usage: myapp [options]")
290
- t.expect(helpText).toContain("--output")
291
- t.expect(helpText).toContain("-o,")
292
- t.expect(helpText).toContain("Output file")
293
- t.expect(helpText).toContain("--help")
346
+ test
347
+ .expect(helpText)
348
+ .toContain("My awesome application")
349
+ test
350
+ .expect(helpText)
351
+ .toContain("Usage: myapp [options]")
352
+ test
353
+ .expect(helpText)
354
+ .toContain("--output")
355
+ test
356
+ .expect(helpText)
357
+ .toContain("-o,")
358
+ test
359
+ .expect(helpText)
360
+ .toContain("Output file")
361
+ test
362
+ .expect(helpText)
363
+ .toContain("--help")
294
364
  })
295
365
  })
296
366
 
297
- t.describe("BooleanFromString", () => {
298
- t.it("should decode true value", async () => {
367
+ test.describe("BooleanFromString", () => {
368
+ test.it("should decode true value", async () => {
299
369
  const result = await Effect.runPromise(
300
370
  Schema.decode(Schema.BooleanFromString)("true"),
301
371
  )
302
- t.expect(result).toBe(true)
372
+ test
373
+ .expect(result)
374
+ .toBe(true)
303
375
  })
304
376
 
305
- t.it("should decode false value", async () => {
377
+ test.it("should decode false value", async () => {
306
378
  const result = await Effect.runPromise(
307
379
  Schema.decode(Schema.BooleanFromString)("false"),
308
380
  )
309
- t.expect(result).toBe(false)
381
+ test
382
+ .expect(result)
383
+ .toBe(false)
310
384
  })
311
385
  })
312
386
 
313
- t.describe(`${Commander.choice.name}`, () => {
314
- t.it("should accept valid choice", async () => {
387
+ test.describe(`${Commander.choice.name}`, () => {
388
+ test.it("should accept valid choice", async () => {
315
389
  const ColorSchema = Schema.compose(
316
390
  Schema.String,
317
391
  Schema.Literal("red", "green", "blue"),
@@ -321,10 +395,12 @@ t.describe(`${Commander.choice.name}`, () => {
321
395
  Schema.decode(ColorSchema)("red"),
322
396
  )
323
397
 
324
- t.expect(result).toBe("red")
398
+ test
399
+ .expect(result)
400
+ .toBe("red")
325
401
  })
326
402
 
327
- t.it("should fail on invalid choice", async () => {
403
+ test.it("should fail on invalid choice", async () => {
328
404
  const ColorSchema = Schema.compose(
329
405
  Schema.String,
330
406
  Schema.Literal("red", "green", "blue"),
@@ -334,54 +410,64 @@ t.describe(`${Commander.choice.name}`, () => {
334
410
  Effect.either(Schema.decode(ColorSchema)("yellow")),
335
411
  )
336
412
 
337
- t.expect(result._tag).toBe("Left")
413
+ test
414
+ .expect(result._tag)
415
+ .toBe("Left")
338
416
  })
339
417
  })
340
418
 
341
- t.describe(`${Commander.repeatable.name}`, () => {
342
- t.it("should parse comma-separated values", async () => {
419
+ test.describe(`${Commander.repeatable.name}`, () => {
420
+ test.it("should parse comma-separated values", async () => {
343
421
  const schema = Commander.repeatable(Schema.String)
344
422
 
345
423
  const result = await Effect.runPromise(
346
424
  Schema.decode(schema)("foo,bar,baz"),
347
425
  )
348
426
 
349
- t.expect(result).toEqual(["foo", "bar", "baz"])
427
+ test
428
+ .expect(result)
429
+ .toEqual(["foo", "bar", "baz"])
350
430
  })
351
431
 
352
- t.it("should parse comma-separated numbers", async () => {
432
+ test.it("should parse comma-separated numbers", async () => {
353
433
  const schema = Commander.repeatable(Commander.NumberFromString)
354
434
 
355
435
  const result = await Effect.runPromise(
356
436
  Schema.decode(schema)("1,2,3,4,5"),
357
437
  )
358
438
 
359
- t.expect(result).toEqual([1, 2, 3, 4, 5])
439
+ test
440
+ .expect(result)
441
+ .toEqual([1, 2, 3, 4, 5])
360
442
  })
361
443
 
362
- t.it("should trim whitespace", async () => {
444
+ test.it("should trim whitespace", async () => {
363
445
  const schema = Commander.repeatable(Schema.String)
364
446
 
365
447
  const result = await Effect.runPromise(
366
448
  Schema.decode(schema)("foo, bar , baz"),
367
449
  )
368
450
 
369
- t.expect(result).toEqual(["foo", "bar", "baz"])
451
+ test
452
+ .expect(result)
453
+ .toEqual(["foo", "bar", "baz"])
370
454
  })
371
455
 
372
- t.it("should encode back to string", async () => {
456
+ test.it("should encode back to string", async () => {
373
457
  const schema = Commander.repeatable(Schema.String)
374
458
 
375
459
  const result = await Effect.runPromise(
376
460
  Schema.encode(schema)(["foo", "bar", "baz"]),
377
461
  )
378
462
 
379
- t.expect(result).toBe("foo,bar,baz")
463
+ test
464
+ .expect(result)
465
+ .toBe("foo,bar,baz")
380
466
  })
381
467
  })
382
468
 
383
- t.describe("integration", () => {
384
- t.it("should work with builder pattern", async () => {
469
+ test.describe("integration", () => {
470
+ test.it("should work with builder pattern", async () => {
385
471
  const cmd = Commander
386
472
  .make({
387
473
  name: "converter",
@@ -423,13 +509,21 @@ t.describe("integration", () => {
423
509
  ]),
424
510
  )
425
511
 
426
- t.expect(result.input).toBe("input.txt")
427
- t.expect(result.output).toBe("output.txt")
428
- t.expect(result.format).toBe("yaml")
429
- t.expect(result.help).toBe(false)
430
- })
431
-
432
- t.it("should handle kebab-case option names", async () => {
512
+ test
513
+ .expect(result.input)
514
+ .toBe("input.txt")
515
+ test
516
+ .expect(result.output)
517
+ .toBe("output.txt")
518
+ test
519
+ .expect(result.format)
520
+ .toBe("yaml")
521
+ test
522
+ .expect(result.help)
523
+ .toBe(false)
524
+ })
525
+
526
+ test.it("should handle kebab-case option names", async () => {
433
527
  const cmd = Commander
434
528
  .make({ name: "app" })
435
529
  .option(
@@ -448,13 +542,17 @@ t.describe("integration", () => {
448
542
  Commander.parse(cmd, ["--dry-run", "true", "--cache-dir", "/tmp/cache"]),
449
543
  )
450
544
 
451
- t.expect(result.dryRun).toBe(true)
452
- t.expect(result.cacheDir).toBe("/tmp/cache")
545
+ test
546
+ .expect(result.dryRun)
547
+ .toBe(true)
548
+ test
549
+ .expect(result.cacheDir)
550
+ .toBe("/tmp/cache")
453
551
  })
454
552
  })
455
553
 
456
- t.describe(`${Commander.parse.name} - comprehensive`, () => {
457
- t.it("should parse with explicit args", async () => {
554
+ test.describe(`${Commander.parse.name} - comprehensive`, () => {
555
+ test.it("should parse with explicit args", async () => {
458
556
  const cmd = Commander
459
557
  .make({ name: "app" })
460
558
  .option(
@@ -467,10 +565,12 @@ t.describe(`${Commander.parse.name} - comprehensive`, () => {
467
565
  Commander.parse(cmd, ["--port", "3000"]),
468
566
  )
469
567
 
470
- t.expect(result.port).toBe(3000)
568
+ test
569
+ .expect(result.port)
570
+ .toBe(3000)
471
571
  })
472
572
 
473
- t.it("should parse short options", async () => {
573
+ test.it("should parse short options", async () => {
474
574
  const cmd = Commander
475
575
  .make({ name: "app" })
476
576
  .option(
@@ -483,10 +583,12 @@ t.describe(`${Commander.parse.name} - comprehensive`, () => {
483
583
  Commander.parse(cmd, ["-p", "8080"]),
484
584
  )
485
585
 
486
- t.expect(result.port).toBe(8080)
586
+ test
587
+ .expect(result.port)
588
+ .toBe(8080)
487
589
  })
488
590
 
489
- t.it("should parse multiple options", async () => {
591
+ test.it("should parse multiple options", async () => {
490
592
  const cmd = Commander
491
593
  .make({ name: "app" })
492
594
  .option(
@@ -504,11 +606,15 @@ t.describe(`${Commander.parse.name} - comprehensive`, () => {
504
606
  Commander.parse(cmd, ["--host", "localhost", "--port", "3000"]),
505
607
  )
506
608
 
507
- t.expect(result.host).toBe("localhost")
508
- t.expect(result.port).toBe(3000)
609
+ test
610
+ .expect(result.host)
611
+ .toBe("localhost")
612
+ test
613
+ .expect(result.port)
614
+ .toBe(3000)
509
615
  })
510
616
 
511
- t.it("should handle options with equals syntax", async () => {
617
+ test.it("should handle options with equals syntax", async () => {
512
618
  const cmd = Commander
513
619
  .make({ name: "app" })
514
620
  .option(
@@ -521,10 +627,12 @@ t.describe(`${Commander.parse.name} - comprehensive`, () => {
521
627
  Commander.parse(cmd, ["--port=3000"]),
522
628
  )
523
629
 
524
- t.expect(result.port).toBe(3000)
630
+ test
631
+ .expect(result.port)
632
+ .toBe(3000)
525
633
  })
526
634
 
527
- t.it("should parse combined short flags", async () => {
635
+ test.it("should parse combined short flags", async () => {
528
636
  const cmd = Commander
529
637
  .make({ name: "app" })
530
638
  .option(
@@ -544,13 +652,17 @@ t.describe(`${Commander.parse.name} - comprehensive`, () => {
544
652
  Commander.parse(cmd, []),
545
653
  )
546
654
 
547
- t.expect(result.verbose).toBe(false)
548
- t.expect(result.debug).toBe(false)
655
+ test
656
+ .expect(result.verbose)
657
+ .toBe(false)
658
+ test
659
+ .expect(result.debug)
660
+ .toBe(false)
549
661
  })
550
662
  })
551
663
 
552
- t.describe("boolean options", () => {
553
- t.it("should return false for boolean flag when not specified", async () => {
664
+ test.describe("boolean options", () => {
665
+ test.it("should return false for boolean flag when not specified", async () => {
554
666
  const cmd = Commander
555
667
  .make({ name: "app" })
556
668
  .option(
@@ -564,10 +676,12 @@ t.describe("boolean options", () => {
564
676
  Commander.parse(cmd, []),
565
677
  )
566
678
 
567
- t.expect(result.verbose).toBe(false)
679
+ test
680
+ .expect(result.verbose)
681
+ .toBe(false)
568
682
  })
569
683
 
570
- t.it("should return true for boolean flag when specified", async () => {
684
+ test.it("should return true for boolean flag when specified", async () => {
571
685
  const cmd = Commander
572
686
  .make({ name: "app" })
573
687
  .option(
@@ -581,10 +695,12 @@ t.describe("boolean options", () => {
581
695
  Commander.parse(cmd, ["--verbose", "true"]),
582
696
  )
583
697
 
584
- t.expect(result.verbose).toBe(true)
698
+ test
699
+ .expect(result.verbose)
700
+ .toBe(true)
585
701
  })
586
702
 
587
- t.it("should handle boolean with custom default", async () => {
703
+ test.it("should handle boolean with custom default", async () => {
588
704
  const cmd = Commander
589
705
  .make({ name: "app" })
590
706
  .option(
@@ -598,12 +714,14 @@ t.describe("boolean options", () => {
598
714
  Commander.parse(cmd, []),
599
715
  )
600
716
 
601
- t.expect(result.color).toBe("auto")
717
+ test
718
+ .expect(result.color)
719
+ .toBe("auto")
602
720
  })
603
721
  })
604
722
 
605
- t.describe("options with choices", () => {
606
- t.it("should accept valid choice", async () => {
723
+ test.describe("options with choices", () => {
724
+ test.it("should accept valid choice", async () => {
607
725
  const cmd = Commander
608
726
  .make({ name: "app" })
609
727
  .option(
@@ -621,10 +739,12 @@ t.describe("options with choices", () => {
621
739
  Commander.parse(cmd, ["--color", "red"]),
622
740
  )
623
741
 
624
- t.expect(result.color).toBe("red")
742
+ test
743
+ .expect(result.color)
744
+ .toBe("red")
625
745
  })
626
746
 
627
- t.it("should reject invalid choice", async () => {
747
+ test.it("should reject invalid choice", async () => {
628
748
  const cmd = Commander
629
749
  .make({ name: "app" })
630
750
  .option(
@@ -642,10 +762,12 @@ t.describe("options with choices", () => {
642
762
  Effect.either(Commander.parse(cmd, ["--color", "yellow"])),
643
763
  )
644
764
 
645
- t.expect(result._tag).toBe("Left")
765
+ test
766
+ .expect(result._tag)
767
+ .toBe("Left")
646
768
  })
647
769
 
648
- t.it("should handle multiple choice options", async () => {
770
+ test.it("should handle multiple choice options", async () => {
649
771
  const cmd = Commander
650
772
  .make({ name: "app" })
651
773
  .option(
@@ -675,13 +797,17 @@ t.describe("options with choices", () => {
675
797
  Commander.parse(cmd, ["--format", "xml", "--level", "debug"]),
676
798
  )
677
799
 
678
- t.expect(result.format).toBe("xml")
679
- t.expect(result.level).toBe("debug")
800
+ test
801
+ .expect(result.format)
802
+ .toBe("xml")
803
+ test
804
+ .expect(result.level)
805
+ .toBe("debug")
680
806
  })
681
807
  })
682
808
 
683
- t.describe("options with defaults", () => {
684
- t.it("should use default when option not specified", async () => {
809
+ test.describe("options with defaults", () => {
810
+ test.it("should use default when option not specified", async () => {
685
811
  const cmd = Commander
686
812
  .make({ name: "app" })
687
813
  .option(
@@ -695,10 +821,12 @@ t.describe("options with defaults", () => {
695
821
  Commander.parse(cmd, []),
696
822
  )
697
823
 
698
- t.expect(result.port).toBe(3000)
824
+ test
825
+ .expect(result.port)
826
+ .toBe(3000)
699
827
  })
700
828
 
701
- t.it("should override default when option specified", async () => {
829
+ test.it("should override default when option specified", async () => {
702
830
  const cmd = Commander
703
831
  .make({ name: "app" })
704
832
  .option(
@@ -712,10 +840,12 @@ t.describe("options with defaults", () => {
712
840
  Commander.parse(cmd, ["--port", "8080"]),
713
841
  )
714
842
 
715
- t.expect(result.port).toBe(8080)
843
+ test
844
+ .expect(result.port)
845
+ .toBe(8080)
716
846
  })
717
847
 
718
- t.it("should handle multiple defaults", async () => {
848
+ test.it("should handle multiple defaults", async () => {
719
849
  const cmd = Commander
720
850
  .make({ name: "app" })
721
851
  .option(
@@ -741,12 +871,18 @@ t.describe("options with defaults", () => {
741
871
  Commander.parse(cmd, []),
742
872
  )
743
873
 
744
- t.expect(result.host).toBe("localhost")
745
- t.expect(result.port).toBe(3000)
746
- t.expect(result.debug).toBe(false)
874
+ test
875
+ .expect(result.host)
876
+ .toBe("localhost")
877
+ test
878
+ .expect(result.port)
879
+ .toBe(3000)
880
+ test
881
+ .expect(result.debug)
882
+ .toBe(false)
747
883
  })
748
884
 
749
- t.it("should use default for string option", async () => {
885
+ test.it("should use default for string option", async () => {
750
886
  const cmd = Commander
751
887
  .make({ name: "app" })
752
888
  .option(
@@ -760,12 +896,14 @@ t.describe("options with defaults", () => {
760
896
  Commander.parse(cmd, []),
761
897
  )
762
898
 
763
- t.expect(result.output).toBe("output.txt")
899
+ test
900
+ .expect(result.output)
901
+ .toBe("output.txt")
764
902
  })
765
903
  })
766
904
 
767
- t.describe("action/handler", () => {
768
- t.it("should invoke handler with parsed options", async () => {
905
+ test.describe("action/handler", () => {
906
+ test.it("should invoke handler with parsed options", async () => {
769
907
  let capturedOptions: any = null
770
908
 
771
909
  const cmd = Commander
@@ -785,10 +923,12 @@ t.describe("action/handler", () => {
785
923
  Commander.parse(cmd, ["--name", "test"]),
786
924
  )
787
925
 
788
- t.expect(parsed.name).toBe("test")
926
+ test
927
+ .expect(parsed.name)
928
+ .toBe("test")
789
929
  })
790
930
 
791
- t.it("should support async handlers", async () => {
931
+ test.it("should support async handlers", async () => {
792
932
  let executed = false
793
933
 
794
934
  const cmd = Commander
@@ -810,10 +950,12 @@ t.describe("action/handler", () => {
810
950
  Commander.parse(cmd, ["--delay", "10"]),
811
951
  )
812
952
 
813
- t.expect(executed).toBe(false)
953
+ test
954
+ .expect(executed)
955
+ .toBe(false)
814
956
  })
815
957
 
816
- t.it("should pass all options to handler", async () => {
958
+ test.it("should pass all options to handler", async () => {
817
959
  let capturedOpts: any = null
818
960
 
819
961
  const cmd = Commander
@@ -846,38 +988,50 @@ t.describe("action/handler", () => {
846
988
  })
847
989
  })
848
990
 
849
- t.describe(`${Commander.optionVersion.name} - version behavior`, () => {
850
- t.it("should include version in command definition", () => {
991
+ test.describe(`${Commander.optionVersion.name} - version behavior`, () => {
992
+ test.it("should include version in command definition", () => {
851
993
  const cmd = Commander
852
994
  .make({ name: "app", version: "1.0.0" })
853
995
  .optionVersion()
854
996
 
855
- t.expect(cmd.version).toBe("1.0.0")
856
- t.expect(cmd.options.version).toBeDefined()
997
+ test
998
+ .expect(cmd.version)
999
+ .toBe("1.0.0")
1000
+ test
1001
+ .expect(cmd.options.version)
1002
+ .toBeDefined()
857
1003
  })
858
1004
 
859
- t.it("should handle version without version option", () => {
1005
+ test.it("should handle version without version option", () => {
860
1006
  const cmd = Commander
861
1007
  .make({ name: "app", version: "2.0.0" })
862
1008
 
863
- t.expect(cmd.version).toBe("2.0.0")
864
- t.expect(cmd.options["version"]).toBeUndefined()
1009
+ test
1010
+ .expect(cmd.version)
1011
+ .toBe("2.0.0")
1012
+ test
1013
+ .expect(cmd.options["version"])
1014
+ .toBeUndefined()
865
1015
  })
866
1016
 
867
- t.it("should include version option in help", () => {
1017
+ test.it("should include version option in help", () => {
868
1018
  const cmd = Commander
869
1019
  .make({ name: "app", version: "1.0.0" })
870
1020
  .optionVersion()
871
1021
 
872
1022
  const help = Commander.help(cmd)
873
1023
 
874
- t.expect(help).toContain("--version")
875
- t.expect(help).toContain("-V")
1024
+ test
1025
+ .expect(help)
1026
+ .toContain("--version")
1027
+ test
1028
+ .expect(help)
1029
+ .toContain("-V")
876
1030
  })
877
1031
  })
878
1032
 
879
- t.describe(`${Commander.help.name} - comprehensive`, () => {
880
- t.it("should generate help with description", () => {
1033
+ test.describe(`${Commander.help.name} - comprehensive`, () => {
1034
+ test.it("should generate help with description", () => {
881
1035
  const cmd = Commander
882
1036
  .make({
883
1037
  name: "myapp",
@@ -887,11 +1041,15 @@ t.describe(`${Commander.help.name} - comprehensive`, () => {
887
1041
 
888
1042
  const help = Commander.help(cmd)
889
1043
 
890
- t.expect(help).toContain("A test application")
891
- t.expect(help).toContain("Usage: myapp [options]")
1044
+ test
1045
+ .expect(help)
1046
+ .toContain("A test application")
1047
+ test
1048
+ .expect(help)
1049
+ .toContain("Usage: myapp [options]")
892
1050
  })
893
1051
 
894
- t.it("should include all options in help", () => {
1052
+ test.it("should include all options in help", () => {
895
1053
  const cmd = Commander
896
1054
  .make({ name: "app" })
897
1055
  .option(
@@ -910,15 +1068,27 @@ t.describe(`${Commander.help.name} - comprehensive`, () => {
910
1068
 
911
1069
  const help = Commander.help(cmd)
912
1070
 
913
- t.expect(help).toContain("--input")
914
- t.expect(help).toContain("-i,")
915
- t.expect(help).toContain("Input file")
916
- t.expect(help).toContain("--output")
917
- t.expect(help).toContain("-o,")
918
- t.expect(help).toContain("Output file")
919
- })
920
-
921
- t.it("should show subcommands in help", () => {
1071
+ test
1072
+ .expect(help)
1073
+ .toContain("--input")
1074
+ test
1075
+ .expect(help)
1076
+ .toContain("-i,")
1077
+ test
1078
+ .expect(help)
1079
+ .toContain("Input file")
1080
+ test
1081
+ .expect(help)
1082
+ .toContain("--output")
1083
+ test
1084
+ .expect(help)
1085
+ .toContain("-o,")
1086
+ test
1087
+ .expect(help)
1088
+ .toContain("Output file")
1089
+ })
1090
+
1091
+ test.it("should show subcommands in help", () => {
922
1092
  const subCmd = Commander
923
1093
  .make({ name: "init", description: "Initialize project" })
924
1094
  .handle(() => Effect.void)
@@ -930,12 +1100,18 @@ t.describe(`${Commander.help.name} - comprehensive`, () => {
930
1100
 
931
1101
  const help = Commander.help(cmd)
932
1102
 
933
- t.expect(help).toContain("Commands:")
934
- t.expect(help).toContain("init")
935
- t.expect(help).toContain("Initialize project")
1103
+ test
1104
+ .expect(help)
1105
+ .toContain("Commands:")
1106
+ test
1107
+ .expect(help)
1108
+ .toContain("init")
1109
+ test
1110
+ .expect(help)
1111
+ .toContain("Initialize project")
936
1112
  })
937
1113
 
938
- t.it("should format option descriptions properly", () => {
1114
+ test.it("should format option descriptions properly", () => {
939
1115
  const cmd = Commander
940
1116
  .make({ name: "app" })
941
1117
  .option(
@@ -947,13 +1123,17 @@ t.describe(`${Commander.help.name} - comprehensive`, () => {
947
1123
 
948
1124
  const help = Commander.help(cmd)
949
1125
 
950
- t.expect(help).toContain("-c, --config")
951
- t.expect(help).toContain("Config file path")
1126
+ test
1127
+ .expect(help)
1128
+ .toContain("-c, --config")
1129
+ test
1130
+ .expect(help)
1131
+ .toContain("Config file path")
952
1132
  })
953
1133
  })
954
1134
 
955
- t.describe(`${Commander.subcommand.name} - comprehensive`, () => {
956
- t.it("should add subcommand", () => {
1135
+ test.describe(`${Commander.subcommand.name} - comprehensive`, () => {
1136
+ test.it("should add subcommand", () => {
957
1137
  const subCmd = Commander
958
1138
  .make({ name: "build" })
959
1139
  .option(
@@ -968,30 +1148,40 @@ t.describe(`${Commander.subcommand.name} - comprehensive`, () => {
968
1148
  .make({ name: "app" })
969
1149
  .subcommand(subCmd)
970
1150
 
971
- t.expect(cmd.subcommands.length).toBe(1)
972
- t.expect(cmd.subcommands[0]!.command.name).toBe("build")
1151
+ test
1152
+ .expect(cmd.subcommands.length)
1153
+ .toBe(1)
1154
+ test
1155
+ .expect(cmd.subcommands[0]!.command.name)
1156
+ .toBe("build")
973
1157
  })
974
1158
 
975
- t.it("should add multiple subcommands", () => {
1159
+ test.it("should add multiple subcommands", () => {
976
1160
  const build = Commander
977
1161
  .make({ name: "build" })
978
1162
  .handle(() => Effect.void)
979
1163
 
980
- const test = Commander
1164
+ const testCmd = Commander
981
1165
  .make({ name: "test" })
982
1166
  .handle(() => Effect.void)
983
1167
 
984
1168
  const cmd = Commander
985
1169
  .make({ name: "app" })
986
1170
  .subcommand(build)
987
- .subcommand(test)
1171
+ .subcommand(testCmd)
988
1172
 
989
- t.expect(cmd.subcommands.length).toBe(2)
990
- t.expect(cmd.subcommands[0]!.command.name).toBe("build")
991
- t.expect(cmd.subcommands[1]!.command.name).toBe("test")
1173
+ test
1174
+ .expect(cmd.subcommands.length)
1175
+ .toBe(2)
1176
+ test
1177
+ .expect(cmd.subcommands[0]!.command.name)
1178
+ .toBe("build")
1179
+ test
1180
+ .expect(cmd.subcommands[1]!.command.name)
1181
+ .toBe("test")
992
1182
  })
993
1183
 
994
- t.it("should nest subcommands", () => {
1184
+ test.it("should nest subcommands", () => {
995
1185
  const deploy = Commander
996
1186
  .make({ name: "deploy" })
997
1187
  .handle(() => Effect.void)
@@ -1005,15 +1195,17 @@ t.describe(`${Commander.subcommand.name} - comprehensive`, () => {
1005
1195
  .make({ name: "app" })
1006
1196
  .subcommand(build)
1007
1197
 
1008
- t.expect(cmd.subcommands[0]!.command.subcommands.length).toBe(1)
1009
- t.expect(cmd.subcommands[0]!.command.subcommands[0]!.command.name).toBe(
1010
- "deploy",
1011
- )
1198
+ test
1199
+ .expect(cmd.subcommands[0]!.command.subcommands.length)
1200
+ .toBe(1)
1201
+ test
1202
+ .expect(cmd.subcommands[0]!.command.subcommands[0]!.command.name)
1203
+ .toBe("deploy")
1012
1204
  })
1013
1205
  })
1014
1206
 
1015
- t.describe("option types", () => {
1016
- t.it("should parse string option", async () => {
1207
+ test.describe("option types", () => {
1208
+ test.it("should parse string option", async () => {
1017
1209
  const cmd = Commander
1018
1210
  .make({ name: "app" })
1019
1211
  .option(
@@ -1026,11 +1218,15 @@ t.describe("option types", () => {
1026
1218
  Commander.parse(cmd, ["--name", "test"]),
1027
1219
  )
1028
1220
 
1029
- t.expect(result.name).toBe("test")
1030
- t.expect(typeof result.name).toBe("string")
1221
+ test
1222
+ .expect(result.name)
1223
+ .toBe("test")
1224
+ test
1225
+ .expect(typeof result.name)
1226
+ .toBe("string")
1031
1227
  })
1032
1228
 
1033
- t.it("should parse number option", async () => {
1229
+ test.it("should parse number option", async () => {
1034
1230
  const cmd = Commander
1035
1231
  .make({ name: "app" })
1036
1232
  .option(
@@ -1043,11 +1239,15 @@ t.describe("option types", () => {
1043
1239
  Commander.parse(cmd, ["--count", "42"]),
1044
1240
  )
1045
1241
 
1046
- t.expect(result.count).toBe(42)
1047
- t.expect(typeof result.count).toBe("number")
1242
+ test
1243
+ .expect(result.count)
1244
+ .toBe(42)
1245
+ test
1246
+ .expect(typeof result.count)
1247
+ .toBe("number")
1048
1248
  })
1049
1249
 
1050
- t.it("should parse boolean option", async () => {
1250
+ test.it("should parse boolean option", async () => {
1051
1251
  const cmd = Commander
1052
1252
  .make({ name: "app" })
1053
1253
  .option(
@@ -1060,11 +1260,15 @@ t.describe("option types", () => {
1060
1260
  Commander.parse(cmd, ["--enabled", "true"]),
1061
1261
  )
1062
1262
 
1063
- t.expect(result.enabled).toBe(true)
1064
- t.expect(typeof result.enabled).toBe("boolean")
1263
+ test
1264
+ .expect(result.enabled)
1265
+ .toBe(true)
1266
+ test
1267
+ .expect(typeof result.enabled)
1268
+ .toBe("boolean")
1065
1269
  })
1066
1270
 
1067
- t.it("should fail on invalid number", async () => {
1271
+ test.it("should fail on invalid number", async () => {
1068
1272
  const cmd = Commander
1069
1273
  .make({ name: "app" })
1070
1274
  .option(
@@ -1077,12 +1281,14 @@ t.describe("option types", () => {
1077
1281
  Effect.either(Commander.parse(cmd, ["--count", "not-a-number"])),
1078
1282
  )
1079
1283
 
1080
- t.expect(result._tag).toBe("Left")
1284
+ test
1285
+ .expect(result._tag)
1286
+ .toBe("Left")
1081
1287
  })
1082
1288
  })
1083
1289
 
1084
- t.describe("complex scenarios", () => {
1085
- t.it("should handle mixed option types", async () => {
1290
+ test.describe("complex scenarios", () => {
1291
+ test.it("should handle mixed option types", async () => {
1086
1292
  const cmd = Commander
1087
1293
  .make({ name: "server" })
1088
1294
  .option(
@@ -1128,13 +1334,21 @@ t.describe("complex scenarios", () => {
1128
1334
  ]),
1129
1335
  )
1130
1336
 
1131
- t.expect(result.host).toBe("0.0.0.0")
1132
- t.expect(result.port).toBe(8080)
1133
- t.expect(result.ssl).toBe(true)
1134
- t.expect(result.env).toBe("production")
1135
- })
1136
-
1137
- t.it("should handle repeatable options", async () => {
1337
+ test
1338
+ .expect(result.host)
1339
+ .toBe("0.0.0.0")
1340
+ test
1341
+ .expect(result.port)
1342
+ .toBe(8080)
1343
+ test
1344
+ .expect(result.ssl)
1345
+ .toBe(true)
1346
+ test
1347
+ .expect(result.env)
1348
+ .toBe("production")
1349
+ })
1350
+
1351
+ test.it("should handle repeatable options", async () => {
1138
1352
  const cmd = Commander
1139
1353
  .make({ name: "app" })
1140
1354
  .option(
@@ -1147,10 +1361,12 @@ t.describe("complex scenarios", () => {
1147
1361
  Commander.parse(cmd, ["--tags", "foo,bar,baz"]),
1148
1362
  )
1149
1363
 
1150
- t.expect(result.tags).toEqual(["foo", "bar", "baz"])
1364
+ test
1365
+ .expect(result.tags)
1366
+ .toEqual(["foo", "bar", "baz"])
1151
1367
  })
1152
1368
 
1153
- t.it("should preserve option order independence", async () => {
1369
+ test.it("should preserve option order independence", async () => {
1154
1370
  const cmd = Commander
1155
1371
  .make({ name: "app" })
1156
1372
  .option(
@@ -1172,13 +1388,21 @@ t.describe("complex scenarios", () => {
1172
1388
  Commander.parse(cmd, ["--second", "2", "--first", "1"]),
1173
1389
  )
1174
1390
 
1175
- t.expect(result1.first).toBe("1")
1176
- t.expect(result1.second).toBe("2")
1177
- t.expect(result2.first).toBe("1")
1178
- t.expect(result2.second).toBe("2")
1179
- })
1180
-
1181
- t.it("should handle options with hyphens in names", async () => {
1391
+ test
1392
+ .expect(result1.first)
1393
+ .toBe("1")
1394
+ test
1395
+ .expect(result1.second)
1396
+ .toBe("2")
1397
+ test
1398
+ .expect(result2.first)
1399
+ .toBe("1")
1400
+ test
1401
+ .expect(result2.second)
1402
+ .toBe("2")
1403
+ })
1404
+
1405
+ test.it("should handle options with hyphens in names", async () => {
1182
1406
  const cmd = Commander
1183
1407
  .make({ name: "app" })
1184
1408
  .option(
@@ -1198,13 +1422,17 @@ t.describe("complex scenarios", () => {
1198
1422
  Commander.parse(cmd, ["--dry-run", "true", "--no-cache", "true"]),
1199
1423
  )
1200
1424
 
1201
- t.expect(result.dryRun).toBe(true)
1202
- t.expect(result.noCache).toBe(true)
1425
+ test
1426
+ .expect(result.dryRun)
1427
+ .toBe(true)
1428
+ test
1429
+ .expect(result.noCache)
1430
+ .toBe(true)
1203
1431
  })
1204
1432
  })
1205
1433
 
1206
- t.describe("error handling", () => {
1207
- t.it("should fail gracefully on invalid option value", async () => {
1434
+ test.describe("error handling", () => {
1435
+ test.it("should fail gracefully on invalid option value", async () => {
1208
1436
  const cmd = Commander
1209
1437
  .make({ name: "app" })
1210
1438
  .option(
@@ -1218,10 +1446,12 @@ t.describe("error handling", () => {
1218
1446
  )
1219
1447
 
1220
1448
  assert.strictEqual(result._tag, "Left")
1221
- t.expect(result.left.message).toContain("Invalid value")
1449
+ test
1450
+ .expect(result.left.message)
1451
+ .toContain("Invalid value")
1222
1452
  })
1223
1453
 
1224
- t.it("should fail on invalid choice", async () => {
1454
+ test.it("should fail on invalid choice", async () => {
1225
1455
  const cmd = Commander
1226
1456
  .make({ name: "app" })
1227
1457
  .option(
@@ -1234,12 +1464,14 @@ t.describe("error handling", () => {
1234
1464
  Effect.either(Commander.parse(cmd, ["--mode", "staging"])),
1235
1465
  )
1236
1466
 
1237
- t.expect(result._tag).toBe("Left")
1467
+ test
1468
+ .expect(result._tag)
1469
+ .toBe("Left")
1238
1470
  })
1239
1471
  })
1240
1472
 
1241
- t.describe("builder pattern", () => {
1242
- t.it("should chain option definitions fluently", () => {
1473
+ test.describe("builder pattern", () => {
1474
+ test.it("should chain option definitions fluently", () => {
1243
1475
  const cmd = Commander
1244
1476
  .make({ name: "app" })
1245
1477
  .option(
@@ -1256,12 +1488,18 @@ t.describe("builder pattern", () => {
1256
1488
  .schema(Schema.String),
1257
1489
  )
1258
1490
 
1259
- t.expect(cmd.options.input.description).toBe("Input file")
1260
- t.expect(cmd.options.output.description).toBe("Output file")
1261
- t.expect(cmd.options.output.defaultValue).toBe("out.txt")
1491
+ test
1492
+ .expect(cmd.options.input.description)
1493
+ .toBe("Input file")
1494
+ test
1495
+ .expect(cmd.options.output.description)
1496
+ .toBe("Output file")
1497
+ test
1498
+ .expect(cmd.options.output.defaultValue)
1499
+ .toBe("out.txt")
1262
1500
  })
1263
1501
 
1264
- t.it("should chain description and default in any order", () => {
1502
+ test.it("should chain description and default in any order", () => {
1265
1503
  const cmd1 = Commander
1266
1504
  .make({ name: "app" })
1267
1505
  .option(
@@ -1282,13 +1520,21 @@ t.describe("builder pattern", () => {
1282
1520
  .schema(Commander.NumberFromString),
1283
1521
  )
1284
1522
 
1285
- t.expect(cmd1.options.port.description).toBe("Port number")
1286
- t.expect(cmd1.options.port.defaultValue).toBe(3000)
1287
- t.expect(cmd2.options.port.description).toBe("Port number")
1288
- t.expect(cmd2.options.port.defaultValue).toBe(3000)
1523
+ test
1524
+ .expect(cmd1.options.port.description)
1525
+ .toBe("Port number")
1526
+ test
1527
+ .expect(cmd1.options.port.defaultValue)
1528
+ .toBe(3000)
1529
+ test
1530
+ .expect(cmd2.options.port.description)
1531
+ .toBe("Port number")
1532
+ test
1533
+ .expect(cmd2.options.port.defaultValue)
1534
+ .toBe(3000)
1289
1535
  })
1290
1536
 
1291
- t.it("should support method chaining with subcommands", () => {
1537
+ test.it("should support method chaining with subcommands", () => {
1292
1538
  const sub1 = Commander
1293
1539
  .make({ name: "sub1" })
1294
1540
  .handle(() => Effect.void)
@@ -1308,14 +1554,20 @@ t.describe("builder pattern", () => {
1308
1554
  .subcommand(sub2)
1309
1555
  .optionHelp()
1310
1556
 
1311
- t.expect(cmd.options.global).toBeDefined()
1312
- t.expect(cmd.options.help).toBeDefined()
1313
- t.expect(cmd.subcommands.length).toBe(2)
1557
+ test
1558
+ .expect(cmd.options.global)
1559
+ .toBeDefined()
1560
+ test
1561
+ .expect(cmd.options.help)
1562
+ .toBeDefined()
1563
+ test
1564
+ .expect(cmd.subcommands.length)
1565
+ .toBe(2)
1314
1566
  })
1315
1567
  })
1316
1568
 
1317
- t.describe("example scenario", () => {
1318
- t.it("should handle main command with subcommand", async () => {
1569
+ test.describe("example scenario", () => {
1570
+ test.it("should handle main command with subcommand", async () => {
1319
1571
  const unhandledFormat = Commander.make({
1320
1572
  name: "format",
1321
1573
  description: "Format source files",
@@ -1362,16 +1614,26 @@ t.describe("example scenario", () => {
1362
1614
  Commander.parse(main, ["--source", "test.ts", "--verbose", "true"]),
1363
1615
  )
1364
1616
 
1365
- t.expect(resultMain.source).toBe("test.ts")
1366
- t.expect(resultMain.verbose).toBe(true)
1367
- t.expect(resultMain.help).toBe(false)
1368
-
1369
- t.expect(main.subcommands.length).toBe(1)
1370
- t.expect(main.subcommands[0]!.command.name).toBe("format")
1371
-
1372
- t.expect(main.subcommands[0]!.command.options.style).toBeDefined()
1373
- t.expect(main.subcommands[0]!.command.options.style.defaultValue).toBe(
1374
- "standard",
1375
- )
1617
+ test
1618
+ .expect(resultMain.source)
1619
+ .toBe("test.ts")
1620
+ test
1621
+ .expect(resultMain.verbose)
1622
+ .toBe(true)
1623
+ test
1624
+ .expect(resultMain.help)
1625
+ .toBe(false)
1626
+ test
1627
+ .expect(main.subcommands.length)
1628
+ .toBe(1)
1629
+ test
1630
+ .expect(main.subcommands[0]!.command.name)
1631
+ .toBe("format")
1632
+ test
1633
+ .expect(main.subcommands[0]!.command.options.style)
1634
+ .toBeDefined()
1635
+ test
1636
+ .expect(main.subcommands[0]!.command.options.style.defaultValue)
1637
+ .toBe("standard")
1376
1638
  })
1377
1639
  })