@jterrazz/test 3.2.0 → 3.3.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.cts CHANGED
@@ -109,6 +109,24 @@ declare class Orchestrator {
109
109
  getAppUrl(): null | string;
110
110
  }
111
111
  //#endregion
112
+ //#region src/specification/ports/command.port.d.ts
113
+ /**
114
+ * Result of executing a CLI command.
115
+ */
116
+ interface CommandResult {
117
+ exitCode: number;
118
+ stdout: string;
119
+ stderr: string;
120
+ }
121
+ /**
122
+ * Abstract CLI interface for specification runners.
123
+ * Implement this to plug in your command execution strategy.
124
+ */
125
+ interface CommandPort {
126
+ /** Execute a CLI command with the given arguments in the given working directory. */
127
+ exec(args: string, cwd: string): Promise<CommandResult>;
128
+ }
129
+ //#endregion
112
130
  //#region src/specification/ports/server.port.d.ts
113
131
  /**
114
132
  * HTTP response returned by a server port.
@@ -129,47 +147,76 @@ interface ServerPort {
129
147
  //#endregion
130
148
  //#region src/specification/specification.d.ts
131
149
  interface SpecificationConfig {
150
+ command?: CommandPort;
132
151
  database?: DatabasePort;
133
152
  databases?: Map<string, DatabasePort>;
134
- server: ServerPort;
153
+ fixturesRoot?: string;
154
+ server?: ServerPort;
135
155
  }
136
156
  interface RequestInfo {
157
+ body?: unknown;
137
158
  method: string;
138
159
  path: string;
139
- body?: unknown;
140
160
  }
141
161
  declare class SpecificationResult {
142
- private response;
162
+ private commandResult?;
143
163
  private config;
164
+ private requestInfo?;
165
+ private response?;
144
166
  private testDir;
145
- private requestInfo;
146
- constructor(response: ServerResponse, config: SpecificationConfig, testDir: string, requestInfo: RequestInfo);
167
+ private workDir?;
168
+ constructor(options: {
169
+ commandResult?: CommandResult;
170
+ config: SpecificationConfig;
171
+ requestInfo?: RequestInfo;
172
+ response?: ServerResponse;
173
+ testDir: string;
174
+ workDir?: string;
175
+ });
147
176
  expectStatus(code: number): this;
148
177
  expectResponse(file: string): this;
178
+ expectExitCode(code: number): this;
179
+ expectStdout(file: string): this;
180
+ expectStdoutContains(str: string): this;
181
+ expectStderr(file: string): this;
182
+ expectStderrContains(str: string): this;
149
183
  expectTable(table: string, options: {
150
184
  columns: string[];
151
185
  rows: unknown[][];
152
186
  service?: string;
153
187
  }): Promise<this>;
188
+ expectFile(path: string): this;
189
+ expectNoFile(path: string): this;
190
+ expectFileContains(path: string, content: string): this;
154
191
  private resolveDatabase;
192
+ private resolveWorkPath;
155
193
  }
156
194
  declare class SpecificationBuilder {
195
+ private commandArgs;
157
196
  private config;
158
- private testDir;
197
+ private fixtures;
159
198
  private label;
160
- private seeds;
161
199
  private mocks;
200
+ private projectName;
162
201
  private request;
202
+ private seeds;
203
+ private testDir;
163
204
  constructor(config: SpecificationConfig, testDir: string, label: string);
164
205
  seed(file: string, options?: {
165
206
  service?: string;
166
207
  }): this;
208
+ fixture(file: string): this;
209
+ project(name: string): this;
167
210
  mock(file: string): this;
168
211
  get(path: string): this;
169
212
  post(path: string, bodyFile?: string): this;
170
213
  put(path: string, bodyFile?: string): this;
171
214
  delete(path: string): this;
215
+ exec(args: string): this;
172
216
  run(): Promise<SpecificationResult>;
217
+ private prepareWorkDir;
218
+ private runHttpAction;
219
+ private runCliAction;
173
220
  }
174
221
  type SpecificationRunner = (label: string) => SpecificationBuilder;
175
222
  //#endregion
@@ -240,6 +287,17 @@ declare class RedisHandle implements ServiceHandle {
240
287
  */
