Skip to content

Commit 2a76f4f

Browse files
dmealingclaude
andcommitted
test(codegen-ts): multi-surface + baseUrl cross-link integrity gate (polyglot)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 3d7dcda commit 2a76f4f

1 file changed

Lines changed: 50 additions & 0 deletions

File tree

server/typescript/packages/codegen-ts/test/golden/docs-cross-link-conformance.test.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import type { GenContext } from "../../src/generator.js";
2222
import { docsFile } from "../../src/generators/docs-file.js";
2323
import { apiDocsFile } from "../../src/generators/api-docs-file.js";
2424
import type { OutputLayout } from "../../src/import-path.js";
25+
import { apiSurfaceHref } from "../../src/docs-paths.js";
2526
import { buildPkMap } from "../../src/pk-resolver.js";
2627
import { buildRelationMap } from "../../src/relation-resolver.js";
2728
import { makeRenderContext } from "../../src/render-context.js";
@@ -95,6 +96,21 @@ async function emitBoth(fixture: string, layout: OutputLayout): Promise<Emitted[
9596
return [...model, ...api];
9697
}
9798

99+
const TWO_SURFACES = [
100+
{ label: "TypeScript", subDir: "api/ts" },
101+
{ label: "Java", subDir: "api/java" },
102+
];
103+
/** Emit the model + BOTH api surfaces (the 2nd simulates another language's
104+
* port by re-running the api engine under a second subDir). */
105+
async function emitMulti(fixture: string, layout: OutputLayout): Promise<Emitted[]> {
106+
const { root, inputDir } = await loadFixture(fixture);
107+
const ctx = makeCtx(root, inputDir, layout);
108+
const model = (await docsFile({ apiSurfaces: TWO_SURFACES }).generate(ctx)) as Emitted[];
109+
const tsApi = (await apiDocsFile({ subDir: "api/ts", modelSurface: true }).generate(ctx)) as Emitted[];
110+
const javaApi = (await apiDocsFile({ subDir: "api/java", modelSurface: true }).generate(ctx)) as Emitted[];
111+
return [...model, ...tsApi, ...javaApi];
112+
}
113+
98114
// ── Cross-link finder (pure — unit-testable for teeth) ───────────────────────
99115

100116
const isApi = (p: string): boolean => p.startsWith("api/");
@@ -187,3 +203,37 @@ describe("unified-docs-door cross-link integrity", () => {
187203
]);
188204
});
189205
});
206+
207+
// ── Polyglot: model + TWO api surfaces (e.g. a TS + Java solution) ────────────
208+
209+
describe("polyglot multi-surface cross-links", () => {
210+
for (const [label, fixture, layout] of [
211+
["flat", FIXTURE, "flat"],
212+
["package", FIXTURE_PACKAGE, "package"],
213+
] as const) {
214+
it(`every cross-link resolves with 2 api surfaces (${label})`, async () => {
215+
const files = await emitMulti(fixture, layout);
216+
const present = new Set(files.map((f) => f.path));
217+
expect(findBrokenCrossLinks(files, present), `broken (${label})`).toEqual([]);
218+
219+
// a model ENTITY page links BOTH surfaces:
220+
const entity = files.find((f) => !isApi(f.path) && f.path !== "README.md" && f.path.endsWith(".md"))!;
221+
expect(entity.content).toContain("api/ts/");
222+
expect(entity.content).toContain("api/java/");
223+
224+
// both api surfaces are present + each links back to the model:
225+
expect([...present].some((p) => p.startsWith("api/ts/"))).toBe(true);
226+
expect([...present].some((p) => p.startsWith("api/java/"))).toBe(true);
227+
const apiTs = files.find((f) => f.path.startsWith("api/ts/") && f.path.endsWith(".md") && !f.path.endsWith("README.md") && !f.path.endsWith("AGENT-API.md"))!;
228+
const apiJava = files.find((f) => f.path.startsWith("api/java/") && f.path.endsWith(".md") && !f.path.endsWith("README.md") && !f.path.endsWith("AGENT-API.md"))!;
229+
expect(apiTs.content).toMatch(/Model|metadata/i);
230+
expect(apiJava.content).toMatch(/Model|metadata/i);
231+
});
232+
}
233+
234+
it("a baseUrl surface yields an absolute (federated) link", () => {
235+
const href = apiSurfaceHref("Order.md", { subDir: "api/java", baseUrl: "https://docs.example/java" }, "Order.md");
236+
expect(href).toBe("https://docs.example/java/Order.md");
237+
expect(href.startsWith("http")).toBe(true); // not in the local tree → not a broken local link
238+
});
239+
});

0 commit comments

Comments
 (0)