import { describe, expect, it } from "vitest"; import { defineToolcraft } from "./define-toolcraft"; import type { ToolcraftControlSchema } from "./types"; function createSchema(control: ToolcraftControlSchema) { return { canvas: { enabled: false }, panels: { controls: { sections: [{ controls: { layers: control }, title: "Layers" }], title: "Controls", }, }, }; } function compoundCollection( overrides: Record = {}, ): ToolcraftControlSchema { return { defaultValue: [{ invert: false, strength: 0.4 }], itemControls: { strength: { defaultValue: 0.5, label: "Strength", max: 1, min: 0, step: 0.01, type: "slider", }, invert: { defaultValue: false, label: "Invert", type: "switch", }, }, itemLabel: "Layer", minItems: 1, target: "surface.layers", type: "collectionActions", ...overrides, } as ToolcraftControlSchema; } describe("defineToolcraft compound collectionActions items", () => { it("accepts one logical record made from several built-in fields", () => { const app = defineToolcraft(createSchema(compoundCollection())); const control = app.panels.controls?.sections.find( (section) => section.title === "Layers", )?.controls.layers; expect(Object.keys(control?.itemControls ?? {})).toEqual([ "strength", "invert", ]); }); it("rejects competing scalar and record templates", () => { expect(() => defineToolcraft( createSchema( compoundCollection({ itemControl: { defaultValue: 0, type: "slider" }, }), ), ), ).toThrow(/collection-item-template.*itemControl.*itemControls/u); }); it("requires at least two fields in a compound collection item", () => { expect(() => defineToolcraft( createSchema( compoundCollection({ itemControls: { strength: { defaultValue: 0.5, type: "slider" }, }, }), ), ), ).toThrow(/collection-item-controls.*at least two/u); }); it("requires one default source per compound field", () => { expect(() => defineToolcraft( createSchema( compoundCollection({ itemControls: { invert: { defaultValue: false, type: "switch" }, strength: { type: "slider" }, }, }), ), ), ).toThrow(/itemControls\.strength.*defaultValue/u); }); it("rejects a competing itemDefaultValue", () => { expect(() => defineToolcraft( createSchema( compoundCollection({ itemDefaultValue: { invert: true, strength: 1 }, }), ), ), ).toThrow(/collection-item-default.*itemDefaultValue/u); }); it("rejects non-record initial compound items", () => { expect(() => defineToolcraft( createSchema(compoundCollection({ defaultValue: [new Date()] })), ), ).toThrow(/collection-item-value.*plain record/u); }); it("keeps sourceCollection single-field only", () => { expect(() => defineToolcraft( createSchema(compoundCollection({ type: "sourceCollection" })), ), ).toThrow(/collection-item-controls.*collectionActions.*fileDrop/u); }); });