import { describe, expect, it } from "vitest"; import type { ToolcraftEnvelopePerformanceConfig, ToolcraftRenderPass, } from "./performance"; import { assessToolcraftRenderPlan } from "./performance-render-plan-assessment"; import { validateToolcraftPerformanceCoverage } from "./performance-coverage-validator"; import { TOOLCRAFT_FUNCTIONAL_PERFORMANCE_COVERAGE_POLICY, } from "./performance-coverage-validator"; import { createBenchmarkDecision, createEnvelopeConfig, createPass, } from "./performance-render-plan-test-fixtures"; import { testSchema } from "./performance-test-fixtures"; describe("Toolcraft render plan integration", () => { it("allows a no-cache composite pass to omit cacheKey", () => { const pass = createPass({ cacheKey: undefined, kind: "composite", lifecycle: { cache: "none", resourceScope: "call" }, }); const errors = validateToolcraftPerformanceCoverage( testSchema, createEnvelopeConfig({ pass }), TOOLCRAFT_FUNCTIONAL_PERFORMANCE_COVERAGE_POLICY, ); expect(errors).not.toContain( 'rendererPipeline pass "effect" is a cache-sensitive composite pass and must declare cacheKey so tests can reject full recomputation on every control change.', ); }); it("allows off-main retina rasterization to preserve exact backing during viewport zoom", () => { const pass = createPass({ cacheKey: undefined, cost: { dimensions: ["output-units"], frequency: "interaction", relationship: "linear", }, id: "viewport-raster", inputs: ["canvas.viewport.zoom"], invalidatedBy: ["canvas.viewport.zoom"], kind: "rasterize", lifecycle: { cache: "none", resourceScope: "interaction" }, quality: "retina", runsOn: "worker", }); const baseConfig = createEnvelopeConfig({ pass }); const rendererPipeline = { ...baseConfig.rendererPipeline!, interactionInvalidation: [ { interaction: "viewport-zoom" as const, invalidates: [pass.id], targets: ["canvas.viewport.zoom"], }, ], }; const renderScaleSchema = { ...testSchema, canvas: { ...testSchema.canvas, renderScale: { ...testSchema.canvas.renderScale, enabled: true }, }, }; const errors = validateToolcraftPerformanceCoverage( renderScaleSchema, { ...baseConfig, rendererPipeline }, TOOLCRAFT_FUNCTIONAL_PERFORMANCE_COVERAGE_POLICY, ); expect(errors).not.toContainEqual( expect.stringContaining( 'viewport-zoom must not invalidate expensive pass "viewport-raster"', ), ); expect( validateToolcraftPerformanceCoverage( renderScaleSchema, { ...baseConfig, rendererPipeline: { ...rendererPipeline, passes: [{ ...pass, quality: "full" }], }, }, TOOLCRAFT_FUNCTIONAL_PERFORMANCE_COVERAGE_POLICY, ), ).toContainEqual( expect.stringContaining( 'viewport-zoom must not invalidate expensive pass "viewport-raster"', ), ); }); it.each(["memoized", "retained-resource"] as const)( "requires cacheKey for a composite pass with %s cache", (cache) => { const pass = createPass({ cacheKey: undefined, kind: "composite", lifecycle: { cache, resourceScope: "renderer" }, }); expect( validateToolcraftPerformanceCoverage( testSchema, createEnvelopeConfig({ pass }), TOOLCRAFT_FUNCTIONAL_PERFORMANCE_COVERAGE_POLICY, ), ).toContain( 'rendererPipeline pass "effect" is a cache-sensitive composite pass and must declare cacheKey so tests can reject full recomputation on every control change.', ); }, ); it("routes envelope render-plan failures through public coverage validation", () => { const pass = { ...createPass(), cost: undefined, lifecycle: undefined, } as unknown as ToolcraftRenderPass; expect( validateToolcraftPerformanceCoverage(testSchema, createEnvelopeConfig({ pass })), ).toEqual( expect.arrayContaining([ 'rendererPipeline pass "effect" must declare cost for envelope render-plan assessment.', 'rendererPipeline pass "effect" must declare lifecycle for envelope render-plan assessment.', ]), ); }); it("makes unresolved benchmark requirements fail public coverage", () => { const unresolvedErrors = validateToolcraftPerformanceCoverage( testSchema, createEnvelopeConfig(), ); const resolvedErrors = validateToolcraftPerformanceCoverage( testSchema, createEnvelopeConfig({ kernelBenchmarkDecisions: [createBenchmarkDecision()] }), ); expect(unresolvedErrors).toContain( 'rendererPipeline pass "effect" requires a protected kernel benchmark decision for candidates canvas-2d, webgl at workload {"output-units":12,"samples":4} before the render plan is accepted.', ); expect(resolvedErrors).not.toEqual( expect.arrayContaining([ expect.stringContaining("requires a protected kernel benchmark decision"), ]), ); }); it("defers only unresolved benchmark decisions for functional coverage", () => { const unresolvedConfig = createEnvelopeConfig(); const malformedConfig = { ...unresolvedConfig, kernelBenchmarkDecisions: [{ id: "effect" }], } as unknown as ToolcraftEnvelopePerformanceConfig; expect( validateToolcraftPerformanceCoverage( testSchema, unresolvedConfig, TOOLCRAFT_FUNCTIONAL_PERFORMANCE_COVERAGE_POLICY, ), ).not.toEqual( expect.arrayContaining([ expect.stringContaining("requires a protected kernel benchmark decision"), ]), ); expect( validateToolcraftPerformanceCoverage( testSchema, malformedConfig, TOOLCRAFT_FUNCTIONAL_PERFORMANCE_COVERAGE_POLICY, ), ).toEqual( expect.arrayContaining([ expect.stringContaining( 'kernelBenchmarkDecisions "effect" decision must be non-empty', ), ]), ); expect( validateToolcraftPerformanceCoverage(testSchema, unresolvedConfig), ).toEqual( expect.arrayContaining([ expect.stringContaining("requires a protected kernel benchmark decision"), ]), ); }); it("reports malformed raw envelopes without invoking a parallel workload validator", () => { const [controlDragInvalidation] = createEnvelopeConfig().rendererPipeline!.interactionInvalidation; if (!controlDragInvalidation) { throw new Error("Expected a control-drag invalidation fixture."); } const malformedConfig = { ...createEnvelopeConfig(), scenarios: [ { automated: true, automatedTestName: "perf: initial preview stays responsive", browser: true, browserTestName: "browser perf: initial preview stays responsive", controlLabel: "Samples", coversTargets: controlDragInvalidation.targets, expectedObservable: "Dragging samples keeps the preview responsive.", fixture: "control drag fixture", id: "control-drag", interaction: "control-drag" as const, pathId: "missing-control-drag-path", }, ], workloadEnvelope: null, } as unknown as ToolcraftEnvelopePerformanceConfig; expect(() => validateToolcraftPerformanceCoverage(testSchema, malformedConfig), ).not.toThrow(); const errors = validateToolcraftPerformanceCoverage(testSchema, malformedConfig); expect(errors).toContain("workloadEnvelope must be a non-null object."); expect(errors).toContain( 'Performance scenario control-drag references unknown pathId "missing-control-drag-path".', ); }); it("rejects renderer strategies that contradict envelope renderer ownership", () => { const customConfig = createEnvelopeConfig({ rendererStrategy: "none" }); const nonCustomConfig = { ...createEnvelopeConfig({ rendererStrategy: "svg" }), rendererPipeline: undefined, usesCustomRenderer: false, } as unknown as ToolcraftEnvelopePerformanceConfig; expect(assessToolcraftRenderPlan(testSchema, customConfig).errors).toContain( 'Envelope custom renderers must declare rendererStrategy "dom", "svg", "canvas-2d", "webgl", or "webgpu".', ); expect(assessToolcraftRenderPlan(testSchema, nonCustomConfig).errors).toContain( 'Envelope non-custom renderers must use rendererStrategy "none", received "svg".', ); }); it("captures immutable backing-resolution snapshots", () => { const assessment = assessToolcraftRenderPlan( testSchema, createEnvelopeConfig({ kernelBenchmarkDecisions: [createBenchmarkDecision()] }), ); expect(assessment.invariants.backingResolution.canvasSize).not.toBe( testSchema.canvas.size, ); expect(assessment.invariants.backingResolution.renderScale).not.toBe( testSchema.canvas.renderScale, ); expect(Object.isFrozen(assessment.invariants)).toBe(true); expect(Object.isFrozen(assessment.invariants.backingResolution)).toBe(true); expect(Object.isFrozen(assessment.invariants.backingResolution.canvasSize)).toBe( true, ); expect( Object.isFrozen(assessment.invariants.backingResolution.defaultBackingSize), ).toBe(true); expect( Object.isFrozen(assessment.invariants.backingResolution.runtimeTargets), ).toBe(true); expect(Object.isFrozen(assessment.invariants.outputQuality)).toBe(true); expect(Object.isFrozen(assessment.invariants.outputQuality[0])).toBe(true); }); it("tracks fixed canvas size and editable render scale as separate sources", () => { const schema = { ...testSchema, canvas: { ...testSchema.canvas, renderScale: { ...testSchema.canvas.renderScale, defaultValue: 2, enabled: true, }, sizing: { mode: "fixed-output" as const }, }, }; const assessment = assessToolcraftRenderPlan( schema, createEnvelopeConfig({ kernelBenchmarkDecisions: [createBenchmarkDecision()] }), ); expect(assessment.invariants.backingResolution).toMatchObject({ canvasSizeSource: "schema", effectiveDefaultScale: 2, renderScaleSource: "runtime-state", }); }); it("validates renderer ownership even when an envelope has no pipeline", () => { const config = { ...createEnvelopeConfig({ rendererStrategy: "svg" }), rendererPipeline: undefined, usesCustomRenderer: false, } as unknown as ToolcraftEnvelopePerformanceConfig; expect(validateToolcraftPerformanceCoverage(testSchema, config)).toContain( 'Envelope non-custom renderers must use rendererStrategy "none", received "svg".', ); }); });