@jterrazz/test 4.0.1 → 5.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/dist/index.d.ts CHANGED
@@ -110,99 +110,6 @@ declare class Orchestrator {
110
110
  getAppUrl(): null | string;
111
111
  }
112
112
  //#endregion
113
- //#region src/specification/assertions/base.d.ts
114
- /**
115
- * Base assertion that handles .not negation.
116
- * Subclasses call this.assert(condition, message, negatedMessage) for each predicate.
117
- */
118
- declare class BaseAssertion {
119
- protected negated: boolean;
120
- get not(): this;
121
- protected assert(condition: boolean, message: string, negatedMessage: string): void;
122
- }
123
- //#endregion
124
- //#region src/specification/assertions/file.d.ts
125
- /**
126
- * Assertions on a file in the working directory.
127
- * Usage: result.file("dist/index.js").toExist()
128
- */
129
- declare class FileAssertion extends BaseAssertion {
130
- private filePath;
131
- private resolvedPath;
132
- constructor(filePath: string, workDir: string);
133
- toExist(): void;
134
- toContain(expected: string): void;
135
- toMatch(pattern: RegExp): void;
136
- }
137
- //#endregion
138
- //#region src/specification/assertions/response.d.ts
139
- /**
140
- * Assertions on an HTTP response body.
141
- * Usage: result.response.toMatchFile("expected.json")
142
- */
143
- declare class ResponseAssertion extends BaseAssertion {
144
- private body;
145
- private testDir;
146
- constructor(body: unknown, testDir: string);
147
- toMatchFile(file: string): void;
148
- toContain(subset: Record<string, unknown>): void;
149
- }
150
- //#endregion
151
- //#region src/specification/assertions/string.d.ts
152
- /**
153
- * Assertions on a string (stdout, stderr, response body).
154
- * Usage: result.stdout.toContain("hello")
155
- */
156
- declare class StringAssertion extends BaseAssertion {
157
- private actual;
158
- private label;
159
- private testDir?;
160
- constructor(actual: string, label: string, testDir?: string);
161
- toContain(expected: string, options?: {
162
- near?: string;
163
- }): void;
164
- toMatch(pattern: RegExp): void;
165
- toMatchFile(file: string): void;
166
- toBeEmpty(): void;
167
- private containsNear;
168
- private stripAnsi;
169
- private truncate;
170
- }
171
- //#endregion
172
- //#region src/specification/assertions/table.d.ts
173
- /**
174
- * Assertions on a database table.
175
- * Usage: await result.table("users").toMatch({ columns: ["name"], rows: [["Alice"]] })
176
- */
177
- declare class TableAssertion extends BaseAssertion {
178
- private tableName;
179
- private db;
180
- constructor(tableName: string, db: DatabasePort);
181
- toMatch(expected: {
182
- columns: string[];
183
- rows: unknown[][];
184
- }): Promise<void>;
185
- toBeEmpty(): Promise<void>;
186
- }
187
- //#endregion
188
- //#region src/specification/assertions/value.d.ts
189
- /**
190
- * Assertions on a single value (exit code, status code).
191
- * Usage: result.exitCode.toBe(0)
192
- */
193
- declare class ValueAssertion extends BaseAssertion {
194
- private actual;
195
- private label;
196
- private context?;
197
- constructor(actual: number, label: string, context?: {
198
- request?: any;
199
- responseBody?: unknown;
200
- stdout?: string;
201
- stderr?: string;
202
- });
203
- toBe(expected: number): void;
204
- }
205
- //#endregion
206
113
  //#region src/specification/ports/command.port.d.ts
207
114
  /**
208
115
  * Result of executing a CLI command.
@@ -221,15 +128,20 @@ interface SpawnOptions {
221
128
  /** Kill the process after this many milliseconds. */
222
129
  timeout: number;
223
130
  }
131
+ /**
132
+ * Extra environment variables to set for the child process.
133
+ * Values are merged on top of process.env. A `null` value unsets the variable.
134
+ */
135
+ type CommandEnv = Record<string, null | string>;
224
136
  /**
225
137
  * Abstract CLI interface for specification runners.
226
138
  * Implement this to plug in your command execution strategy.
227
139
  */
