Spaces:
Running
Running
| 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); | |
| }); | |
| }); | |