@jterrazz/test 6.2.0 → 6.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
@@ -1,3 +1,4 @@
1
+ import { n as InterceptResponse, r as InterceptTrigger } from "./types.cjs";
1
2
  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
3
  import { i as mockOfDate, n as mockOf, r as MockDatePort, t as MockPort } from "./mock-of.cjs";
3
4
 
@@ -210,6 +211,7 @@ declare class SpecificationBuilder {
210
211
  private commandEnv;
211
212
  private config;
212
213
  private fixtures;
214
+ private intercepts;
213
215
  private label;
214
216
  private mocks;
215
217
  private projectName;
@@ -252,6 +254,22 @@ declare class SpecificationBuilder {
252
254
  * spec("french").headers({ 'Accept-Language': 'fr' }).get("/articles").run();
253
255
  */
254
256
  headers(headers: Record<string, string>): this;
257
+ /**
258
+ * Intercept an outgoing HTTP request and return a controlled response.
259
+ * Uses MSW under the hood. Intercepts are queued — multiple calls with the
260
+ * same trigger fire sequentially (first match consumed first).
261
+ *
262
+ * @param trigger - What to match (use openai.chat(), anthropic.messages(), http.get(), etc.)
263
+ * @param response - What to return (use openai.response(), http.json(), etc.)
264
+ *
265
+ * @example
266
+ * spec('pipeline')
267
+ * .intercept(openai.chat(), openai.response({ categories: ['TECH'] }))
268
+ * .intercept(openai.chat(), openai.response({ headline: 'AI News' }))
269
+ * .exec('process')
270
+ * .run();
271
+ */
272
+ intercept(trigger: InterceptTrigger, response: InterceptResponse): this;
255
273
  /**
256
274
  * Send a GET request to the server adapter.
257
275
  *
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { n as InterceptResponse, r as InterceptTrigger } from "./types.js";
1
2
  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.js";
2
3
  import { i as mockOfDate, n as mockOf, r as MockDatePort, t as MockPort } from "./mock-of.js";
3
4
 
@@ -210,6 +211,7 @@ declare class SpecificationBuilder {
210
211
  private commandEnv;
211
212
  private config;
212
213
  private fixtures;
214
+ private intercepts;
213
215
  private label;
214
216
  private mocks;
215
217
  private projectName;
@@ -252,6 +254,22 @@ declare class SpecificationBuilder {
252
254
  * spec("french").headers({ 'Accept-Language': 'fr' }).get("/articles").run();
253
255
  */
254
256
  headers(headers: Record<string, string>): this;
257
+ /**
258
+ * Intercept an outgoing HTTP request and return a controlled response.
259
+ * Uses MSW under the hood. Intercepts are queued — multiple calls with the
260
+ * same trigger fire sequentially (first match consumed first).
261
+ *
262
+ * @param trigger - What to match (use openai.chat(), anthropic.messages(), http.get(), etc.)
263
+ * @param response - What to return (use openai.response(), http.json(), etc.)
264
+ *
265
+ * @example
266
+ * spec('pipeline')
267
+ * .intercept(openai.chat(), openai.response({ categories: ['TECH'] }))
268
+ * .intercept(openai.chat(), openai.response({ headline: 'AI News' }))
269
+ * .exec('process')
270
+ * .run();
271
+ */
272
+ intercept(trigger: InterceptTrigger, response: InterceptResponse): this;
255
273
  /**
256
274
  * Send a GET request to the server adapter.
257
275
  *
package/dist/index.js CHANGED
@@ -590,6 +590,7 @@ var SpecificationBuilder = class {
590
590
  commandEnv = {};
591
591
  config;
592
592
  fixtures = [];
593
+ intercepts = [];
593
594
  label;
594
595
  mocks = [];
595
596
  projectName = null;
@@ -662,6 +663,28 @@ var SpecificationBuilder = class {
662
663
  return this;
663
664
  }
664
665
  /**
666
+ * Intercept an outgoing HTTP request and return a controlled response.
667
+ * Uses MSW under the hood. Intercepts are queued — multiple calls with the
668
+ * same trigger fire sequentially (first match consumed first).
669
+ *
670
+ * @param trigger - What to match (use openai.chat(), anthropic.messages(), http.get(), etc.)
671
+ * @param response - What to return (use openai.response(), http.json(), etc.)
672
+ *
673
+ * @example
674
+ * spec('pipeline')
675
+ * .intercept(openai.chat(), openai.response({ categories: ['TECH'] }))
676
+ * .intercept(openai.chat(), openai.response({ headline: 'AI News' }))
677
+ * .exec('process')
678
+ * .run();
679
+ */
680
+ intercept(trigger, response) {
681
+ this.intercepts.push({
682
+ trigger,
683
+ response
684
+ });
685
+ return this;
686
+ }
687
+ /**
665
688
  * Send a GET request to the server adapter.
666
689
  *
667
690
  * @example
@@ -755,9 +778,17 @@ var SpecificationBuilder = class {
755
778
  await db.seed(sql);
756
779
  }
757
780
  if (this.fixtures.length > 0 && workDir) for (const entry of this.fixtures) cpSync(resolve(this.testDir, "fixtures", entry.file), resolve(workDir, entry.file), { recursive: true });
758
- for (const entry of this.mocks) JSON.parse(readFileSync(resolve(this.testDir, "mock", entry.file), "utf8"));
759
- if (hasHttpAction) return this.runHttpAction();
760
- return this.runCliAction(workDir);
781
+ let cleanupIntercepts = null;
782
+ if (this.intercepts.length > 0) {
783
+ const { registerIntercepts } = await import("./server.js");
784
+ cleanupIntercepts = await registerIntercepts(this.intercepts);
785
+ }
786
+ try {
787
+ if (hasHttpAction) return await this.runHttpAction();
788
+ return await this.runCliAction(workDir);
789
+ } finally {
790
+ if (cleanupIntercepts) cleanupIntercepts();
791
+ }
761
792
  }
762
793
  resolveEnv(workDir) {
763
794
  const keys = Object.keys(this.commandEnv);