Skip to content

Commit 939e2c6

Browse files
committed
test: isolate runtime contract doc parity
1 parent c87aa64 commit 939e2c6

4 files changed

Lines changed: 96 additions & 76 deletions

File tree

lib/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ export * from "./accounts.js";
22
export * from "./storage.js";
33
export * from "./config.js";
44
export * from "./constants.js";
5-
export * from "./runtime-contracts.js";
65
export * from "./types.js";
76
export * from "./logger.js";
87
export * from "./auth/auth.js";

lib/runtime-contracts.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
/**
2+
* Shared runtime constants and sentinel helpers only. This module is pure: it
3+
* does not perform I/O, persistence, or logging, so centralizing these values
4+
* does not introduce new Windows lock or token-redaction surfaces.
5+
*/
16
export const OAUTH_CALLBACK_LOOPBACK_HOST = "127.0.0.1";
27
export const OAUTH_CALLBACK_PORT = 1455;
38
export const OAUTH_CALLBACK_PATH = "/auth/callback";
@@ -17,3 +22,7 @@ export function isDeactivatedWorkspaceErrorMessage(message: string | undefined):
1722
export function createUsageRequestTimeoutError(): Error {
1823
return new Error(USAGE_REQUEST_TIMEOUT_MESSAGE);
1924
}
25+
26+
export function isUsageRequestTimeoutMessage(message: string | undefined): boolean {
27+
return message === USAGE_REQUEST_TIMEOUT_MESSAGE;
28+
}

test/doc-parity.test.ts

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import { readFileSync } from "node:fs";
2+
import path from "node:path";
3+
import { fileURLToPath } from "node:url";
4+
import { describe, expect, it } from "vitest";
5+
import { OAUTH_CALLBACK_PATH, OAUTH_CALLBACK_PORT } from "../lib/runtime-contracts.js";
6+
import { transformRequestBody } from "../lib/request/request-transformer.js";
7+
import type { RequestBody, UserConfig } from "../lib/types.js";
8+
9+
const testDir = path.dirname(fileURLToPath(import.meta.url));
10+
11+
function readRepoFile(relativePath: string): string {
12+
try {
13+
return readFileSync(path.resolve(testDir, "..", relativePath), "utf8");
14+
} catch (error) {
15+
const message = error instanceof Error ? error.message : String(error);
16+
throw new Error(`Failed to read ${relativePath}: ${message}`);
17+
}
18+
}
19+
20+
describe("runtime documentation parity", () => {
21+
it("keeps the documented stateless request contract aligned with the runtime transform", async () => {
22+
const requestBody: RequestBody = {
23+
model: "gpt-5",
24+
input: [
25+
{
26+
type: "message",
27+
role: "user",
28+
content: [{ type: "input_text", text: "quota ping" }],
29+
},
30+
],
31+
};
32+
const userConfig: UserConfig = { global: {}, models: {} };
33+
34+
const transformedBody = await transformRequestBody(requestBody, "test instructions", userConfig);
35+
36+
expect(transformedBody.store).toBe(false);
37+
expect(transformedBody.include).toContain("reasoning.encrypted_content");
38+
39+
const docsExpectations: Array<[string, string[]]> = [
40+
[
41+
"docs/getting-started.md",
42+
[
43+
`http://127.0.0.1:${OAUTH_CALLBACK_PORT}${OAUTH_CALLBACK_PATH}`,
44+
"`store: false`",
45+
"`reasoning.encrypted_content`",
46+
],
47+
],
48+
[
49+
"docs/configuration.md",
50+
[
51+
"`reasoning.encrypted_content`",
52+
"store\": false",
53+
],
54+
],
55+
[
56+
"docs/development/ARCHITECTURE.md",
57+
[
58+
"`store: false`",
59+
"`reasoning.encrypted_content`",
60+
],
61+
],
62+
[
63+
"docs/troubleshooting.md",
64+
[
65+
"1455",
66+
"`reasoning.encrypted_content`",
67+
],
68+
],
69+
[
70+
"docs/faq.md",
71+
[
72+
"`1455`",
73+
],
74+
],
75+
];
76+
77+
for (const [relativePath, fragments] of docsExpectations) {
78+
const fileContents = readRepoFile(relativePath);
79+
for (const fragment of fragments) {
80+
expect(fileContents).toContain(fragment);
81+
}
82+
}
83+
});
84+
});

