import { describe, expect, it } from "vitest"; import { describeHiveOps, partsAddedBy } from "./describe"; import { inlineCatalog, part, templateState } from "./test-utils"; import type { HiveOp, HiveState } from "./types"; describe("describeHiveOps", () => { const catalog = inlineCatalog(); function stateWithInsert(): HiveState { const state = templateState(); state.stack[0].inserts = [part("fi", "floor-insert")]; return state; } it("describes removed inserts and added parts", () => { const ops: HiveOp[] = [ { op: "removePart", id: "fi" }, { op: "addPart", part: part("b2", "box"), at: 2 }, ]; expect(describeHiveOps(ops, stateWithInsert(), catalog)).toBe("Bausperre entfernt, Zarge hinzugefügt"); }); it("names parts that were added by earlier changes and are gone now", () => { const pocket = part("p1", "frame-feeder", { slot: 1, state: { syrupLiters: 1 } }); const earlier: HiveOp[] = [{ op: "addInsert", hostId: "b", part: pocket }]; const seen = partsAddedBy(earlier); const later: HiveOp[] = [ { op: "setState", id: "p1", key: "syrupLiters", value: 1.5 }, { op: "removePart", id: "p1" }, ]; expect(describeHiveOps(later, templateState(), catalog, seen)).toBe("Flüssigfutter 1,5 l, Futtertasche entfernt"); expect(describeHiveOps(later, templateState(), catalog)).toContain("Teil entfernt"); }); it("uses the label of a part when it has one", () => { const state = templateState(); state.stack[1].label = "Honigraum 1"; expect(describeHiveOps([{ op: "removePart", id: "b" }], state, catalog)).toBe("Honigraum 1 entfernt"); expect(describeHiveOps([{ op: "movePart", id: "b", to: 2 }], state, catalog)).toBe("Honigraum 1 verschoben"); }); it("describes insert ops", () => { expect( describeHiveOps([{ op: "addInsert", hostId: "f", part: part("fi", "floor-insert") }], templateState(), catalog), ).toBe("Bausperre eingelegt"); expect( describeHiveOps([{ op: "addInsert", hostId: "b", part: part("e", "evaporator") }], templateState(), catalog), ).toBe("Verdunster eingesetzt"); }); it("describes setState with unit and option labels", () => { const state = templateState(); state.stack.splice(2, 0, part("fe", "feeder")); expect(describeHiveOps([{ op: "setState", id: "fe", key: "syrupLiters", value: 2.5 }], state, catalog)).toBe( "Flüssigfutter 2,5 l", ); expect(describeHiveOps([{ op: "setState", id: "l", key: "feedHole", value: "OPEN" }], state, catalog)).toBe( "Futterloch offen", ); }); it("describes setFrame, setFrames and setLabel", () => { const state = templateState(); expect(describeHiveOps([{ op: "setFrame", boxId: "b", slot: 4, type: "BROOD" }], state, catalog)).toBe( "Rähmchen 4 in Zarge: Brutwabe", ); expect(describeHiveOps([{ op: "setFrames", boxId: "b", frames: [] }], state, catalog)).toBe( "Rähmchen in Zarge neu gesetzt", ); expect(describeHiveOps([{ op: "setLabel", id: "b", label: "Brutraum" }], state, catalog)).toBe( "Zarge heißt jetzt „Brutraum“", ); }); it("resolves parts added earlier in the same batch", () => { const ops: HiveOp[] = [ { op: "addPart", part: { ...part("n", "box"), label: "Aufsatz" }, at: 2 }, { op: "setFrame", boxId: "n", slot: 1, type: "HONEY" }, ]; expect(describeHiveOps(ops, templateState(), catalog)).toBe( "Aufsatz hinzugefügt, Rähmchen 1 in Aufsatz: Honigwabe", ); }); it("shortens more than three ops", () => { const ops: HiveOp[] = [1, 2, 3, 4, 5].map((slot) => ({ op: "setFrame", boxId: "b", slot, type: "BROOD" })); expect(describeHiveOps(ops, templateState(), catalog)).toBe( "Rähmchen 1 in Zarge: Brutwabe, Rähmchen 2 in Zarge: Brutwabe, Rähmchen 3 in Zarge: Brutwabe und 2 weitere", ); }); });