import { describe, expect, it } from "vitest"; import { calculateInitiative, formatInitiativeModifier, } from "../initiative.js"; describe("calculateInitiative", () => { it("returns positive modifier for creature with expertise (Aboleth: DEX 9, CR 10, proficiency 2)", () => { const result = calculateInitiative({ dexScore: 9, cr: "10", initiativeProficiency: 2, }); // DEX mod = floor((9-10)/2) = -1, PB for CR 10 = 4, -1 + 2*4 = +7 expect(result.modifier).toBe(7); expect(result.passive).toBe(17); }); it("returns negative modifier for low DEX with no proficiency", () => { const result = calculateInitiative({ dexScore: 8, cr: "1", initiativeProficiency: 0, }); // DEX mod = floor((8-10)/2) = -1, 0 * PB = 0, -1 + 0 = -1 expect(result.modifier).toBe(-1); expect(result.passive).toBe(9); }); it("returns zero modifier for DEX 10 with no proficiency", () => { const result = calculateInitiative({ dexScore: 10, cr: "1", initiativeProficiency: 0, }); expect(result.modifier).toBe(0); expect(result.passive).toBe(10); }); it("adds single proficiency bonus (multiplier 1)", () => { const result = calculateInitiative({ dexScore: 14, cr: "5", initiativeProficiency: 1, }); // DEX mod = +2, PB for CR 5 = 3, 2 + 1*3 = 5 expect(result.modifier).toBe(5); expect(result.passive).toBe(15); }); it("adds double proficiency bonus (multiplier 2 / expertise)", () => { const result = calculateInitiative({ dexScore: 14, cr: "5", initiativeProficiency: 2, }); // DEX mod = +2, PB for CR 5 = 3, 2 + 2*3 = 8 expect(result.modifier).toBe(8); expect(result.passive).toBe(18); }); it("handles no proficiency (multiplier 0) — reduces to raw DEX modifier", () => { const result = calculateInitiative({ dexScore: 14, cr: "5", initiativeProficiency: 0, }); // DEX mod = +2, 0 * PB = 0, 2 + 0 = 2 expect(result.modifier).toBe(2); expect(result.passive).toBe(12); }); it("handles negative result even with proficiency (very low DEX)", () => { const result = calculateInitiative({ dexScore: 3, cr: "0", initiativeProficiency: 1, }); // DEX mod = floor((3-10)/2) = -4, PB for CR 0 = 2, -4 + 1*2 = -2 expect(result.modifier).toBe(-2); expect(result.passive).toBe(8); }); it("handles fractional CR values", () => { const result = calculateInitiative({ dexScore: 12, cr: "1/4", initiativeProficiency: 1, }); // DEX mod = +1, PB for CR 1/4 = 2, 1 + 1*2 = 3 expect(result.modifier).toBe(3); expect(result.passive).toBe(13); }); }); describe("formatInitiativeModifier", () => { it("formats positive modifier with plus sign", () => { expect(formatInitiativeModifier(7)).toBe("+7"); }); it("formats negative modifier with U+2212 minus sign", () => { expect(formatInitiativeModifier(-1)).toBe("\u22121"); }); it("formats zero modifier with plus sign", () => { expect(formatInitiativeModifier(0)).toBe("+0"); }); });