Refactoring unit tests in packages/cli/src/ui (#12251)

Co-authored-by: riddhi <duttariddhi@google.com>
This commit is contained in:
Riddhi Dutta
2025-10-30 12:48:45 +05:30
committed by GitHub
parent 42c79c64d7
commit c583b510e0
3 changed files with 748 additions and 1330 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`SettingsDialog > Snapshot Tests > should render default state correctly 1`] = `
exports[`SettingsDialog > Initial Rendering > should render settings list with visual indicators 1`] = `
"╭──────────────────────────────────────────────────────────────────────────────────────────────────╮
│ │
│ > Settings │
@@ -35,42 +35,7 @@ exports[`SettingsDialog > Snapshot Tests > should render default state correctly
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯"
`;
exports[`SettingsDialog > Snapshot Tests > should render focused on scope selector 1`] = `
"╭──────────────────────────────────────────────────────────────────────────────────────────────────╮
│ │
│ > Settings │
│ │
│ ▲ │
│ ● Vim Mode false │
│ │
│ Disable Auto Update false │
│ │
│ Enable Prompt Completion false │
│ │
│ Debug Keystroke Logging false │
│ │
│ Session Retention undefined │
│ │
│ Enable Session Cleanup false │
│ │
│ Output Format Text │
│ │
│ Hide Window Title false │
│ │
│ ▼ │
│ │
│ │
│ Apply To │
│ ● User Settings │
│ Workspace Settings │
│ System Settings │
│ │
│ (Use Enter to select, Tab to change focus, Esc to close) │
│ │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯"
`;
exports[`SettingsDialog > Snapshot Tests > should render with accessibility settings enabled 1`] = `
exports[`SettingsDialog > Snapshot Tests > should render 'accessibility settings enabled' correctly 1`] = `
"╭──────────────────────────────────────────────────────────────────────────────────────────────────╮
│ │
│ > Settings │
@@ -105,7 +70,7 @@ exports[`SettingsDialog > Snapshot Tests > should render with accessibility sett
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯"
`;
exports[`SettingsDialog > Snapshot Tests > should render with all boolean settings disabled 1`] = `
exports[`SettingsDialog > Snapshot Tests > should render 'all boolean settings disabled' correctly 1`] = `
"╭──────────────────────────────────────────────────────────────────────────────────────────────────╮
│ │
│ > Settings │
@@ -140,77 +105,7 @@ exports[`SettingsDialog > Snapshot Tests > should render with all boolean settin
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯"
`;
exports[`SettingsDialog > Snapshot Tests > should render with different scope selected (System) 1`] = `
"╭──────────────────────────────────────────────────────────────────────────────────────────────────╮
│ │
│ > Settings │
│ │
│ ▲ │
│ ● Vim Mode (Modified in System) false │
│ │
│ Disable Auto Update (Modified in System) false │
│ │
│ Enable Prompt Completion false │
│ │
│ Debug Keystroke Logging false │
│ │
│ Session Retention undefined │
│ │
│ Enable Session Cleanup false │
│ │
│ Output Format Text │
│ │
│ Hide Window Title false │
│ │
│ ▼ │
│ │
│ │
│ Apply To │
│ ● User Settings │
│ Workspace Settings │
│ System Settings │
│ │
│ (Use Enter to select, Tab to change focus, Esc to close) │
│ │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯"
`;
exports[`SettingsDialog > Snapshot Tests > should render with different scope selected (Workspace) 1`] = `
"╭──────────────────────────────────────────────────────────────────────────────────────────────────╮
│ │
│ > Settings │
│ │
│ ▲ │
│ ● Vim Mode (Modified in Workspace) false │
│ │
│ Disable Auto Update false │
│ │
│ Enable Prompt Completion false │
│ │
│ Debug Keystroke Logging (Modified in Workspace) false │
│ │
│ Session Retention undefined │
│ │
│ Enable Session Cleanup false │
│ │
│ Output Format Text │
│ │
│ Hide Window Title false │
│ │
│ ▼ │
│ │
│ │
│ Apply To │
│ ● User Settings │
│ Workspace Settings │
│ System Settings │
│ │
│ (Use Enter to select, Tab to change focus, Esc to close) │
│ │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯"
`;
exports[`SettingsDialog > Snapshot Tests > should render with file filtering settings configured 1`] = `
exports[`SettingsDialog > Snapshot Tests > should render 'default state' correctly 1`] = `
"╭──────────────────────────────────────────────────────────────────────────────────────────────────╮
│ │
│ > Settings │
@@ -245,7 +140,77 @@ exports[`SettingsDialog > Snapshot Tests > should render with file filtering set
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯"
`;
exports[`SettingsDialog > Snapshot Tests > should render with mixed boolean and number settings 1`] = `
exports[`SettingsDialog > Snapshot Tests > should render 'file filtering settings configured' correctly 1`] = `
"╭──────────────────────────────────────────────────────────────────────────────────────────────────╮
│ │
│ > Settings │
│ │
│ ▲ │
│ ● Vim Mode false │
│ │
│ Disable Auto Update false │
│ │
│ Enable Prompt Completion false │
│ │
│ Debug Keystroke Logging false │
│ │
│ Session Retention undefined │
│ │
│ Enable Session Cleanup false │
│ │
│ Output Format Text │
│ │
│ Hide Window Title false │
│ │
│ ▼ │
│ │
│ │
│ Apply To │
│ ● User Settings │
│ Workspace Settings │
│ System Settings │
│ │
│ (Use Enter to select, Tab to change focus, Esc to close) │
│ │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯"
`;
exports[`SettingsDialog > Snapshot Tests > should render 'focused on scope selector' correctly 1`] = `
"╭──────────────────────────────────────────────────────────────────────────────────────────────────╮
│ │
│ > Settings │
│ │
│ ▲ │
│ ● Vim Mode false │
│ │
│ Disable Auto Update false │
│ │
│ Enable Prompt Completion false │
│ │
│ Debug Keystroke Logging false │
│ │
│ Session Retention undefined │
│ │
│ Enable Session Cleanup false │
│ │
│ Output Format Text │
│ │
│ Hide Window Title false │
│ │
│ ▼ │
│ │
│ │
│ Apply To │
│ ● User Settings │
│ Workspace Settings │
│ System Settings │
│ │
│ (Use Enter to select, Tab to change focus, Esc to close) │
│ │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯"
`;
exports[`SettingsDialog > Snapshot Tests > should render 'mixed boolean and number settings' correctly 1`] = `
"╭──────────────────────────────────────────────────────────────────────────────────────────────────╮
│ │
│ > Settings │
@@ -280,7 +245,7 @@ exports[`SettingsDialog > Snapshot Tests > should render with mixed boolean and
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯"
`;
exports[`SettingsDialog > Snapshot Tests > should render with tools and security settings 1`] = `
exports[`SettingsDialog > Snapshot Tests > should render 'tools and security settings' correctly 1`] = `
"╭──────────────────────────────────────────────────────────────────────────────────────────────────╮
│ │
│ > Settings │
@@ -315,7 +280,7 @@ exports[`SettingsDialog > Snapshot Tests > should render with tools and security
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯"
`;
exports[`SettingsDialog > Snapshot Tests > should render with various boolean settings enabled 1`] = `
exports[`SettingsDialog > Snapshot Tests > should render 'various boolean settings enabled' correctly 1`] = `
"╭──────────────────────────────────────────────────────────────────────────────────────────────────╮
│ │
│ > Settings │

View File

@@ -51,6 +51,21 @@ class MockStdin extends EventEmitter {
}
}
// Helper function to setup keypress test with standard configuration
const setupKeypressTest = (kittyProtocolEnabled = true) => {
const keyHandler = vi.fn();
const wrapper = ({ children }: { children: React.ReactNode }) => (
<KeypressProvider kittyProtocolEnabled={kittyProtocolEnabled}>
{children}
</KeypressProvider>
);
const { result } = renderHook(() => useKeypressContext(), { wrapper });
act(() => result.current.subscribe(keyHandler));
return { result, keyHandler };
};
describe('KeypressContext - Kitty Protocol', () => {
let stdin: MockStdin;
const mockSetRawMode = vi.fn();
@@ -77,19 +92,20 @@ describe('KeypressContext - Kitty Protocol', () => {
});
describe('Enter key handling', () => {
it('should recognize regular enter key (keycode 13) in kitty protocol', async () => {
const keyHandler = vi.fn();
it.each([
{
name: 'regular enter key (keycode 13)',
sequence: '\x1b[13u',
},
{
name: 'numpad enter key (keycode 57414)',
sequence: '\x1b[57414u',
},
])('should recognize $name in kitty protocol', async ({ sequence }) => {
const { keyHandler } = setupKeypressTest(true);
const { result } = renderHook(() => useKeypressContext(), {
wrapper: ({ children }) =>
wrapper({ children, kittyProtocolEnabled: true }),
});
act(() => result.current.subscribe(keyHandler));
// Send kitty protocol sequence for regular enter: ESC[13u
act(() => {
stdin.write(`\x1b[13u`);
stdin.write(sequence);
});
expect(keyHandler).toHaveBeenCalledWith(
@@ -103,117 +119,41 @@ describe('KeypressContext - Kitty Protocol', () => {
);
});
it('should recognize numpad enter key (keycode 57414) in kitty protocol', async () => {
const keyHandler = vi.fn();
it.each([
{
modifier: 'Shift',
sequence: '\x1b[57414;2u',
expected: { ctrl: false, meta: false, shift: true },
},
{
modifier: 'Ctrl',
sequence: '\x1b[57414;5u',
expected: { ctrl: true, meta: false, shift: false },
},
{
modifier: 'Alt',
sequence: '\x1b[57414;3u',
expected: { ctrl: false, meta: true, shift: false },
},
])(
'should handle numpad enter with $modifier modifier',
async ({ sequence, expected }) => {
const { keyHandler } = setupKeypressTest(true);
const { result } = renderHook(() => useKeypressContext(), {
wrapper: ({ children }) =>
wrapper({ children, kittyProtocolEnabled: true }),
});
act(() => stdin.write(sequence));
act(() => result.current.subscribe(keyHandler));
// Send kitty protocol sequence for numpad enter: ESC[57414u
act(() => {
stdin.write(`\x1b[57414u`);
});
expect(keyHandler).toHaveBeenCalledWith(
expect.objectContaining({
name: 'return',
kittyProtocol: true,
ctrl: false,
meta: false,
shift: false,
}),
);
});
it('should handle numpad enter with modifiers', async () => {
const keyHandler = vi.fn();
const { result } = renderHook(() => useKeypressContext(), {
wrapper: ({ children }) =>
wrapper({ children, kittyProtocolEnabled: true }),
});
act(() => result.current.subscribe(keyHandler));
// Send kitty protocol sequence for numpad enter with Shift (modifier 2): ESC[57414;2u
act(() => {
stdin.write(`\x1b[57414;2u`);
});
expect(keyHandler).toHaveBeenCalledWith(
expect.objectContaining({
name: 'return',
kittyProtocol: true,
ctrl: false,
meta: false,
shift: true,
}),
);
});
it('should handle numpad enter with Ctrl modifier', async () => {
const keyHandler = vi.fn();
const { result } = renderHook(() => useKeypressContext(), {
wrapper: ({ children }) =>
wrapper({ children, kittyProtocolEnabled: true }),
});
act(() => result.current.subscribe(keyHandler));
// Send kitty protocol sequence for numpad enter with Ctrl (modifier 5): ESC[57414;5u
act(() => stdin.write(`\x1b[57414;5u`));
expect(keyHandler).toHaveBeenCalledWith(
expect.objectContaining({
name: 'return',
kittyProtocol: true,
ctrl: true,
meta: false,
shift: false,
}),
);
});
it('should handle numpad enter with Alt modifier', async () => {
const keyHandler = vi.fn();
const { result } = renderHook(() => useKeypressContext(), {
wrapper: ({ children }) =>
wrapper({ children, kittyProtocolEnabled: true }),
});
act(() => result.current.subscribe(keyHandler));
// Send kitty protocol sequence for numpad enter with Alt (modifier 3): ESC[57414;3u
act(() => {
stdin.write(`\x1b[57414;3u`);
});
expect(keyHandler).toHaveBeenCalledWith(
expect.objectContaining({
name: 'return',
kittyProtocol: true,
ctrl: false,
meta: true,
shift: false,
}),
);
});
expect(keyHandler).toHaveBeenCalledWith(
expect.objectContaining({
name: 'return',
kittyProtocol: true,
...expected,
}),
);
},
);
it('should not process kitty sequences when kitty protocol is disabled', async () => {
const keyHandler = vi.fn();
const { result } = renderHook(() => useKeypressContext(), {
wrapper: ({ children }) =>
wrapper({ children, kittyProtocolEnabled: false }),
});
act(() => result.current.subscribe(keyHandler));
const { keyHandler } = setupKeypressTest(false);
// Send kitty protocol sequence for numpad enter
act(() => {
@@ -233,14 +173,7 @@ describe('KeypressContext - Kitty Protocol', () => {
describe('Escape key handling', () => {
it('should recognize escape key (keycode 27) in kitty protocol', async () => {
const keyHandler = vi.fn();
const { result } = renderHook(() => useKeypressContext(), {
wrapper: ({ children }) =>
wrapper({ children, kittyProtocolEnabled: true }),
});
act(() => result.current.subscribe(keyHandler));
const { keyHandler } = setupKeypressTest(true);
// Send kitty protocol sequence for escape: ESC[27u
act(() => {
@@ -257,174 +190,90 @@ describe('KeypressContext - Kitty Protocol', () => {
});
describe('Tab and Backspace handling', () => {
it('should recognize Tab key in kitty protocol', async () => {
const keyHandler = vi.fn();
const { result } = renderHook(() => useKeypressContext(), { wrapper });
act(() => result.current.subscribe(keyHandler));
it.each([
{
name: 'Tab key',
sequence: '\x1b[9u',
expected: { name: 'tab', shift: false },
},
{
name: 'Shift+Tab',
sequence: '\x1b[9;2u',
expected: { name: 'tab', shift: true },
},
{
name: 'Backspace',
sequence: '\x1b[127u',
expected: { name: 'backspace', meta: false },
},
{
name: 'Option+Backspace',
sequence: '\x1b[127;3u',
expected: { name: 'backspace', meta: true },
},
{
name: 'Ctrl+Backspace',
sequence: '\x1b[127;5u',
expected: { name: 'backspace', ctrl: true },
},
])(
'should recognize $name in kitty protocol',
async ({ sequence, expected }) => {
const { keyHandler } = setupKeypressTest(true);
act(() => {
stdin.write(`\x1b[9u`);
});
act(() => {
stdin.write(sequence);
});
expect(keyHandler).toHaveBeenCalledWith(
expect.objectContaining({
name: 'tab',
kittyProtocol: true,
shift: false,
}),
);
});
it('should recognize Shift+Tab in kitty protocol', async () => {
const keyHandler = vi.fn();
const { result } = renderHook(() => useKeypressContext(), { wrapper });
act(() => result.current.subscribe(keyHandler));
// Modifier 2 is Shift
act(() => {
stdin.write(`\x1b[9;2u`);
});
expect(keyHandler).toHaveBeenCalledWith(
expect.objectContaining({
name: 'tab',
kittyProtocol: true,
shift: true,
}),
);
});
it('should recognize Backspace key in kitty protocol', async () => {
const keyHandler = vi.fn();
const { result } = renderHook(() => useKeypressContext(), { wrapper });
act(() => result.current.subscribe(keyHandler));
act(() => {
stdin.write(`\x1b[127u`);
});
expect(keyHandler).toHaveBeenCalledWith(
expect.objectContaining({
name: 'backspace',
kittyProtocol: true,
meta: false,
}),
);
});
it('should recognize Option+Backspace in kitty protocol', async () => {
const keyHandler = vi.fn();
const { result } = renderHook(() => useKeypressContext(), { wrapper });
act(() => result.current.subscribe(keyHandler));
// Modifier 3 is Alt/Option
act(() => {
stdin.write(`\x1b[127;3u`);
});
expect(keyHandler).toHaveBeenCalledWith(
expect.objectContaining({
name: 'backspace',
kittyProtocol: true,
meta: true,
}),
);
});
it('should recognize Ctrl+Backspace in kitty protocol', async () => {
const keyHandler = vi.fn();
const { result } = renderHook(() => useKeypressContext(), { wrapper });
act(() => result.current.subscribe(keyHandler));
// Modifier 5 is Ctrl
act(() => {
stdin.write(`\x1b[127;5u`);
});
expect(keyHandler).toHaveBeenCalledWith(
expect.objectContaining({
name: 'backspace',
kittyProtocol: true,
ctrl: true,
}),
);
});
expect(keyHandler).toHaveBeenCalledWith(
expect.objectContaining({
...expected,
kittyProtocol: true,
}),
);
},
);
});
describe('paste mode', () => {
it('should handle multiline paste as a single event', async () => {
it.each([
{
name: 'handle multiline paste as a single event',
pastedText: 'This \n is \n a \n multiline \n paste.',
writeSequence: (text: string) => {
stdin.write(PASTE_START);
stdin.write(text);
stdin.write(PASTE_END);
},
},
{
name: 'handle paste start code split over multiple writes',
pastedText: 'pasted content',
writeSequence: (text: string) => {
stdin.write(PASTE_START.slice(0, 3));
stdin.write(PASTE_START.slice(3));
stdin.write(text);
stdin.write(PASTE_END);
},
},
{
name: 'handle paste end code split over multiple writes',
pastedText: 'pasted content',
writeSequence: (text: string) => {
stdin.write(PASTE_START);
stdin.write(text);
stdin.write(PASTE_END.slice(0, 3));
stdin.write(PASTE_END.slice(3));
},
},
])('should $name', async ({ pastedText, writeSequence }) => {
const keyHandler = vi.fn();
const pastedText = 'This \n is \n a \n multiline \n paste.';
const { result } = renderHook(() => useKeypressContext(), {
wrapper,
});
act(() => result.current.subscribe(keyHandler));
// Simulate a bracketed paste event
act(() => {
stdin.write(PASTE_START);
stdin.write(pastedText);
stdin.write(PASTE_END);
});
await vi.waitFor(() => {
// Expect the handler to be called exactly once for the entire paste
expect(keyHandler).toHaveBeenCalledTimes(1);
});
// Verify the single event contains the full pasted text
expect(keyHandler).toHaveBeenCalledWith(
expect.objectContaining({
paste: true,
sequence: pastedText,
}),
);
});
it('should paste start code split over multiple writes', async () => {
const keyHandler = vi.fn();
const pastedText = 'pasted content';
const { result } = renderHook(() => useKeypressContext(), { wrapper });
act(() => result.current.subscribe(keyHandler));
act(() => {
// Split PASTE_START into two parts
stdin.write(PASTE_START.slice(0, 3));
stdin.write(PASTE_START.slice(3));
stdin.write(pastedText);
stdin.write(PASTE_END);
});
await vi.waitFor(() => {
expect(keyHandler).toHaveBeenCalledTimes(1);
});
expect(keyHandler).toHaveBeenCalledWith(
expect.objectContaining({
paste: true,
sequence: pastedText,
}),
);
});
it('should paste end code split over multiple writes', async () => {
const keyHandler = vi.fn();
const pastedText = 'pasted content';
const { result } = renderHook(() => useKeypressContext(), { wrapper });
act(() => result.current.subscribe(keyHandler));
act(() => {
stdin.write(PASTE_START);
stdin.write(pastedText);
// Split PASTE_END into two parts
stdin.write(PASTE_END.slice(0, 3));
stdin.write(PASTE_END.slice(3));
});
act(() => writeSequence(pastedText));
await vi.waitFor(() => {
expect(keyHandler).toHaveBeenCalledTimes(1);
@@ -666,9 +515,7 @@ describe('KeypressContext - Kitty Protocol', () => {
describe('Double-tap and batching', () => {
it('should emit two delete events for double-tap CSI[3~', async () => {
const keyHandler = vi.fn();
const { result } = renderHook(() => useKeypressContext(), { wrapper });
act(() => result.current.subscribe(keyHandler));
const { keyHandler } = setupKeypressTest(true);
act(() => stdin.write(`\x1b[3~`));
act(() => stdin.write(`\x1b[3~`));
@@ -684,9 +531,7 @@ describe('KeypressContext - Kitty Protocol', () => {
});
it('should parse two concatenated tilde-coded sequences in one chunk', async () => {
const keyHandler = vi.fn();
const { result } = renderHook(() => useKeypressContext(), { wrapper });
act(() => result.current.subscribe(keyHandler));
const { keyHandler } = setupKeypressTest(true);
act(() => stdin.write(`\x1b[3~\x1b[5~`));
@@ -699,9 +544,7 @@ describe('KeypressContext - Kitty Protocol', () => {
});
it('should ignore incomplete CSI then parse the next complete sequence', async () => {
const keyHandler = vi.fn();
const { result } = renderHook(() => useKeypressContext(), { wrapper });
act(() => result.current.subscribe(keyHandler));
const { keyHandler } = setupKeypressTest(true);
// Incomplete ESC sequence then a complete Delete
act(() => {
@@ -749,93 +592,61 @@ describe('Drag and Drop Handling', () => {
});
describe('drag start by quotes', () => {
it('should start collecting when single quote arrives and not broadcast immediately', async () => {
const keyHandler = vi.fn();
it.each([
{ name: 'single quote', quote: SINGLE_QUOTE },
{ name: 'double quote', quote: DOUBLE_QUOTE },
])(
'should start collecting when $name arrives and not broadcast immediately',
async ({ quote }) => {
const keyHandler = vi.fn();
const { result } = renderHook(() => useKeypressContext(), { wrapper });
const { result } = renderHook(() => useKeypressContext(), { wrapper });
act(() => result.current.subscribe(keyHandler));
act(() => result.current.subscribe(keyHandler));
act(() => stdin.write(SINGLE_QUOTE));
act(() => stdin.write(quote));
expect(keyHandler).not.toHaveBeenCalled();
});
it('should start collecting when double quote arrives and not broadcast immediately', async () => {
const keyHandler = vi.fn();
const { result } = renderHook(() => useKeypressContext(), { wrapper });
act(() => result.current.subscribe(keyHandler));
act(() => stdin.write(DOUBLE_QUOTE));
expect(keyHandler).not.toHaveBeenCalled();
});
expect(keyHandler).not.toHaveBeenCalled();
},
);
});
describe('drag collection and completion', () => {
it('should collect single character inputs during drag mode', async () => {
it.each([
{
name: 'collect single character inputs during drag mode',
characters: ['a'],
expectedText: 'a',
},
{
name: 'collect multiple characters and complete on timeout',
characters: ['p', 'a', 't', 'h'],
expectedText: 'path',
},
])('should $name', async ({ characters, expectedText }) => {
const keyHandler = vi.fn();
const { result } = renderHook(() => useKeypressContext(), { wrapper });
act(() => result.current.subscribe(keyHandler));
// Start by single quote
act(() => stdin.write(SINGLE_QUOTE));
// Send single character
act(() => stdin.write('a'));
characters.forEach((char) => {
act(() => stdin.write(char));
});
// Character should not be immediately broadcast
expect(keyHandler).not.toHaveBeenCalled();
// Fast-forward to completion timeout
act(() => {
vi.advanceTimersByTime(DRAG_COMPLETION_TIMEOUT_MS + 10);
});
// Should broadcast the collected path as paste (includes starting quote)
expect(keyHandler).toHaveBeenCalledWith(
expect.objectContaining({
name: '',
paste: true,
sequence: `${SINGLE_QUOTE}a`,
}),
);
});
it('should collect multiple characters and complete on timeout', async () => {
const keyHandler = vi.fn();
const { result } = renderHook(() => useKeypressContext(), { wrapper });
act(() => result.current.subscribe(keyHandler));
// Start by single quote
act(() => stdin.write(SINGLE_QUOTE));
// Send multiple characters
act(() => stdin.write('p'));
act(() => stdin.write('a'));
act(() => stdin.write('t'));
act(() => stdin.write('h'));
// Characters should not be immediately broadcast
expect(keyHandler).not.toHaveBeenCalled();
// Fast-forward to completion timeout
act(() => {
vi.advanceTimersByTime(DRAG_COMPLETION_TIMEOUT_MS + 10);
});
// Should broadcast the collected path as paste (includes starting quote)
expect(keyHandler).toHaveBeenCalledWith(
expect.objectContaining({
name: '',
paste: true,
sequence: `${SINGLE_QUOTE}path`,
sequence: `${SINGLE_QUOTE}${expectedText}`,
}),
);
});
@@ -995,9 +806,7 @@ describe('Kitty Sequence Parsing', () => {
});
it('should treat backslash as a regular keystroke', () => {
const keyHandler = vi.fn();
const { result } = renderHook(() => useKeypressContext(), { wrapper });
act(() => result.current.subscribe(keyHandler));
const { keyHandler } = setupKeypressTest(true);
act(() => stdin.write('\\'));
@@ -1207,7 +1016,7 @@ describe('Kitty Sequence Parsing', () => {
act(() => {
stdin.emit('data', Buffer.from(char));
});
await new Promise((resolve) => setTimeout(resolve, 0));
await new Promise((resolve) => setImmediate(resolve));
}
// Should parse once complete