import { describe, expect, it } from "vitest"; import { TOOLCRAFT_MODEL_IMPORT_LIMIT_CEILINGS } from "../model-import-limits"; import { decodeToolcraftModelDocument, encodeToolcraftModelDocument, ToolcraftModelDocumentCodecError, } from "./model-document-codec"; import { resolveToolcraftCanonicalModelLimits } from "./model-document-limits"; import { createModelMaterial, createModelPrimitiveV2, createModelTexture, createValidModelDocument, createValidModelDocumentV2, } from "./model-document-test-support"; import { estimateToolcraftModelEncodeWorkerBytes } from "./model-document-worker-memory"; function expectWorkerLimitFailure(operation: () => unknown): void { try { operation(); throw new Error("Expected worker-memory preflight to fail."); } catch (error) { expect(error).toBeInstanceOf(ToolcraftModelDocumentCodecError); expect(error).toMatchObject({ code: "estimated-worker-memory-limit-exceeded", }); } } describe("canonical model worker memory limits", () => { it("defaults to and rejects widening the protected worker-memory ceiling", () => { expect(resolveToolcraftCanonicalModelLimits().maxEstimatedWorkerBytes).toBe( TOOLCRAFT_MODEL_IMPORT_LIMIT_CEILINGS.maxEstimatedWorkerBytes, ); expect(() => resolveToolcraftCanonicalModelLimits({ maxEstimatedWorkerBytes: Number.MAX_SAFE_INTEGER, }), ).toThrow(/maxEstimatedWorkerBytes.*protected ceiling/u); }); it("preserves a caller-narrowed worker-memory limit", () => { expect( resolveToolcraftCanonicalModelLimits({ maxEstimatedWorkerBytes: 64 * 1024, }).maxEstimatedWorkerBytes, ).toBe(64 * 1024); }); it("rejects a small encode before payload allocation", () => { expectWorkerLimitFailure(() => encodeToolcraftModelDocument(createValidModelDocument(), { maxEstimatedWorkerBytes: 1, }), ); }); it("rejects a small decode before metadata or geometry allocation", () => { const encoded = encodeToolcraftModelDocument(createValidModelDocument()); expectWorkerLimitFailure(() => decodeToolcraftModelDocument(encoded, { maxEstimatedWorkerBytes: 1 }), ); }); it("round-trips within the protected default worker-memory budget", () => { const document = createValidModelDocument(); expect( decodeToolcraftModelDocument(encodeToolcraftModelDocument(document)), ).toEqual(document); }); it("charges v2 appearance arrays and metadata to encode memory", () => { const withoutAppearance = createValidModelDocumentV2({ materials: [], primitives: [createModelPrimitiveV2({ colors: undefined, materialId: undefined, textureCoordinates: undefined, })], textures: [], }); const withAppearance = createValidModelDocumentV2({ materials: [createModelMaterial()], primitives: [createModelPrimitiveV2()], textures: [createModelTexture()], }); expect(estimateToolcraftModelEncodeWorkerBytes(withAppearance)).toBeGreaterThan( estimateToolcraftModelEncodeWorkerBytes(withoutAppearance), ); }); });