@optique/testing 1.3.0-dev.2488 → 1.3.0-dev.2497

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.
package/README.md CHANGED
@@ -18,6 +18,60 @@ visible from its import:
18
18
  The package root holds only the contracts that mean the same thing at more than
19
19
  one boundary. It depends on no test framework and no assertion library.
20
20
 
21
+ The parser layer is available through `parseArgs()` and `parseArgsSync()`:
22
+
23
+ ~~~~ typescript
24
+ import { option } from "@optique/core/primitives";
25
+ import { parseArgsSync } from "@optique/testing/parser";
26
+
27
+ const result = parseArgsSync(option("--verbose"), ["--verbose"]);
28
+ if (result.success) {
29
+ console.log(result.value);
30
+ } else {
31
+ console.error(result.error, result.remainingArgs, result.commandPath);
32
+ }
33
+ ~~~~
34
+
35
+ The runner layer is available through `captureRun()`:
36
+
37
+ ~~~~ typescript
38
+ import { argument } from "@optique/core/primitives";
39
+ import { string } from "@optique/core/valueparser";
40
+ import { captureRun } from "@optique/testing/run";
41
+
42
+ const result = await captureRun(argument(string()), {
43
+ args: ["--help"],
44
+ programName: "greet",
45
+ help: "option",
46
+ colors: false,
47
+ maxWidth: 80,
48
+ });
49
+
50
+ console.log(result.kind, result.exitCode, result.stdout, result.stderr);
51
+ ~~~~
52
+
53
+ Use `captureProgramRun()` to include command discovery and handler dispatch:
54
+
55
+ ~~~~ typescript
56
+ import { captureProgramRun } from "@optique/testing/discover";
57
+
58
+ const result = await captureProgramRun({
59
+ dir: new URL("./commands/", import.meta.url),
60
+ metadata: { name: "example" },
61
+ args: ["--help"],
62
+ colors: false,
63
+ maxWidth: 80,
64
+ });
65
+
66
+ console.log(result.exitCode, result.stdout, result.stderr);
67
+ ~~~~
68
+
69
+ The helper runs real command modules, hooks, and handlers. It captures
70
+ Optique's output callbacks; direct console or process-stream writes bypass
71
+ capture. Unexpected errors reject the promise.
72
+
73
+ The child-process entry point remains reserved while its helpers are developed.
74
+
21
75
  [Optique]: https://optique.dev/
22
76
 
23
77
 
