Implement the 013-hp-status-indicators feature that adds visual HP status indicators to combatant rows with a pure domain function deriving bloodied/unconscious states
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
55
packages/domain/src/__tests__/hp-status.test.ts
Normal file
55
packages/domain/src/__tests__/hp-status.test.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { deriveHpStatus } from "../hp-status.js";
|
||||
|
||||
describe("deriveHpStatus", () => {
|
||||
it("returns healthy when currentHp >= maxHp / 2", () => {
|
||||
expect(deriveHpStatus(10, 20)).toBe("healthy");
|
||||
expect(deriveHpStatus(15, 20)).toBe("healthy");
|
||||
expect(deriveHpStatus(20, 20)).toBe("healthy");
|
||||
});
|
||||
|
||||
it("returns bloodied when 0 < currentHp < maxHp / 2", () => {
|
||||
expect(deriveHpStatus(9, 20)).toBe("bloodied");
|
||||
expect(deriveHpStatus(1, 20)).toBe("bloodied");
|
||||
expect(deriveHpStatus(5, 20)).toBe("bloodied");
|
||||
});
|
||||
|
||||
it("returns unconscious when currentHp <= 0", () => {
|
||||
expect(deriveHpStatus(0, 20)).toBe("unconscious");
|
||||
});
|
||||
|
||||
it("returns unconscious with negative HP", () => {
|
||||
expect(deriveHpStatus(-5, 20)).toBe("unconscious");
|
||||
});
|
||||
|
||||
it("returns undefined when maxHp is undefined", () => {
|
||||
expect(deriveHpStatus(10, undefined)).toBeUndefined();
|
||||
});
|
||||
|
||||
it("returns undefined when currentHp is undefined", () => {
|
||||
expect(deriveHpStatus(undefined, 20)).toBeUndefined();
|
||||
});
|
||||
|
||||
it("returns undefined when both are undefined", () => {
|
||||
expect(deriveHpStatus(undefined, undefined)).toBeUndefined();
|
||||
});
|
||||
|
||||
it("handles maxHp=1 (no bloodied state possible)", () => {
|
||||
expect(deriveHpStatus(1, 1)).toBe("healthy");
|
||||
expect(deriveHpStatus(0, 1)).toBe("unconscious");
|
||||
});
|
||||
|
||||
it("handles maxHp=2 (1/2 is healthy, not bloodied)", () => {
|
||||
expect(deriveHpStatus(1, 2)).toBe("healthy");
|
||||
expect(deriveHpStatus(0, 2)).toBe("unconscious");
|
||||
});
|
||||
|
||||
it("handles odd maxHp=21 (10 is bloodied since 10 < 10.5)", () => {
|
||||
expect(deriveHpStatus(10, 21)).toBe("bloodied");
|
||||
expect(deriveHpStatus(11, 21)).toBe("healthy");
|
||||
});
|
||||
|
||||
it("returns healthy when currentHp exceeds maxHp", () => {
|
||||
expect(deriveHpStatus(25, 20)).toBe("healthy");
|
||||
});
|
||||
});
|
||||
11
packages/domain/src/hp-status.ts
Normal file
11
packages/domain/src/hp-status.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
export type HpStatus = "healthy" | "bloodied" | "unconscious";
|
||||
|
||||
export function deriveHpStatus(
|
||||
currentHp: number | undefined,
|
||||
maxHp: number | undefined,
|
||||
): HpStatus | undefined {
|
||||
if (currentHp === undefined || maxHp === undefined) return undefined;
|
||||
if (currentHp <= 0) return "unconscious";
|
||||
if (currentHp < maxHp / 2) return "bloodied";
|
||||
return "healthy";
|
||||
}
|
||||
@@ -18,6 +18,7 @@ export type {
|
||||
TurnAdvanced,
|
||||
TurnRetreated,
|
||||
} from "./events.js";
|
||||
export { deriveHpStatus, type HpStatus } from "./hp-status.js";
|
||||
export {
|
||||
type RemoveCombatantSuccess,
|
||||
removeCombatant,
|
||||
|
||||
Reference in New Issue
Block a user