Files
healer-man/src/game/manastormClientOverlay.test.ts
T
2026-08-14 15:56:39 -04:00

95 lines
3.2 KiB
TypeScript

import { beforeEach, describe, expect, it } from "vitest";
import {
MANASTORM_BUBBLE_DEFAULT_RADIUS,
createManastormClientOverlayState,
manastormBubbleFillPercent,
manastormBubbleSeverity,
withManastormNextWaveCountdown,
withManastormSafetyBubble,
} from "./manastormClientOverlay";
import { useManastormStore } from "./manastormStore";
describe("Manastorm client overlay contract", () => {
beforeEach(() => {
useManastormStore.getState().resetRun();
});
it("shows only explicit non-negative countdown values", () => {
const initial = createManastormClientOverlayState();
expect(withManastormNextWaveCountdown(initial, 4.9).nextWaveCountdownSeconds).toBe(4);
expect(withManastormNextWaveCountdown(initial, 0).nextWaveCountdownSeconds).toBe(0);
expect(withManastormNextWaveCountdown(initial, -1).nextWaveCountdownSeconds).toBeNull();
expect(withManastormNextWaveCountdown(initial, Number.NaN).nextWaveCountdownSeconds).toBeNull();
expect(withManastormNextWaveCountdown(initial, null).nextWaveCountdownSeconds).toBeNull();
});
it("normalizes safety-bubble distance and preserves decoded warning thresholds", () => {
const initial = createManastormClientOverlayState();
const safe = withManastormSafetyBubble(initial, {
active: true,
radius: 9,
distanceRemaining: 6,
});
const warning = withManastormSafetyBubble(safe, {
active: true,
radius: 9,
distanceRemaining: 3,
});
const danger = withManastormSafetyBubble(warning, {
active: true,
radius: 9,
distanceRemaining: 1.5,
});
const clamped = withManastormSafetyBubble(danger, {
active: true,
radius: 8,
distanceRemaining: 20,
});
expect(safe.safetyBubble.severity).toBe("safe");
expect(warning.safetyBubble.severity).toBe("warning");
expect(danger.safetyBubble.severity).toBe("danger");
expect(clamped.safetyBubble.distanceRemaining).toBe(8);
expect(manastormBubbleFillPercent(clamped.safetyBubble)).toBe(100);
expect(manastormBubbleSeverity(3.01)).toBe("safe");
});
it("uses the decoded nine-yard default and hides cleanly", () => {
const initial = createManastormClientOverlayState();
const active = withManastormSafetyBubble(initial, { active: true });
const hidden = withManastormSafetyBubble(active, { active: false });
expect(active.safetyBubble).toMatchObject({
active: true,
radius: MANASTORM_BUBBLE_DEFAULT_RADIUS,
distanceRemaining: MANASTORM_BUBBLE_DEFAULT_RADIUS,
severity: "safe",
});
expect(hidden).toEqual(initial);
});
it("exposes data-driven store actions and clears transient client state on reset", () => {
useManastormStore.getState().setNextWaveCountdown(7);
useManastormStore.getState().setSafetyBubble({
active: true,
radius: 9,
distanceRemaining: 2,
});
expect(useManastormStore.getState().clientOverlay).toMatchObject({
nextWaveCountdownSeconds: 7,
safetyBubble: {
active: true,
severity: "warning",
distanceRemaining: 2,
},
});
useManastormStore.getState().resetRun();
expect(useManastormStore.getState().clientOverlay).toEqual(
createManastormClientOverlayState(),
);
});
});