Triviaverse / src /lib /game /scoring.test.ts
Simeon Garratt
feat: core types, scoring logic, and ELO rating system with tests
4ce4246
Raw
History Blame Contribute Delete
1.68 kB
import { describe, it, expect } from "vitest";
import { calculateScore, getStreakMultiplier, getSpeedBonus } from "./scoring";
describe("getStreakMultiplier", () => {
it("returns 1.0 for streak 0-2", () => {
expect(getStreakMultiplier(0)).toBe(1.0);
expect(getStreakMultiplier(2)).toBe(1.0);
});
it("returns 1.5 for streak 3-4", () => {
expect(getStreakMultiplier(3)).toBe(1.5);
expect(getStreakMultiplier(4)).toBe(1.5);
});
it("returns 2.0 for streak 5-9", () => {
expect(getStreakMultiplier(5)).toBe(2.0);
expect(getStreakMultiplier(9)).toBe(2.0);
});
it("returns 3.0 for streak 10+", () => {
expect(getStreakMultiplier(10)).toBe(3.0);
expect(getStreakMultiplier(50)).toBe(3.0);
});
});
describe("getSpeedBonus", () => {
it("returns max bonus when most time remains", () => {
expect(getSpeedBonus(9, 10)).toBeCloseTo(1.45, 1);
});
it("returns min bonus when no time remains", () => {
expect(getSpeedBonus(0, 10)).toBe(1.0);
});
it("returns middle value at half time", () => {
const bonus = getSpeedBonus(5, 10);
expect(bonus).toBeGreaterThan(1.0);
expect(bonus).toBeLessThan(1.5);
});
});
describe("calculateScore", () => {
it("scores easy question with no streak and no speed bonus", () => {
expect(calculateScore("easy", 0, 0, 10)).toBe(100);
});
it("scores hard question with streak 10 and full speed", () => {
const score = calculateScore("hard", 10, 9, 10);
expect(score).toBe(Math.round(300 * 3.0 * (1.0 + 0.9 * 0.5)));
});
it("rounds to integer", () => {
const score = calculateScore("medium", 3, 3, 10);
expect(Number.isInteger(score)).toBe(true);
});
});