Files
healer-man/src/ui/partyHealPopups.test.ts
T
2026-09-20 21:50:50 -04:00

59 lines
2.0 KiB
TypeScript

import { describe, expect, it } from "vitest";
import type { StructuredCombatEvent } from "../game/combatEvents";
import {
MAX_PARTY_HEAL_POPUPS,
addedPartyHealPopups,
appendPartyHealPopups,
} from "./partyHealPopups";
function event(
id: number,
kind: StructuredCombatEvent["kind"] = "healing",
effectiveAmount = 125,
): StructuredCombatEvent {
return {
id,
occurredAt: 1_000 + id,
kind,
sourceActorId: "healer",
targetActorId: `party-${id}`,
rawAmount: effectiveAmount,
effectiveAmount,
overheal: 0,
absorbed: 0,
critical: id % 2 === 0,
};
}
describe("party-frame healing popups", () => {
it("turns newly committed effective heals into rounded green-number events", () => {
const previous = [event(1)];
const next = [...previous, event(2, "damage", 80), event(3, "healing", 149.6)];
expect(addedPartyHealPopups(previous, next, true)).toEqual([{
key: "1003:3",
targetActorId: "party-3",
amount: 150,
critical: false,
horizontalOffset: -14,
}]);
});
it("ignores old heals, pure overheal, and all healing outside combat", () => {
const previous = [event(1)];
const overheal = event(2, "healing", 0);
expect(addedPartyHealPopups(previous, [...previous, overheal], true)).toEqual([]);
expect(addedPartyHealPopups(previous, [...previous, event(3)], false)).toEqual([]);
});
it("deduplicates replayed keys and bounds the active burst", () => {
const first = addedPartyHealPopups([], [event(1)], true)[0];
const burst = Array.from({ length: MAX_PARTY_HEAL_POPUPS + 4 }, (_, index) => (
addedPartyHealPopups([], [event(index + 2)], true)[0]
));
const result = appendPartyHealPopups([first], [first, ...burst]);
expect(result).toHaveLength(MAX_PARTY_HEAL_POPUPS);
expect(new Set(result.map((popup) => popup.key)).size).toBe(MAX_PARTY_HEAL_POPUPS);
expect(result.at(-1)?.key).toBe(`${1_000 + MAX_PARTY_HEAL_POPUPS + 5}:${MAX_PARTY_HEAL_POPUPS + 5}`);
});
});