import { describe, expect, it } from "vitest"; import { activityColorSlug, activityDurationLabel, activityHeldMs, } from "./activity.js"; describe("activityHeldMs", () => { it("measures time spent in the current state", () => { const now = Date.now(); const since = new Date(now - 90_000).toISOString(); expect(activityHeldMs(since, now)).toBe(90_000); }); it("returns null for payloads that predate #102 (epoch default)", () => { expect(activityHeldMs(undefined, Date.now())).toBeNull(); expect(activityHeldMs(new Date(0).toISOString(), Date.now())).toBeNull(); }); it("returns null for unparseable timestamps", () => { expect(activityHeldMs("not-a-time", Date.now())).toBeNull(); }); it("never goes negative", () => { const now = Date.now(); expect(activityHeldMs(new Date(now + 5_000).toISOString(), now)).toBe(0); }); }); describe("activityDurationLabel (#102)", () => { it("floors whole seconds under a minute", () => { expect(activityDurationLabel(30_400)).toBe("30s"); expect(activityDurationLabel(59_900)).toBe("59s"); }); it("floors whole minutes under an hour", () => { expect(activityDurationLabel(60_000)).toBe("1m"); expect(activityDurationLabel(4 * 60_000 + 59_999)).toBe("4m"); }); it("floors whole hours from an hour up, with no days unit", () => { expect(activityDurationLabel(60 * 60_000)).toBe("1h"); expect(activityDurationLabel(2 * 3_600_000 + 59 * 60_000 + 59_999)).toBe("2h"); expect(activityDurationLabel(26 * 3_600_000)).toBe("26h"); }); }); describe("activityColorSlug", () => { it("maps each known state to its contract slug", () => { expect(activityColorSlug("Active")).toBe("active"); expect(activityColorSlug("Idle")).toBe("idle"); expect(activityColorSlug("AwaitingInput")).toBe("awaiting-input"); expect(activityColorSlug("Error")).toBe("error"); }); it("treats an unknown variant as idle so rendering never fails", () => { expect(activityColorSlug("Teleported")).toBe("idle"); }); });