Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
365 changes: 365 additions & 0 deletions frontend/__tests__/input/helpers/fail-or-finish.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,365 @@
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";
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<
typeof import("../../../src/ts/utils/misc")
>();
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<string, any>;
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);
}
);
});
Loading
Loading