94 lines
2.8 KiB
TypeScript
94 lines
2.8 KiB
TypeScript
|
|
/**
|
||
|
|
* Task CAD-12b - Globale Keyboard-Shortcuts fuer den Editor.
|
||
|
|
*
|
||
|
|
* ESC = aktives Tool abbrechen, Delete/Entf = Auswahl loeschen,
|
||
|
|
* Strg+A = alles auswaehlen, Strg+D = Auswahl duplizieren,
|
||
|
|
* F7 = Grid toggle, F8 = Ortho toggle, F3 = Snap toggle.
|
||
|
|
*/
|
||
|
|
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
||
|
|
import { createKeyboardShortcuts, type ShortcutAction } from '../src/services/keyboardShortcuts';
|
||
|
|
describe('CAD-12b: keyboardShortcuts', () => {
|
||
|
|
let actions: Record<string, ReturnType<typeof vi.fn>>;
|
||
|
|
let handler: (e: KeyboardEvent) => void;
|
||
|
|
let cleanup: () => void;
|
||
|
|
|
||
|
|
beforeEach(() => {
|
||
|
|
actions = {
|
||
|
|
escape: vi.fn(),
|
||
|
|
delete: vi.fn(),
|
||
|
|
selectAll: vi.fn(),
|
||
|
|
duplicate: vi.fn(),
|
||
|
|
toggleGrid: vi.fn(),
|
||
|
|
toggleOrtho: vi.fn(),
|
||
|
|
toggleSnap: vi.fn(),
|
||
|
|
};
|
||
|
|
const ctrl = createKeyboardShortcuts(actions as unknown as ShortcutAction);
|
||
|
|
handler = ctrl.handler;
|
||
|
|
cleanup = ctrl.destroy;
|
||
|
|
});
|
||
|
|
|
||
|
|
afterEach(() => { cleanup(); });
|
||
|
|
|
||
|
|
const fire = (key: string, opts: { ctrl?: boolean; shift?: boolean } = {}) => {
|
||
|
|
handler({ key, ctrlKey: opts.ctrl ?? false, shiftKey: opts.shift ?? false, preventDefault: vi.fn() } as unknown as KeyboardEvent);
|
||
|
|
};
|
||
|
|
|
||
|
|
it('ESC ruft escape auf (Tool abbrechen)', () => {
|
||
|
|
fire('Escape');
|
||
|
|
expect(actions.escape).toHaveBeenCalledTimes(1);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('Delete und Entf rufen delete auf (Auswahl loeschen)', () => {
|
||
|
|
fire('Delete');
|
||
|
|
expect(actions.delete).toHaveBeenCalledTimes(1);
|
||
|
|
fire('Backspace');
|
||
|
|
expect(actions.delete).toHaveBeenCalledTimes(2);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('Strg+A ruft selectAll auf', () => {
|
||
|
|
fire('a', { ctrl: true });
|
||
|
|
expect(actions.selectAll).toHaveBeenCalledTimes(1);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('Strg+D ruft duplicate auf', () => {
|
||
|
|
fire('d', { ctrl: true });
|
||
|
|
expect(actions.duplicate).toHaveBeenCalledTimes(1);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('F7 ruft toggleGrid auf', () => {
|
||
|
|
fire('F7');
|
||
|
|
expect(actions.toggleGrid).toHaveBeenCalledTimes(1);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('F8 ruft toggleOrtho auf', () => {
|
||
|
|
fire('F8');
|
||
|
|
expect(actions.toggleOrtho).toHaveBeenCalledTimes(1);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('F3 ruft toggleSnap auf', () => {
|
||
|
|
fire('F3');
|
||
|
|
expect(actions.toggleSnap).toHaveBeenCalledTimes(1);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('Buchstaben ohne Strg loesen KEINE Aktion aus', () => {
|
||
|
|
fire('a');
|
||
|
|
fire('d');
|
||
|
|
fire('x');
|
||
|
|
expect(actions.selectAll).not.toHaveBeenCalled();
|
||
|
|
expect(actions.duplicate).not.toHaveBeenCalled();
|
||
|
|
});
|
||
|
|
|
||
|
|
it('Input-Feld-Fokus wird ignoriert (kein Shortcut wenn in Input/Textarea)', () => {
|
||
|
|
// Simuliere: Event-Target ist ein Input-Element
|
||
|
|
const inputEvent = {
|
||
|
|
key: 'a',
|
||
|
|
ctrlKey: true,
|
||
|
|
shiftKey: false,
|
||
|
|
preventDefault: vi.fn(),
|
||
|
|
target: { tagName: 'INPUT', isContentEditable: false },
|
||
|
|
} as unknown as KeyboardEvent & { target: { tagName: string } };
|
||
|
|
handler(inputEvent);
|
||
|
|
expect(actions.selectAll).not.toHaveBeenCalled();
|
||
|
|
});
|
||
|
|
});
|