import { assertEquals, assertStringIncludes } from "@std/assert"; import * as path from "@std/path"; import { buildCoverageResolvedComment, COVERAGE_SUGGESTION_MARKER, } from "./perf-lib.ts"; import { postCoverageComment } from "./post-coverage-comment.ts"; interface RecordedRequest { method: string; url: string; body: string; } /** * Run postCoverageComment with a payload file and a fetch mock that returns the * given existing comments for the GET and records any POST/PATCH. */ async function runWithPayload( payload: unknown, existingCommentBodies: string[], options: { getStatus?: number } = {}, ): Promise { const dir = await Deno.makeTempDir({ prefix: "coverage-comment-test-" }); const file = path.join(dir, "coverage-comment.json"); await Deno.writeTextFile(file, JSON.stringify(payload)); const requests: RecordedRequest[] = []; const originalFetch = globalThis.fetch; Deno.env.set("COVERAGE_COMMENT_FILE", file); globalThis.fetch = ((input: string | URL | Request, init?: RequestInit) => { const url = typeof input === "string" ? input : input.toString(); const method = init?.method ?? "GET"; if (method === "POST" || method === "PATCH") { const parsed = JSON.parse(String(init?.body)); requests.push({ method, url, body: parsed.body }); return Promise.resolve( new Response(JSON.stringify({ id: 1 }), { status: method === "POST" ? 201 : 200, }), ); } // GET comments. A non-200 status (404 is non-retryable) makes the lookup // throw, exercising the best-effort error path. const getStatus = options.getStatus ?? 200; if (getStatus !== 200) { return Promise.resolve( new Response("not found", { status: getStatus }), ); } // One page, fewer than per_page so pagination stops. const comments = existingCommentBodies.map((body, index) => ({ id: index + 1, body, })); return Promise.resolve( new Response(JSON.stringify(comments), { status: 200 }), ); }) as typeof fetch; try { await postCoverageComment(); } finally { globalThis.fetch = originalFetch; Deno.env.delete("COVERAGE_COMMENT_FILE"); await Deno.remove(dir, { recursive: true }); } return requests; } Deno.test("postCoverageComment posts when no marked comment exists", async () => { const body = `${COVERAGE_SUGGESTION_MARKER}\nCover these lines.`; const requests = await runWithPayload( { prNumber: 4211, state: "regressed", body }, ["a normal review comment"], ); assertEquals(requests.length, 1); assertEquals(requests[0].method, "POST"); assertEquals( requests[0].url, "https://api.github.com/repos/commontoolsinc/labs/issues/4211/comments", ); assertEquals(requests[0].body, body); }); Deno.test("postCoverageComment updates the existing comment in place", async () => { const body = `${COVERAGE_SUGGESTION_MARKER}\nCover these.`; const requests = await runWithPayload( { prNumber: 4211, state: "regressed", body }, [`${COVERAGE_SUGGESTION_MARKER}\nan earlier run said this`], ); assertEquals(requests.length, 1); assertEquals(requests[0].method, "PATCH"); assertEquals( requests[0].url, "https://api.github.com/repos/commontoolsinc/labs/issues/comments/1", ); assertEquals(requests[0].body, body); }); Deno.test("postCoverageComment leaves an up-to-date comment untouched", async () => { const body = `${COVERAGE_SUGGESTION_MARKER}\nidentical.`; const requests = await runWithPayload( { prNumber: 4211, state: "regressed", body }, [body], ); assertEquals(requests.length, 0); }); Deno.test("postCoverageComment resolves an existing comment when coverage is acceptable", async () => { const existing = [ COVERAGE_SUGGESTION_MARKER, "
", "

🕵🏻‍♀️ Test coverage regressed by 3 lines

", "", "table goes here", "", "### Prompt for an AI coding agent", "", "
", ].join("\n"); const requests = await runWithPayload( { prNumber: 4211, state: "resolved", improvedLines: 5, groups: [{ group: "packages/runner", baseline: 15, current: 12 }], }, [existing], ); assertEquals(requests.length, 1); assertEquals(requests[0].method, "PATCH"); assertEquals( requests[0].url, "https://api.github.com/repos/commontoolsinc/labs/issues/comments/1", ); assertStringIncludes(requests[0].body, "
"); assertStringIncludes( requests[0].body, "🕵🏻‍♀️ Code coverage debt reduced by 5 lines!", ); // The stale regression body is replaced by a per-group coverage summary. assertStringIncludes( requests[0].body, "| `packages/runner` | 15 | 12 | 3 lines fewer |", ); assertEquals( requests[0].body.includes("Prompt for an AI coding agent"), false, ); }); Deno.test("postCoverageComment reports an overridden metric rather than improved coverage", async () => { const existing = `${COVERAGE_SUGGESTION_MARKER}\n
\nregression\n
`; const requests = await runWithPayload( { prNumber: 4211, state: "resolved", improvedLines: 0, groups: [{ group: "packages/runner", baseline: 12, current: 15 }], overridden: true, }, [existing], ); assertEquals(requests.length, 1); assertStringIncludes( requests[0].body, "🕵🏻‍♀️ Code coverage debt accepted with an override.", ); assertEquals( requests[0].body.includes("Code coverage debt reduced by"), false, ); }); Deno.test("postCoverageComment does nothing to resolve when no comment exists", async () => { const requests = await runWithPayload( { prNumber: 4211, state: "resolved", improvedLines: 5 }, ["a normal review comment"], ); assertEquals(requests.length, 0); }); Deno.test("postCoverageComment leaves an already-resolved comment untouched", async () => { const groups = [{ group: "tasks", baseline: 8, current: 8 }]; // A comment already carrying exactly what this run would write is left alone. const existing = buildCoverageResolvedComment(0, groups); const requests = await runWithPayload( { prNumber: 4211, state: "resolved", improvedLines: 0, groups }, [existing], ); assertEquals(requests.length, 0); }); Deno.test("postCoverageComment treats a legacy body-only payload as a regression", async () => { const body = `${COVERAGE_SUGGESTION_MARKER}\nlegacy comment.`; const requests = await runWithPayload({ prNumber: 4211, body }, []); assertEquals(requests.length, 1); assertEquals(requests[0].method, "POST"); assertEquals(requests[0].body, body); }); Deno.test("postCoverageComment skips a regression payload with an empty body", async () => { const requests = await runWithPayload( { prNumber: 4211, state: "regressed", body: "" }, [], ); assertEquals(requests.length, 0); }); Deno.test("postCoverageComment swallows a comment-lookup failure", async () => { const requests = await runWithPayload( { prNumber: 4211, state: "regressed", body: `${COVERAGE_SUGGESTION_MARKER}\nbody.`, }, [], { getStatus: 404 }, ); assertEquals(requests.length, 0); }); Deno.test("postCoverageComment skips an invalid payload without posting", async () => { const requests = await runWithPayload({ prNumber: "not-a-number" }, []); assertEquals(requests.length, 0); });