import { describe, expect, it } from "vitest"; import { hpForVariant, hpRange } from "../hp-range.js"; describe("hpRange", () => { it("derives min and max from a formula with a positive modifier", () => { const range = hpRange({ average: 16, formula: "3d6 + 6" }); expect(range).toEqual({ min: 9, average: 16, max: 24 }); }); it("derives min and max from a formula without a modifier", () => { const range = hpRange({ average: 40, formula: "9d8" }); expect(range).toEqual({ min: 9, average: 40, max: 72 }); }); it("subtracts a negative modifier", () => { const range = hpRange({ average: 45, formula: "10d8 - 5" }); expect(range).toEqual({ min: 5, average: 45, max: 75 }); }); it("treats an en dash as a minus sign", () => { // Bundled bestiary data contains e.g. "2d6 – 2" (U+2013). const range = hpRange({ average: 5, formula: "2d6 – 2" }); expect(range).toEqual({ min: 1, average: 5, max: 10 }); }); it("never drops below 1 HP when the modifier exceeds the dice", () => { const range = hpRange({ average: 1, formula: "1d4 - 10" }); expect(range?.min).toBe(1); expect(range?.max).toBe(1); }); it("handles large pools without whitespace", () => { expect(hpRange({ average: 256, formula: "19d12+133" })).toEqual({ min: 152, average: 256, max: 361, }); }); it("returns null for a missing formula", () => { expect(hpRange({ average: 7, formula: "" })).toBeNull(); }); it("returns null for prose instead of a dice pool", () => { expect( hpRange({ average: 0, formula: "equal to the summoner's" }), ).toBeNull(); }); it("returns null for a flat number", () => { expect(hpRange({ average: 50, formula: "50" })).toBeNull(); }); it("returns null for a pool with zero dice or zero sides", () => { expect(hpRange({ average: 0, formula: "0d6" })).toBeNull(); expect(hpRange({ average: 0, formula: "2d0" })).toBeNull(); }); it("returns null for compound formulas it cannot reason about", () => { expect(hpRange({ average: 20, formula: "2d6 + 2d8" })).toBeNull(); }); }); describe("hpForVariant", () => { const range = { min: 9, average: 16, max: 24 }; it("returns the average when no variant is set", () => { expect(hpForVariant(range, undefined)).toBe(16); }); it("returns the minimum for the min variant", () => { expect(hpForVariant(range, "min")).toBe(9); }); it("returns the maximum for the max variant", () => { expect(hpForVariant(range, "max")).toBe(24); }); });