228
140
  interface CommandPort {
229
141
  /** Execute a CLI command with the given arguments in the given working directory. */
230
- exec(args: string, cwd: string): Promise<CommandResult>;
142
+ exec(args: string, cwd: string, env?: CommandEnv): Promise<CommandResult>;
231
143
  /** Spawn a long-running process and wait for a pattern or timeout. */
232
- spawn(args: string, cwd: string, options: SpawnOptions): Promise<CommandResult>;
144
+ spawn(args: string, cwd: string, options: SpawnOptions, env?: CommandEnv): Promise<CommandResult>;
233
145
  }
234
146
  //#endregion
235
147
  //#region src/specification/ports/server.port.d.ts
@@ -258,10 +170,52 @@ interface SpecificationConfig {
258
170
  fixturesRoot?: string;
259
171
  server?: ServerPort;
260
172
  }
261
- interface RequestInfo {
262
- body?: unknown;
263
- method: string;
264
- path: string;
173
+ interface FileAccessor {
174
+ readonly content: string;
175
+ readonly exists: boolean;
176
+ }
177
+ declare class TableAssertion {
178
+ private tableName;
179
+ private db;
180
+ constructor(tableName: string, db: DatabasePort);
181
+ toMatch(expected: {
182
+ columns: string[];
183
+ rows: unknown[][];
184
+ }): Promise<void>;
185
+ toBeEmpty(): Promise<void>;
186
+ }
187
+ interface DirectorySnapshotOptions {
188
+ /** Extra path segments to ignore (in addition to default: .git, node_modules, etc.). */
189
+ ignore?: string[];
190
+ /**
191
+ * Force update mode regardless of vitest flags / env vars.
192
+ * `true` writes the fixture, `false` always asserts. Defaults to auto-detect.
193
+ */
194
+ update?: boolean;
195
+ }
196
+ declare class DirectoryAccessor {
197
+ private absPath;
198
+ private testDir;
199
+ constructor(absPath: string, testDir: string);
200
+ /**
201
+ * Compare the directory tree against `expected/{name}/` (relative to the test file).
202
+ * On mismatch, throws with a structured diff. With update mode enabled, the
203
+ * fixture is overwritten with the current contents instead.
204
+ */
205
+ toMatchFixture(name: string, options?: DirectorySnapshotOptions): Promise<void>;
206
+ /**
207
+ * List all files in the directory (recursive, sorted, ignoring defaults).
208
+ * Useful for ad-hoc assertions when you don't want a full snapshot.
209
+ */
210
+ files(options?: {
211
+ ignore?: string[];
212
+ }): Promise<string[]>;
213
+ }
214
+ declare class ResponseAccessor {
215
+ readonly body: unknown;
216
+ private testDir;
217
+ constructor(body: unknown, testDir: string);
218
+ toMatchFile(file: string): void;
265
219
  }
266
220
  declare class SpecificationResult {
267
221
  private commandResult?;
@@ -273,17 +227,22 @@ declare class SpecificationResult {
273
227
  constructor(options: {
274
228
  commandResult?: CommandResult;
275
229
  config: SpecificationConfig;
276
- requestInfo?: RequestInfo;
230
+ requestInfo?: {
231
+ body?: unknown;
232
+ method: string;
233
+ path: string;
234
+ };
277
235
  response?: ServerResponse;
278
236
  testDir: string;
279
237
  workDir?: string;
280
238
  });
281
- get exitCode(): ValueAssertion;
282
- get status(): ValueAssertion;
283
- get response(): ResponseAssertion;
284
- get stdout(): StringAssertion;
285
- get stderr(): StringAssertion;
286
- file(path: string): FileAssertion;
239
+ get exitCode(): number;
240
+ get status(): number;
241
+ get stdout(): string;
242
+ get stderr(): string;
243
+ get response(): ResponseAccessor;
244
+ directory(path?: string): DirectoryAccessor;
245
+ file(path: string): FileAccessor;
287
246
  table(tableName: string, options?: {
288
247
  service?: string;
289
248
  }): TableAssertion;
@@ -291,6 +250,7 @@ declare class SpecificationResult {
291
250
  }
292
251
  declare class SpecificationBuilder {
293
252
  private commandArgs;
253
+ private commandEnv;
294
254
  private config;
295
255
  private fixtures;
296
256
  private label;
@@ -307,6 +267,17 @@ declare class SpecificationBuilder {
307
267
  fixture(file: string): this;
308
268
  project(name: string): this;
309
269
  mock(file: string): this;
270
+ /**
271
+ * Set environment variables for the CLI process. Merged on top of process.env.
272
+ * Use `null` to unset a variable. Multiple calls merge.
273
+ *
274
+ * The token `$WORKDIR` (in any value) is replaced with the actual working
275
+ * directory at run-time — useful for tests that need a fully isolated `HOME`.
276
+ *
277
+ * @example
278
+ * spec("...").env({ HOME: "$WORKDIR", TZ: "UTC" }).exec("status").run();
279
+ */
280
+ env(env: CommandEnv): this;
310
281
  get(path: string): this;
311
282
  post(path: string, bodyFile?: string): this;
312
283
  put(path: string, bodyFile?: string): this;
@@ -314,6 +285,7 @@ declare class SpecificationBuilder {
314
285
  exec(args: string | string[]): this;
315
286
  spawn(args: string, options: SpawnOptions): this;
316
287
  run(): Promise<SpecificationResult>;
288
+ private resolveEnv;
317
289
  private prepareWorkDir;
318
290
  private runHttpAction;
319
291
  private runCliAction;
@@ -396,8 +368,8 @@ declare function redis(options?: RedisOptions): RedisHandle;
396
368
  declare class ExecAdapter implements CommandPort {
397
369
  private command;
398
370
  constructor(command: string);
399
- exec(args: string, cwd: string): Promise<CommandResult>;
400
- spawn(args: string, cwd: string, options: SpawnOptions): Promise<CommandResult>;
371
+ exec(args: string, cwd: string, extraEnv?: CommandEnv): Promise<CommandResult>;
372
+ spawn(args: string, cwd: string, options: SpawnOptions, extraEnv?: CommandEnv): Promise<CommandResult>;
401
373
  }
402
374
  //#endregion
403
375
  //#region src/specification/adapters/fetch.adapter.d.ts
@@ -424,6 +396,18 @@ declare class HonoAdapter implements ServerPort {
424
396
  request(method: string, path: string, body?: unknown): Promise<ServerResponse>;
425
397
  }
426
398
  //#endregion
399
+ //#region src/specification/grep.d.ts
400
+ /**
401
+ * Extract text blocks from output that contain a pattern.
402
+ * Splits by blank lines (how linter/compiler output is structured),
403
+ * returns only blocks matching the pattern.
404
+ *
405
+ * @example
406
+ * expect(grep(result.stdout, "unused-var.ts")).toContain("no-unused-vars")
407
+ * expect(grep(result.stdout, "valid/sorted.ts")).not.toContain("sort-imports")
408
+ */
409
+ declare function grep(output: string, pattern: string): string;
410
+ //#endregion
427
411
  //#region src/infrastructure/reporter.d.ts
428
412
  declare function stripAnsi(str: string): string;
429
413
  declare function normalizeOutput(str: string): string;
@@ -479,5 +463,90 @@ declare function e2e(options?: E2eOptions): Promise<SpecificationRunnerWithClean
479
463
  */
480
464
  declare function cli(options: CliOptions): Promise<SpecificationRunnerWithCleanup>;
481
465
  //#endregion
482
- export { type CommandPort, type CommandResult, type DatabasePort, ExecAdapter, FetchAdapter, HonoAdapter, type MockDatePort, type MockPort, Orchestrator, type ServerPort, type ServerResponse, cli, e2e, integration, mockOf, mockOfDate, normalizeOutput, postgres, redis, stripAnsi };
466
+ //#region src/infrastructure/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/infrastructure/docker/docker-adapter.d.ts
515
+ /** Create a Docker container port for an existing container */
516
+ declare function dockerContainer(containerId: string): DockerContainerPort;
517
+ //#endregion
518
+ //#region src/infrastructure/docker/docker-assertion.d.ts
519
+ /** Fluent assertion builder for Docker containers */
520
+ declare class DockerAssertion {
521
+ private container;
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>;
549
+ }
550
+ //#endregion
551
+ export { type CommandEnv, type CommandPort, type CommandResult, type DatabasePort, type DirectoryAccessor, type DirectorySnapshotOptions, DockerAssertion, type DockerContainerPort, type DockerInspectResult, ExecAdapter, FetchAdapter, HonoAdapter, type MockDatePort, type MockPort, Orchestrator, type ServerPort, type ServerResponse, type SpecificationResult, cli, dockerContainer, e2e, grep, integration, mockOf, mockOfDate, normalizeOutput, postgres, redis, stripAnsi };
483
552
  //# sourceMappingURL=index.d.ts.map