import { describe, it, expect } from "vitest"; import { parseVariables, mergeVariables, renderTemplate, labelFor, variablesToAsk } from "@/lib/prompts/variables"; describe("parseVariables", () => { it("returns unique names in order of first appearance", () => { expect(parseVariables("Translate {{text}} into {{lang}}. Keep {{text}} tone.")).toEqual(["text", "lang"]); }); it("tolerates whitespace and allows _ - . in names", () => { expect(parseVariables("{{ customer_name }} / {{ order-id }} / {{ meta.locale }}")).toEqual(["customer_name", "order-id", "meta.locale"]); }); it("ignores JSON examples, single braces and invalid names", () => { expect(parseVariables('{"a": 1} {b} {{1bad}} {{ }} {{ok}}')).toEqual(["ok"]); expect(parseVariables("")).toEqual([]); }); }); describe("mergeVariables", () => { it("keeps labels/defaults for surviving names, appends new, drops removed", () => { const merged = mergeVariables("Hi {{name}}, {{tone}} please", [ { name: "name", label: "Customer", default: "there" }, { name: "removed", default: "x" }, ]); expect(merged).toEqual([{ name: "name", label: "Customer", default: "there" }, { name: "tone" }]); }); }); describe("renderTemplate", () => { it("fills values, then defaults, then empty strings and reports both", () => { const r = renderTemplate("{{a}}-{{b}}-{{c}}", { a: "A" }, [{ name: "b", default: "B" }, { name: "c" }]); expect(r.text).toBe("A-B-"); expect(r.defaulted).toEqual(["b"]); expect(r.missing).toEqual(["c"]); }); it("replaces every occurrence and leaves non-variables intact", () => { expect(renderTemplate("{{x}} {{ x }} {y} {{1}}", { x: "ok" }).text).toBe("ok ok {y} {{1}}"); }); }); describe("labelFor / variablesToAsk", () => { it("humanizes names and asks only for variables without defaults", () => { expect(labelFor({ name: "customer_name" })).toBe("Customer name"); expect(labelFor({ name: "targetLang" })).toBe("Target lang"); expect(labelFor({ name: "x", label: " Custom " })).toBe("Custom"); expect(variablesToAsk([{ name: "a", default: "1" }, { name: "b" }, { name: "c", default: "2", required: true }]).map((v) => v.name)).toEqual(["b", "c"]); }); });