241
288
  declare function redis(options?: RedisOptions): RedisHandle;
242
289
  //#endregion
290
+ //#region src/specification/adapters/exec.adapter.d.ts
291
+ /**
292
+ * Executes CLI commands via execSync.
293
+ * Used by cli() for local command execution.
294
+ */
295
+ declare class ExecAdapter implements CommandPort {
296
+ private command;
297
+ constructor(command: string);
298
+ exec(args: string, cwd: string): Promise<CommandResult>;
299
+ }
300
+ //#endregion
243
301
  //#region src/specification/adapters/fetch.adapter.d.ts
244
302
  /**
245
303
  * Server adapter for real HTTP — sends actual fetch requests.
@@ -274,17 +332,25 @@ type HonoApp = {
274
332
  request: (path: string, init?: RequestInit) => Promise<Response> | Response;
275
333
  };
276
334
  interface IntegrationOptions {
277
- /** Declared services — started via testcontainers. */
278
- services: ServiceHandle[];
279
335
  /** Factory that returns a Hono app — called after services start. */
280
336
  app: () => HonoApp;
281
337
  /** Project root for compose detection (relative paths supported). */
282
338
  root?: string;
339
+ /** Declared services — started via testcontainers. */
340
+ services: ServiceHandle[];
283
341
  }
284
342
  interface E2eOptions {
285
343
  /** Project root — must contain docker/compose.test.yaml. */
286
344
  root?: string;
287
345
  }