@@ -0,0 +1,30 @@
1
+ //#region rolldown:runtime
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
10
+ key = keys[i];
11
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
12
+ get: ((k) => from[k]).bind(null, key),
13
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
14
+ });
15
+ }
16
+ return to;
17
+ };
18
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
19
+ value: mod,
20
+ enumerable: true
21
+ }) : target, mod));
22
+
23
+ //#endregion
24
+
25
+ Object.defineProperty(exports, '__toESM', {
26
+ enumerable: true,
27
+ get: function () {
28
+ return __toESM;
29
+ }
30
+ });
package/dist/discover.cjs CHANGED
@@ -0,0 +1,66 @@
1
+ const require_chunk = require('./chunk-CUT6urMc.cjs');
2
+ const __optique_discover = require_chunk.__toESM(require("@optique/discover"));
3
+
4
+ //#region src/discover.ts
5
+ /**
6
+ * Runs a command program in process and captures Optique-controlled output.
7
+ *
8
+ * Discovery, hooks, and command handlers execute normally. Help, version,
9
+ * completion, and parse-error exits become results; other errors continue to
10
+ * reject as they do in `runProgram()`. Writes through `console.log()`,
11
+ * `print()`, or process streams bypass the injected callbacks and are not
12
+ * captured. Each callback write includes the default writer's trailing newline.
13
+ *
14
+ * Options retain `runProgram()`'s defaults, including process arguments and
15
+ * terminal-dependent colors and width. Set `args`, `colors`, and `maxWidth`
16
+ * explicitly for deterministic tests.
17
+ *
18
+ * @template R The resource made available by program-level lifecycle hooks.
19
+ * @param options Program options other than the captured callbacks.
20
+ * @returns Captured output and the exit code after execution completes.
21
+ * @throws Any error propagated by `runProgram()`, including discovery, parser,
22
+ * hook, handler, callback, and context disposal failures.
23
+ * @since 1.3.0
24
+ */
25
+ async function captureProgramRun(options) {
26
+ class ProgramExit extends Error {
27
+ exitCode;
28
+ constructor(exitCode) {
29
+ super(`Program exited with code ${exitCode}.`);
30
+ this.name = "ProgramExit";
31
+ this.exitCode = exitCode;
32
+ }
33
+ }
34
+ let stdout = "";
35
+ let stderr = "";
36
+ const runOptions = {
37
+ ...options,
38
+ stdout(text) {
39
+ stdout += `${text}\n`;
40
+ },
41
+ stderr(text) {
42
+ stderr += `${text}\n`;
43
+ },
44
+ onExit(exitCode) {
45
+ throw new ProgramExit(exitCode);
46
+ }
47
+ };
48
+ try {
49
+ await (0, __optique_discover.runProgram)(runOptions);
50
+ return {
51
+ exitCode: 0,
52
+ stdout,
53
+ stderr
54
+ };
55
+ } catch (error) {
56
+ if (!(error instanceof ProgramExit)) throw error;
57
+ return {
58
+ exitCode: error.exitCode,
59
+ stdout,
60
+ stderr
61
+ };
62
+ }
63
+ }
64
+
65
+ //#endregion
66
+ exports.captureProgramRun = captureProgramRun;
@@ -1 +1,54 @@
1
- export { };
1
+ import { CapturedOutput } from "./index-Cuf92ZIO.cjs";
2
+ import { RunProgramOptions } from "@optique/discover";
3
+
4
+ //#region src/discover.d.ts
5
+
6
+ type DistributiveOmit<T, K extends PropertyKey> = T extends unknown ? Omit<T, K> : never;
7
+ /**
8
+ * Options for {@link captureProgramRun}, preserving the command source union
9
+ * and program hook resource type of `RunProgramOptions`.
10
+ *
11
+ * Output and exit callbacks are controlled by the capture helper.
12
+ *
13
+ * @template R The resource made available by program-level lifecycle hooks.
14
+ * @since 1.3.0
15
+ */
16
+ type CaptureProgramRunOptions<R = unknown> = DistributiveOmit<RunProgramOptions<R>, "stdout" | "stderr" | "onExit"> & {
17
+ readonly stdout?: never;
18
+ readonly stderr?: never;
19
+ readonly onExit?: never;
20
+ };
21
+ /**
22
+ * Captured output and exit code from a command program execution.
23
+ *
24
+ * @since 1.3.0
25
+ */
26
+ interface ProgramRunResult extends CapturedOutput {
27
+ /**
28
+ * Zero after normal completion, or the code requested by an intentional exit.
29
+ */
30
+ readonly exitCode: number;
31
+ }
32
+ /**
33
+ * Runs a command program in process and captures Optique-controlled output.
34
+ *
35
+ * Discovery, hooks, and command handlers execute normally. Help, version,
36
+ * completion, and parse-error exits become results; other errors continue to
37
+ * reject as they do in `runProgram()`. Writes through `console.log()`,
38
+ * `print()`, or process streams bypass the injected callbacks and are not
39
+ * captured. Each callback write includes the default writer's trailing newline.
40
+ *
41
+ * Options retain `runProgram()`'s defaults, including process arguments and
42
+ * terminal-dependent colors and width. Set `args`, `colors`, and `maxWidth`
43
+ * explicitly for deterministic tests.
44
+ *
45
+ * @template R The resource made available by program-level lifecycle hooks.
46
+ * @param options Program options other than the captured callbacks.
47
+ * @returns Captured output and the exit code after execution completes.
48
+ * @throws Any error propagated by `runProgram()`, including discovery, parser,
49
+ * hook, handler, callback, and context disposal failures.
50
+ * @since 1.3.0
51
+ */
52
+ declare function captureProgramRun<R = unknown>(options: CaptureProgramRunOptions<R>): Promise<ProgramRunResult>;
53
+ //#endregion
54
+ export { CaptureProgramRunOptions, ProgramRunResult, captureProgramRun };
@@ -1 +1,54 @@
1
- export { };
1
+ import { CapturedOutput } from "./index-t_PHSvz_.js";
2
+ import { RunProgramOptions } from "@optique/discover";
3
+
4
+ //#region src/discover.d.ts
5
+
6
+ type DistributiveOmit<T, K extends PropertyKey> = T extends unknown ? Omit<T, K> : never;
7
+ /**
8
+ * Options for {@link captureProgramRun}, preserving the command source union
9
+ * and program hook resource type of `RunProgramOptions`.
10
+ *
11
+ * Output and exit callbacks are controlled by the capture helper.
12
+ *
13
+ * @template R The resource made available by program-level lifecycle hooks.
14
+ * @since 1.3.0
15
+ */
16
+ type CaptureProgramRunOptions<R = unknown> = DistributiveOmit<RunProgramOptions<R>, "stdout" | "stderr" | "onExit"> & {
17
+ readonly stdout?: never;
18
+ readonly stderr?: never;
19
+ readonly onExit?: never;
20
+ };
21
+ /**
22
+ * Captured output and exit code from a command program execution.
23
+ *
24
+ * @since 1.3.0
25
+ */
26
+ interface ProgramRunResult extends CapturedOutput {
27
+ /**
28
+ * Zero after normal completion, or the code requested by an intentional exit.
29
+ */
30
+ readonly exitCode: number;
31
+ }
32
+ /**
33
+ * Runs a command program in process and captures Optique-controlled output.
34
+ *
35
+ * Discovery, hooks, and command handlers execute normally. Help, version,
36
+ * completion, and parse-error exits become results; other errors continue to
37
+ * reject as they do in `runProgram()`. Writes through `console.log()`,
38
+ * `print()`, or process streams bypass the injected callbacks and are not
39
+ * captured. Each callback write includes the default writer's trailing newline.
40
+ *
41
+ * Options retain `runProgram()`'s defaults, including process arguments and
42
+ * terminal-dependent colors and width. Set `args`, `colors`, and `maxWidth`
43
+ * explicitly for deterministic tests.
44
+ *
45
+ * @template R The resource made available by program-level lifecycle hooks.
46
+ * @param options Program options other than the captured callbacks.
47
+ * @returns Captured output and the exit code after execution completes.
48
+ * @throws Any error propagated by `runProgram()`, including discovery, parser,
49
+ * hook, handler, callback, and context disposal failures.
50
+ * @since 1.3.0
51
+ */
52
+ declare function captureProgramRun<R = unknown>(options: CaptureProgramRunOptions<R>): Promise<ProgramRunResult>;
53
+ //#endregion
54
+ export { CaptureProgramRunOptions, ProgramRunResult, captureProgramRun };
package/dist/discover.js CHANGED
@@ -0,0 +1,65 @@
1
+ import { runProgram } from "@optique/discover";
2
+
3
+ //#region src/discover.ts
4
+ /**
5
+ * Runs a command program in process and captures Optique-controlled output.
6
+ *
7
+ * Discovery, hooks, and command handlers execute normally. Help, version,
8
+ * completion, and parse-error exits become results; other errors continue to
9
+ * reject as they do in `runProgram()`. Writes through `console.log()`,
10
+ * `print()`, or process streams bypass the injected callbacks and are not
11
+ * captured. Each callback write includes the default writer's trailing newline.
12
+ *
13
+ * Options retain `runProgram()`'s defaults, including process arguments and
14
+ * terminal-dependent colors and width. Set `args`, `colors`, and `maxWidth`
15
+ * explicitly for deterministic tests.
16
+ *
17
+ * @template R The resource made available by program-level lifecycle hooks.
18
+ * @param options Program options other than the captured callbacks.
19
+ * @returns Captured output and the exit code after execution completes.
20
+ * @throws Any error propagated by `runProgram()`, including discovery, parser,
21
+ * hook, handler, callback, and context disposal failures.
22
+ * @since 1.3.0
23
+ */
24
+ async function captureProgramRun(options) {
25
+ class ProgramExit extends Error {
26
+ exitCode;
27
+ constructor(exitCode) {
28
+ super(`Program exited with code ${exitCode}.`);
29
+ this.name = "ProgramExit";
30
+ this.exitCode = exitCode;
31
+ }
32
+ }
33
+ let stdout = "";
34
+ let stderr = "";
35
+ const runOptions = {
36
+ ...options,
37
+ stdout(text) {
38
+ stdout += `${text}\n`;
39
+ },
40
+ stderr(text) {
41
+ stderr += `${text}\n`;
42
+ },
43
+ onExit(exitCode) {
44
+ throw new ProgramExit(exitCode);
45
+ }
46
+ };
47
+ try {
48
+ await runProgram(runOptions);
49
+ return {
50
+ exitCode: 0,
51
+ stdout,
52
+ stderr
53
+ };
54
+ } catch (error) {
55
+ if (!(error instanceof ProgramExit)) throw error;
56
+ return {
57
+ exitCode: error.exitCode,
58
+ stdout,
59
+ stderr
60
+ };
61
+ }
62
+ }
63
+
64
+ //#endregion
65
+ export { captureProgramRun };
@@ -0,0 +1,46 @@
1
+ //#region src/index.d.ts
2
+ /**
3
+ * Testing support for Optique command-line interfaces.
4
+ *
5
+ * An Optique application can be exercised at four distinct execution
6
+ * boundaries, and this package gives each one its own entry point:
7
+ *
8
+ * - `@optique/testing/parser` runs a parser against an argument list without
9
+ * help rendering, process integration, or command dispatch.
10
+ * - `@optique/testing/run` captures what `run()` and `runAsync()` write
11
+ * through their injected output callbacks, along with intentional exits.
12
+ * - `@optique/testing/discover` captures a `runProgram()` invocation,
13
+ * including command discovery and handler dispatch.
14
+ * - `@optique/testing/cli` invokes a real CLI entry point in a child process.
15
+ *
16
+ * This module holds only the contracts that mean the same thing at more than
17
+ * one of those boundaries. Results that differ by layer—parsed values,
18
+ * intentional exits, terminating signals—belong to the subpath that produces
19
+ * them.
20
+ *
21
+ * @module
22
+ * @since 1.3.0
23
+ */
24
+ /**
25
+ * Text captured from a program's standard output and standard error streams.
26
+ *
27
+ * The two streams are kept apart and their text is preserved exactly, so a
28
+ * test can assert on trailing newlines and on which stream a message reached.
29
+ * Each layer documents how it fills these fields: the in-process layers
30
+ * accumulate the text their injected writers receive, while the subprocess
31
+ * layer decodes whatever the child actually wrote.
32
+ *
33
+ * @since 1.3.0
34
+ */
35
+ interface CapturedOutput {
36
+ /**
37
+ * The text written to standard output. Empty when nothing was written.
38
+ */
39
+ readonly stdout: string;
40
+ /**
41
+ * The text written to standard error. Empty when nothing was written.
42
+ */
43
+ readonly stderr: string;
44
+ }
45
+ //#endregion
46
+ export { CapturedOutput };
@@ -0,0 +1,46 @@
1
+ //#region src/index.d.ts
2
+ /**
3
+ * Testing support for Optique command-line interfaces.
4
+ *
5
+ * An Optique application can be exercised at four distinct execution
6
+ * boundaries, and this package gives each one its own entry point:
7
+ *
8
+ * - `@optique/testing/parser` runs a parser against an argument list without
9
+ * help rendering, process integration, or command dispatch.
10
+ * - `@optique/testing/run` captures what `run()` and `runAsync()` write
11
+ * through their injected output callbacks, along with intentional exits.
12
+ * - `@optique/testing/discover` captures a `runProgram()` invocation,
13
+ * including command discovery and handler dispatch.
14
+ * - `@optique/testing/cli` invokes a real CLI entry point in a child process.
15
+ *
16
+ * This module holds only the contracts that mean the same thing at more than
17
+ * one of those boundaries. Results that differ by layer—parsed values,
18
+ * intentional exits, terminating signals—belong to the subpath that produces
19
+ * them.
20
+ *
21
+ * @module
22
+ * @since 1.3.0
23
+ */
24
+ /**
25
+ * Text captured from a program's standard output and standard error streams.
26
+ *
27
+ * The two streams are kept apart and their text is preserved exactly, so a
28
+ * test can assert on trailing newlines and on which stream a message reached.
29
+ * Each layer documents how it fills these fields: the in-process layers
30
+ * accumulate the text their injected writers receive, while the subprocess
31
+ * layer decodes whatever the child actually wrote.
32
+ *
33
+ * @since 1.3.0
34
+ */
35
+ interface CapturedOutput {
36
+ /**
37
+ * The text written to standard output. Empty when nothing was written.
38
+ */
39
+ readonly stdout: string;
40
+ /**
41
+ * The text written to standard error. Empty when nothing was written.
42
+ */
43
+ readonly stderr: string;
44
+ }
45
+ //#endregion
46
+ export { CapturedOutput };
package/dist/index.d.cts CHANGED
@@ -1,46 +1,2 @@
1
- //#region src/index.d.ts
2
- /**
3
- * Testing support for Optique command-line interfaces.
4
- *
5
- * An Optique application can be exercised at four distinct execution
6
- * boundaries, and this package gives each one its own entry point:
7
- *
8
- * - `@optique/testing/parser` runs a parser against an argument list without
9
- * help rendering, process integration, or command dispatch.
10
- * - `@optique/testing/run` captures what `run()` and `runAsync()` write
11
- * through their injected output callbacks, along with intentional exits.
12
- * - `@optique/testing/discover` captures a `runProgram()` invocation,
13
- * including command discovery and handler dispatch.
14
- * - `@optique/testing/cli` invokes a real CLI entry point in a child process.
15
- *
16
- * This module holds only the contracts that mean the same thing at more than
17
- * one of those boundaries. Results that differ by layer—parsed values,
18
- * intentional exits, terminating signals—belong to the subpath that produces
19
- * them.
20
- *
21
- * @module
22
- * @since 1.3.0
23
- */
24
- /**
25
- * Text captured from a program's standard output and standard error streams.
26
- *
27
- * The two streams are kept apart and their text is preserved exactly, so a
28
- * test can assert on trailing newlines and on which stream a message reached.
29
- * Each layer documents how it fills these fields: the in-process layers
30
- * accumulate the text their injected writers receive, while the subprocess
31
- * layer decodes whatever the child actually wrote.
32
- *
33
- * @since 1.3.0
34
- */
35
- interface CapturedOutput {
36
- /**
37
- * The text written to standard output. Empty when nothing was written.
38
- */
39
- readonly stdout: string;
40
- /**
41
- * The text written to standard error. Empty when nothing was written.
42
- */
43
- readonly stderr: string;
44
- }
45
- //#endregion
1
+ import { CapturedOutput } from "./index-Cuf92ZIO.cjs";
46
2
  export { CapturedOutput };
