import { describe, it, expect } from "vitest"; import { calculateElo, getKFactor, expectedScore } from "./elo"; describe("getKFactor", () => { it("returns 32 for new players (<20 games)", () => { expect(getKFactor(0)).toBe(32); expect(getKFactor(19)).toBe(32); }); it("returns 16 for established players (20+ games)", () => { expect(getKFactor(20)).toBe(16); expect(getKFactor(100)).toBe(16); }); }); describe("expectedScore", () => { it("returns 0.5 for equal ratings", () => { expect(expectedScore(1500, 1500)).toBeCloseTo(0.5); }); it("higher rated player has higher expected score", () => { expect(expectedScore(1600, 1400)).toBeGreaterThan(0.5); }); it("lower rated player has lower expected score", () => { expect(expectedScore(1400, 1600)).toBeLessThan(0.5); }); }); describe("calculateElo", () => { it("winner gains, loser loses equal amount for equal ratings", () => { const result = calculateElo(1500, 1500, "player1", 10, 10); expect(result.player1Delta).toBeGreaterThan(0); expect(result.player2Delta).toBeLessThan(0); expect(result.player1Delta).toBe(-result.player2Delta); }); it("upset victory yields larger rating change", () => { const upset = calculateElo(1300, 1700, "player1", 10, 10); const expected = calculateElo(1700, 1300, "player1", 10, 10); expect(Math.abs(upset.player1Delta)).toBeGreaterThan(Math.abs(expected.player1Delta)); }); it("returns zero deltas for a draw", () => { const result = calculateElo(1500, 1500, null, 10, 10); expect(result.player1Delta).toBe(0); expect(result.player2Delta).toBe(0); }); });