112 lines
3.1 KiB
TypeScript
112 lines
3.1 KiB
TypeScript
/**
|
|
* Unit tests for desktop/keyboard.ts — typeText CJK routing, pressKey, hotkey.
|
|
*/
|
|
|
|
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
|
|
const mockType = vi.fn();
|
|
const mockPressKey = vi.fn();
|
|
const mockReleaseKey = vi.fn();
|
|
|
|
vi.mock('@nut-tree-fork/nut-js', () => ({
|
|
keyboard: {
|
|
type: mockType,
|
|
pressKey: mockPressKey,
|
|
releaseKey: mockReleaseKey,
|
|
},
|
|
Key: {
|
|
Enter: 'Enter_Val',
|
|
Tab: 'Tab_Val',
|
|
Escape: 'Escape_Val',
|
|
LeftSuper: 'LeftSuper_Val', // Meta/Command/Cmd alias
|
|
LeftControl: 'LeftControl_Val',
|
|
LeftAlt: 'LeftAlt_Val',
|
|
LeftShift: 'LeftShift_Val',
|
|
C: 'C_Val',
|
|
V: 'V_Val',
|
|
},
|
|
}));
|
|
|
|
const mockPasteText = vi.fn();
|
|
vi.mock('../../src/desktop/clipboard.js', () => ({
|
|
pasteText: (...args: any[]) => mockPasteText(...args),
|
|
}));
|
|
|
|
import { typeText, pressKey, hotkey } from '../../src/desktop/keyboard.js';
|
|
|
|
describe('typeText', () => {
|
|
beforeEach(() => {
|
|
vi.clearAllMocks();
|
|
});
|
|
|
|
it('uses nut.js type for short ASCII text', async () => {
|
|
await typeText('hello');
|
|
expect(mockType).toHaveBeenCalledWith('hello');
|
|
expect(mockPasteText).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('routes CJK text to clipboard paste', async () => {
|
|
await typeText('你好世界');
|
|
expect(mockPasteText).toHaveBeenCalledWith('你好世界');
|
|
expect(mockType).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('routes non-ASCII text to clipboard paste', async () => {
|
|
await typeText('café');
|
|
expect(mockPasteText).toHaveBeenCalledWith('café');
|
|
expect(mockType).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('routes long text (>50 chars) to clipboard paste', async () => {
|
|
const longText = 'a'.repeat(51);
|
|
await typeText(longText);
|
|
expect(mockPasteText).toHaveBeenCalledWith(longText);
|
|
expect(mockType).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('uses nut.js type for exactly 50 ASCII chars', async () => {
|
|
const text = 'a'.repeat(50);
|
|
await typeText(text);
|
|
expect(mockType).toHaveBeenCalledWith(text);
|
|
expect(mockPasteText).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('uses nut.js type for empty string', async () => {
|
|
await typeText('');
|
|
expect(mockType).toHaveBeenCalledWith('');
|
|
expect(mockPasteText).not.toHaveBeenCalled();
|
|
});
|
|
});
|
|
|
|
describe('pressKey', () => {
|
|
beforeEach(() => {
|
|
vi.clearAllMocks();
|
|
});
|
|
|
|
it('presses and releases a valid key', async () => {
|
|
await pressKey('Enter');
|
|
expect(mockPressKey).toHaveBeenCalledWith('Enter_Val');
|
|
expect(mockReleaseKey).toHaveBeenCalledWith('Enter_Val');
|
|
});
|
|
|
|
it('throws DesktopError for unknown key', async () => {
|
|
await expect(pressKey('UnknownKey')).rejects.toThrow('Unknown key: UnknownKey');
|
|
});
|
|
});
|
|
|
|
describe('hotkey', () => {
|
|
beforeEach(() => {
|
|
vi.clearAllMocks();
|
|
});
|
|
|
|
it('uses keyboard.type() for hotkey combinations', async () => {
|
|
await hotkey(['Meta', 'C']);
|
|
// Meta is aliased to LeftSuper
|
|
expect(mockType).toHaveBeenCalledWith('LeftSuper_Val', 'C_Val');
|
|
});
|
|
|
|
it('throws DesktopError for unknown key in combination', async () => {
|
|
await expect(hotkey(['Meta', 'UnknownKey'])).rejects.toThrow('Unknown key: UnknownKey');
|
|
});
|
|
});
|