import { describe, it, expect, vi, beforeEach, afterAll } from "vitest"; import { checkIfFailedDueToMinBurst, checkIfFailedDueToDifficulty, checkIfFinished, } from "../../../src/ts/input/helpers/fail-or-finish"; import { __testing } from "../../../src/ts/config/testing"; import * as Misc from "../../../src/ts/utils/misc"; import * as TestLogic from "../../../src/ts/test/test-logic"; import * as Strings from "../../../src/ts/utils/strings"; const { replaceConfig } = __testing; vi.mock("../../../src/ts/utils/misc", async (importOriginal) => { const actual = await importOriginal(); return { ...actual, whorf: vi.fn(), }; }); vi.mock("../../../src/ts/test/test-logic", () => ({ areAllTestWordsGenerated: vi.fn(), })); vi.mock("../../../src/ts/utils/strings", () => ({ isSpace: vi.fn(), })); describe("checkIfFailedDueToMinBurst", () => { beforeEach(() => { vi.clearAllMocks(); replaceConfig({ minBurst: "off", mode: "time", minBurstCustomSpeed: 100, }); (Misc.whorf as any).mockReturnValue(0); (TestLogic.areAllTestWordsGenerated as any).mockReturnValue(true); }); afterAll(() => { replaceConfig({}); }); it.each([ { desc: "returns false if minBurst is off", config: { minBurst: "off" }, lastBurst: 50, expected: false, }, { desc: "returns false if lastBurst is null", config: { minBurst: "fixed" }, lastBurst: null, expected: false, }, { desc: "returns true if fixed burst is too slow", config: { minBurst: "fixed", minBurstCustomSpeed: 100 }, lastBurst: 99, expected: true, }, { desc: "returns false if fixed burst is fast enough", config: { minBurst: "fixed", minBurstCustomSpeed: 100 }, lastBurst: 100, expected: false, }, { desc: "returns true if flex burst is too slow", config: { minBurst: "flex", minBurstCustomSpeed: 100 }, lastBurst: 49, whorfRet: 50, expected: true, }, { desc: "returns false if flex burst is fast enough", config: { minBurst: "flex", minBurstCustomSpeed: 100 }, lastBurst: 50, whorfRet: 50, expected: false, }, ])("$desc", ({ config, lastBurst, whorfRet, expected }) => { replaceConfig(config as any); if (whorfRet !== undefined) { (Misc.whorf as any).mockReturnValue(whorfRet); } const result = checkIfFailedDueToMinBurst({ testInputWithData: "test", currentWord: "test", lastBurst, }); expect(result).toBe(expected); }); it("uses correct length for whorf calculation in zen mode", () => { replaceConfig({ minBurst: "flex", mode: "zen", minBurstCustomSpeed: 100 }); checkIfFailedDueToMinBurst({ testInputWithData: "zeninput", currentWord: "ignored", lastBurst: 50, }); expect(Misc.whorf).toHaveBeenCalledWith(100, 8); }); it("uses correct length for whorf calculation in normal mode", () => { replaceConfig({ minBurst: "flex", mode: "time", minBurstCustomSpeed: 100 }); checkIfFailedDueToMinBurst({ testInputWithData: "input", currentWord: "target", lastBurst: 50, }); expect(Misc.whorf).toHaveBeenCalledWith(100, 6); }); }); describe("checkIfFailedDueToDifficulty", () => { beforeEach(() => { replaceConfig({ mode: "time", difficulty: "normal", }); }); afterAll(() => { replaceConfig({}); }); it.each([ { desc: "zen mode, master - never fails", config: { mode: "zen", difficulty: "master" }, correct: false, spaceOrNewline: true, input: "hello", expected: false, }, { desc: "zen mode - never fails", config: { mode: "zen", difficulty: "normal" }, correct: false, spaceOrNewline: true, input: "hello", expected: false, }, // { desc: "normal typing incorrect- never fails", config: { difficulty: "normal" }, correct: false, spaceOrNewline: false, input: "hello", expected: false, }, { desc: "normal typing space incorrect - never fails", config: { difficulty: "normal" }, correct: false, spaceOrNewline: true, input: "hello", expected: false, }, { desc: "normal typing correct - never fails", config: { difficulty: "normal" }, correct: true, spaceOrNewline: false, input: "hello", expected: false, }, { desc: "normal typing space correct - never fails", config: { difficulty: "normal" }, correct: true, spaceOrNewline: true, input: "hello", expected: false, }, // { desc: "expert - fail if incorrect space", config: { difficulty: "expert" }, correct: false, spaceOrNewline: true, input: "he", expected: true, }, { desc: "expert - dont fail if space is the first character", config: { difficulty: "expert" }, correct: false, spaceOrNewline: true, input: " ", expected: false, }, { desc: "expert: - dont fail if just typing", config: { difficulty: "expert" }, correct: false, spaceOrNewline: false, input: "h", expected: false, }, { desc: "expert: - dont fail if just typing", config: { difficulty: "expert" }, correct: true, spaceOrNewline: false, input: "h", expected: false, }, // { desc: "master - fail if incorrect char", config: { difficulty: "master" }, correct: false, spaceOrNewline: false, input: "h", expected: true, }, { desc: "master - fail if incorrect first space", config: { difficulty: "master" }, correct: true, spaceOrNewline: true, input: " ", expected: false, }, { desc: "master - dont fail if correct char", config: { difficulty: "master" }, correct: true, spaceOrNewline: false, input: "a", expected: false, }, { desc: "master - dont fail if correct space", config: { difficulty: "master" }, correct: true, spaceOrNewline: true, input: " ", expected: false, }, ])("$desc", ({ config, correct, spaceOrNewline, input, expected }) => { replaceConfig(config as any); const result = checkIfFailedDueToDifficulty({ testInputWithData: input, correct, spaceOrNewline, }); expect(result).toBe(expected); }); }); describe("checkIfFinished", () => { beforeEach(() => { vi.clearAllMocks(); replaceConfig({ quickEnd: false, stopOnError: "off", }); (Strings.isSpace as any).mockReturnValue(false); (TestLogic.areAllTestWordsGenerated as any).mockReturnValue(true); }); afterAll(() => { replaceConfig({}); }); it.each([ { desc: "false if not all words typed", allWordsTyped: false, testInputWithData: "word", currentWord: "word", expected: false, }, { desc: "false if not all words generated, but on the last word", allWordsGenerated: false, allWordsTyped: true, testInputWithData: "word", currentWord: "word", expected: false, }, { desc: "true if last word is correct", allWordsTyped: true, testInputWithData: "word", currentWord: "word", expected: true, }, { desc: "true if quickEnd enabled and lengths match", allWordsTyped: true, testInputWithData: "asdf", currentWord: "word", config: { quickEnd: true }, expected: true, }, { desc: "false if quickEnd disabled and lengths match", allWordsTyped: true, testInputWithData: "asdf", currentWord: "word", config: { quickEnd: false }, expected: false, }, { desc: "true if space on the last word", allWordsTyped: true, testInputWithData: "wo ", currentWord: "word", shouldGoToNextWord: true, expected: true, }, { desc: "false if still typing, quickend disabled", allWordsTyped: true, testInputWithData: "wordwordword", currentWord: "word", expected: false, }, ] as { desc: string; allWordsTyped: boolean; allWordsGenerated?: boolean; shouldGoToNextWord: boolean; testInputWithData: string; currentWord: string; config?: Record; isSpace?: boolean; expected: boolean; }[])( "$desc", ({ allWordsTyped, allWordsGenerated, shouldGoToNextWord, testInputWithData, currentWord, config, expected, }) => { if (config) replaceConfig(config as any); const result = checkIfFinished({ shouldGoToNextWord, testInputWithData, currentWord, allWordsTyped, allWordsGenerated: allWordsGenerated ?? true, }); expect(result).toBe(expected); }, ); });