Triviaverse / src /lib /game /elo.test.ts
Simeon Garratt
feat: core types, scoring logic, and ELO rating system with tests
4ce4246
Raw
History Blame Contribute Delete
1.64 kB
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);
});
});