import { describe, expect, it } from "vitest"; import { defineToolcraft } from "./define-toolcraft"; import type { ToolcraftCanvasRenderScaleSchema } from "./types"; const authoredRenderScaleStep: ToolcraftCanvasRenderScaleSchema = { step: 0.5 }; const authoredRenderScaleDefaultValue = { defaultValue: 1, step: 0.5 }; const authoredRenderScaleEnabled = { enabled: true, step: 0.5 }; const authoredRenderScaleMax = { max: 1, step: 0.5 }; const authoredRenderScaleMin = { min: 1, step: 0.5 }; // @ts-expect-error Authored render scale cannot select its resolved default value. const authoredRenderScaleDefaultValueAssignment: ToolcraftCanvasRenderScaleSchema = authoredRenderScaleDefaultValue; // @ts-expect-error Authored render scale is always enabled when provided. const authoredRenderScaleEnabledAssignment: ToolcraftCanvasRenderScaleSchema = { ...authoredRenderScaleEnabled, }; // @ts-expect-error Authored render scale cannot change the canonical maximum. const authoredRenderScaleMaxAssignment: ToolcraftCanvasRenderScaleSchema = authoredRenderScaleMax; // @ts-expect-error Authored render scale cannot change the canonical minimum. const authoredRenderScaleMinAssignment: ToolcraftCanvasRenderScaleSchema = { ...authoredRenderScaleMin, }; void authoredRenderScaleStep; void authoredRenderScaleDefaultValue; void authoredRenderScaleEnabled; void authoredRenderScaleMax; void authoredRenderScaleMin; void authoredRenderScaleDefaultValueAssignment; void authoredRenderScaleEnabledAssignment; void authoredRenderScaleMaxAssignment; void authoredRenderScaleMinAssignment; describe("defineToolcraft runtime setup render scale and timeline controls", () => { it("appends raster render scale to the technical setup controls when enabled", () => { const app = defineToolcraft({ canvas: { enabled: true, renderScale: true, size: { height: 900, unit: "px", width: 1440 }, sizing: { mode: "editable-output" }, }, panels: { controls: { sections: [], title: "Controls", }, }, }); const setupSection = app.panels.controls?.sections[0]; expect(app.canvas.renderScale).toEqual({ defaultValue: 2, enabled: true, max: 2, min: 1, step: 0.25, }); expect(app.assembly.capabilities).toContain("canvas.renderScale"); expect(Object.keys(setupSection?.controls ?? {})).toEqual([ "settingsTransfer", "infinityCanvas", "canvasAspectRatio", "canvasWidth", "canvasHeight", "canvasRenderScale", ]); expect(setupSection?.controls.canvasRenderScale).toMatchObject({ defaultValue: 2, label: "Resolution scale", markerCount: 5, max: 2, min: 1, step: 0.25, target: "canvas.renderScale", type: "slider", variant: "discrete", }); }); it("places timeline last when no managed background controls exist", () => { const app = defineToolcraft({ canvas: { enabled: true, renderScale: true, size: { height: 900, unit: "px", width: 1440 }, sizing: { mode: "editable-output" }, }, panels: { controls: { sections: [], title: "Controls", }, timeline: { mode: "playback" }, }, }); const setupSection = app.panels.controls?.sections[0]; expect(Object.keys(setupSection?.controls ?? {})).toEqual([ "settingsTransfer", "infinityCanvas", "canvasAspectRatio", "canvasWidth", "canvasHeight", "canvasRenderScale", "timelineExtended", ]); expect(setupSection?.controls.timelineExtended).toMatchObject({ defaultValue: false, label: "Timeline", target: "panels.timeline.extended", type: "switch", }); expect(setupSection?.controls.timelineExtended).not.toHaveProperty("description"); expect(setupSection?.controls.infinityCanvas).not.toHaveProperty("description"); expect(setupSection?.layoutGroups).toEqual([ { columns: 2, controls: ["canvasWidth", "canvasHeight"], layout: "inline", }, ]); }); it("uses the canonical authored raster scale with a custom step", () => { const app = defineToolcraft({ canvas: { enabled: true, renderScale: { step: 0.5 }, size: { height: 900, unit: "px", width: 1440 }, sizing: { mode: "fixed-output" }, }, panels: { controls: { sections: [], title: "Controls", }, timeline: { mode: "playback" }, }, }); const setupSection = app.panels.controls?.sections[0]; expect(Object.keys(setupSection?.controls ?? {})).toEqual([ "settingsTransfer", "canvasRenderScale", "timelineExtended", ]); expect(setupSection?.controls.canvasRenderScale).toMatchObject({ defaultValue: 2, max: 2, min: 1, step: 0.5, target: "canvas.renderScale", type: "slider", }); expect(app.canvas.renderScale).toEqual({ defaultValue: 2, enabled: true, max: 2, min: 1, step: 0.5, }); expect(setupSection?.controls.timelineExtended).toMatchObject({ defaultValue: false, label: "Timeline", target: "panels.timeline.extended", type: "switch", }); expect(setupSection?.controls.timelineExtended).not.toHaveProperty("description"); expect(setupSection?.layoutGroups ?? []).toEqual([]); }); it("rejects an authored step that cannot reach the canonical maximum", () => { expect(() => defineToolcraft({ canvas: { enabled: true, renderScale: { step: 0.3 }, }, panels: {}, }), ).toThrow("Canvas render scale step must divide the canonical range exactly."); }); it.each([0, Number.NaN])("rejects invalid authored step %s", (step) => { expect(() => defineToolcraft({ canvas: { enabled: true, renderScale: { step }, }, panels: {}, }), ).toThrow("Canvas render scale step must be a finite value between 0.01 and 1."); }); });