import { describe, expect, it } from "vitest"; import { defineToolcraft } from "../schema/define-toolcraft"; import type { ResolvedToolcraftControlSchema } from "../schema/types"; import { normalizeToolcraftControlValue } from "./control-value-normalization"; const schema = defineToolcraft({ canvas: { enabled: true, sizing: { mode: "editable-output" } }, panels: { controls: { sections: [ { controls: { format: { defaultValue: "png", options: [ { label: "PNG", value: "png" }, { label: "JPEG", value: "jpeg" }, ], target: "output.format", type: "select", }, opacity: { defaultValue: 50, max: 100, min: 0, target: "appearance.opacity", type: "slider", }, position: { defaultValue: { x: "0.00", y: "0.00" }, target: "appearance.position", type: "vector", }, prompt: { defaultValue: "Initial prompt", target: "generation.prompt", type: "text", }, view: { defaultValue: "simple", label: "Template view", options: [ { label: "Simple", value: "simple" }, { label: "Mega", value: "mega" }, ], target: "template.view", type: "tabs", }, }, id: "appearance", title: "Appearance", }, ], title: "Controls", }, }, }); function getControl(id: string): ResolvedToolcraftControlSchema { const control = schema.panels.controls?.sections .map((section) => section.controls[id]) .find((candidate) => candidate !== undefined); if (!control) { throw new Error(`Missing test control ${id}`); } return control; } describe("normalizeToolcraftControlValue", () => { it("restores canonical numeric canvas dimensions from text setup controls", () => { const canvasWidth = getControl("canvasWidth"); expect(normalizeToolcraftControlValue(canvasWidth, 1919)).toEqual({ accepted: true, value: 1919, }); expect(normalizeToolcraftControlValue(canvasWidth, "640.4")).toEqual({ accepted: true, value: 640, }); }); it("accepts a finite slider value inside the schema range", () => { expect(normalizeToolcraftControlValue(getControl("opacity"), 80)).toEqual({ accepted: true, value: 80, }); }); it("rejects a slider value outside its schema range", () => { expect(normalizeToolcraftControlValue(getControl("opacity"), 200)).toEqual({ accepted: false, fallback: 50, }); }); it("accepts current options and rejects removed options", () => { expect(normalizeToolcraftControlValue(getControl("format"), "jpeg")).toEqual({ accepted: true, value: "jpeg", }); expect(normalizeToolcraftControlValue(getControl("format"), "webp")).toEqual({ accepted: false, fallback: "png", }); }); it("normalizes tabs against their declared content views", () => { expect(normalizeToolcraftControlValue(getControl("view"), "mega")).toEqual({ accepted: true, value: "mega", }); expect( normalizeToolcraftControlValue(getControl("view"), "archive"), ).toEqual({ accepted: false, fallback: "simple", }); }); it("rejects malformed compound vector values", () => { expect( normalizeToolcraftControlValue(getControl("position"), { x: "0.25", y: null, }), ).toEqual({ accepted: false, fallback: { x: 0, y: 0 }, }); }); it("accepts values matching a text control", () => { expect( normalizeToolcraftControlValue(getControl("prompt"), "Restored prompt"), ).toEqual({ accepted: true, value: "Restored prompt" }); }); });