@jterrazz/test 5.3.2 → 6.1.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.
- package/README.md +66 -56
- package/dist/chunk.cjs +28 -0
- package/dist/index.cjs +597 -463
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +343 -246
- package/dist/index.d.ts +343 -246
- package/dist/index.js +589 -438
- package/dist/index.js.map +1 -1
- package/dist/mock-of.cjs +32 -0
- package/dist/mock-of.cjs.map +1 -0
- package/dist/mock-of.d.cts +27 -0
- package/dist/mock-of.d.ts +27 -0
- package/dist/mock-of.js +19 -0
- package/dist/mock-of.js.map +1 -0
- package/dist/mock.cjs +4 -0
- package/dist/mock.d.cts +2 -0
- package/dist/mock.d.ts +2 -0
- package/dist/mock.js +2 -0
- package/dist/services.cjs +5 -0
- package/dist/services.d.cts +2 -0
- package/dist/services.d.ts +2 -0
- package/dist/services.js +2 -0
- package/dist/sqlite.adapter.cjs +331 -0
- package/dist/sqlite.adapter.cjs.map +1 -0
- package/dist/sqlite.adapter.d.cts +209 -0
- package/dist/sqlite.adapter.d.ts +209 -0
- package/dist/sqlite.adapter.js +312 -0
- package/dist/sqlite.adapter.js.map +1 -0
- package/package.json +16 -8
package/dist/index.d.cts
CHANGED
|
@@ -1,58 +1,16 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { a as PostgresOptions, c as IsolationStrategy, i as redis, l as DatabasePort, n as sqlite, o as postgres, r as RedisOptions, s as ServiceHandle, t as SqliteOptions } from "./sqlite.adapter.cjs";
|
|
2
|
+
import { i as mockOfDate, n as mockOf, r as MockDatePort, t as MockPort } from "./mock-of.cjs";
|
|
2
3
|
|
|
3
|
-
//#region src/ports/database.port.d.ts
|
|
4
|
-
/**
|
|
5
|
-
* Abstract database interface for specification runners.
|
|
6
|
-
* Implement this to plug in your database stack.
|
|
7
|
-
*/
|
|
8
|
-
interface DatabasePort {
|
|
9
|
-
/** Execute raw SQL (for seeding test data). */
|
|
10
|
-
seed(sql: string): Promise<void>;
|
|
11
|
-
/** Query a table and return rows as arrays of values. */
|
|
12
|
-
query(table: string, columns: string[]): Promise<unknown[][]>;
|
|
13
|
-
/** Reset database to clean state between tests. */
|
|
14
|
-
reset(): Promise<void>;
|
|
15
|
-
}
|
|
16
|
-
//#endregion
|
|
17
|
-
//#region src/ports/service.port.d.ts
|
|
18
|
-
/**
|
|
19
|
-
* A service handle — returned by factory functions like postgres(), redis().
|
|
20
|
-
* Mutable: connectionString is populated after the orchestrator starts containers.
|
|
21
|
-
*/
|
|
22
|
-
interface ServiceHandle {
|
|
23
|
-
/** Service type identifier. */
|
|
24
|
-
readonly type: string;
|
|
25
|
-
/** Compose service name (if linked). */
|
|
26
|
-
readonly composeName: null | string;
|
|
27
|
-
/** Default container port for this service type. */
|
|
28
|
-
readonly defaultPort: number;
|
|
29
|
-
/** Default Docker image for this service type. */
|
|
30
|
-
readonly defaultImage: string;
|
|
31
|
-
/** Environment variables to pass to the container. */
|
|
32
|
-
readonly environment: Record<string, string>;
|
|
33
|
-
/** Connection string — populated after start. */
|
|
34
|
-
connectionString: string;
|
|
35
|
-
/** Whether this service has been started. */
|
|
36
|
-
started: boolean;
|
|
37
|
-
/** Build the connection string from host and port. */
|
|
38
|
-
buildConnectionString(host: string, port: number): string;
|
|
39
|
-
/** Create a DatabasePort adapter (if this is a database). Returns null otherwise. */
|
|
40
|
-
createDatabaseAdapter(): DatabasePort | null;
|
|
41
|
-
/** Verify the service is ready and accepting connections. Throws with context if not. */
|
|
42
|
-
healthcheck(): Promise<void>;
|
|
43
|
-
/** Run initialization scripts (e.g., init.sql). Throws with SQL error context if it fails. */
|
|
44
|
-
initialize(composeDir: string): Promise<void>;
|
|
45
|
-
/** Reset state between tests (truncate tables, flush cache, etc.) */
|
|
46
|
-
reset(): Promise<void>;
|
|
47
|
-
}
|
|
48
|
-
//#endregion
|
|
49
4
|
//#region src/ports/command.port.d.ts
|
|
50
5
|
/**
|
|
51
|
-
* Result of executing a CLI command.
|
|
6
|
+
* Result of executing a CLI command, including exit code and captured output streams.
|
|
52
7
|
*/
|
|
53
8
|
interface CommandResult {
|
|
9
|
+
/** Process exit code (0 = success). */
|
|
54
10
|
exitCode: number;
|
|
11
|
+
/** Captured standard output. */
|
|
55
12
|
stdout: string;
|
|
13
|
+
/** Captured standard error. */
|
|
56
14
|
stderr: string;
|
|
57
15
|
}
|
|
58
16
|
/**
|
|
@@ -82,19 +40,22 @@ interface CommandPort {
|
|
|
82
40
|
//#endregion
|
|
83
41
|
//#region src/ports/server.port.d.ts
|
|
84
42
|
/**
|
|
85
|
-
* HTTP response returned by a server port.
|
|
43
|
+
* HTTP response returned by a server port, with parsed JSON body.
|
|
86
44
|
*/
|
|
87
45
|
interface ServerResponse {
|
|
46
|
+
/** HTTP status code. */
|
|
88
47
|
status: number;
|
|
48
|
+
/** Parsed JSON response body, or null if parsing failed. */
|
|
89
49
|
body: unknown;
|
|
50
|
+
/** Response headers as a flat key-value map. */
|
|
90
51
|
headers: Record<string, string>;
|
|
91
52
|
}
|
|
92
53
|
/**
|
|
93
54
|
* Abstract server interface for specification runners.
|
|
94
|
-
* Integration mode uses in-process app
|
|
55
|
+
* Integration mode uses an in-process Hono app; E2E mode uses real HTTP via fetch.
|
|
95
56
|
*/
|
|
96
57
|
interface ServerPort {
|
|
97
|
-
/** Send an HTTP request and return the response. */
|
|
58
|
+
/** Send an HTTP request and return the parsed response. */
|
|
98
59
|
request(method: string, path: string, body?: unknown): Promise<ServerResponse>;
|
|
99
60
|
}
|
|
100
61
|
//#endregion
|
|
@@ -108,6 +69,10 @@ interface DirectorySnapshotOptions {
|
|
|
108
69
|
*/
|
|
109
70
|
update?: boolean;
|
|
110
71
|
}
|
|
72
|
+
/**
|
|
73
|
+
* Handle to a directory produced by a specification run.
|
|
74
|
+
* Supports snapshot-based assertions via {@link toMatchFixture} and file listing via {@link files}.
|
|
75
|
+
*/
|
|
111
76
|
declare class DirectoryAccessor {
|
|
112
77
|
private absPath;
|
|
113
78
|
private testDir;
|
|
@@ -128,30 +93,54 @@ declare class DirectoryAccessor {
|
|
|
128
93
|
}
|
|
129
94
|
//#endregion
|
|
130
95
|
//#region src/builder/response-accessor.d.ts
|
|
96
|
+
/** Accessor for an HTTP response body with file-based assertion support. */
|
|
131
97
|
declare class ResponseAccessor {
|
|
132
98
|
readonly body: unknown;
|
|
133
99
|
private testDir;
|
|
134
100
|
constructor(body: unknown, testDir: string);
|
|
101
|
+
/**
|
|
102
|
+
* Assert that the response body matches the JSON in `responses/{file}`.
|
|
103
|
+
*
|
|
104
|
+
* @example
|
|
105
|
+
* result.response.toMatchFile("expected-items.json");
|
|
106
|
+
*/
|
|
135
107
|
toMatchFile(file: string): void;
|
|
136
108
|
}
|
|
137
109
|
//#endregion
|
|
138
110
|
//#region src/builder/table-assertion.d.ts
|
|
111
|
+
/** Assertion helper for verifying database table contents after a specification run. */
|
|
139
112
|
declare class TableAssertion {
|
|
140
113
|
private tableName;
|
|
141
114
|
private db;
|
|
142
115
|
constructor(tableName: string, db: DatabasePort);
|
|
116
|
+
/**
|
|
117
|
+
* Assert that the table contains exactly the expected rows for the given columns.
|
|
118
|
+
*
|
|
119
|
+
* @example
|
|
120
|
+
* await result.table("users").toMatch({
|
|
121
|
+
* columns: ["name", "email"],
|
|
122
|
+
* rows: [["Alice", "alice@example.com"]],
|
|
123
|
+
* });
|
|
124
|
+
*/
|
|
143
125
|
toMatch(expected: {
|
|
144
126
|
columns: string[];
|
|
145
127
|
rows: unknown[][];
|
|
146
128
|
}): Promise<void>;
|
|
129
|
+
/** Assert that the table has zero rows. */
|
|
147
130
|
toBeEmpty(): Promise<void>;
|
|
148
131
|
}
|
|
149
132
|
//#endregion
|
|
150
133
|
//#region src/builder/specification-result.d.ts
|
|
134
|
+
/** Read-only handle to a single file produced by a CLI action. */
|
|
151
135
|
interface FileAccessor {
|
|
136
|
+
/** The UTF-8 text content. Throws if the file does not exist. */
|
|
152
137
|
readonly content: string;
|
|
153
138
|
readonly exists: boolean;
|
|
154
139
|
}
|
|
140
|
+
/**
|
|
141
|
+
* The outcome of a single specification run.
|
|
142
|
+
* Provides accessors for CLI output, HTTP responses, files, directories, and database tables.
|
|
143
|
+
*/
|
|
155
144
|
declare class SpecificationResult {
|
|
156
145
|
private commandResult?;
|
|
157
146
|
private config;
|
|
@@ -171,13 +160,29 @@ declare class SpecificationResult {
|
|
|
171
160
|
testDir: string;
|
|
172
161
|
workDir?: string;
|
|
173
162
|
});
|
|
163
|
+
/** The process exit code. Only available after a CLI action. */
|
|
174
164
|
get exitCode(): number;
|
|
165
|
+
/** The HTTP response status code. Only available after an HTTP action. */
|
|
175
166
|
get status(): number;
|
|
167
|
+
/** The captured standard output. Only available after a CLI action. */
|
|
176
168
|
get stdout(): string;
|
|
169
|
+
/** The captured standard error. Only available after a CLI action. */
|
|
177
170
|
get stderr(): string;
|
|
171
|
+
/**
|
|
172
|
+
* Extract text blocks from stdout that contain a pattern.
|
|
173
|
+
* Useful for parsing structured CLI output (linters, compilers).
|
|
174
|
+
*
|
|
175
|
+
* @example
|
|
176
|
+
* expect(result.grep('error.ts')).toContain('no-unused-vars');
|
|
177
|
+
*/
|
|
178
|
+
grep(pattern: string): string;
|
|
179
|
+
/** Access the HTTP response body for assertions. Only available after an HTTP action. */
|
|
178
180
|
get response(): ResponseAccessor;
|
|
181
|
+
/** Access a directory (relative to the working directory) for snapshot assertions. */
|
|
179
182
|
directory(path?: string): DirectoryAccessor;
|
|
183
|
+
/** Access a single file (relative to the working directory) for content assertions. */
|
|
180
184
|
file(path: string): FileAccessor;
|
|
185
|
+
/** Access a database table for row-level assertions. */
|
|
181
186
|
table(tableName: string, options?: {
|
|
182
187
|
service?: string;
|
|
183
188
|
}): TableAssertion;
|
|
@@ -185,6 +190,7 @@ declare class SpecificationResult {
|
|
|
185
190
|
}
|
|
186
191
|
//#endregion
|
|
187
192
|
//#region src/builder/specification-builder.d.ts
|
|
193
|
+
/** Adapter configuration passed to the specification runner at setup time. */
|
|
188
194
|
interface SpecificationConfig {
|
|
189
195
|
command?: CommandPort;
|
|
190
196
|
database?: DatabasePort;
|
|
@@ -192,6 +198,13 @@ interface SpecificationConfig {
|
|
|
192
198
|
fixturesRoot?: string;
|
|
193
199
|
server?: ServerPort;
|
|
194
200
|
}
|
|
201
|
+
/**
|
|
202
|
+
* Fluent builder for declaring a single test specification.
|
|
203
|
+
*
|
|
204
|
+
* Chain setup methods ({@link seed}, {@link fixture}, {@link env}), an action
|
|
205
|
+
* ({@link get}, {@link post}, {@link exec}), then call {@link run} to execute
|
|
206
|
+
* and receive a {@link SpecificationResult} for assertions.
|
|
207
|
+
*/
|
|
195
208
|
declare class SpecificationBuilder {
|
|
196
209
|
private commandArgs;
|
|
197
210
|
private commandEnv;
|
|
@@ -205,11 +218,20 @@ declare class SpecificationBuilder {
|
|
|
205
218
|
private spawnConfig;
|
|
206
219
|
private testDir;
|
|
207
220
|
constructor(config: SpecificationConfig, testDir: string, label: string);
|
|
221
|
+
/**
|
|
222
|
+
* Queue a SQL seed file to run before the action.
|
|
223
|
+
*
|
|
224
|
+
* @example
|
|
225
|
+
* spec("creates user").seed("users.sql").exec("list-users").run();
|
|
226
|
+
*/
|
|
208
227
|
seed(file: string, options?: {
|
|
209
228
|
service?: string;
|
|
210
229
|
}): this;
|
|
230
|
+
/** Copy a file or directory from `fixtures/` into the working directory before execution. */
|
|
211
231
|
fixture(file: string): this;
|
|
232
|
+
/** Copy an entire project fixture from `fixturesRoot` into the working directory. */
|
|
212
233
|
project(name: string): this;
|
|
234
|
+
/** Register an MSW mock definition file from `mock/` to intercept HTTP calls. */
|
|
213
235
|
mock(file: string): this;
|
|
214
236
|
/**
|
|
215
237
|
* Set environment variables for the CLI process. Merged on top of process.env.
|
|
@@ -222,26 +244,152 @@ declare class SpecificationBuilder {
|
|
|
222
244
|
* spec("...").env({ HOME: "$WORKDIR", TZ: "UTC" }).exec("status").run();
|
|
223
245
|
*/
|
|
224
246
|
env(env: CommandEnv): this;
|
|
247
|
+
/**
|
|
248
|
+
* Send a GET request to the server adapter.
|
|
249
|
+
*
|
|
250
|
+
* @example
|
|
251
|
+
* spec("list items").get("/api/items").run();
|
|
252
|
+
*/
|
|
225
253
|
get(path: string): this;
|
|
254
|
+
/**
|
|
255
|
+
* Send a POST request to the server adapter.
|
|
256
|
+
*
|
|
257
|
+
* @param bodyFile - Optional JSON file from `requests/` to use as the request body.
|
|
258
|
+
* @example
|
|
259
|
+
* spec("create item").post("/api/items", "new-item.json").run();
|
|
260
|
+
*/
|
|
226
261
|
post(path: string, bodyFile?: string): this;
|
|
262
|
+
/** Send a PUT request to the server adapter. */
|
|
227
263
|
put(path: string, bodyFile?: string): this;
|
|
264
|
+
/** Send a DELETE request to the server adapter. */
|
|
228
265
|
delete(path: string): this;
|
|
266
|
+
/**
|
|
267
|
+
* Execute a CLI command (or a sequence of commands) in an isolated working directory.
|
|
268
|
+
* When an array is passed, commands run sequentially and stop on the first non-zero exit code.
|
|
269
|
+
*
|
|
270
|
+
* @example
|
|
271
|
+
* spec("init project").exec("init --name demo").run();
|
|
272
|
+
* spec("multi-step").exec(["init", "build"]).run();
|
|
273
|
+
*/
|
|
229
274
|
exec(args: string | string[]): this;
|
|
275
|
+
/** Spawn a long-running CLI process with custom spawn options (e.g. timeout, signal). */
|
|
230
276
|
spawn(args: string, options: SpawnOptions): this;
|
|
277
|
+
/**
|
|
278
|
+
* Execute the specification: run seeds, copy fixtures, then perform the
|
|
279
|
+
* configured action (HTTP or CLI).
|
|
280
|
+
*
|
|
281
|
+
* @returns The result object used for assertions.
|
|
282
|
+
* @example
|
|
283
|
+
* const result = await spec("test").exec("status").run();
|
|
284
|
+
* expect(result.exitCode).toBe(0);
|
|
285
|
+
*/
|
|
231
286
|
run(): Promise<SpecificationResult>;
|
|
232
287
|
private resolveEnv;
|
|
233
288
|
private prepareWorkDir;
|
|
234
289
|
private runHttpAction;
|
|
235
290
|
private runCliAction;
|
|
236
291
|
}
|
|
292
|
+
/** Factory function returned by `cli()`, `integration()`, or `e2e()` that starts a new spec. */
|
|
237
293
|
type SpecificationRunner = (label: string) => SpecificationBuilder;
|
|
294
|
+
/**
|
|
295
|
+
* Create a {@link SpecificationRunner} bound to the given adapter configuration.
|
|
296
|
+
* The test file directory is auto-detected from the call stack.
|
|
297
|
+
*/
|
|
238
298
|
declare function createSpecificationRunner(config: SpecificationConfig): SpecificationRunner;
|
|
239
299
|
//#endregion
|
|
300
|
+
//#region src/docker/docker-port.d.ts
|
|
301
|
+
/** Abstract interface for interacting with a Docker container (exec, inspect, file I/O). */
|
|
302
|
+
interface DockerContainerPort {
|
|
303
|
+
/** Execute a command inside the container, return stdout */
|
|
304
|
+
exec(cmd: string[]): Promise<string>;
|
|
305
|
+
/** Read a file from inside the container */
|
|
306
|
+
file(path: string): Promise<{
|
|
307
|
+
exists: boolean;
|
|
308
|
+
content: string;
|
|
309
|
+
}>;
|
|
310
|
+
/** Check if container is running */
|
|
311
|
+
isRunning(): Promise<boolean>;
|
|
312
|
+
/** Get container logs */
|
|
313
|
+
logs(tail?: number): Promise<string>;
|
|
314
|
+
/** Get full docker inspect JSON */
|
|
315
|
+
inspect(): Promise<DockerInspectResult>;
|
|
316
|
+
/** Check if a file/directory exists */
|
|
317
|
+
exists(path: string): Promise<boolean>;
|
|
318
|
+
}
|
|
319
|
+
/** Normalized subset of `docker inspect` output for assertion use. */
|
|
320
|
+
interface DockerInspectResult {
|
|
321
|
+
id: string;
|
|
322
|
+
name: string;
|
|
323
|
+
state: {
|
|
324
|
+
running: boolean;
|
|
325
|
+
exitCode: number;
|
|
326
|
+
status: string;
|
|
327
|
+
};
|
|
328
|
+
config: {
|
|
329
|
+
image: string;
|
|
330
|
+
env: string[];
|
|
331
|
+
};
|
|
332
|
+
hostConfig: {
|
|
333
|
+
memory: number;
|
|
334
|
+
cpuQuota: number;
|
|
335
|
+
networkMode: string;
|
|
336
|
+
mounts: Array<{
|
|
337
|
+
source: string;
|
|
338
|
+
destination: string;
|
|
339
|
+
type: string;
|
|
340
|
+
}>;
|
|
341
|
+
};
|
|
342
|
+
networkSettings: {
|
|
343
|
+
networks: Record<string, {
|
|
344
|
+
gateway: string;
|
|
345
|
+
ipAddress: string;
|
|
346
|
+
}>;
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
//#endregion
|
|
350
|
+
//#region src/docker/docker-assertion.d.ts
|
|
351
|
+
/**
|
|
352
|
+
* Fluent assertion builder for Docker containers.
|
|
353
|
+
* Chain async assertions like `toBeRunning()`, `toHaveFile()`, `toHaveMount()`.
|
|
354
|
+
*/
|
|
355
|
+
declare class DockerAssertion {
|
|
356
|
+
private container;
|
|
357
|
+
constructor(container: DockerContainerPort);
|
|
358
|
+
/** Assert the container is running */
|
|
359
|
+
toBeRunning(): Promise<this>;
|
|
360
|
+
/** Assert the container is NOT running / doesn't exist */
|
|
361
|
+
toNotExist(): Promise<this>;
|
|
362
|
+
/** Assert a file exists inside the container */
|
|
363
|
+
toHaveFile(path: string, opts?: {
|
|
364
|
+
containing?: string;
|
|
365
|
+
}): Promise<this>;
|
|
366
|
+
/** Assert a file does NOT exist */
|
|
367
|
+
toNotHaveFile(path: string): Promise<this>;
|
|
368
|
+
/** Assert a directory exists */
|
|
369
|
+
toHaveDirectory(path: string): Promise<this>;
|
|
370
|
+
/** Assert a mount exists */
|
|
371
|
+
toHaveMount(destination: string): Promise<this>;
|
|
372
|
+
/** Assert network mode */
|
|
373
|
+
toHaveNetwork(mode: string): Promise<this>;
|
|
374
|
+
/** Assert memory limit */
|
|
375
|
+
toHaveMemoryLimit(bytes: number): Promise<this>;
|
|
376
|
+
/** Assert CPU quota */
|
|
377
|
+
toHaveCpuQuota(quota: number): Promise<this>;
|
|
378
|
+
/** Execute a command and return output for custom assertions */
|
|
379
|
+
exec(cmd: string[]): Promise<string>;
|
|
380
|
+
/** Read a file for custom assertions */
|
|
381
|
+
readFile(path: string): Promise<string>;
|
|
382
|
+
/** Get logs for custom assertions */
|
|
383
|
+
getLogs(tail?: number): Promise<string>;
|
|
384
|
+
}
|
|
385
|
+
//#endregion
|
|
240
386
|
//#region src/orchestrator/orchestrator.d.ts
|
|
241
387
|
interface OrchestratorOptions {
|
|
242
388
|
services: ServiceHandle[];
|
|
243
389
|
mode: 'e2e' | 'integration';
|
|
244
390
|
root?: string;
|
|
391
|
+
/** Compose project name — used for per-worker stack isolation. */
|
|
392
|
+
projectName?: string;
|
|
245
393
|
}
|
|
246
394
|
/**
|
|
247
395
|
* Orchestrator for test infrastructure.
|
|
@@ -252,6 +400,7 @@ declare class Orchestrator {
|
|
|
252
400
|
private services;
|
|
253
401
|
private mode;
|
|
254
402
|
private root;
|
|
403
|
+
private projectName;
|
|
255
404
|
private running;
|
|
256
405
|
private composeStack;
|
|
257
406
|
private composeHandles;
|
|
@@ -290,54 +439,107 @@ declare class Orchestrator {
|
|
|
290
439
|
getAppUrl(): null | string;
|
|
291
440
|
}
|
|
292
441
|
//#endregion
|
|
293
|
-
//#region src/runner/
|
|
294
|
-
type HonoApp = {
|
|
442
|
+
//#region src/runner/targets.d.ts
|
|
443
|
+
type HonoApp$1 = {
|
|
295
444
|
fetch: (...args: any[]) => any;
|
|
296
445
|
request: (path: string, init?: RequestInit) => Promise<Response> | Response;
|
|
297
446
|
};
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
}
|
|
306
|
-
interface
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
}
|
|
447
|
+
/** Services map passed to the app factory after infrastructure starts. */
|
|
448
|
+
type AppServices = Record<string, ServiceHandle>;
|
|
449
|
+
/** In-process Hono app target. Created by {@link app}. */
|
|
450
|
+
interface AppTarget {
|
|
451
|
+
readonly kind: 'app';
|
|
452
|
+
readonly factory: (services: AppServices) => HonoApp$1;
|
|
453
|
+
}
|
|
454
|
+
/** Docker compose stack target. Created by {@link stack}. */
|
|
455
|
+
interface StackTarget {
|
|
456
|
+
readonly kind: 'stack';
|
|
457
|
+
readonly root: string;
|
|
458
|
+
}
|
|
459
|
+
/** CLI command target. Created by {@link command}. */
|
|
460
|
+
interface CommandTarget {
|
|
461
|
+
readonly kind: 'command';
|
|
462
|
+
readonly bin: string;
|
|
463
|
+
}
|
|
464
|
+
/** Any target that produces an HTTP interface (app or stack). */
|
|
465
|
+
type HttpTarget = AppTarget | StackTarget;
|
|
466
|
+
/** Any valid spec target. */
|
|
467
|
+
type SpecTarget = AppTarget | CommandTarget | StackTarget;
|
|
310
468
|
/**
|
|
311
|
-
*
|
|
312
|
-
*
|
|
469
|
+
* Test against an in-process Hono app. The factory receives started services
|
|
470
|
+
* so you can wire connection strings into your app/DI container.
|
|
471
|
+
*
|
|
472
|
+
* @param factory - Function that receives services and returns a Hono app instance.
|
|
473
|
+
*
|
|
474
|
+
* @example
|
|
475
|
+
* const db = postgres({ compose: 'db' });
|
|
476
|
+
* await spec(
|
|
477
|
+
* app((services) => createApp({ databaseUrl: services.db.connectionString })),
|
|
478
|
+
* { services: [db] },
|
|
479
|
+
* );
|
|
313
480
|
*/
|
|
314
|
-
declare function
|
|
315
|
-
//#endregion
|
|
316
|
-
//#region src/runner/cli.d.ts
|
|
317
|
-
interface CliOptions {
|
|
318
|
-
/** CLI command to run (resolved from node_modules/.bin or PATH). */
|
|
319
|
-
command: string;
|
|
320
|
-
/** Project root — base dir for .project() fixture lookup (relative paths supported). */
|
|
321
|
-
root?: string;
|
|
322
|
-
/** Optional infrastructure services (started via testcontainers). */
|
|
323
|
-
services?: ServiceHandle[];
|
|
324
|
-
}
|
|
481
|
+
declare function app(factory: (services: AppServices) => HonoApp$1): AppTarget;
|
|
325
482
|
/**
|
|
326
|
-
*
|
|
327
|
-
*
|
|
483
|
+
* Test against a full docker compose stack. The stack is started with
|
|
484
|
+
* `docker compose up` and real HTTP requests are sent to the app service.
|
|
485
|
+
*
|
|
486
|
+
* @param root - Project root containing `docker/compose.test.yaml`.
|
|
487
|
+
*
|
|
488
|
+
* @example
|
|
489
|
+
* await spec(stack('../../'));
|
|
328
490
|
*/
|
|
329
|
-
declare function
|
|
491
|
+
declare function stack(root: string): StackTarget;
|
|
492
|
+
/**
|
|
493
|
+
* Test a CLI binary. Each spec runs in a fresh temp directory.
|
|
494
|
+
*
|
|
495
|
+
* @param bin - Path to the CLI binary or command name (resolved from node_modules/.bin or PATH).
|
|
496
|
+
*
|
|
497
|
+
* @example
|
|
498
|
+
* await spec(command('my-cli'), { root: '../fixtures' });
|
|
499
|
+
*/
|
|
500
|
+
declare function command(bin: string): CommandTarget;
|
|
330
501
|
//#endregion
|
|
331
|
-
//#region src/runner/
|
|
332
|
-
|
|
333
|
-
|
|
502
|
+
//#region src/runner/spec.d.ts
|
|
503
|
+
/** Shared options for all spec targets. */
|
|
504
|
+
interface SpecOptions {
|
|
505
|
+
/** Project root for fixture lookup and compose detection (relative paths supported). */
|
|
334
506
|
root?: string;
|
|
507
|
+
/** Infrastructure services to start via testcontainers. */
|
|
508
|
+
services?: ServiceHandle[];
|
|
509
|
+
}
|
|
510
|
+
/** A specification runner with teardown support and orchestrator access. */
|
|
511
|
+
interface SpecRunner {
|
|
512
|
+
/** The function to create individual specs: `runner('label').get('/path').run()`. */
|
|
513
|
+
(label: string): SpecificationBuilder;
|
|
514
|
+
/** Stop all infrastructure started by this runner. */
|
|
515
|
+
cleanup: () => Promise<void>;
|
|
516
|
+
/**
|
|
517
|
+
* Get a Docker assertion builder for a running container.
|
|
518
|
+
*
|
|
519
|
+
* @example
|
|
520
|
+
* await runner.docker('my-container').toBeRunning();
|
|
521
|
+
*/
|
|
522
|
+
docker: (containerId: string) => DockerAssertion;
|
|
523
|
+
/** The orchestrator managing the test infrastructure lifecycle. */
|
|
524
|
+
orchestrator: Orchestrator;
|
|
335
525
|
}
|
|
336
526
|
/**
|
|
337
|
-
* Create
|
|
338
|
-
*
|
|
527
|
+
* Create a specification runner for the given target.
|
|
528
|
+
*
|
|
529
|
+
* @param target - What to test against: {@link app}, {@link stack}, or {@link command}.
|
|
530
|
+
* @param options - Shared options: root directory, infrastructure services.
|
|
531
|
+
*
|
|
532
|
+
* @example
|
|
533
|
+
* // HTTP — in-process app with testcontainers
|
|
534
|
+
* const s = await spec(app(() => createApp(db)), { services: [db] });
|
|
535
|
+
*
|
|
536
|
+
* // HTTP — full docker compose stack
|
|
537
|
+
* const s = await spec(stack('../../'));
|
|
538
|
+
*
|
|
539
|
+
* // CLI — command binary
|
|
540
|
+
* const s = await spec(command('my-cli'), { root: '../fixtures' });
|
|
339
541
|
*/
|
|
340
|
-
declare function
|
|
542
|
+
declare function spec(target: SpecTarget, options?: SpecOptions): Promise<SpecRunner>;
|
|
341
543
|
//#endregion
|
|
342
544
|
//#region src/ports/container.port.d.ts
|
|
343
545
|
/**
|
|
@@ -361,8 +563,9 @@ interface ContainerPort {
|
|
|
361
563
|
//#endregion
|
|
362
564
|
//#region src/adapters/exec.adapter.d.ts
|
|
363
565
|
/**
|
|
364
|
-
* Executes CLI commands via
|
|
365
|
-
*
|
|
566
|
+
* Executes CLI commands via Node.js child_process.
|
|
567
|
+
* Uses `execSync` for one-shot commands and `spawn` for long-running processes.
|
|
568
|
+
* Used by the `cli()` specification runner.
|
|
366
569
|
*/
|
|
367
570
|
declare class ExecAdapter implements CommandPort {
|
|
368
571
|
private command;
|
|
@@ -373,8 +576,8 @@ declare class ExecAdapter implements CommandPort {
|
|
|
373
576
|
//#endregion
|
|
374
577
|
//#region src/adapters/fetch.adapter.d.ts
|
|
375
578
|
/**
|
|
376
|
-
* Server adapter
|
|
377
|
-
* Used by e2e() specification runner.
|
|
579
|
+
* Server adapter that sends real HTTP requests via the Fetch API.
|
|
580
|
+
* Used by the `e2e()` specification runner to hit a live server.
|
|
378
581
|
*/
|
|
379
582
|
declare class FetchAdapter implements ServerPort {
|
|
380
583
|
private baseUrl;
|
|
@@ -384,8 +587,8 @@ declare class FetchAdapter implements ServerPort {
|
|
|
384
587
|
//#endregion
|
|
385
588
|
//#region src/adapters/hono.adapter.d.ts
|
|
386
589
|
/**
|
|
387
|
-
* Server adapter
|
|
388
|
-
* Used by integration() specification runner.
|
|
590
|
+
* Server adapter that dispatches requests in-process through a Hono app instance.
|
|
591
|
+
* Used by the `integration()` specification runner -- no network overhead.
|
|
389
592
|
*/
|
|
390
593
|
declare class HonoAdapter implements ServerPort {
|
|
391
594
|
private app;
|
|
@@ -395,158 +598,57 @@ declare class HonoAdapter implements ServerPort {
|
|
|
395
598
|
request(method: string, path: string, body?: unknown): Promise<ServerResponse>;
|
|
396
599
|
}
|
|
397
600
|
//#endregion
|
|
398
|
-
//#region src/
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
/**
|
|
405
|
-
|
|
601
|
+
//#region src/runner/integration.d.ts
|
|
602
|
+
type HonoApp = {
|
|
603
|
+
fetch: (...args: any[]) => any;
|
|
604
|
+
request: (path: string, init?: RequestInit) => Promise<Response> | Response;
|
|
605
|
+
};
|
|
606
|
+
interface IntegrationOptions {
|
|
607
|
+
/** Factory that returns a Hono app — called after services start. */
|
|
608
|
+
app: () => HonoApp;
|
|
609
|
+
/** Project root for compose detection (relative paths supported). */
|
|
610
|
+
root?: string;
|
|
611
|
+
/** Declared services — started via testcontainers. */
|
|
612
|
+
services: ServiceHandle[];
|
|
406
613
|
}
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
connectionString: string;
|
|
414
|
-
started: boolean;
|
|
415
|
-
private client;
|
|
416
|
-
constructor(options?: PostgresOptions);
|
|
417
|
-
buildConnectionString(host: string, port: number): string;
|
|
418
|
-
createDatabaseAdapter(): DatabasePort;
|
|
419
|
-
healthcheck(): Promise<void>;
|
|
420
|
-
initialize(composeDir: string): Promise<void>;
|
|
421
|
-
private getClient;
|
|
422
|
-
seed(sql: string): Promise<void>;
|
|
423
|
-
query(table: string, columns: string[]): Promise<unknown[][]>;
|
|
424
|
-
reset(): Promise<void>;
|
|
614
|
+
/** A specification runner that also exposes teardown and the underlying orchestrator. */
|
|
615
|
+
interface SpecificationRunnerWithCleanup extends SpecificationRunner {
|
|
616
|
+
/** Stop all infrastructure containers started by this runner. */
|
|
617
|
+
cleanup: () => Promise<void>;
|
|
618
|
+
/** The orchestrator managing the test infrastructure lifecycle. */
|
|
619
|
+
orchestrator: Orchestrator;
|
|
425
620
|
}
|
|
426
621
|
/**
|
|
427
|
-
* Create
|
|
428
|
-
*
|
|
429
|
-
* @example
|
|
430
|
-
* const db = postgres({ compose: "db" });
|
|
431
|
-
* // After start: db.connectionString is populated
|
|
622
|
+
* Create an integration specification runner.
|
|
623
|
+
* Starts infra containers via testcontainers, app runs in-process.
|
|
432
624
|
*/
|
|
433
|
-
declare function
|
|
625
|
+
declare function integration(options: IntegrationOptions): Promise<SpecificationRunnerWithCleanup>;
|
|
434
626
|
//#endregion
|
|
435
|
-
//#region src/
|
|
436
|
-
interface
|
|
437
|
-
/**
|
|
438
|
-
|
|
439
|
-
/**
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
readonly type = "redis";
|
|
444
|
-
readonly composeName: null | string;
|
|
445
|
-
readonly defaultPort = 6379;
|
|
446
|
-
readonly defaultImage: string;
|
|
447
|
-
readonly environment: Record<string, string>;
|
|
448
|
-
connectionString: string;
|
|
449
|
-
started: boolean;
|
|
450
|
-
constructor(options?: RedisOptions);
|
|
451
|
-
buildConnectionString(host: string, port: number): string;
|
|
452
|
-
createDatabaseAdapter(): DatabasePort | null;
|
|
453
|
-
healthcheck(): Promise<void>;
|
|
454
|
-
initialize(): Promise<void>;
|
|
455
|
-
reset(): Promise<void>;
|
|
627
|
+
//#region src/runner/cli.d.ts
|
|
628
|
+
interface CliOptions {
|
|
629
|
+
/** CLI command to run (resolved from node_modules/.bin or PATH). */
|
|
630
|
+
command: string;
|
|
631
|
+
/** Project root — base dir for .project() fixture lookup (relative paths supported). */
|
|
632
|
+
root?: string;
|
|
633
|
+
/** Optional infrastructure services (started via testcontainers). */
|
|
634
|
+
services?: ServiceHandle[];
|
|
456
635
|
}
|
|
457
636
|
/**
|
|
458
|
-
* Create a
|
|
459
|
-
*
|
|
460
|
-
* @example
|
|
461
|
-
* const cache = redis({ compose: "cache" });
|
|
462
|
-
* // After start: cache.connectionString is populated
|
|
637
|
+
* Create a CLI specification runner.
|
|
638
|
+
* Runs CLI commands against fixture projects. Optionally starts infrastructure.
|
|
463
639
|
*/
|
|
464
|
-
declare function
|
|
465
|
-
//#endregion
|
|
466
|
-
//#region src/docker/docker-port.d.ts
|
|
467
|
-
interface DockerContainerPort {
|
|
468
|
-
/** Execute a command inside the container, return stdout */
|
|
469
|
-
exec(cmd: string[]): Promise<string>;
|
|
470
|
-
/** Read a file from inside the container */
|
|
471
|
-
file(path: string): Promise<{
|
|
472
|
-
exists: boolean;
|
|
473
|
-
content: string;
|
|
474
|
-
}>;
|
|
475
|
-
/** Check if container is running */
|
|
476
|
-
isRunning(): Promise<boolean>;
|
|
477
|
-
/** Get container logs */
|
|
478
|
-
logs(tail?: number): Promise<string>;
|
|
479
|
-
/** Get full docker inspect JSON */
|
|
480
|
-
inspect(): Promise<DockerInspectResult>;
|
|
481
|
-
/** Check if a file/directory exists */
|
|
482
|
-
exists(path: string): Promise<boolean>;
|
|
483
|
-
}
|
|
484
|
-
interface DockerInspectResult {
|
|
485
|
-
id: string;
|
|
486
|
-
name: string;
|
|
487
|
-
state: {
|
|
488
|
-
running: boolean;
|
|
489
|
-
exitCode: number;
|
|
490
|
-
status: string;
|
|
491
|
-
};
|
|
492
|
-
config: {
|
|
493
|
-
image: string;
|
|
494
|
-
env: string[];
|
|
495
|
-
};
|
|
496
|
-
hostConfig: {
|
|
497
|
-
memory: number;
|
|
498
|
-
cpuQuota: number;
|
|
499
|
-
networkMode: string;
|
|
500
|
-
mounts: Array<{
|
|
501
|
-
source: string;
|
|
502
|
-
destination: string;
|
|
503
|
-
type: string;
|
|
504
|
-
}>;
|
|
505
|
-
};
|
|
506
|
-
networkSettings: {
|
|
507
|
-
networks: Record<string, {
|
|
508
|
-
gateway: string;
|
|
509
|
-
ipAddress: string;
|
|
510
|
-
}>;
|
|
511
|
-
};
|
|
512
|
-
}
|
|
513
|
-
//#endregion
|
|
514
|
-
//#region src/docker/docker-adapter.d.ts
|
|
515
|
-
/** Create a Docker container port for an existing container */
|
|
516
|
-
declare function dockerContainer(containerId: string): DockerContainerPort;
|
|
640
|
+
declare function cli(options: CliOptions): Promise<SpecificationRunnerWithCleanup>;
|
|
517
641
|
//#endregion
|
|
518
|
-
//#region src/
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
constructor(container: DockerContainerPort);
|
|
523
|
-
/** Assert the container is running */
|
|
524
|
-
toBeRunning(): Promise<this>;
|
|
525
|
-
/** Assert the container is NOT running / doesn't exist */
|
|
526
|
-
toNotExist(): Promise<this>;
|
|
527
|
-
/** Assert a file exists inside the container */
|
|
528
|
-
toHaveFile(path: string, opts?: {
|
|
529
|
-
containing?: string;
|
|
530
|
-
}): Promise<this>;
|
|
531
|
-
/** Assert a file does NOT exist */
|
|
532
|
-
toNotHaveFile(path: string): Promise<this>;
|
|
533
|
-
/** Assert a directory exists */
|
|
534
|
-
toHaveDirectory(path: string): Promise<this>;
|
|
535
|
-
/** Assert a mount exists */
|
|
536
|
-
toHaveMount(destination: string): Promise<this>;
|
|
537
|
-
/** Assert network mode */
|
|
538
|
-
toHaveNetwork(mode: string): Promise<this>;
|
|
539
|
-
/** Assert memory limit */
|
|
540
|
-
toHaveMemoryLimit(bytes: number): Promise<this>;
|
|
541
|
-
/** Assert CPU quota */
|
|
542
|
-
toHaveCpuQuota(quota: number): Promise<this>;
|
|
543
|
-
/** Execute a command and return output for custom assertions */
|
|
544
|
-
exec(cmd: string[]): Promise<string>;
|
|
545
|
-
/** Read a file for custom assertions */
|
|
546
|
-
readFile(path: string): Promise<string>;
|
|
547
|
-
/** Get logs for custom assertions */
|
|
548
|
-
getLogs(tail?: number): Promise<string>;
|
|
642
|
+
//#region src/runner/e2e.d.ts
|
|
643
|
+
interface E2eOptions {
|
|
644
|
+
/** Project root — must contain docker/compose.test.yaml. */
|
|
645
|
+
root?: string;
|
|
549
646
|
}
|
|
647
|
+
/**
|
|
648
|
+
* Create an E2E specification runner.
|
|
649
|
+
* Starts full docker compose stack. App URL and database auto-detected.
|
|
650
|
+
*/
|
|
651
|
+
declare function e2e(options?: E2eOptions): Promise<SpecificationRunnerWithCleanup>;
|
|
550
652
|
//#endregion
|
|
551
653
|
//#region src/utilities/grep.d.ts
|
|
552
654
|
/**
|
|
@@ -561,19 +663,14 @@ declare class DockerAssertion {
|
|
|
561
663
|
declare function grep(output: string, pattern: string): string;
|
|
562
664
|
//#endregion
|
|
563
665
|
//#region src/utilities/reporter.d.ts
|
|
666
|
+
/** Strip ANSI escape codes from a string. */
|
|
564
667
|
declare function stripAnsi(str: string): string;
|
|
668
|
+
/** Strip ANSI codes and replace volatile tokens (ports, durations) with placeholders. */
|
|
565
669
|
declare function normalizeOutput(str: string): string;
|
|
566
670
|
//#endregion
|
|
567
|
-
//#region src/
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
set: (date: Date | number | string) => void;
|
|
571
|
-
}
|
|
572
|
-
declare const mockOfDate: MockDatePort;
|
|
573
|
-
//#endregion
|
|
574
|
-
//#region src/mocking/mock-of.d.ts
|
|
575
|
-
type MockPort = <T>() => DeepMockProxy<T>;
|
|
576
|
-
declare const mockOf: MockPort;
|
|
671
|
+
//#region src/docker/docker-adapter.d.ts
|
|
672
|
+
/** Create a {@link DockerContainerPort} bound to an existing container by ID. */
|
|
673
|
+
declare function dockerContainer(containerId: string): DockerContainerPort;
|
|
577
674
|
//#endregion
|
|
578
|
-
export { type CliOptions, type CommandEnv, type CommandPort, type CommandResult, type ContainerPort, type DatabasePort, DirectoryAccessor, type DirectorySnapshotOptions, DockerAssertion, type DockerContainerPort, type DockerInspectResult, type E2eOptions, ExecAdapter, FetchAdapter, type FileAccessor, HonoAdapter, type IntegrationOptions, type MockDatePort, type MockPort, Orchestrator, type PostgresOptions, type RedisOptions, ResponseAccessor, type ServerPort, type ServerResponse, type ServiceHandle, type SpawnOptions, SpecificationBuilder, type SpecificationConfig, SpecificationResult, type SpecificationRunner, type SpecificationRunnerWithCleanup, TableAssertion, cli, createSpecificationRunner, dockerContainer, e2e, grep, integration, mockOf, mockOfDate, normalizeOutput, postgres, redis, stripAnsi };
|
|
675
|
+
export { type AppServices, type AppTarget, type CliOptions, type CommandEnv, type CommandPort, type CommandResult, type CommandTarget, type ContainerPort, type DatabasePort, DirectoryAccessor, type DirectorySnapshotOptions, DockerAssertion, type DockerContainerPort, type DockerInspectResult, type E2eOptions, ExecAdapter, FetchAdapter, type FileAccessor, HonoAdapter, type HttpTarget, type IntegrationOptions, type IsolationStrategy, type MockDatePort, type MockPort, Orchestrator, type PostgresOptions, type RedisOptions, ResponseAccessor, type ServerPort, type ServerResponse, type ServiceHandle, type SpawnOptions, type SpecOptions, type SpecRunner, type SpecTarget, SpecificationBuilder, type SpecificationConfig, SpecificationResult, type SpecificationRunner, type SpecificationRunnerWithCleanup, type SqliteOptions, type StackTarget, TableAssertion, app, cli, command, createSpecificationRunner, dockerContainer, e2e, grep, integration, mockOf, mockOfDate, normalizeOutput, postgres, redis, spec, sqlite, stack, stripAnsi };
|
|
579
676
|
//# sourceMappingURL=index.d.cts.map
|