Add hotkey tests, make them pass

Includes updating vitest and supporting hotkeys with both ctrl+shift
This commit is contained in:
thepaperpilot 2024-02-23 01:48:20 -06:00
parent dfb14acc6e
commit 90d0307cf0
4 changed files with 1474 additions and 378 deletions

1720
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -51,7 +51,7 @@
"jsdom": "^20.0.0",
"prettier": "^2.5.1",
"typescript": "^5.0.2",
"vitest": "^0.29.3",
"vitest": "^1.3.1",
"vue-tsc": "^0.38.1"
},
"engines": {

View file

@ -99,16 +99,30 @@ document.onkeydown = function (e) {
if (hasWon.value && !player.keepGoing) {
return;
}
let key = e.key;
if (uppercaseNumbers.includes(key)) {
key = "shift+" + uppercaseNumbers.indexOf(key);
const keysToCheck: string[] = [e.key];
if (e.shiftKey && e.ctrlKey) {
keysToCheck.splice(0, 1);
keysToCheck.push("ctrl+shift+" + e.key.toUpperCase());
keysToCheck.push("shift+ctrl+" + e.key.toUpperCase());
if (uppercaseNumbers.includes(e.key)) {
keysToCheck.push("ctrl+shift+" + uppercaseNumbers.indexOf(e.key));
keysToCheck.push("shift+ctrl+" + uppercaseNumbers.indexOf(e.key));
} else {
keysToCheck.push("ctrl+shift+" + e.key.toLowerCase());
keysToCheck.push("shift+ctrl+" + e.key.toLowerCase());
}
} else if (uppercaseNumbers.includes(e.key)) {
keysToCheck.push("shift+" + e.key);
keysToCheck.push("shift+" + uppercaseNumbers.indexOf(e.key));
} else if (e.shiftKey) {
key = "shift+" + key;
keysToCheck.push("shift+" + e.key.toUpperCase());
keysToCheck.push("shift+" + e.key.toLowerCase());
} else if (e.ctrlKey) {
// remove e.key since the key doesn't change based on ctrl being held or not
keysToCheck.splice(0, 1);
keysToCheck.push("ctrl+" + e.key);
}
if (e.ctrlKey) {
key = "ctrl+" + key;
}
const hotkey = hotkeys[key] ?? hotkeys[key.toLowerCase()];
const hotkey = hotkeys[keysToCheck.find(key => key in hotkeys) ?? ""];
if (hotkey && unref(hotkey.enabled)) {
e.preventDefault();
hotkey.onPress();

View file

@ -0,0 +1,100 @@
import { createHotkey, hotkeys } from "features/hotkey";
import { afterEach, describe, expect, onTestFailed, test } from "vitest";
import { Ref, ref } from "vue";
import "../utils";
function createSuccessHotkey(key: string, triggered: Ref<boolean>) {
hotkeys[key] = createHotkey(() => ({
description: "",
key: key,
onPress: () => (triggered.value = true)
}));
}
function createFailHotkey(key: string) {
hotkeys[key] = createHotkey(() => ({
description: "Fail test",
key,
onPress: () => expect(true).toBe(false)
}));
}
function mockKeypress(key: string, shiftKey = false, ctrlKey = false) {
const event = new KeyboardEvent("keydown", { key, shiftKey, ctrlKey });
expect(document.dispatchEvent(event)).toBe(true);
return event;
}
function testHotkey(pass: string, fail: string, key: string, shiftKey = false, ctrlKey = false) {
const triggered = ref(false);
createSuccessHotkey(pass, triggered);
createFailHotkey(fail);
mockKeypress(key, shiftKey, ctrlKey);
expect(triggered.value).toBe(true);
}
describe("Hotkeys fire correctly", () => {
afterEach(() => {
Object.keys(hotkeys).forEach(key => delete hotkeys[key]);
});
test("Lower case letters", () => testHotkey("a", "A", "a"));
test.each([["A"], ["shift+a"], ["shift+A"]])("Upper case letters using %s as key", key => {
testHotkey(key, "a", "A", true);
});
describe.each([
[0, ")"],
[1, "!"],
[2, "@"],
[3, "#"],
[4, "$"],
[5, "%"],
[6, "^"],
[7, "&"],
[8, "*"],
[9, "("]
])("Handle number %i and it's 'capital', %s", (number, symbol) => {
test("Triggering number", () =>
testHotkey(number.toString(), symbol, number.toString(), true));
test.each([symbol, `shift+${number}`, `shift+${symbol}`])(
"Triggering symbol using %s as key",
key => testHotkey(key, number.toString(), symbol, true)
);
});
test("Ctrl modifier", () => testHotkey("ctrl+a", "a", "a", false, true));
test.each(["shift+ctrl+a", "ctrl+shift+a", "shift+ctrl+A", "ctrl+shift+A"])(
"Shift and Ctrl modifiers using %s as key",
key => {
const triggered = ref(false);
createSuccessHotkey(key, triggered);
createFailHotkey("a");
createFailHotkey("A");
createFailHotkey("shift+A");
createFailHotkey("shift+a");
createFailHotkey("ctrl+a");
createFailHotkey("ctrl+A");
mockKeypress("a", true, true);
expect(triggered.value).toBe(true);
}
);
test.each(["shift+ctrl+1", "ctrl+shift+1", "shift+ctrl+!", "ctrl+shift+!"])(
"Shift and Ctrl modifiers using %s as key",
key => {
const triggered = ref(false);
createSuccessHotkey(key, triggered);
createFailHotkey("1");
createFailHotkey("!");
createFailHotkey("shift+1");
createFailHotkey("shift+!");
createFailHotkey("ctrl+1");
createFailHotkey("ctrl+!");
mockKeypress("!", true, true);
expect(triggered.value).toBe(true);
}
);
});