import { describe, expect, it, vi } from "vitest"; import { encodeToolcraftModelDocument } from "../canonical/model-document-codec"; import { createValidModelDocument } from "../canonical/model-document-test-support"; import { analyzeToolcraftModel } from "../topology/model-topology-analysis"; import type { ToolcraftModelWorkerRequest, ToolcraftModelWorkerResponse, } from "./model-import-worker-protocol"; import { createToolcraftModelWorkerRuntime } from "./model-import-worker-runtime"; import { copyArrayBuffer, fakeRepairPlan, limits, repairRequest, } from "./model-import-worker-runtime-test-support"; describe("createToolcraftModelWorkerRuntime repair cache", () => { it("keys repair results by canonical digest and repair plan digest", async () => { const repaired = createValidModelDocument(); const repair = vi.fn(() => repaired); const runtime = createToolcraftModelWorkerRuntime({ adapters: [], post: vi.fn(), repair, }); const planA = `sha256:${"a".repeat(64)}`; const planB = `sha256:${"b".repeat(64)}`; await runtime.handleMessage(repairRequest(1, fakeRepairPlan(planA))); await runtime.handleMessage(repairRequest(2, fakeRepairPlan(planA))); await runtime.handleMessage(repairRequest(3, fakeRepairPlan(planB))); expect(repair).toHaveBeenCalledTimes(2); expect(runtime.inspectCacheSizes().repair).toBe(2); }); it("revalidates cached repair bytes and analysis under later normalized limits", async () => { const repaired = createValidModelDocument(); const repair = vi.fn(() => repaired); const analyze = vi.fn(analyzeToolcraftModel); const responses: ToolcraftModelWorkerResponse[] = []; const runtime = createToolcraftModelWorkerRuntime({ adapters: [], analyze, post: (response) => responses.push(response), repair, }); const plan = fakeRepairPlan(); const first = repairRequest(1, plan); const secondBase = repairRequest(2, plan); if (secondBase.kind !== "repair") throw new Error("Expected repair request."); const second: ToolcraftModelWorkerRequest = { ...secondBase, payload: { ...secondBase.payload, canonicalDocument: copyArrayBuffer( encodeToolcraftModelDocument(createValidModelDocument()), ), limits: { ...limits, maxSourceBytes: 1_024 }, }, }; await runtime.handleMessage(first); await runtime.handleMessage(second); expect(repair).toHaveBeenCalledTimes(1); expect(analyze).toHaveBeenCalledTimes(2); const result = responses.filter((response) => response.kind === "result").at(-1); expect(result).toMatchObject({ kind: "result", result: { analysis: { limits: { maxSourceBytes: 1_024 } } }, }); }); });