346
+ interface CliOptions {
347
+ /** CLI command to run (resolved from node_modules/.bin or PATH). */
348
+ command: string;
349
+ /** Project root — base dir for .project() fixture lookup (relative paths supported). */
350
+ root?: string;
351
+ /** Optional infrastructure services (started via testcontainers). */
352
+ services?: ServiceHandle[];
353
+ }
288
354
  interface SpecificationRunnerWithCleanup extends SpecificationRunner {
289
355
  cleanup: () => Promise<void>;
290
356
  orchestrator: Orchestrator;
@@ -292,25 +358,24 @@ interface SpecificationRunnerWithCleanup extends SpecificationRunner {
292
358
  /**
293
359
  * Create an integration specification runner.
294
360
  * Starts infra containers via testcontainers, app runs in-process.
295
- *
296
- * @example
297
- * const db = postgres({ compose: "db" });
298
- * export const spec = await integration({
299
- * services: [db],
300
- * app: () => createApp({ databaseUrl: db.connectionString }),
301
- * });
302
361
  */
303
362
  declare function integration(options: IntegrationOptions): Promise<SpecificationRunnerWithCleanup>;
304
363
  /**
305
364
  * Create an E2E specification runner.
306
365
  * Starts full docker compose stack. App URL and database auto-detected.
366
+ */
367
+ declare function e2e(options?: E2eOptions): Promise<SpecificationRunnerWithCleanup>;
368
+ /**
369
+ * Create a CLI specification runner.
370
+ * Runs CLI commands against fixture projects. Optionally starts infrastructure.
307
371
  *
308
372
  * @example
309
- * export const spec = await e2e({
310
- * root: "../fixtures/app",
373
+ * export const spec = await cli({
374
+ * command: resolve(import.meta.dirname, "../../bin/my-cli.sh"),
375
+ * root: "../fixtures",
311
376
  * });
312
377
  */
313
- declare function e2e(options?: E2eOptions): Promise<SpecificationRunnerWithCleanup>;
378
+ declare function cli(options: CliOptions): Promise<SpecificationRunnerWithCleanup>;
314
379
  //#endregion
315
- export { type DatabasePort, FetchAdapter, HonoAdapter, type MockDatePort, type MockPort, Orchestrator, type ServerPort, type ServerResponse, e2e, integration, mockOf, mockOfDate, normalizeOutput, postgres, redis, stripAnsi };
380
+ 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 };
316
381
  //# sourceMappingURL=index.d.cts.map
package/dist/index.d.ts CHANGED
@@ -109,6 +109,24 @@ declare class Orchestrator {
109
109
  getAppUrl(): null | string;
110
110
  }
111
111
  //#endregion
112
+ //#region src/specification/ports/command.port.d.ts
113
+ /**
114
+ * Result of executing a CLI command.
115
+ */
116
+ interface CommandResult {
117
+ exitCode: number;
118
+ stdout: string;
119
+ stderr: string;
120
+ }
121
+ /**
122
+ * Abstract CLI interface for specification runners.
123
+ * Implement this to plug in your command execution strategy.
124
+ */
125
+ interface CommandPort {
126
+ /** Execute a CLI command with the given arguments in the given working directory. */
127
+ exec(args: string, cwd: string): Promise<CommandResult>;
128
+ }
129
+ //#endregion
112
130
  //#region src/specification/ports/server.port.d.ts
113
131
  /**
114
132
  * HTTP response returned by a server port.
@@ -129,47 +147,76 @@ interface ServerPort {
129
147
  //#endregion
130
148
  //#region src/specification/specification.d.ts
131
149
  interface SpecificationConfig {
150
+ command?: CommandPort;
132
151
  database?: DatabasePort;
133
152
  databases?: Map<string, DatabasePort>;
134
- server: ServerPort;
153
+ fixturesRoot?: string;
154
+ server?: ServerPort;
135
155
  }
136
156
  interface RequestInfo {
157
+ body?: unknown;
137
158
  method: string;
138
159
  path: string;
139
- body?: unknown;
140
160
  }
141
161
  declare class SpecificationResult {
142
- private response;
162
+ private commandResult?;
143
163
  private config;
164
+ private requestInfo?;
165
+ private response?;
144
166
  private testDir;
145
- private requestInfo;
146
- constructor(response: ServerResponse, config: SpecificationConfig, testDir: string, requestInfo: RequestInfo);
167
+ private workDir?;
168
+ constructor(options: {
169
+ commandResult?: CommandResult;
170
+ config: SpecificationConfig;
171
+ requestInfo?: RequestInfo;
172
+ response?: ServerResponse;
173
+ testDir: string;
174
+ workDir?: string;
175
+ });
147
176
  expectStatus(code: number): this;
148
177
  expectResponse(file: string): this;
178
+ expectExitCode(code: number): this;
179
+ expectStdout(file: string): this;
180
+ expectStdoutContains(str: string): this;
181
+ expectStderr(file: string): this;
182
+ expectStderrContains(str: string): this;
149
183
  expectTable(table: string, options: {
150
184
  columns: string[];
151
185
  rows: unknown[][];
152
186
  service?: string;
153
187
  }): Promise<this>;
188
+ expectFile(path: string): this;
189
+ expectNoFile(path: string): this;
190
+ expectFileContains(path: string, content: string): this;
154
191
  private resolveDatabase;
192
+ private resolveWorkPath;
155
193
  }
156
194
  declare class SpecificationBuilder {
195
+ private commandArgs;
157
196
  private config;
158
- private testDir;
197
+ private fixtures;
159
198
  private label;
160
- private seeds;
161
199
  private mocks;
200
+ private projectName;
162
201
  private request;
202
+ private seeds;
203
+ private testDir;
163
204
  constructor(config: SpecificationConfig, testDir: string, label: string);
164
205
  seed(file: string, options?: {
165
206
  service?: string;
166
207
  }): this;
208
+ fixture(file: string): this;
209
+ project(name: string): this;
167
210
  mock(file: string): this;
168
211
  get(path: string): this;
169
212
  post(path: string, bodyFile?: string): this;
170
213
  put(path: string, bodyFile?: string): this;
171
214
  delete(path: string): this;
215
+ exec(args: string): this;
172
216
  run(): Promise<SpecificationResult>;
217
+ private prepareWorkDir;
218
+ private runHttpAction;
219
+ private runCliAction;
173
220
  }
174
221
  type SpecificationRunner = (label: string) => SpecificationBuilder;
175
222
  //#endregion
@@ -240,6 +287,17 @@ declare class RedisHandle implements ServiceHandle {
240
287
  */
241
288
  declare function redis(options?: RedisOptions): RedisHandle;
242
289
  //#endregion
290
+ //#region src/specification/adapters/exec.adapter.d.ts
291
+ /**
292
+ * Executes CLI commands via execSync.
293
+ * Used by cli() for local command execution.
294
+ */
295
+ declare class ExecAdapter implements CommandPort {
296
+ private command;
297
+ constructor(command: string);
298
+ exec(args: string, cwd: string): Promise<CommandResult>;
299
+ }
300
+ //#endregion
243
301
  //#region src/specification/adapters/fetch.adapter.d.ts
244
302
  /**
245
303
  * Server adapter for real HTTP — sends actual fetch requests.
@@ -274,17 +332,25 @@ type HonoApp = {
274
332
  request: (path: string, init?: RequestInit) => Promise<Response> | Response;
275
333
  };
276
334
  interface IntegrationOptions {
277
- /** Declared services — started via testcontainers. */
278
- services: ServiceHandle[];
279
335
  /** Factory that returns a Hono app — called after services start. */
280
336
  app: () => HonoApp;
281
337
  /** Project root for compose detection (relative paths supported). */
282
338
  root?: string;
339
+ /** Declared services — started via testcontainers. */
340
+ services: ServiceHandle[];
283
341
  }
