@alchemy.run/test 0.0.0 → 2.0.0-beta.86

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 (119) hide show
  1. package/LICENSE +201 -0
  2. package/bin/alchemy-test.ts +2 -0
  3. package/lib/Alchemy.d.ts +77 -0
  4. package/lib/Alchemy.d.ts.map +1 -0
  5. package/lib/Alchemy.js +195 -0
  6. package/lib/Alchemy.js.map +1 -0
  7. package/lib/Api.d.ts +135 -0
  8. package/lib/Api.d.ts.map +1 -0
  9. package/lib/Api.js +245 -0
  10. package/lib/Api.js.map +1 -0
  11. package/lib/Bun.d.ts +66 -0
  12. package/lib/Bun.d.ts.map +1 -0
  13. package/lib/Bun.js +142 -0
  14. package/lib/Bun.js.map +1 -0
  15. package/lib/Capture.d.ts +10 -0
  16. package/lib/Capture.d.ts.map +1 -0
  17. package/lib/Capture.js +68 -0
  18. package/lib/Capture.js.map +1 -0
  19. package/lib/Core.d.ts +301 -0
  20. package/lib/Core.d.ts.map +1 -0
  21. package/lib/Core.js +442 -0
  22. package/lib/Core.js.map +1 -0
  23. package/lib/DevCli.d.ts +47 -0
  24. package/lib/DevCli.d.ts.map +1 -0
  25. package/lib/DevCli.js +181 -0
  26. package/lib/DevCli.js.map +1 -0
  27. package/lib/Expect.d.ts +84 -0
  28. package/lib/Expect.d.ts.map +1 -0
  29. package/lib/Expect.js +518 -0
  30. package/lib/Expect.js.map +1 -0
  31. package/lib/FileLog.d.ts +27 -0
  32. package/lib/FileLog.d.ts.map +1 -0
  33. package/lib/FileLog.js +136 -0
  34. package/lib/FileLog.js.map +1 -0
  35. package/lib/Http.d.ts +109 -0
  36. package/lib/Http.d.ts.map +1 -0
  37. package/lib/Http.js +123 -0
  38. package/lib/Http.js.map +1 -0
  39. package/lib/Model.d.ts +111 -0
  40. package/lib/Model.d.ts.map +1 -0
  41. package/lib/Model.js +59 -0
  42. package/lib/Model.js.map +1 -0
  43. package/lib/PlainReporter.d.ts +18 -0
  44. package/lib/PlainReporter.d.ts.map +1 -0
  45. package/lib/PlainReporter.js +274 -0
  46. package/lib/PlainReporter.js.map +1 -0
  47. package/lib/Plan.d.ts +19 -0
  48. package/lib/Plan.d.ts.map +1 -0
  49. package/lib/Plan.js +32 -0
  50. package/lib/Plan.js.map +1 -0
  51. package/lib/Registry.d.ts +34 -0
  52. package/lib/Registry.d.ts.map +1 -0
  53. package/lib/Registry.js +80 -0
  54. package/lib/Registry.js.map +1 -0
  55. package/lib/Reporter.d.ts +160 -0
  56. package/lib/Reporter.d.ts.map +1 -0
  57. package/lib/Reporter.js +9 -0
  58. package/lib/Reporter.js.map +1 -0
  59. package/lib/Runner.d.ts +51 -0
  60. package/lib/Runner.d.ts.map +1 -0
  61. package/lib/Runner.js +1075 -0
  62. package/lib/Runner.js.map +1 -0
  63. package/lib/StrayOutput.d.ts +8 -0
  64. package/lib/StrayOutput.d.ts.map +1 -0
  65. package/lib/StrayOutput.js +259 -0
  66. package/lib/StrayOutput.js.map +1 -0
  67. package/lib/Tags.d.ts +17 -0
  68. package/lib/Tags.d.ts.map +1 -0
  69. package/lib/Tags.js +84 -0
  70. package/lib/Tags.js.map +1 -0
  71. package/lib/TestState.d.ts +12 -0
  72. package/lib/TestState.d.ts.map +1 -0
  73. package/lib/TestState.js +15 -0
  74. package/lib/TestState.js.map +1 -0
  75. package/lib/Tui.d.ts +4 -0
  76. package/lib/Tui.d.ts.map +1 -0
  77. package/lib/Tui.js +1137 -0
  78. package/lib/Tui.js.map +1 -0
  79. package/lib/Vitest.d.ts +58 -0
  80. package/lib/Vitest.d.ts.map +1 -0
  81. package/lib/Vitest.js +131 -0
  82. package/lib/Vitest.js.map +1 -0
  83. package/lib/WorktreeStage.d.ts +17 -0
  84. package/lib/WorktreeStage.d.ts.map +1 -0
  85. package/lib/WorktreeStage.js +48 -0
  86. package/lib/WorktreeStage.js.map +1 -0
  87. package/lib/cli.d.ts +2 -0
  88. package/lib/cli.d.ts.map +1 -0
  89. package/lib/cli.js +222 -0
  90. package/lib/cli.js.map +1 -0
  91. package/lib/index.d.ts +14 -0
  92. package/lib/index.d.ts.map +1 -0
  93. package/lib/index.js +12 -0
  94. package/lib/index.js.map +1 -0
  95. package/package.json +73 -3
  96. package/src/Alchemy.ts +337 -0
  97. package/src/Api.ts +522 -0
  98. package/src/Bun.ts +254 -0
  99. package/src/Capture.ts +72 -0
  100. package/src/Core.ts +906 -0
  101. package/src/DevCli.ts +229 -0
  102. package/src/Expect.ts +763 -0
  103. package/src/FileLog.ts +158 -0
  104. package/src/Http.ts +201 -0
  105. package/src/Model.ts +178 -0
  106. package/src/PlainReporter.ts +338 -0
  107. package/src/Plan.ts +45 -0
  108. package/src/Registry.ts +101 -0
  109. package/src/Reporter.ts +171 -0
  110. package/src/Runner.ts +1361 -0
  111. package/src/StrayOutput.ts +283 -0
  112. package/src/Tags.ts +100 -0
  113. package/src/TestState.ts +35 -0
  114. package/src/Tui.ts +1272 -0
  115. package/src/Vitest.ts +238 -0
  116. package/src/WorktreeStage.ts +45 -0
  117. package/src/cli.ts +330 -0
  118. package/src/index.ts +58 -0
  119. package/README.md +0 -9
