import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { formatBinding, installKeyboardDispatcher, isMouseBinding, isValidBinding, mouseStrokeOf, normalizeBinding, PRESETS, primaryKeyBinding, shortcutLabel, suspendKeyboardDispatch, useKeymap, } from "./keymap"; import { registerAction } from "./actions"; const noMods = { metaKey: false, ctrlKey: false, altKey: false, shiftKey: false }; describe("mouse shortcuts", () => { it.each(Object.keys(PRESETS))("%s binds the side buttons to Back / Forward", (preset) => { expect(PRESETS[preset]!["navigate.back"]).toContain("Button4"); expect(PRESETS[preset]!["navigate.forward"]).toContain("Button5"); }); it("names DOM side buttons 1-based, with modifiers", () => { expect(mouseStrokeOf({ ...noMods, button: 3 })).toBe("Button4"); expect(mouseStrokeOf({ ...noMods, button: 4 })).toBe("Button5"); expect(mouseStrokeOf({ ...noMods, button: 3, altKey: true, shiftKey: true })).toBe("Alt+Shift+Button4"); for (const button of [0, 1, 2]) expect(mouseStrokeOf({ ...noMods, button })).toBeNull(); }); it("parses, normalizes and formats mouse bindings", () => { expect(isValidBinding("Button4")).toBe(true); expect(isMouseBinding("shift+button5")).toBe(true); expect(isMouseBinding("Meta+B")).toBe(false); expect(normalizeBinding("shift+button5")).toBe("Shift+Button5"); expect(formatBinding("Button4", true)).toBe("Button4 Click"); expect(formatBinding("Shift+Button4", true)).toBe("⇧Button4 Click"); expect(formatBinding("Ctrl+Button5", false)).toBe("Ctrl+Button5 Click"); }); it("keeps mouse bindings out of menu / tooltip shortcuts", () => { useKeymap.setState({ preset: "intellij-windows", overrides: { "t.mouseFirst": ["Button4", "Ctrl+Alt+Q"] } }); expect(primaryKeyBinding("t.mouseFirst")).toBe("Ctrl+Alt+Q"); useKeymap.setState({ overrides: { "t.mouseFirst": ["Button4"] } }); expect(shortcutLabel("t.mouseFirst")).toBeUndefined(); }); describe("dispatch", () => { let uninstall = () => {}; const back = vi.fn(); const forward = vi.fn(); let editor: HTMLElement; beforeEach(() => { back.mockReset(); forward.mockReset(); registerAction({ id: "navigate.back", title: "Back", run: back }); registerAction({ id: "navigate.forward", title: "Forward", run: forward }); useKeymap.setState({ preset: "intellij-macos", overrides: {} }); document.body.innerHTML = `