284
342
  interface E2eOptions {
285
343
  /** Project root — must contain docker/compose.test.yaml. */
286
344
  root?: string;
287
345
  }
346
+ interface CliOptions {
347
+ /** CLI command to run (resolved from node_modules/.bin or PATH). */
348
+ command: string;
349
+ /** Project root — base dir for .project() fixture lookup (relative paths supported). */
350
+ root?: string;
351
+ /** Optional infrastructure services (started via testcontainers). */
352
+ services?: ServiceHandle[];
353
+ }
288
354
  interface SpecificationRunnerWithCleanup extends SpecificationRunner {
289
355
  cleanup: () => Promise<void>;
290
356
  orchestrator: Orchestrator;
@@ -292,25 +358,24 @@ interface SpecificationRunnerWithCleanup extends SpecificationRunner {
292
358
  /**
293
359
  * Create an integration specification runner.
294
360
  * Starts infra containers via testcontainers, app runs in-process.
295
- *
296
- * @example
297
- * const db = postgres({ compose: "db" });
298
- * export const spec = await integration({
299
- * services: [db],
300
- * app: () => createApp({ databaseUrl: db.connectionString }),
301
- * });
302
361
  */
303
362
  declare function integration(options: IntegrationOptions): Promise<SpecificationRunnerWithCleanup>;
304
363
  /**
305
364
  * Create an E2E specification runner.
306
365
  * Starts full docker compose stack. App URL and database auto-detected.
366
+ */
367
+ declare function e2e(options?: E2eOptions): Promise<SpecificationRunnerWithCleanup>;
368
+ /**
369
+ * Create a CLI specification runner.
370
+ * Runs CLI commands against fixture projects. Optionally starts infrastructure.
307
371
  *
308
372
  * @example
309
- * export const spec = await e2e({
310
- * root: "../fixtures/app",
373
+ * export const spec = await cli({
374
+ * command: resolve(import.meta.dirname, "../../bin/my-cli.sh"),
375
+ * root: "../fixtures",
311
376
  * });
312
377
  */
313
- declare function e2e(options?: E2eOptions): Promise<SpecificationRunnerWithCleanup>;
378
+ declare function cli(options: CliOptions): Promise<SpecificationRunnerWithCleanup>;
314
379
  //#endregion
315
- export { type DatabasePort, FetchAdapter, HonoAdapter, type MockDatePort, type MockPort, Orchestrator, type ServerPort, type ServerResponse, e2e, integration, mockOf, mockOfDate, normalizeOutput, postgres, redis, stripAnsi };
380
+ 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 };
316
381
  //# sourceMappingURL=index.d.ts.map