import { describe, it, expect } from 'vitest'; import { computeBudget } from './budget'; describe('5e encounter budget', () => { it('rates a single CR 1/4 vs a level-1 party of 4 as easy-ish', () => { const r = computeBudget('5e', [1, 1, 1, 1], [{ cr: 0.25 }]); expect(r.totalXp).toBe(50); expect(r.ratingXp).toBe(50); // single monster, x1 multiplier expect(['trivial', 'easy']).toContain(r.difficulty); }); it('applies the count multiplier to the rating but not the award', () => { const r = computeBudget('5e', [3, 3, 3, 3], [{ cr: 1 }, { cr: 1 }, { cr: 1 }]); expect(r.totalXp).toBe(600); // 3 * 200 expect(r.ratingXp).toBe(1200); // x2 for 3 monsters expect(r.awardPerCharacter).toBe(150); // 600 / 4 }); it('flags a deadly fight', () => { const r = computeBudget('5e', [1, 1, 1, 1], [{ cr: 3 }, { cr: 3 }]); expect(r.difficulty).toBe('deadly'); }); }); describe('pf2e encounter budget', () => { it('a same-level creature is worth 40 XP', () => { const r = computeBudget('pf2e', [3, 3, 3, 3], [{ level: 3 }]); expect(r.totalXp).toBe(40); expect(r.awardPerCharacter).toBe(40); }); it('rates a moderate encounter', () => { const r = computeBudget('pf2e', [5, 5, 5, 5], [{ level: 5 }, { level: 5 }]); expect(r.totalXp).toBe(80); expect(r.difficulty).toBe('moderate'); }); it('adjusts thresholds for party size', () => { const four = computeBudget('pf2e', [1, 1, 1, 1], []); const five = computeBudget('pf2e', [1, 1, 1, 1, 1], []); const sevFour = four.thresholds.find((t) => t.label === 'Severe')!.value; const sevFive = five.thresholds.find((t) => t.label === 'Severe')!.value; expect(sevFive - sevFour).toBe(30); }); });