puck / frontend /src /engine /reactions.test.ts
vu1n's picture
Puck — desktop fairy familiar (HF Build Small)
3c124f3
Raw
History Blame Contribute Delete
2.96 kB
import { describe, expect, it } from "vitest";
import { EVENTS } from "./events";
import {
asPeekEmotion,
PEEK_EMOTIONS,
reactionForEmotion,
reactionForEvent,
reactionForRating,
} from "./reactions";
const ev = (id: string) => {
const e = EVENTS.find((x) => x.id === id);
if (!e) throw new Error(`no such event: ${id}`);
return e;
};
const stableRng = () => 0.99; // never trips the mischief-dance branch
describe("reactionForEvent", () => {
it("celebrates a fresh win and shouts", () => {
const r = reactionForEvent(ev("git_push"), { repeats: 0, rng: stableRng });
expect(r.kind).toBe("celebrate");
expect(r.shout).toBe("shipped!");
});
it("decays to a shrug when the same event keeps recurring", () => {
expect(reactionForEvent(ev("git_push"), { repeats: 1, rng: stableRng }).kind).toBe("pop");
expect(reactionForEvent(ev("git_push"), { repeats: 3, rng: stableRng }).kind).toBe("shrug");
});
it("keeps alarms sharp no matter how often they fire", () => {
expect(reactionForEvent(ev("build_fail"), { repeats: 0, rng: stableRng }).kind).toBe("nani");
expect(reactionForEvent(ev("build_fail"), { repeats: 9, rng: stableRng }).kind).toBe("nani");
});
it("high mischief can turn a celebration into a dance", () => {
const r = reactionForEvent(ev("claude_done"), { repeats: 0, mischief: 90, rng: () => 0 });
expect(r.kind).toBe("dance");
});
it("falls back to a pop for an unmapped event", () => {
const fake = { ...ev("git_push"), id: "totally_new" };
expect(reactionForEvent(fake, { rng: stableRng }).kind).toBe("pop");
});
});
describe("reactionForRating", () => {
it("maps ratings to felt reactions", () => {
expect(reactionForRating("cute").kind).toBe("dance");
expect(reactionForRating("annoying").kind).toBe("sulk");
expect(reactionForRating("helpful").kind).toBe("pop");
});
});
describe("peek emotions", () => {
const stable = () => 0.99;
it("maps each emotion to its gesture with a shout", () => {
expect(reactionForEmotion("confused").kind).toBe("nani");
expect(reactionForEmotion("amused").kind).toBe("laugh");
expect(reactionForEmotion("worried").kind).toBe("fret");
expect(reactionForEmotion("wistful").kind).toBe("sad");
expect(reactionForEmotion("curious").kind).toBe("perk");
expect(reactionForEmotion("delighted", { rng: stable }).kind).toBe("celebrate");
for (const e of PEEK_EMOTIONS) expect(reactionForEmotion(e).shout).toBeTruthy();
});
it("lets a giddy (high-mischief) Puck escalate delight into a dance", () => {
expect(reactionForEmotion("delighted", { mischief: 90, rng: () => 0 }).kind).toBe("dance");
});
it("coerces unknown/missing brain strings to curious", () => {
expect(asPeekEmotion("amused")).toBe("amused");
expect(asPeekEmotion("nonsense")).toBe("curious");
expect(asPeekEmotion(undefined)).toBe("curious");
expect(asPeekEmotion(null)).toBe("curious");
});
});