import { describe, expect, it, vi } from "vitest"; import { defineToolcraft } from "../schema/define-toolcraft"; import { createToolcraftState } from "../state/create-template-state"; import { getToolcraftFiniteArtboardRect } from "./canvas-world-geometry"; import type { ToolcraftProductSceneBoundsProvider } from "./scene-bounds"; import { resolveToolcraftProductSceneFrame, toolcraftProductSceneFramesEqual, } from "./product-scene-frame"; const state = createToolcraftState( defineToolcraft({ base: { identity: { id: "runtime-test", title: "Toolcraft fixture", }, canvas: { enabled: true }, panels: {}, }, modules: [], }), ); const fallbackRect = getToolcraftFiniteArtboardRect(state.canvas.size); describe("resolveToolcraftProductSceneFrame", () => { it("uses one declared product rect as the ready frame", () => { expect( resolveToolcraftProductSceneFrame({ boundsProvider: () => [{ height: 128, width: 192, x: -96, y: -64 }], fallbackRect, state, }), ).toEqual({ kind: "ready", rect: { height: 128, width: 192, x: -96, y: -64 }, }); }); it("unions several declared product rects", () => { expect( resolveToolcraftProductSceneFrame({ boundsProvider: () => [ { height: 40, width: 80, x: -96, y: -64 }, { height: 64, width: 32, x: 64, y: 0 }, ], fallbackRect, state, }), ).toEqual({ kind: "ready", rect: { height: 128, width: 192, x: -96, y: -64 }, }); }); it("reports an empty declared product scene without using the fallback", () => { expect( resolveToolcraftProductSceneFrame({ boundsProvider: () => [], fallbackRect, state, }), ).toEqual({ kind: "empty", rect: null }); }); it("reports invalid declared product bounds as unavailable", () => { const boundsProvider = (() => [ { height: 128, width: Number.NaN, x: -96, y: -64 }, ]) as ToolcraftProductSceneBoundsProvider; expect( resolveToolcraftProductSceneFrame({ boundsProvider, fallbackRect, state, }), ).toEqual({ kind: "unavailable", rect: null }); }); it("reports a throwing declared provider as unavailable", () => { const boundsProvider = vi.fn(() => { throw new Error("broken provider"); }); expect( resolveToolcraftProductSceneFrame({ boundsProvider, fallbackRect, state, }), ).toEqual({ kind: "unavailable", rect: null }); }); it("uses the finite artboard fallback only when no provider is declared", () => { expect(resolveToolcraftProductSceneFrame({ fallbackRect, state })).toEqual({ kind: "ready", rect: fallbackRect, }); }); it("reports unavailable when neither provider nor fallback exists", () => { expect(resolveToolcraftProductSceneFrame({ state })).toEqual({ kind: "unavailable", rect: null, }); }); it("compares resolved frames by status and exact rectangle", () => { expect( toolcraftProductSceneFramesEqual( { kind: "ready", rect: fallbackRect }, { kind: "ready", rect: { ...fallbackRect } }, ), ).toBe(true); expect( toolcraftProductSceneFramesEqual( { kind: "ready", rect: fallbackRect }, { kind: "ready", rect: { ...fallbackRect, width: fallbackRect.width + 1 }, }, ), ).toBe(false); expect( toolcraftProductSceneFramesEqual( { kind: "empty", rect: null }, { kind: "unavailable", rect: null }, ), ).toBe(false); }); });