package/lib/DevCli.js ADDED
@@ -0,0 +1,181 @@
1
+ import { spawn, spawnSync } from "node:child_process";
2
+ import * as path from "node:path";
3
+ export const pollUntil = async (what, effect, options = {}) => {
4
+ const { tries = 30, delayMs = 1_000, diagnostics, abandonIf } = options;
5
+ for (let attempt = 0; attempt < tries; attempt++) {
6
+ const value = await effect();
7
+ if (value !== undefined)
8
+ return value;
9
+ const reason = abandonIf?.();
10
+ if (reason !== undefined) {
11
+ const detail = diagnostics?.();
12
+ throw new Error(`Gave up waiting for ${what}: ${reason}.${detail ? `\n${detail}` : ""}`);
13
+ }
14
+ await Bun.sleep(delayMs);
15
+ }
16
+ const detail = diagnostics?.();
17
+ throw new Error(`Timed out waiting for ${what}.${detail ? `\n${detail}` : ""}`);
18
+ };
19
+ export async function fetchOk(url, initOrOptions = {}, explicitOptions) {
20
+ const optionsOnly = explicitOptions === undefined && ("tries" in initOrOptions || "delayMs" in initOrOptions);
21
+ const init = optionsOnly ? undefined : initOrOptions;
22
+ const options = optionsOnly ? initOrOptions : (explicitOptions ?? {});
23
+ const { tries = 20, delayMs = 500 } = options;
24
+ let last;
25
+ for (let attempt = 0; attempt < tries; attempt++) {
26
+ try {
27
+ last = await fetch(url, init);
28
+ if (last.ok)
29
+ return last;
30
+ }
31
+ catch {
32
+ // The dev endpoint may not be listening yet.
33
+ }
34
+ await Bun.sleep(delayMs);
35
+ }
36
+ throw new Error(`${init?.method ?? "GET"} ${url} never returned 2xx (last status: ${last?.status})`);
37
+ }
38
+ export const parseOutputUrl = (output, key) => {
39
+ const escaped = key.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
40
+ return output.match(new RegExp(`\\b${escaped}(?:\\s*:\\s*|\\s+)['"]?(http[^\\s'",]+)['"]?(?=[\\s,}])`))?.[1];
41
+ };
42
+ export const parseOutputValue = (output, key) => {
43
+ const escaped = key.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
44
+ return output.match(new RegExp(`\\b${escaped}(?:\\s*:\\s*|\\s+)['"]?([^\\s'",]+)`))?.[1];
45
+ };
46
+ /** Owns a real `alchemy dev` child and its complete detached process group. */
47
+ export class DevCli {
48
+ root;
49
+ stage;
50
+ alchemyBin;
51
+ env;
52
+ #process;
53
+ #output = "";
54
+ constructor(options) {
55
+ this.root = options.root;
56
+ this.stage = options.stage ?? "dev-cli-test";
57
+ this.alchemyBin =
58
+ options.alchemyBin ?? path.join(this.root, "node_modules", "alchemy", "bin", "alchemy.js");
59
+ this.env = { ...process.env, ...options.env };
60
+ }
61
+ get output() {
62
+ return this.#output;
63
+ }
64
+ get outputTail() {
65
+ return `--- alchemy dev output (tail) ---\n${this.#output.slice(-4_000)}`;
66
+ }
67
+ start() {
68
+ if (this.#process !== undefined)
69
+ throw new Error("alchemy dev is running");
70
+ const child = spawn("bun", [this.alchemyBin, "dev", "--stage", this.stage], {
71
+ cwd: this.root,
72
+ detached: true,
73
+ env: this.env,
74
+ stdio: ["ignore", "pipe", "pipe"],
75
+ });
76
+ this.#process = child;
77
+ forwardSignals(child);
78
+ const capture = (chunk) => {
79
+ const text = chunk.toString();
80
+ this.#output += text;
81
+ if (process.env.DEBUG)
82
+ process.stderr.write(text);
83
+ };
84
+ child.stdout.on("data", capture);
85
+ child.stderr.on("data", capture);
86
+ }
87
+ outputUrl(key) {
88
+ return parseOutputUrl(this.#output, key);
89
+ }
90
+ outputValue(key) {
91
+ return parseOutputValue(this.#output, key);
92
+ }
93
+ pollUntil(what, effect, options = {}) {
94
+ return pollUntil(what, effect, {
95
+ ...options,
96
+ diagnostics: () => this.outputTail,
97
+ // A dev child that died (crash, failed apply) never produces what we're
98
+ // waiting for — fail immediately with its output instead of sitting
99
+ // through the full poll budget.
100
+ abandonIf: () => {
101
+ const child = this.#process;
102
+ if (child === undefined)
103
+ return "alchemy dev is not running";
104
+ if (child.exitCode !== null) {
105
+ return `alchemy dev exited with code ${child.exitCode}`;
106
+ }
107
+ if (child.signalCode !== null) {
108
+ return `alchemy dev was killed by ${child.signalCode}`;
109
+ }
110
+ return undefined;
111
+ },
112
+ });
113
+ }
114
+ outputUrlWhenReady(key, options) {
115
+ return this.pollUntil(`${key} url in stack outputs`, () => this.outputUrl(key), options);
116
+ }
117
+ async stop() {
118
+ const child = this.#process;
119
+ if (child?.pid === undefined)
120
+ return;
121
+ if (child.exitCode !== null || child.signalCode !== null) {
122
+ this.#process = undefined;
123
+ return;
124
+ }
125
+ const killGroup = (signal) => {
126
+ try {
127
+ process.kill(-child.pid, signal);
128
+ }
129
+ catch {
130
+ // The group has already exited.
131
+ }
132
+ };
133
+ const exited = new Promise((resolve) => child.once("exit", () => resolve()));
134
+ killGroup("SIGINT");
135
+ await Promise.race([exited, Bun.sleep(15_000)]);
136
+ if (child.exitCode === null && child.signalCode === null) {
137
+ killGroup("SIGKILL");
138
+ await Promise.race([exited, Bun.sleep(5_000)]);
139
+ }
140
+ this.#process = undefined;
141
+ }
142
+ destroy(options = {}) {
143
+ const result = spawnSync("bun", [this.alchemyBin, "destroy", "--stage", this.stage, "--yes"], {
144
+ cwd: this.root,
145
+ env: this.env,
146
+ stdio: "inherit",
147
+ timeout: options.timeout ?? 120_000,
148
+ });
149
+ if (result.error !== undefined)
150
+ throw result.error;
151
+ if (result.status !== 0) {
152
+ throw new Error(`alchemy destroy exited ${result.status ?? "by signal"}`);
153
+ }
154
+ }
155
+ }
156
+ /** Forward Ctrl-C to a detached CLI and let it finish its own cleanup. */
157
+ export const forwardSignals = (child) => {
158
+ let interrupted;
159
+ const forward = (signal) => {
160
+ if (interrupted !== undefined)
161
+ return;
162
+ interrupted = signal;
163
+ child.kill(signal);
164
+ };
165
+ const removeListeners = () => {
166
+ process.off("SIGINT", forward);
167
+ process.off("SIGTERM", forward);
168
+ };
169
+ process.on("SIGINT", forward);
170
+ process.on("SIGTERM", forward);
171
+ child.once("error", removeListeners);
172
+ child.once("exit", () => {
173
+ removeListeners();
174
+ // Bun skips afterAll on Ctrl-C. Exit only after the CLI has shut down,
175
+ // without resuming the interrupted tests or starting the next command.
176
+ if (interrupted !== undefined) {
177
+ process.exit(interrupted === "SIGINT" ? 130 : 143);
178
+ }
179
+ });
180
+ };
181
+ //# sourceMappingURL=DevCli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DevCli.js","sources":["../src/DevCli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,84 @@
1
+ /**
2
+ * A from-scratch, dependency-free `expect` covering the matcher surface used
3
+ * by the alchemy test suite. Vitest-compatible semantics for:
4
+ *
5
+ * - equality: toBe, toEqual, toStrictEqual
6
+ * - presence: toBeDefined, toBeUndefined, toBeNull, toBeTruthy, toBeFalsy, toBeNaN
7
+ * - containers: toContain, toContainEqual, toHaveLength, toHaveProperty
8
+ * - strings: toMatch
9
+ * - objects: toMatchObject, toBeInstanceOf, toBeTypeOf
10
+ * - numbers: toBeGreaterThan(OrEqual), toBeLessThan(OrEqual), toBeCloseTo
11
+ * - misc: toSatisfy, toBeOneOf, toThrow / toThrowError
12
+ * - modifiers: .not, .resolves, .rejects
13
+ * - asymmetric: expect.any, expect.anything, expect.arrayContaining,
14
+ * expect.objectContaining, expect.stringContaining, expect.stringMatching
15
+ * - expect.fail
16
+ *
17
+ * Assertion failures throw {@link AssertionError} (a plain Error subclass) so
18
+ * they propagate through Effect as defects and render with a clean message.
19
+ */
20
+ export declare class AssertionError extends Error {
21
+ readonly actual?: unknown;
22
+ readonly expected?: unknown;
23
+ readonly name = "AssertionError";
24
+ constructor(message: string, actual?: unknown, expected?: unknown);
25
+ }
26
+ export declare const stringify: (value: unknown) => string;
27
+ export declare const equals: (actual: unknown, expected: unknown, strict?: boolean) => boolean;
28
+ export interface Matchers<A = unknown> {
29
+ toBe(expected: unknown): void;
30
+ toEqual(expected: unknown): void;
31
+ toStrictEqual(expected: unknown): void;
32
+ toBeDefined(): void;
33
+ toBeUndefined(): void;
34
+ toBeNull(): void;
35
+ toBeTruthy(): void;
36
+ toBeFalsy(): void;
37
+ toBeNaN(): void;
38
+ toContain(item: unknown): void;
39
+ toContainEqual(item: unknown): void;
40
+ toHaveLength(length: number): void;
41
+ toHaveProperty(path: string | Array<PropertyKey>, value?: unknown): void;
42
+ toMatch(pattern: string | RegExp): void;
43
+ toMatchObject(expected: object): void;
44
+ toThrow(expected?: string | RegExp | Error | (new (...args: Array<any>) => Error)): void;
45
+ toThrowError(expected?: string | RegExp | Error | (new (...args: Array<any>) => Error)): void;
46
+ toBeGreaterThan(expected: number | bigint): void;
47
+ toBeGreaterThanOrEqual(expected: number | bigint): void;
48
+ toBeLessThan(expected: number | bigint): void;
49
+ toBeLessThanOrEqual(expected: number | bigint): void;
50
+ toBeCloseTo(expected: number, precision?: number): void;
51
+ toBeInstanceOf(ctor: abstract new (...args: Array<any>) => unknown): void;
52
+ toBeTypeOf(type: "string" | "number" | "boolean" | "bigint" | "symbol" | "function" | "object" | "undefined"): void;
53
+ toSatisfy(predicate: (value: A) => boolean): void;
54
+ toBeOneOf(values: ReadonlyArray<unknown>): void;
55
+ readonly not: Matchers<A>;
56
+ readonly resolves: PromiseMatchers<A>;
57
+ readonly rejects: PromiseMatchers<A>;
58
+ }
59
+ export type PromiseMatchers<A> = {
60
+ readonly [K in Exclude<keyof Matchers<A>, "not" | "resolves" | "rejects">]: (...args: Parameters<Matchers<A>[K]>) => Promise<void>;
61
+ } & {
62
+ readonly not: PromiseMatchers<A>;
63
+ };
64
+ export interface Expect {
65
+ <A>(actual: A, message?: string): Matchers<A>;
66
+ any(ctor: any): any;
67
+ anything(): any;
68
+ arrayContaining(items: ReadonlyArray<unknown>): any;
69
+ objectContaining(subset: Record<string, unknown>): any;
70
+ stringContaining(substring: string): any;
71
+ stringMatching(pattern: string | RegExp): any;
72
+ toSatisfy(predicate: (value: any) => boolean, description?: string): any;
73
+ fail(message?: string): never;
74
+ }
75
+ export declare const expect: Expect;
76
+ export interface Assert {
77
+ (condition: unknown, message?: string): asserts condition;
78
+ strictEqual(actual: unknown, expected: unknown, message?: string): void;
79
+ deepStrictEqual(actual: unknown, expected: unknown, message?: string): void;
80
+ isDefined<A>(value: A): asserts value is NonNullable<A>;
81
+ fail(message?: string): never;
82
+ }
83
+ export declare const assert: Assert;
84
+ //# sourceMappingURL=Expect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Expect.d.ts","sources":["../src/Expect.ts"],"names":[],"mappings":"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"}