Skip to content

Commit f21e718

Browse files
committed
test: consolidate strict-503 skip-message matcher into a shared helper
The "candidate fixture(s) skipped by sequence/turn state" regex was duplicated 10x across test files, each re-encoding the message built by strictNoMatchMessage in src/helpers.ts. Move it to a single SKIPPED_BY_STATE_RE in src/__tests__/helpers/strict-matchers.ts with an import-time drift guard against strictNoMatchMessage(1), and import it at all former duplication sites.
1 parent ad84820 commit f21e718

10 files changed

Lines changed: 36 additions & 13 deletions

src/__tests__/bedrock.test.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { bedrockToCompletionRequest, handleBedrock, handleBedrockStream } from "
66
import { Journal } from "../journal.js";
77
import { Logger } from "../logger.js";
88
import { createMockReq, createMockRes, createDefaults } from "./helpers/mock-res.js";
9+
import { SKIPPED_BY_STATE_RE } from "./helpers/strict-matchers.js";
910

1011
// --- helpers ---
1112

@@ -1551,7 +1552,7 @@ describe("POST /model/{modelId}/invoke (strict mode)", () => {
15511552
);
15521553
expect(res.status).toBe(503);
15531554
const body = JSON.parse(res.body);
1554-
expect(body.error.message).toMatch(/candidate fixture\(s\) skipped by sequence\/turn state/);
1555+
expect(body.error.message).toMatch(SKIPPED_BY_STATE_RE);
15551556
});
15561557
});
15571558

@@ -1845,6 +1846,6 @@ describe("POST /model/{modelId}/converse (strict mode)", () => {
18451846
);
18461847
expect(res.status).toBe(503);
18471848
const body = JSON.parse(res.body);
1848-
expect(body.error.message).toMatch(/candidate fixture\(s\) skipped by sequence\/turn state/);
1849+
expect(body.error.message).toMatch(SKIPPED_BY_STATE_RE);
18491850
});
18501851
});

src/__tests__/cohere.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { createServer, type ServerInstance } from "../server.js";
55
import { cohereToCompletionRequest, handleCohere } from "../cohere.js";
66
import { Journal } from "../journal.js";
77
import { Logger } from "../logger.js";
8+
import { SKIPPED_BY_STATE_RE } from "./helpers/strict-matchers.js";
89

910
// --- helpers ---
1011

@@ -871,7 +872,7 @@ describe("POST /v2/chat (strict mode)", () => {
871872
});
872873
expect(res.status).toBe(503);
873874
const body = JSON.parse(res.body);
874-
expect(body.error.message).toMatch(/candidate fixture\(s\) skipped by sequence\/turn state/);
875+
expect(body.error.message).toMatch(SKIPPED_BY_STATE_RE);
875876
});
876877
});
877878

src/__tests__/gemini-interactions.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
} from "../gemini-interactions.js";
1616
import { collapseGeminiInteractionsSSE } from "../stream-collapse.js";
1717
import { Logger } from "../logger.js";
18+
import { SKIPPED_BY_STATE_RE } from "./helpers/strict-matchers.js";
1819

1920
// --- helpers ---
2021

@@ -1017,7 +1018,7 @@ describe("Gemini Interactions — non-streaming", () => {
10171018
});
10181019
expect(res.status).toBe(503);
10191020
const body = JSON.parse(res.body);
1020-
expect(body.error.message).toMatch(/candidate fixture\(s\) skipped by sequence\/turn state/);
1021+
expect(body.error.message).toMatch(SKIPPED_BY_STATE_RE);
10211022
});
10221023

10231024
it("matches userMessage fixture when input is Step[] envelope (issue #228)", async () => {

src/__tests__/gemini.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import * as http from "node:http";
33
import type { Fixture } from "../types.js";
44
import { createServer, type ServerInstance } from "../server.js";
55
import { geminiToCompletionRequest } from "../gemini.js";
6+
import { SKIPPED_BY_STATE_RE } from "./helpers/strict-matchers.js";
67

78
// --- helpers ---
89

@@ -1168,7 +1169,7 @@ describe("Gemini strict mode", () => {
11681169
});
11691170
expect(res.status).toBe(503);
11701171
const body = JSON.parse(res.body);
1171-
expect(body.error.message).toMatch(/candidate fixture\(s\) skipped by sequence\/turn state/);
1172+
expect(body.error.message).toMatch(SKIPPED_BY_STATE_RE);
11721173
});
11731174
});
11741175

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { strictNoMatchMessage } from "../../helpers.js";
2+
3+
/**
4+
* Shared matcher for the strict-mode 503 "skipped by sequence/turn state"
5+
* message built by `strictNoMatchMessage` (src/helpers.ts). Import this
6+
* instead of re-encoding the message text in individual test files.
7+
*/
8+
export const SKIPPED_BY_STATE_RE = /candidate fixture\(s\) skipped by sequence\/turn state/;
9+
10+
// Drift guard: fail loudly at import time if the matcher no longer matches the
11+
// message actually produced by the source of truth.
12+
if (!SKIPPED_BY_STATE_RE.test(strictNoMatchMessage(1))) {
13+
throw new Error(
14+
`SKIPPED_BY_STATE_RE is out of sync with strictNoMatchMessage(): ${strictNoMatchMessage(1)}`,
15+
);
16+
}