package/dist/index.d.ts CHANGED
@@ -1,46 +1,2 @@
1
- //#region src/index.d.ts
2
- /**
3
- * Testing support for Optique command-line interfaces.
4
- *
5
- * An Optique application can be exercised at four distinct execution
6
- * boundaries, and this package gives each one its own entry point:
7
- *
8
- * - `@optique/testing/parser` runs a parser against an argument list without
9
- * help rendering, process integration, or command dispatch.
10
- * - `@optique/testing/run` captures what `run()` and `runAsync()` write
11
- * through their injected output callbacks, along with intentional exits.
12
- * - `@optique/testing/discover` captures a `runProgram()` invocation,
13
- * including command discovery and handler dispatch.
14
- * - `@optique/testing/cli` invokes a real CLI entry point in a child process.
15
- *
16
- * This module holds only the contracts that mean the same thing at more than
17
- * one of those boundaries. Results that differ by layer—parsed values,
18
- * intentional exits, terminating signals—belong to the subpath that produces
19
- * them.
20
- *
21
- * @module
22
- * @since 1.3.0
23
- */
24
- /**
25
- * Text captured from a program's standard output and standard error streams.
26
- *
27
- * The two streams are kept apart and their text is preserved exactly, so a
28
- * test can assert on trailing newlines and on which stream a message reached.
29
- * Each layer documents how it fills these fields: the in-process layers
30
- * accumulate the text their injected writers receive, while the subprocess
31
- * layer decodes whatever the child actually wrote.
32
- *
33
- * @since 1.3.0
34
- */
35
- interface CapturedOutput {
36
- /**
37
- * The text written to standard output. Empty when nothing was written.
38
- */
39
- readonly stdout: string;
40
- /**
41
- * The text written to standard error. Empty when nothing was written.
42
- */
43
- readonly stderr: string;
44
- }
45
- //#endregion
1
+ import { CapturedOutput } from "./index-t_PHSvz_.js";
46
2
  export { CapturedOutput };
