123import { describe, it, expect } from "vitest";4import {5 DEFAULT_BINDINGS,6 findConflict,7 formatKeybinding,8 getActiveBindings,9 keybindingFromEvent,10 matchKeybinding,11} from "./shortcuts";1213function ev(key: string, mods: { ctrl?: boolean; meta?: boolean; shift?: boolean; alt?: boolean } = {}): KeyboardEvent {14 return new KeyboardEvent("keydown", {15 key,16 ctrlKey: Boolean(mods.ctrl),17 metaKey: Boolean(mods.meta),18 shiftKey: Boolean(mods.shift),19 altKey: Boolean(mods.alt),20 });21}2223describe("matchKeybinding", () => {24 it("matches case-insensitively on the key letter", () => {25 expect(matchKeybinding(ev("c"), { key: "c" })).toBe(true);26 expect(matchKeybinding(ev("C", { shift: true }), { key: "c", shift: true })).toBe(true);27 });2829 it("requires every modifier to match exactly", () => {30 expect(matchKeybinding(ev("l", { ctrl: true }), { key: "l", ctrl: true })).toBe(true);31 expect(matchKeybinding(ev("l"), { key: "l", ctrl: true })).toBe(false);32 expect(matchKeybinding(ev("l", { ctrl: true, shift: true }), { key: "l", ctrl: true })).toBe(false);33 });3435 it("rejects when key differs", () => {36 expect(matchKeybinding(ev("c"), { key: "n" })).toBe(false);37 });38});3940describe("getActiveBindings", () => {41 it("returns full default map when no overrides", () => {42 const active = getActiveBindings(undefined);43 expect(active.copy_password).toEqual(DEFAULT_BINDINGS.copy_password);44 expect(Object.keys(active).length).toBe(Object.keys(DEFAULT_BINDINGS).length);45 });4647 it("user override replaces default for that action only", () => {48 const active = getActiveBindings({ copy_password: { key: "p", ctrl: true } });49 expect(active.copy_password).toEqual({ key: "p", ctrl: true });50 expect(active.copy_username).toEqual(DEFAULT_BINDINGS.copy_username);51 });52});5354describe("keybindingFromEvent", () => {55 it("returns null for bare modifier presses", () => {56 expect(keybindingFromEvent(ev("Shift"))).toBeNull();57 expect(keybindingFromEvent(ev("Control"))).toBeNull();58 expect(keybindingFromEvent(ev("Meta"))).toBeNull();59 expect(keybindingFromEvent(ev("Alt"))).toBeNull();60 });6162 it("captures key + modifiers from the event", () => {63 const b = keybindingFromEvent(ev("k", { ctrl: true, shift: true }));64 expect(b).toEqual({ key: "k", ctrl: true, shift: true });65 });6667 it("omits unset modifier flags rather than storing false", () => {68 const b = keybindingFromEvent(ev("a"));69 expect(b).toEqual({ key: "a" });70 });71});7273describe("formatKeybinding", () => {74 it("uses Ctrl+K style on non-mac", () => {75 expect(formatKeybinding({ key: "k", ctrl: true }, false)).toBe("Ctrl+K");76 });7778 it("uses ⌘ glyph on mac", () => {79 expect(formatKeybinding({ key: "k", meta: true }, true)).toBe("⌘K");80 });8182 it("renames named keys (arrows, escape, enter)", () => {83 expect(formatKeybinding({ key: "ArrowUp" }, false)).toBe("↑");84 expect(formatKeybinding({ key: "Escape" }, false)).toBe("Esc");85 expect(formatKeybinding({ key: "Enter" }, false)).toBe("↵");86 expect(formatKeybinding({ key: " " }, false)).toBe("Space");87 });8889 it("orders mac modifiers ⌃⌥⇧⌘ then key", () => {90 expect(formatKeybinding({ key: "k", ctrl: true, alt: true, shift: true, meta: true }, true))91 .toBe("⌃⌥⇧⌘K");92 });93});9495describe("findConflict", () => {96 it("returns the conflicting action when binding collides", () => {97 const bindings = getActiveBindings({});98 const conflict = findConflict(bindings, { key: "c" });99 expect(conflict).toBe("copy_password");100 });101102 it("excludes the action being rebound from conflict checks", () => {103 const bindings = getActiveBindings({});104 const conflict = findConflict(bindings, { key: "c" }, "copy_password");105 expect(conflict).toBeNull();106 });107108 it("returns null when binding is unique", () => {109 const bindings = getActiveBindings({});110 const conflict = findConflict(bindings, { key: "z", ctrl: true, shift: true });111 expect(conflict).toBeNull();112 });113});