import { describe, expect, it, vi } from "vitest"; import { defineToolcraft } from "../schema/define-toolcraft"; import { createToolcraftState } from "../state/create-template-state"; import { createToolcraftRuntimeSceneVisibility } from "../scene"; import { ToolcraftSceneExportError } from "./export-frame"; import { resolveToolcraftStillArtifactFrame, resolveToolcraftVideoArtifactFrame, } from "./artifact-scene-frame"; import { createToolcraftVideoArtifactFramePlan } from "./artifact-frame-state"; import { createToolcraftVideoFrameSchedule } from "./video-frame-schedule"; const visibility = createToolcraftRuntimeSceneVisibility({ renderDefaultImages: true, suppressedModelTargets: [], }); function createState(mode: "finite" | "infinite") { return createToolcraftState( defineToolcraft({ canvas: { enabled: true }, panels: {} }), { canvas: { mode } }, ); } describe("artifact scene frame", () => { it("returns a finite frame without invoking product bounds", () => { const state = createState("finite"); const boundsProvider = vi.fn(() => []); expect( resolveToolcraftStillArtifactFrame({ boundsProvider, productSceneRequired: true, state, visibility, }), ).toEqual({ height: state.canvas.size.height, width: state.canvas.size.width, x: 0, y: 0, }); expect(boundsProvider).not.toHaveBeenCalled(); }); it("unions moving infinite-scene bounds across the exact frame plan", () => { const state = createState("infinite"); const plan = createToolcraftVideoArtifactFramePlan( state, createToolcraftVideoFrameSchedule(0.1), ); const boundsProvider = vi.fn(({ state: frameState }) => [ { height: 10, width: 20, x: frameState.timeline.currentTimeSeconds * 300, y: -5, }, ]); expect( resolveToolcraftVideoArtifactFrame({ boundsProvider, framePlan: plan, productSceneRequired: true, visibility, }), ).toEqual({ height: 10, width: 40, x: 0, y: -5 }); expect(boundsProvider).toHaveBeenCalledTimes(3); expect(boundsProvider.mock.calls[1]?.[0].state).toBe(plan[1]?.state); }); it("fails visibly when an infinite product scene has no bounds provider", () => { expect(() => resolveToolcraftStillArtifactFrame({ boundsProvider: undefined, productSceneRequired: true, state: createState("infinite"), visibility, }), ).toThrow(ToolcraftSceneExportError); }); });