test/runtime-contracts.test.ts

Lines changed: 3 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,16 @@
1-
import { readFileSync } from "node:fs";
2-
import path from "node:path";
3-
import { fileURLToPath } from "node:url";
41
import { describe, expect, it } from "vitest";
52
import { REDIRECT_URI } from "../lib/auth/auth.js";
6-
import { transformRequestBody } from "../lib/request/request-transformer.js";
73
import {
84
createDeactivatedWorkspaceError,
95
createUsageRequestTimeoutError,
106
DEACTIVATED_WORKSPACE_ERROR_CODE,
117
isDeactivatedWorkspaceErrorMessage,
8+
isUsageRequestTimeoutMessage,
129
OAUTH_CALLBACK_BIND_URL,
1310
OAUTH_CALLBACK_PATH,
1411
OAUTH_CALLBACK_PORT,
1512
USAGE_REQUEST_TIMEOUT_MESSAGE,
1613
} from "../lib/runtime-contracts.js";
17-
import type { RequestBody, UserConfig } from "../lib/types.js";
18-
19-
const testDir = path.dirname(fileURLToPath(import.meta.url));
20-
21-
function readRepoFile(relativePath: string): string {
22-
return readFileSync(path.resolve(testDir, "..", relativePath), "utf8");
23-
}
2414

2515
describe("runtime contracts", () => {
2616
it("creates stable sentinel errors for workspace deactivation and usage timeouts", () => {
@@ -32,6 +22,8 @@ describe("runtime contracts", () => {
3222
expect(isDeactivatedWorkspaceErrorMessage("workspace-deactivated")).toBe(false);
3323

3424
expect(usageTimeoutError.message).toBe(USAGE_REQUEST_TIMEOUT_MESSAGE);
25+
expect(isUsageRequestTimeoutMessage(usageTimeoutError.message)).toBe(true);
26+
expect(isUsageRequestTimeoutMessage("request timed out")).toBe(false);
3527
});
3628

3729
it("keeps the OAuth callback runtime values aligned", () => {
@@ -40,68 +32,4 @@ describe("runtime contracts", () => {
4032
expect(OAUTH_CALLBACK_BIND_URL).toBe(`http://127.0.0.1:${OAUTH_CALLBACK_PORT}`);
4133
expect(REDIRECT_URI).toBe(`http://localhost:${OAUTH_CALLBACK_PORT}${OAUTH_CALLBACK_PATH}`);
4234
});
43-
44-
it("keeps the documented stateless request contract aligned with the runtime transform", async () => {
45-
const requestBody: RequestBody = {
46-
model: "gpt-5",
47-
input: [
48-
{
49-
type: "message",
50-
role: "user",
51-
content: [{ type: "input_text", text: "quota ping" }],
52-
},
53-
],
54-
};
55-
const userConfig: UserConfig = { global: {}, models: {} };
56-
57-
const transformedBody = await transformRequestBody(requestBody, "test instructions", userConfig);
58-
59-
expect(transformedBody.store).toBe(false);
60-
expect(transformedBody.include).toContain("reasoning.encrypted_content");
61-
62-
const docsExpectations: Array<[string, string[]]> = [
63-
[
64-
"docs/getting-started.md",
65-
[
66-
`http://127.0.0.1:${OAUTH_CALLBACK_PORT}${OAUTH_CALLBACK_PATH}`,
67-
"`store: false`",
68-
"`reasoning.encrypted_content`",
69-
],
70-
],
71-
[
72-
"docs/configuration.md",
73-
[
74-
"`reasoning.encrypted_content`",
75-
"store\": false",
76-
],
77-
],
78-
[
79-
"docs/development/ARCHITECTURE.md",
80-
[
81-
"`store: false`",
82-
"`reasoning.encrypted_content`",
83-
],
84-
],
85-
[
86-
"docs/troubleshooting.md",
87-
[
88-
"1455",
89-
"`reasoning.encrypted_content`",
90-
],
91-
],
92-
[
93-
"docs/faq.md",
94-
[
95-
"`1455`",
96-
],
97-
],
98-
];
99-
100-
for (const [relativePath, fragments] of docsExpectations) {
101-
const fileContents = readRepoFile(relativePath);
102-
for (const fragment of fragments) {
103-
expect(fileContents).toContain(fragment);
104-
}
105-
}
106-
});
10735
});

0 commit comments

Comments
 (0)