package/dist/parser.cjs CHANGED
@@ -0,0 +1,44 @@
1
+ const require_chunk = require('./chunk-CUT6urMc.cjs');
2
+ const __optique_core_parser = require_chunk.__toESM(require("@optique/core/parser"));
3
+
4
+ //#region src/parser.ts
5
+ /**
6
+ * Parses a complete argument list and always returns a promise.
7
+ *
8
+ * Parser failures are returned as structured values. Exceptions thrown by a
9
+ * parser, or rejections from an asynchronous parser, reject the returned
10
+ * promise.
11
+ *
12
+ * @template TParser The parser type, including its inferred result value.
13
+ * @param parser The parser to exercise.
14
+ * @param args The complete argument list to parse.
15
+ * @param options Optional parser annotations.
16
+ * @returns A promise resolving to the parsed value or structured failure.
17
+ * @since 1.3.0
18
+ */
19
+ async function parseArgs(parser, args, options) {
20
+ return await (0, __optique_core_parser.parseDetailed)(parser, args, options);
21
+ }
22
+ /**
23
+ * Parses a complete argument list with a synchronous parser.
24
+ *
25
+ * Parser failures are returned as structured values. Exceptions thrown by a
26
+ * parser propagate to the caller.
27
+ *
28
+ * @template TParser The synchronous parser type, including its inferred result
29
+ * value.
30
+ * @param parser The synchronous parser to exercise.
31
+ * @param args The complete argument list to parse.
32
+ * @param options Optional parser annotations.
33
+ * @returns The parsed value or structured failure.
34
+ * @throws {TypeError} When called with an asynchronous parser at runtime.
35
+ * @since 1.3.0
36
+ */
37
+ function parseArgsSync(parser, args, options) {
38
+ if (parser.mode !== "sync") throw new TypeError("Cannot use an async parser with parseArgsSync(). Use parseArgs() instead.");
39
+ return (0, __optique_core_parser.parseDetailed)(parser, args, options);
40
+ }
41
+
42
+ //#endregion
43
+ exports.parseArgs = parseArgs;
44
+ exports.parseArgsSync = parseArgsSync;
package/dist/parser.d.cts CHANGED
@@ -1 +1,44 @@
1
- export { };
1
+ import { DetailedParseResult, InferValue, Mode, ParseOptions, Parser } from "@optique/core/parser";
2
+
3
+ //#region src/parser.d.ts
4
+
5
+ /**
6
+ * The result of parsing a complete argument list in a parser-layer test.
7
+ *
8
+ * @template T The inferred parser value type.
9
+ * @since 1.3.0
10
+ */
11
+ type ParseArgsResult<T> = DetailedParseResult<T>;
12
+ /**
13
+ * Parses a complete argument list and always returns a promise.
14
+ *
15
+ * Parser failures are returned as structured values. Exceptions thrown by a
16
+ * parser, or rejections from an asynchronous parser, reject the returned
17
+ * promise.
18
+ *
19
+ * @template TParser The parser type, including its inferred result value.
20
+ * @param parser The parser to exercise.
21
+ * @param args The complete argument list to parse.
22
+ * @param options Optional parser annotations.
23
+ * @returns A promise resolving to the parsed value or structured failure.
24
+ * @since 1.3.0
25
+ */
26
+ declare function parseArgs<TParser extends Parser<Mode, unknown, unknown>>(parser: TParser, args: readonly string[], options?: ParseOptions): Promise<ParseArgsResult<InferValue<TParser>>>;
27
+ /**
28
+ * Parses a complete argument list with a synchronous parser.
29
+ *
30
+ * Parser failures are returned as structured values. Exceptions thrown by a
31
+ * parser propagate to the caller.
32
+ *
33
+ * @template TParser The synchronous parser type, including its inferred result
34
+ * value.
35
+ * @param parser The synchronous parser to exercise.
36
+ * @param args The complete argument list to parse.
37
+ * @param options Optional parser annotations.
38
+ * @returns The parsed value or structured failure.
39
+ * @throws {TypeError} When called with an asynchronous parser at runtime.
40
+ * @since 1.3.0
41
+ */
42
+ declare function parseArgsSync<TParser extends Parser<"sync", unknown, unknown>>(parser: TParser, args: readonly string[], options?: ParseOptions): ParseArgsResult<InferValue<TParser>>;
43
+ //#endregion
44
+ export { ParseArgsResult, parseArgs, parseArgsSync };
package/dist/parser.d.ts CHANGED
@@ -1 +1,44 @@
1
- export { };
1
+ import { DetailedParseResult, InferValue, Mode, ParseOptions, Parser } from "@optique/core/parser";
2
+
3
+ //#region src/parser.d.ts
4
+
5
+ /**
6
+ * The result of parsing a complete argument list in a parser-layer test.
7
+ *
8
+ * @template T The inferred parser value type.
9
+ * @since 1.3.0
10
+ */
11
+ type ParseArgsResult<T> = DetailedParseResult<T>;
12
+ /**
13
+ * Parses a complete argument list and always returns a promise.
14
+ *
15
+ * Parser failures are returned as structured values. Exceptions thrown by a
16
+ * parser, or rejections from an asynchronous parser, reject the returned
17
+ * promise.
18
+ *
19
+ * @template TParser The parser type, including its inferred result value.
20
+ * @param parser The parser to exercise.
21
+ * @param args The complete argument list to parse.
22
+ * @param options Optional parser annotations.
23
+ * @returns A promise resolving to the parsed value or structured failure.
24
+ * @since 1.3.0
25
+ */
26
+ declare function parseArgs<TParser extends Parser<Mode, unknown, unknown>>(parser: TParser, args: readonly string[], options?: ParseOptions): Promise<ParseArgsResult<InferValue<TParser>>>;
27
+ /**
28
+ * Parses a complete argument list with a synchronous parser.
29
+ *
30
+ * Parser failures are returned as structured values. Exceptions thrown by a
31
+ * parser propagate to the caller.
32
+ *
33
+ * @template TParser The synchronous parser type, including its inferred result
34
+ * value.
35
+ * @param parser The synchronous parser to exercise.
36
+ * @param args The complete argument list to parse.
37
+ * @param options Optional parser annotations.
38
+ * @returns The parsed value or structured failure.
39
+ * @throws {TypeError} When called with an asynchronous parser at runtime.
40
+ * @since 1.3.0
41
+ */
42
+ declare function parseArgsSync<TParser extends Parser<"sync", unknown, unknown>>(parser: TParser, args: readonly string[], options?: ParseOptions): ParseArgsResult<InferValue<TParser>>;
43
+ //#endregion
44
+ export { ParseArgsResult, parseArgs, parseArgsSync };
package/dist/parser.js CHANGED
@@ -0,0 +1,42 @@
1
+ import { parseDetailed } from "@optique/core/parser";
2
+
3
+ //#region src/parser.ts
4
+ /**
5
+ * Parses a complete argument list and always returns a promise.
6
+ *
7
+ * Parser failures are returned as structured values. Exceptions thrown by a
8
+ * parser, or rejections from an asynchronous parser, reject the returned
9
+ * promise.
10
+ *
11
+ * @template TParser The parser type, including its inferred result value.
12
+ * @param parser The parser to exercise.
13
+ * @param args The complete argument list to parse.
14
+ * @param options Optional parser annotations.
15
+ * @returns A promise resolving to the parsed value or structured failure.
16
+ * @since 1.3.0
17
+ */
18
+ async function parseArgs(parser, args, options) {
19
+ return await parseDetailed(parser, args, options);
20
+ }
21
+ /**
22
+ * Parses a complete argument list with a synchronous parser.
23
+ *
24
+ * Parser failures are returned as structured values. Exceptions thrown by a
25
+ * parser propagate to the caller.
26
+ *
27
+ * @template TParser The synchronous parser type, including its inferred result
28
+ * value.
29
+ * @param parser The synchronous parser to exercise.
30
+ * @param args The complete argument list to parse.
31
+ * @param options Optional parser annotations.
32
+ * @returns The parsed value or structured failure.
33
+ * @throws {TypeError} When called with an asynchronous parser at runtime.
34
+ * @since 1.3.0
35
+ */
36
+ function parseArgsSync(parser, args, options) {
37
+ if (parser.mode !== "sync") throw new TypeError("Cannot use an async parser with parseArgsSync(). Use parseArgs() instead.");
38
+ return parseDetailed(parser, args, options);
39
+ }
40
+
41
+ //#endregion
42
+ export { parseArgs, parseArgsSync };
package/dist/run.cjs CHANGED
@@ -0,0 +1,49 @@
1
+ const require_chunk = require('./chunk-CUT6urMc.cjs');
2
+ const __optique_run = require_chunk.__toESM(require("@optique/run"));
3
+
4
+ //#region src/run.ts
5
+ async function captureRun(parserOrProgram, options = {}) {
6
+ let stdout = "";
7
+ let stderr = "";
8
+ const runOptions = {
9
+ ...options,
10
+ stdout(text) {
11
+ stdout += `${text}\n`;
12
+ },
13
+ stderr(text) {
14
+ stderr += `${text}\n`;
15
+ },
16
+ onExit(exitCode) {
17
+ throw new CapturedExit(exitCode);
18
+ }
19
+ };
20
+ try {
21
+ const value = "parser" in parserOrProgram && "metadata" in parserOrProgram ? await (0, __optique_run.runAsync)(parserOrProgram, runOptions) : await (0, __optique_run.runAsync)(parserOrProgram, runOptions);
22
+ return {
23
+ kind: "returned",
24
+ value,
25
+ exitCode: 0,
26
+ stdout,
27
+ stderr
28
+ };
29
+ } catch (error) {
30
+ if (!(error instanceof CapturedExit)) throw error;
31
+ return {
32
+ kind: "exited",
33
+ exitCode: error.exitCode,
34
+ stdout,
35
+ stderr
36
+ };
37
+ }
38
+ }
39
+ var CapturedExit = class extends Error {
40
+ exitCode;
41
+ constructor(exitCode) {
42
+ super(`Runner exited with code ${exitCode}.`);
43
+ this.name = "CapturedExit";
44
+ this.exitCode = exitCode;
45
+ }
46
+ };
47
+
48
+ //#endregion
49
+ exports.captureRun = captureRun;
package/dist/run.d.cts CHANGED
@@ -1 +1,80 @@
1
- export { };
1
+ import { CapturedOutput } from "./index-Cuf92ZIO.cjs";
2
+ import { InferValue, Mode, Parser } from "@optique/core/parser";
3
+ import { SourceContext } from "@optique/core/context";
4
+ import { ContextOptionsParam } from "@optique/core/facade";
5
+ import { Program } from "@optique/core/program";
6
+ import { RunOptions } from "@optique/run";
7
+
8
+ //#region src/run.d.ts
9
+
10
+ /**
11
+ * Options for {@link captureRun}.
12
+ *
13
+ * These are the options accepted by `runAsync()`, except for the output and
14
+ * exit callbacks controlled by the capture helper.
15
+ *
16
+ * @since 1.3.0
17
+ */
18
+ type CaptureRunOptions = Omit<RunOptions, "stdout" | "stderr" | "onExit"> & {
19
+ readonly stdout?: never;
20
+ readonly stderr?: never;
21
+ readonly onExit?: never;
22
+ };
23
+ /**
24
+ * The result of an in-process runner execution.
25
+ *
26
+ * A normal parser return includes its inferred value. Help, version,
27
+ * completion, and parse-error exits instead include the requested exit code.
28
+ * Both variants preserve the output written through the runner callbacks.
29
+ *
30
+ * @template T The inferred parser value type.
31
+ * @since 1.3.0
32
+ */
33
+ type CapturedRunResult<T> = CapturedOutput & ({
34
+ readonly kind: "returned";
35
+ readonly value: T;
36
+ readonly exitCode: 0;
37
+ } | {
38
+ readonly kind: "exited";
39
+ readonly exitCode: number;
40
+ });
41
+ type RejectEmptyContexts<TContexts extends readonly SourceContext<unknown>[]> = TContexts extends readonly [] ? never : unknown;
42
+ type ContextsFromOptions<TOptions> = [Exclude<TOptions, undefined>] extends [never] ? undefined : Exclude<TOptions, undefined> extends {
43
+ readonly contexts?: infer TContexts extends readonly SourceContext<unknown>[] | undefined;
44
+ } ? TContexts : undefined;
45
+ type RejectContextfulOptions<TOptions> = [ContextsFromOptions<TOptions>] extends [undefined | readonly []] ? unknown : never;
46
+ type RejectUnknownCaptureRunOptionKeys<TOptions> = [TOptions] extends [undefined] ? unknown : Exclude<keyof TOptions, keyof CaptureRunOptions> extends never ? unknown : never;
47
+ type AcceptExactCaptureRunOptions<TOptions> = [TOptions] extends [CaptureRunOptions] ? [CaptureRunOptions] extends [TOptions] ? unknown : never : never;
48
+ type AcceptExactOptionalCaptureRunOptions<TOptions> = [TOptions] extends [CaptureRunOptions | undefined] ? [CaptureRunOptions | undefined] extends [TOptions] ? unknown : never : never;
49
+ /**
50
+ * Runs a parser or program in process and captures runner-controlled output.
51
+ *
52
+ * The helper always returns a promise. Parser returns become `returned`
53
+ * results, while intentional help, version, completion, and parse-error exits
54
+ * become `exited` results. Writes that bypass the injected callbacks, such as
55
+ * `console.log()` or direct process-stream writes, are not captured.
56
+ * `colors` and `maxWidth` retain `runAsync()`'s terminal-dependent defaults,
57
+ * so set both explicitly when asserting rendered text.
58
+ *
59
+ * @template T The parser or program result type.
60
+ * @param parser The parser or `Program` to execute.
61
+ * @param options Runner options other than the captured callbacks.
62
+ * @returns A promise resolving to the returned value or intentional exit,
63
+ * together with captured standard output and standard error.
64
+ * @throws Any unexpected parser, context, callback, or disposal error. Promise
65
+ * rejections from asynchronous parsers and contexts also propagate.
66
+ * @since 1.3.0
67
+ */
68
+ declare function captureRun<T extends Parser<Mode, unknown, unknown>, TContexts extends readonly SourceContext<unknown>[]>(parser: T, options: CaptureRunOptions & {
69
+ readonly contexts: TContexts;
70
+ } & ContextOptionsParam<TContexts, InferValue<T>>): Promise<CapturedRunResult<InferValue<T>>>;
71
+ declare function captureRun<M extends Mode, T, const TContexts extends readonly SourceContext<unknown>[]>(program: Program<M, T>, options: CaptureRunOptions & {
72
+ readonly contexts: TContexts;
73
+ } & RejectEmptyContexts<TContexts> & ContextOptionsParam<TContexts, T>): Promise<CapturedRunResult<T>>;
74
+ declare function captureRun<T, const TOptions extends CaptureRunOptions | undefined>(program: Program<"sync", T>, options?: TOptions & RejectContextfulOptions<TOptions> & RejectUnknownCaptureRunOptionKeys<TOptions>): Promise<CapturedRunResult<T>>;
75
+ declare function captureRun<T, const TOptions extends CaptureRunOptions | undefined>(program: Program<"async", T>, options?: TOptions & RejectContextfulOptions<TOptions> & RejectUnknownCaptureRunOptionKeys<TOptions>): Promise<CapturedRunResult<T>>;
76
+ declare function captureRun<T, TOptions extends CaptureRunOptions>(program: Program<Mode, T>, options: TOptions & AcceptExactCaptureRunOptions<TOptions>): Promise<CapturedRunResult<T>>;
77
+ declare function captureRun<T, TOptions extends CaptureRunOptions | undefined>(program: Program<Mode, T>, options: TOptions & AcceptExactOptionalCaptureRunOptions<TOptions>): Promise<CapturedRunResult<T>>;
78
+ declare function captureRun<T extends Parser<Mode, unknown, unknown>>(parser: T, options?: CaptureRunOptions): Promise<CapturedRunResult<InferValue<T>>>;
79
+ //#endregion
80
+ export { CaptureRunOptions, CapturedRunResult, captureRun };
package/dist/run.d.ts CHANGED
@@ -1 +1,80 @@
1
- export { };
1
+ import { CapturedOutput } from "./index-t_PHSvz_.js";
2
+ import { InferValue, Mode, Parser } from "@optique/core/parser";
3
+ import { RunOptions } from "@optique/run";
4
+ import { SourceContext } from "@optique/core/context";
5
+ import { ContextOptionsParam } from "@optique/core/facade";
6
+ import { Program } from "@optique/core/program";
7
+
8
+ //#region src/run.d.ts
9
+
10
+ /**
11
+ * Options for {@link captureRun}.
12
+ *
13
+ * These are the options accepted by `runAsync()`, except for the output and
14
+ * exit callbacks controlled by the capture helper.
15
+ *
16
+ * @since 1.3.0
17
+ */
18
+ type CaptureRunOptions = Omit<RunOptions, "stdout" | "stderr" | "onExit"> & {
19
+ readonly stdout?: never;
20
+ readonly stderr?: never;
21
+ readonly onExit?: never;
22
+ };
23
+ /**
24
+ * The result of an in-process runner execution.
25
+ *
26
+ * A normal parser return includes its inferred value. Help, version,
27
+ * completion, and parse-error exits instead include the requested exit code.
28
+ * Both variants preserve the output written through the runner callbacks.
29
+ *
30
+ * @template T The inferred parser value type.
31
+ * @since 1.3.0
32
+ */
33
+ type CapturedRunResult<T> = CapturedOutput & ({
34
+ readonly kind: "returned";
35
+ readonly value: T;
36
+ readonly exitCode: 0;
37
+ } | {
38
+ readonly kind: "exited";
39
+ readonly exitCode: number;
40
+ });
41
+ type RejectEmptyContexts<TContexts extends readonly SourceContext<unknown>[]> = TContexts extends readonly [] ? never : unknown;
42
+ type ContextsFromOptions<TOptions> = [Exclude<TOptions, undefined>] extends [never] ? undefined : Exclude<TOptions, undefined> extends {
43
+ readonly contexts?: infer TContexts extends readonly SourceContext<unknown>[] | undefined;
44
+ } ? TContexts : undefined;
45
+ type RejectContextfulOptions<TOptions> = [ContextsFromOptions<TOptions>] extends [undefined | readonly []] ? unknown : never;
46
+ type RejectUnknownCaptureRunOptionKeys<TOptions> = [TOptions] extends [undefined] ? unknown : Exclude<keyof TOptions, keyof CaptureRunOptions> extends never ? unknown : never;
47
+ type AcceptExactCaptureRunOptions<TOptions> = [TOptions] extends [CaptureRunOptions] ? [CaptureRunOptions] extends [TOptions] ? unknown : never : never;
48
+ type AcceptExactOptionalCaptureRunOptions<TOptions> = [TOptions] extends [CaptureRunOptions | undefined] ? [CaptureRunOptions | undefined] extends [TOptions] ? unknown : never : never;
49
+ /**
50
+ * Runs a parser or program in process and captures runner-controlled output.
51
+ *
52
+ * The helper always returns a promise. Parser returns become `returned`
53
+ * results, while intentional help, version, completion, and parse-error exits
54
+ * become `exited` results. Writes that bypass the injected callbacks, such as
55
+ * `console.log()` or direct process-stream writes, are not captured.
56
+ * `colors` and `maxWidth` retain `runAsync()`'s terminal-dependent defaults,
57
+ * so set both explicitly when asserting rendered text.
58
+ *
59
+ * @template T The parser or program result type.
60
+ * @param parser The parser or `Program` to execute.
61
+ * @param options Runner options other than the captured callbacks.
62
+ * @returns A promise resolving to the returned value or intentional exit,
63
+ * together with captured standard output and standard error.
64
+ * @throws Any unexpected parser, context, callback, or disposal error. Promise
65
+ * rejections from asynchronous parsers and contexts also propagate.
66
+ * @since 1.3.0
67
+ */
68
+ declare function captureRun<T extends Parser<Mode, unknown, unknown>, TContexts extends readonly SourceContext<unknown>[]>(parser: T, options: CaptureRunOptions & {
69
+ readonly contexts: TContexts;
70
+ } & ContextOptionsParam<TContexts, InferValue<T>>): Promise<CapturedRunResult<InferValue<T>>>;
71
+ declare function captureRun<M extends Mode, T, const TContexts extends readonly SourceContext<unknown>[]>(program: Program<M, T>, options: CaptureRunOptions & {
72
+ readonly contexts: TContexts;
73
+ } & RejectEmptyContexts<TContexts> & ContextOptionsParam<TContexts, T>): Promise<CapturedRunResult<T>>;
74
+ declare function captureRun<T, const TOptions extends CaptureRunOptions | undefined>(program: Program<"sync", T>, options?: TOptions & RejectContextfulOptions<TOptions> & RejectUnknownCaptureRunOptionKeys<TOptions>): Promise<CapturedRunResult<T>>;
75
+ declare function captureRun<T, const TOptions extends CaptureRunOptions | undefined>(program: Program<"async", T>, options?: TOptions & RejectContextfulOptions<TOptions> & RejectUnknownCaptureRunOptionKeys<TOptions>): Promise<CapturedRunResult<T>>;
76
+ declare function captureRun<T, TOptions extends CaptureRunOptions>(program: Program<Mode, T>, options: TOptions & AcceptExactCaptureRunOptions<TOptions>): Promise<CapturedRunResult<T>>;
77
+ declare function captureRun<T, TOptions extends CaptureRunOptions | undefined>(program: Program<Mode, T>, options: TOptions & AcceptExactOptionalCaptureRunOptions<TOptions>): Promise<CapturedRunResult<T>>;
78
+ declare function captureRun<T extends Parser<Mode, unknown, unknown>>(parser: T, options?: CaptureRunOptions): Promise<CapturedRunResult<InferValue<T>>>;
79
+ //#endregion
80
+ export { CaptureRunOptions, CapturedRunResult, captureRun };
package/dist/run.js CHANGED
@@ -0,0 +1,48 @@
1
+ import { runAsync } from "@optique/run";
2
+
3
+ //#region src/run.ts
4
+ async function captureRun(parserOrProgram, options = {}) {
5
+ let stdout = "";
6
+ let stderr = "";
7
+ const runOptions = {
8
+ ...options,
9
+ stdout(text) {
10
+ stdout += `${text}\n`;
11
+ },
12
+ stderr(text) {
13
+ stderr += `${text}\n`;
14
+ },
15
+ onExit(exitCode) {
16
+ throw new CapturedExit(exitCode);
17
+ }
18
+ };
19
+ try {
20
+ const value = "parser" in parserOrProgram && "metadata" in parserOrProgram ? await runAsync(parserOrProgram, runOptions) : await runAsync(parserOrProgram, runOptions);
21
+ return {
22
+ kind: "returned",
23
+ value,
24
+ exitCode: 0,
25
+ stdout,
26
+ stderr
27
+ };
28
+ } catch (error) {
29
+ if (!(error instanceof CapturedExit)) throw error;
30
+ return {
31
+ kind: "exited",
32
+ exitCode: error.exitCode,
33
+ stdout,
34
+ stderr
35
+ };
36
+ }
37
+ }
38
+ var CapturedExit = class extends Error {
39
+ exitCode;
40
+ constructor(exitCode) {
41
+ super(`Runner exited with code ${exitCode}.`);
42
+ this.name = "CapturedExit";
43
+ this.exitCode = exitCode;
44
+ }
45
+ };
46
+
47
+ //#endregion
48
+ export { captureRun };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@optique/testing",
3
- "version": "1.3.0-dev.2488",
3
+ "version": "1.3.0-dev.2497",
4
4
  "description": "Testing support for Optique command-line interfaces",
5
5
  "keywords": [
6
6
  "CLI",
@@ -85,6 +85,11 @@
85
85
  }
86
86
  },
87
87
  "sideEffects": false,
88
+ "dependencies": {
89
+ "@optique/core": "1.3.0-dev.2497+23bea5fb",
90
+ "@optique/discover": "1.3.0-dev.2497+23bea5fb",
91
+ "@optique/run": "1.3.0-dev.2497+23bea5fb"
92
+ },
88
93
  "devDependencies": {
89
94
  "@types/node": "^24.0.0",
90
95
  "tsdown": "^0.13.0",