chore: initialize qiming workspace repository
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
/**
|
||||
* 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');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user