src/__tests__/messages.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { createServer, type ServerInstance } from "../server.js";
66
import { claudeToCompletionRequest, handleMessages } from "../messages.js";
77
import { Journal } from "../journal.js";
88
import { Logger } from "../logger.js";
9+
import { SKIPPED_BY_STATE_RE } from "./helpers/strict-matchers.js";
910

1011
// --- helpers ---
1112

@@ -1138,7 +1139,7 @@ describe("POST /v1/messages (strict mode)", () => {
11381139
});
11391140
expect(res.status).toBe(503);
11401141
const body = JSON.parse(res.body);
1141-
expect(body.error.message).toMatch(/candidate fixture\(s\) skipped by sequence\/turn state/);
1142+
expect(body.error.message).toMatch(SKIPPED_BY_STATE_RE);
11421143
});
11431144
});
11441145

src/__tests__/ollama.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { ollamaToCompletionRequest, handleOllama, handleOllamaGenerate } from ".
66
import { writeNDJSONStream } from "../ndjson-writer.js";
77
import { Journal } from "../journal.js";
88
import { Logger } from "../logger.js";
9+
import { SKIPPED_BY_STATE_RE } from "./helpers/strict-matchers.js";
910

1011
// --- helpers ---
1112

@@ -1019,7 +1020,7 @@ describe("POST /api/chat (strict mode)", () => {
10191020
});
10201021
expect(res.status).toBe(503);
10211022
const body = JSON.parse(res.body);
1022-
expect(body.error.message).toMatch(/candidate fixture\(s\) skipped by sequence\/turn state/);
1023+
expect(body.error.message).toMatch(SKIPPED_BY_STATE_RE);
10231024
});
10241025
});
10251026

src/__tests__/responses.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
} from "../responses.js";
1313
import { Journal } from "../journal.js";
1414
import { Logger } from "../logger.js";
15+
import { SKIPPED_BY_STATE_RE } from "./helpers/strict-matchers.js";
1516

1617
// --- helpers ---
1718

@@ -1030,7 +1031,7 @@ describe("POST /v1/responses (strict mode)", () => {
10301031
});
10311032
expect(res.status).toBe(503);
10321033
const body = JSON.parse(res.body);
1033-
expect(body.error.message).toMatch(/candidate fixture\(s\) skipped by sequence\/turn state/);
1034+
expect(body.error.message).toMatch(SKIPPED_BY_STATE_RE);
10341035
});
10351036
});
10361037

src/__tests__/strict-no-match-diagnostic.test.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { matchFixtureDiagnostic } from "../router.js";
44
import { strictNoMatchMessage } from "../helpers.js";
55
import { createServer, type ServerInstance } from "../server.js";
66
import type { Fixture, ChatCompletionRequest } from "../types.js";
7+
import { SKIPPED_BY_STATE_RE } from "./helpers/strict-matchers.js";
78

89
// ---------------------------------------------------------------------------
910
// Helpers
@@ -48,8 +49,6 @@ function chatRequest(userContent: string): ChatCompletionRequest {
4849
};
4950
}
5051

51-
const SKIPPED_RE = /candidate fixture\(s\) skipped by sequence\/turn state/;
52-
5352
// ---------------------------------------------------------------------------
5453
// Unit tests: strictNoMatchMessage helper
5554
// ---------------------------------------------------------------------------
@@ -213,7 +212,7 @@ describe("strict-mode 503 sequence/turn disambiguation", () => {
213212
const res = await httpPost(`${server.url}/v1/chat/completions`, chatRequest("hello"));
214213
expect(res.status).toBe(503);
215214
const body = JSON.parse(res.body);
216-
expect(body.error.message).toMatch(SKIPPED_RE);
215+
expect(body.error.message).toMatch(SKIPPED_BY_STATE_RE);
217216
expect(body.error.type).toBe("invalid_request_error");
218217
});
219218

@@ -226,7 +225,7 @@ describe("strict-mode 503 sequence/turn disambiguation", () => {
226225
const res = await httpPost(`${server.url}/v1/chat/completions`, chatRequest("hello"));
227226
expect(res.status).toBe(503);
228227
const body = JSON.parse(res.body);
229-
expect(body.error.message).toMatch(SKIPPED_RE);
228+
expect(body.error.message).toMatch(SKIPPED_BY_STATE_RE);
230229
expect(body.error.type).toBe("invalid_request_error");
231230
});
232231

src/__tests__/ws-responses.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { describe, it, expect, afterEach } from "vitest";
22
import { createServer, type ServerInstance } from "../server.js";
33
import type { Fixture } from "../types.js";
44
import { connectWebSocket } from "./ws-test-client.js";
5+
import { SKIPPED_BY_STATE_RE } from "./helpers/strict-matchers.js";
56

67
// --- fixtures ---
78

@@ -517,7 +518,7 @@ describe("WebSocket /v1/responses", () => {
517518
ws2.send(responseCreateMsg("hello"));
518519
const close = await ws2.waitForCloseFrame();
519520
expect(close.code).toBe(1008);
520-
expect(close.reason).toMatch(/candidate fixture\(s\) skipped by sequence\/turn state/);
521+
expect(close.reason).toMatch(SKIPPED_BY_STATE_RE);
521522
});
522523

523524
it("streams reasoning events before text via WebSocket", async () => {

0 commit comments

Comments
 (0)