mirror of
https://github.com/QwenLM/qwen-code.git
synced 2025-12-19 09:33:53 +00:00
# 🚀 Sync Gemini CLI v0.2.1 - Major Feature Update (#483)
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import { render } from 'ink-testing-library';
|
||||
import { renderWithProviders } from '../../test-utils/render.js';
|
||||
import { waitFor } from '@testing-library/react';
|
||||
import { InputPrompt, InputPromptProps } from './InputPrompt.js';
|
||||
import type { TextBuffer } from './shared/text-buffer.js';
|
||||
@@ -197,7 +197,7 @@ describe('InputPrompt', () => {
|
||||
|
||||
it('should call shellHistory.getPreviousCommand on up arrow in shell mode', async () => {
|
||||
props.shellModeActive = true;
|
||||
const { stdin, unmount } = render(<InputPrompt {...props} />);
|
||||
const { stdin, unmount } = renderWithProviders(<InputPrompt {...props} />);
|
||||
await wait();
|
||||
|
||||
stdin.write('\u001B[A');
|
||||
@@ -209,7 +209,7 @@ describe('InputPrompt', () => {
|
||||
|
||||
it('should call shellHistory.getNextCommand on down arrow in shell mode', async () => {
|
||||
props.shellModeActive = true;
|
||||
const { stdin, unmount } = render(<InputPrompt {...props} />);
|
||||
const { stdin, unmount } = renderWithProviders(<InputPrompt {...props} />);
|
||||
await wait();
|
||||
|
||||
stdin.write('\u001B[B');
|
||||
@@ -224,7 +224,7 @@ describe('InputPrompt', () => {
|
||||
vi.mocked(mockShellHistory.getPreviousCommand).mockReturnValue(
|
||||
'previous command',
|
||||
);
|
||||
const { stdin, unmount } = render(<InputPrompt {...props} />);
|
||||
const { stdin, unmount } = renderWithProviders(<InputPrompt {...props} />);
|
||||
await wait();
|
||||
|
||||
stdin.write('\u001B[A');
|
||||
@@ -238,7 +238,7 @@ describe('InputPrompt', () => {
|
||||
it('should call shellHistory.addCommandToHistory on submit in shell mode', async () => {
|
||||
props.shellModeActive = true;
|
||||
props.buffer.setText('ls -l');
|
||||
const { stdin, unmount } = render(<InputPrompt {...props} />);
|
||||
const { stdin, unmount } = renderWithProviders(<InputPrompt {...props} />);
|
||||
await wait();
|
||||
|
||||
stdin.write('\r');
|
||||
@@ -251,7 +251,7 @@ describe('InputPrompt', () => {
|
||||
|
||||
it('should NOT call shell history methods when not in shell mode', async () => {
|
||||
props.buffer.setText('some text');
|
||||
const { stdin, unmount } = render(<InputPrompt {...props} />);
|
||||
const { stdin, unmount } = renderWithProviders(<InputPrompt {...props} />);
|
||||
await wait();
|
||||
|
||||
stdin.write('\u001B[A'); // Up arrow
|
||||
@@ -283,7 +283,7 @@ describe('InputPrompt', () => {
|
||||
|
||||
props.buffer.setText('/mem');
|
||||
|
||||
const { stdin, unmount } = render(<InputPrompt {...props} />);
|
||||
const { stdin, unmount } = renderWithProviders(<InputPrompt {...props} />);
|
||||
await wait();
|
||||
|
||||
// Test up arrow
|
||||
@@ -309,7 +309,7 @@ describe('InputPrompt', () => {
|
||||
});
|
||||
props.buffer.setText('/mem');
|
||||
|
||||
const { stdin, unmount } = render(<InputPrompt {...props} />);
|
||||
const { stdin, unmount } = renderWithProviders(<InputPrompt {...props} />);
|
||||
await wait();
|
||||
|
||||
// Test down arrow
|
||||
@@ -331,7 +331,7 @@ describe('InputPrompt', () => {
|
||||
});
|
||||
props.buffer.setText('some text');
|
||||
|
||||
const { stdin, unmount } = render(<InputPrompt {...props} />);
|
||||
const { stdin, unmount } = renderWithProviders(<InputPrompt {...props} />);
|
||||
await wait();
|
||||
|
||||
stdin.write('\u001B[A'); // Up arrow
|
||||
@@ -363,7 +363,9 @@ describe('InputPrompt', () => {
|
||||
'/test/.gemini-clipboard/clipboard-123.png',
|
||||
);
|
||||
|
||||
const { stdin, unmount } = render(<InputPrompt {...props} />);
|
||||
const { stdin, unmount } = renderWithProviders(
|
||||
<InputPrompt {...props} />,
|
||||
);
|
||||
await wait();
|
||||
|
||||
// Send Ctrl+V
|
||||
@@ -384,7 +386,9 @@ describe('InputPrompt', () => {
|
||||
it('should not insert anything when clipboard has no image', async () => {
|
||||
vi.mocked(clipboardUtils.clipboardHasImage).mockResolvedValue(false);
|
||||
|
||||
const { stdin, unmount } = render(<InputPrompt {...props} />);
|
||||
const { stdin, unmount } = renderWithProviders(
|
||||
<InputPrompt {...props} />,
|
||||
);
|
||||
await wait();
|
||||
|
||||
stdin.write('\x16'); // Ctrl+V
|
||||
@@ -400,7 +404,9 @@ describe('InputPrompt', () => {
|
||||
vi.mocked(clipboardUtils.clipboardHasImage).mockResolvedValue(true);
|
||||
vi.mocked(clipboardUtils.saveClipboardImage).mockResolvedValue(null);
|
||||
|
||||
const { stdin, unmount } = render(<InputPrompt {...props} />);
|
||||
const { stdin, unmount } = renderWithProviders(
|
||||
<InputPrompt {...props} />,
|
||||
);
|
||||
await wait();
|
||||
|
||||
stdin.write('\x16'); // Ctrl+V
|
||||
@@ -426,7 +432,9 @@ describe('InputPrompt', () => {
|
||||
mockBuffer.lines = ['Hello world'];
|
||||
mockBuffer.replaceRangeByOffset = vi.fn();
|
||||
|
||||
const { stdin, unmount } = render(<InputPrompt {...props} />);
|
||||
const { stdin, unmount } = renderWithProviders(
|
||||
<InputPrompt {...props} />,
|
||||
);
|
||||
await wait();
|
||||
|
||||
stdin.write('\x16'); // Ctrl+V
|
||||
@@ -454,7 +462,9 @@ describe('InputPrompt', () => {
|
||||
new Error('Clipboard error'),
|
||||
);
|
||||
|
||||
const { stdin, unmount } = render(<InputPrompt {...props} />);
|
||||
const { stdin, unmount } = renderWithProviders(
|
||||
<InputPrompt {...props} />,
|
||||
);
|
||||
await wait();
|
||||
|
||||
stdin.write('\x16'); // Ctrl+V
|
||||
@@ -481,7 +491,7 @@ describe('InputPrompt', () => {
|
||||
});
|
||||
props.buffer.setText('/mem');
|
||||
|
||||
const { stdin, unmount } = render(<InputPrompt {...props} />);
|
||||
const { stdin, unmount } = renderWithProviders(<InputPrompt {...props} />);
|
||||
await wait();
|
||||
|
||||
stdin.write('\t'); // Press Tab
|
||||
@@ -504,7 +514,7 @@ describe('InputPrompt', () => {
|
||||
});
|
||||
props.buffer.setText('/memory ');
|
||||
|
||||
const { stdin, unmount } = render(<InputPrompt {...props} />);
|
||||
const { stdin, unmount } = renderWithProviders(<InputPrompt {...props} />);
|
||||
await wait();
|
||||
|
||||
stdin.write('\t'); // Press Tab
|
||||
@@ -528,7 +538,7 @@ describe('InputPrompt', () => {
|
||||
// The user has backspaced, so the query is now just '/memory'
|
||||
props.buffer.setText('/memory');
|
||||
|
||||
const { stdin, unmount } = render(<InputPrompt {...props} />);
|
||||
const { stdin, unmount } = renderWithProviders(<InputPrompt {...props} />);
|
||||
await wait();
|
||||
|
||||
stdin.write('\t'); // Press Tab
|
||||
@@ -549,7 +559,7 @@ describe('InputPrompt', () => {
|
||||
});
|
||||
props.buffer.setText('/chat resume fi-');
|
||||
|
||||
const { stdin, unmount } = render(<InputPrompt {...props} />);
|
||||
const { stdin, unmount } = renderWithProviders(<InputPrompt {...props} />);
|
||||
await wait();
|
||||
|
||||
stdin.write('\t'); // Press Tab
|
||||
@@ -568,7 +578,7 @@ describe('InputPrompt', () => {
|
||||
});
|
||||
props.buffer.setText('/mem');
|
||||
|
||||
const { stdin, unmount } = render(<InputPrompt {...props} />);
|
||||
const { stdin, unmount } = renderWithProviders(<InputPrompt {...props} />);
|
||||
await wait();
|
||||
|
||||
stdin.write('\r');
|
||||
@@ -599,7 +609,7 @@ describe('InputPrompt', () => {
|
||||
});
|
||||
props.buffer.setText('/?');
|
||||
|
||||
const { stdin, unmount } = render(<InputPrompt {...props} />);
|
||||
const { stdin, unmount } = renderWithProviders(<InputPrompt {...props} />);
|
||||
await wait();
|
||||
|
||||
stdin.write('\t'); // Press Tab for autocomplete
|
||||
@@ -612,7 +622,7 @@ describe('InputPrompt', () => {
|
||||
it('should not submit on Enter when the buffer is empty or only contains whitespace', async () => {
|
||||
props.buffer.setText(' '); // Set buffer to whitespace
|
||||
|
||||
const { stdin, unmount } = render(<InputPrompt {...props} />);
|
||||
const { stdin, unmount } = renderWithProviders(<InputPrompt {...props} />);
|
||||
await wait();
|
||||
|
||||
stdin.write('\r'); // Press Enter
|
||||
@@ -630,7 +640,7 @@ describe('InputPrompt', () => {
|
||||
});
|
||||
props.buffer.setText('/clear');
|
||||
|
||||
const { stdin, unmount } = render(<InputPrompt {...props} />);
|
||||
const { stdin, unmount } = renderWithProviders(<InputPrompt {...props} />);
|
||||
await wait();
|
||||
|
||||
stdin.write('\r');
|
||||
@@ -648,7 +658,7 @@ describe('InputPrompt', () => {
|
||||
});
|
||||
props.buffer.setText('/clear');
|
||||
|
||||
const { stdin, unmount } = render(<InputPrompt {...props} />);
|
||||
const { stdin, unmount } = renderWithProviders(<InputPrompt {...props} />);
|
||||
await wait();
|
||||
|
||||
stdin.write('\r');
|
||||
@@ -667,7 +677,7 @@ describe('InputPrompt', () => {
|
||||
});
|
||||
props.buffer.setText('@src/components/');
|
||||
|
||||
const { stdin, unmount } = render(<InputPrompt {...props} />);
|
||||
const { stdin, unmount } = renderWithProviders(<InputPrompt {...props} />);
|
||||
await wait();
|
||||
|
||||
stdin.write('\r');
|
||||
@@ -684,7 +694,7 @@ describe('InputPrompt', () => {
|
||||
mockBuffer.cursor = [0, 11];
|
||||
mockBuffer.lines = ['first line\\'];
|
||||
|
||||
const { stdin, unmount } = render(<InputPrompt {...props} />);
|
||||
const { stdin, unmount } = renderWithProviders(<InputPrompt {...props} />);
|
||||
await wait();
|
||||
|
||||
stdin.write('\r');
|
||||
@@ -698,7 +708,7 @@ describe('InputPrompt', () => {
|
||||
|
||||
it('should clear the buffer on Ctrl+C if it has text', async () => {
|
||||
props.buffer.setText('some text to clear');
|
||||
const { stdin, unmount } = render(<InputPrompt {...props} />);
|
||||
const { stdin, unmount } = renderWithProviders(<InputPrompt {...props} />);
|
||||
await wait();
|
||||
|
||||
stdin.write('\x03'); // Ctrl+C character
|
||||
@@ -712,7 +722,7 @@ describe('InputPrompt', () => {
|
||||
|
||||
it('should NOT clear the buffer on Ctrl+C if it is empty', async () => {
|
||||
props.buffer.text = '';
|
||||
const { stdin, unmount } = render(<InputPrompt {...props} />);
|
||||
const { stdin, unmount } = renderWithProviders(<InputPrompt {...props} />);
|
||||
await wait();
|
||||
|
||||
stdin.write('\x03'); // Ctrl+C character
|
||||
@@ -735,7 +745,7 @@ describe('InputPrompt', () => {
|
||||
suggestions: [{ label: 'Button.tsx', value: 'Button.tsx' }],
|
||||
});
|
||||
|
||||
const { unmount } = render(<InputPrompt {...props} />);
|
||||
const { unmount } = renderWithProviders(<InputPrompt {...props} />);
|
||||
await wait();
|
||||
|
||||
// Verify useCompletion was called with correct signature
|
||||
@@ -763,7 +773,7 @@ describe('InputPrompt', () => {
|
||||
suggestions: [{ label: 'show', value: 'show' }],
|
||||
});
|
||||
|
||||
const { unmount } = render(<InputPrompt {...props} />);
|
||||
const { unmount } = renderWithProviders(<InputPrompt {...props} />);
|
||||
await wait();
|
||||
|
||||
expect(mockedUseCommandCompletion).toHaveBeenCalledWith(
|
||||
@@ -790,7 +800,7 @@ describe('InputPrompt', () => {
|
||||
suggestions: [],
|
||||
});
|
||||
|
||||
const { unmount } = render(<InputPrompt {...props} />);
|
||||
const { unmount } = renderWithProviders(<InputPrompt {...props} />);
|
||||
await wait();
|
||||
|
||||
expect(mockedUseCommandCompletion).toHaveBeenCalledWith(
|
||||
@@ -817,7 +827,7 @@ describe('InputPrompt', () => {
|
||||
suggestions: [],
|
||||
});
|
||||
|
||||
const { unmount } = render(<InputPrompt {...props} />);
|
||||
const { unmount } = renderWithProviders(<InputPrompt {...props} />);
|
||||
await wait();
|
||||
|
||||
expect(mockedUseCommandCompletion).toHaveBeenCalledWith(
|
||||
@@ -844,7 +854,7 @@ describe('InputPrompt', () => {
|
||||
suggestions: [],
|
||||
});
|
||||
|
||||
const { unmount } = render(<InputPrompt {...props} />);
|
||||
const { unmount } = renderWithProviders(<InputPrompt {...props} />);
|
||||
await wait();
|
||||
|
||||
expect(mockedUseCommandCompletion).toHaveBeenCalledWith(
|
||||
@@ -871,7 +881,7 @@ describe('InputPrompt', () => {
|
||||
suggestions: [],
|
||||
});
|
||||
|
||||
const { unmount } = render(<InputPrompt {...props} />);
|
||||
const { unmount } = renderWithProviders(<InputPrompt {...props} />);
|
||||
await wait();
|
||||
|
||||
// Verify useCompletion was called with the buffer
|
||||
@@ -899,7 +909,7 @@ describe('InputPrompt', () => {
|
||||
suggestions: [{ label: 'show', value: 'show' }],
|
||||
});
|
||||
|
||||
const { unmount } = render(<InputPrompt {...props} />);
|
||||
const { unmount } = renderWithProviders(<InputPrompt {...props} />);
|
||||
await wait();
|
||||
|
||||
expect(mockedUseCommandCompletion).toHaveBeenCalledWith(
|
||||
@@ -927,7 +937,7 @@ describe('InputPrompt', () => {
|
||||
suggestions: [{ label: 'file👍.txt', value: 'file👍.txt' }],
|
||||
});
|
||||
|
||||
const { unmount } = render(<InputPrompt {...props} />);
|
||||
const { unmount } = renderWithProviders(<InputPrompt {...props} />);
|
||||
await wait();
|
||||
|
||||
expect(mockedUseCommandCompletion).toHaveBeenCalledWith(
|
||||
@@ -955,7 +965,7 @@ describe('InputPrompt', () => {
|
||||
suggestions: [],
|
||||
});
|
||||
|
||||
const { unmount } = render(<InputPrompt {...props} />);
|
||||
const { unmount } = renderWithProviders(<InputPrompt {...props} />);
|
||||
await wait();
|
||||
|
||||
expect(mockedUseCommandCompletion).toHaveBeenCalledWith(
|
||||
@@ -983,7 +993,7 @@ describe('InputPrompt', () => {
|
||||
suggestions: [{ label: 'my file.txt', value: 'my file.txt' }],
|
||||
});
|
||||
|
||||
const { unmount } = render(<InputPrompt {...props} />);
|
||||
const { unmount } = renderWithProviders(<InputPrompt {...props} />);
|
||||
await wait();
|
||||
|
||||
expect(mockedUseCommandCompletion).toHaveBeenCalledWith(
|
||||
@@ -1011,7 +1021,7 @@ describe('InputPrompt', () => {
|
||||
suggestions: [],
|
||||
});
|
||||
|
||||
const { unmount } = render(<InputPrompt {...props} />);
|
||||
const { unmount } = renderWithProviders(<InputPrompt {...props} />);
|
||||
await wait();
|
||||
|
||||
expect(mockedUseCommandCompletion).toHaveBeenCalledWith(
|
||||
@@ -1041,7 +1051,7 @@ describe('InputPrompt', () => {
|
||||
],
|
||||
});
|
||||
|
||||
const { unmount } = render(<InputPrompt {...props} />);
|
||||
const { unmount } = renderWithProviders(<InputPrompt {...props} />);
|
||||
await wait();
|
||||
|
||||
expect(mockedUseCommandCompletion).toHaveBeenCalledWith(
|
||||
@@ -1069,7 +1079,7 @@ describe('InputPrompt', () => {
|
||||
suggestions: [{ label: 'test-command', value: 'test-command' }],
|
||||
});
|
||||
|
||||
const { unmount } = render(<InputPrompt {...props} />);
|
||||
const { unmount } = renderWithProviders(<InputPrompt {...props} />);
|
||||
await wait();
|
||||
|
||||
expect(mockedUseCommandCompletion).toHaveBeenCalledWith(
|
||||
@@ -1099,7 +1109,7 @@ describe('InputPrompt', () => {
|
||||
],
|
||||
});
|
||||
|
||||
const { unmount } = render(<InputPrompt {...props} />);
|
||||
const { unmount } = renderWithProviders(<InputPrompt {...props} />);
|
||||
await wait();
|
||||
|
||||
expect(mockedUseCommandCompletion).toHaveBeenCalledWith(
|
||||
@@ -1120,7 +1130,9 @@ describe('InputPrompt', () => {
|
||||
it('should not call buffer.handleInput when vim mode is enabled and vim handles the input', async () => {
|
||||
props.vimModeEnabled = true;
|
||||
props.vimHandleInput = vi.fn().mockReturnValue(true); // Mock that vim handled it.
|
||||
const { stdin, unmount } = render(<InputPrompt {...props} />);
|
||||
const { stdin, unmount } = renderWithProviders(
|
||||
<InputPrompt {...props} />,
|
||||
);
|
||||
await wait();
|
||||
|
||||
stdin.write('i');
|
||||
@@ -1134,7 +1146,9 @@ describe('InputPrompt', () => {
|
||||
it('should call buffer.handleInput when vim mode is enabled but vim does not handle the input', async () => {
|
||||
props.vimModeEnabled = true;
|
||||
props.vimHandleInput = vi.fn().mockReturnValue(false); // Mock that vim did NOT handle it.
|
||||
const { stdin, unmount } = render(<InputPrompt {...props} />);
|
||||
const { stdin, unmount } = renderWithProviders(
|
||||
<InputPrompt {...props} />,
|
||||
);
|
||||
await wait();
|
||||
|
||||
stdin.write('i');
|
||||
@@ -1148,7 +1162,9 @@ describe('InputPrompt', () => {
|
||||
it('should call handleInput when vim mode is disabled', async () => {
|
||||
// Mock vimHandleInput to return false (vim didn't handle the input)
|
||||
props.vimHandleInput = vi.fn().mockReturnValue(false);
|
||||
const { stdin, unmount } = render(<InputPrompt {...props} />);
|
||||
const { stdin, unmount } = renderWithProviders(
|
||||
<InputPrompt {...props} />,
|
||||
);
|
||||
await wait();
|
||||
|
||||
stdin.write('i');
|
||||
@@ -1163,7 +1179,9 @@ describe('InputPrompt', () => {
|
||||
describe('unfocused paste', () => {
|
||||
it('should handle bracketed paste when not focused', async () => {
|
||||
props.focus = false;
|
||||
const { stdin, unmount } = render(<InputPrompt {...props} />);
|
||||
const { stdin, unmount } = renderWithProviders(
|
||||
<InputPrompt {...props} />,
|
||||
);
|
||||
await wait();
|
||||
|
||||
stdin.write('\x1B[200~pasted text\x1B[201~');
|
||||
@@ -1180,7 +1198,9 @@ describe('InputPrompt', () => {
|
||||
|
||||
it('should ignore regular keypresses when not focused', async () => {
|
||||
props.focus = false;
|
||||
const { stdin, unmount } = render(<InputPrompt {...props} />);
|
||||
const { stdin, unmount } = renderWithProviders(
|
||||
<InputPrompt {...props} />,
|
||||
);
|
||||
await wait();
|
||||
|
||||
stdin.write('a');
|
||||
@@ -1191,13 +1211,52 @@ describe('InputPrompt', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('multiline paste', () => {
|
||||
it.each([
|
||||
{
|
||||
description: 'with \n newlines',
|
||||
pastedText: 'This \n is \n a \n multiline \n paste.',
|
||||
},
|
||||
{
|
||||
description: 'with extra slashes before \n newlines',
|
||||
pastedText: 'This \\\n is \\\n a \\\n multiline \\\n paste.',
|
||||
},
|
||||
{
|
||||
description: 'with \r\n newlines',
|
||||
pastedText: 'This\r\nis\r\na\r\nmultiline\r\npaste.',
|
||||
},
|
||||
])('should handle multiline paste $description', async ({ pastedText }) => {
|
||||
const { stdin, unmount } = renderWithProviders(
|
||||
<InputPrompt {...props} />,
|
||||
);
|
||||
await wait();
|
||||
|
||||
// Simulate a bracketed paste event from the terminal
|
||||
stdin.write(`\x1b[200~${pastedText}\x1b[201~`);
|
||||
await wait();
|
||||
|
||||
// Verify that the buffer's handleInput was called once with the full text
|
||||
expect(props.buffer.handleInput).toHaveBeenCalledTimes(1);
|
||||
expect(props.buffer.handleInput).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
paste: true,
|
||||
sequence: pastedText,
|
||||
}),
|
||||
);
|
||||
|
||||
unmount();
|
||||
});
|
||||
});
|
||||
|
||||
describe('enhanced input UX - double ESC clear functionality', () => {
|
||||
it('should clear buffer on second ESC press', async () => {
|
||||
const onEscapePromptChange = vi.fn();
|
||||
props.onEscapePromptChange = onEscapePromptChange;
|
||||
props.buffer.setText('text to clear');
|
||||
|
||||
const { stdin, unmount } = render(<InputPrompt {...props} />);
|
||||
const { stdin, unmount } = renderWithProviders(
|
||||
<InputPrompt {...props} />,
|
||||
);
|
||||
await wait();
|
||||
|
||||
stdin.write('\x1B');
|
||||
@@ -1216,25 +1275,30 @@ describe('InputPrompt', () => {
|
||||
props.onEscapePromptChange = onEscapePromptChange;
|
||||
props.buffer.setText('some text');
|
||||
|
||||
const { stdin, unmount } = render(<InputPrompt {...props} />);
|
||||
await wait();
|
||||
const { stdin, unmount } = renderWithProviders(
|
||||
<InputPrompt {...props} />,
|
||||
);
|
||||
|
||||
stdin.write('\x1B');
|
||||
await wait();
|
||||
|
||||
expect(onEscapePromptChange).toHaveBeenCalledWith(true);
|
||||
await waitFor(() => {
|
||||
expect(onEscapePromptChange).toHaveBeenCalledWith(true);
|
||||
});
|
||||
|
||||
stdin.write('a');
|
||||
await wait();
|
||||
|
||||
expect(onEscapePromptChange).toHaveBeenCalledWith(false);
|
||||
await waitFor(() => {
|
||||
expect(onEscapePromptChange).toHaveBeenCalledWith(false);
|
||||
});
|
||||
unmount();
|
||||
});
|
||||
|
||||
it('should handle ESC in shell mode by disabling shell mode', async () => {
|
||||
props.shellModeActive = true;
|
||||
|
||||
const { stdin, unmount } = render(<InputPrompt {...props} />);
|
||||
const { stdin, unmount } = renderWithProviders(
|
||||
<InputPrompt {...props} />,
|
||||
);
|
||||
await wait();
|
||||
|
||||
stdin.write('\x1B');
|
||||
@@ -1251,7 +1315,9 @@ describe('InputPrompt', () => {
|
||||
suggestions: [{ label: 'suggestion', value: 'suggestion' }],
|
||||
});
|
||||
|
||||
const { stdin, unmount } = render(<InputPrompt {...props} />);
|
||||
const { stdin, unmount } = renderWithProviders(
|
||||
<InputPrompt {...props} />,
|
||||
);
|
||||
await wait();
|
||||
|
||||
stdin.write('\x1B');
|
||||
@@ -1265,7 +1331,9 @@ describe('InputPrompt', () => {
|
||||
props.onEscapePromptChange = undefined;
|
||||
props.buffer.setText('some text');
|
||||
|
||||
const { stdin, unmount } = render(<InputPrompt {...props} />);
|
||||
const { stdin, unmount } = renderWithProviders(
|
||||
<InputPrompt {...props} />,
|
||||
);
|
||||
await wait();
|
||||
|
||||
stdin.write('\x1B');
|
||||
@@ -1275,7 +1343,9 @@ describe('InputPrompt', () => {
|
||||
});
|
||||
|
||||
it('should not interfere with existing keyboard shortcuts', async () => {
|
||||
const { stdin, unmount } = render(<InputPrompt {...props} />);
|
||||
const { stdin, unmount } = renderWithProviders(
|
||||
<InputPrompt {...props} />,
|
||||
);
|
||||
await wait();
|
||||
|
||||
stdin.write('\x0C');
|
||||
@@ -1305,7 +1375,9 @@ describe('InputPrompt', () => {
|
||||
});
|
||||
|
||||
it('invokes reverse search on Ctrl+R', async () => {
|
||||
const { stdin, stdout, unmount } = render(<InputPrompt {...props} />);
|
||||
const { stdin, stdout, unmount } = renderWithProviders(
|
||||
<InputPrompt {...props} />,
|
||||
);
|
||||
await wait();
|
||||
|
||||
stdin.write('\x12');
|
||||
@@ -1321,7 +1393,9 @@ describe('InputPrompt', () => {
|
||||
});
|
||||
|
||||
it('resets reverse search state on Escape', async () => {
|
||||
const { stdin, stdout, unmount } = render(<InputPrompt {...props} />);
|
||||
const { stdin, stdout, unmount } = renderWithProviders(
|
||||
<InputPrompt {...props} />,
|
||||
);
|
||||
await wait();
|
||||
|
||||
stdin.write('\x12');
|
||||
@@ -1338,7 +1412,9 @@ describe('InputPrompt', () => {
|
||||
});
|
||||
|
||||
it('completes the highlighted entry on Tab and exits reverse-search', async () => {
|
||||
const { stdin, stdout, unmount } = render(<InputPrompt {...props} />);
|
||||
const { stdin, stdout, unmount } = renderWithProviders(
|
||||
<InputPrompt {...props} />,
|
||||
);
|
||||
stdin.write('\x12');
|
||||
await wait();
|
||||
stdin.write('\t');
|
||||
@@ -1352,7 +1428,9 @@ describe('InputPrompt', () => {
|
||||
});
|
||||
|
||||
it('submits the highlighted entry on Enter and exits reverse-search', async () => {
|
||||
const { stdin, stdout, unmount } = render(<InputPrompt {...props} />);
|
||||
const { stdin, stdout, unmount } = renderWithProviders(
|
||||
<InputPrompt {...props} />,
|
||||
);
|
||||
stdin.write('\x12');
|
||||
await wait();
|
||||
expect(stdout.lastFrame()).toContain('(r:)');
|
||||
@@ -1369,7 +1447,9 @@ describe('InputPrompt', () => {
|
||||
it('text and cursor position should be restored after reverse search', async () => {
|
||||
props.buffer.setText('initial text');
|
||||
props.buffer.cursor = [0, 3];
|
||||
const { stdin, stdout, unmount } = render(<InputPrompt {...props} />);
|
||||
const { stdin, stdout, unmount } = renderWithProviders(
|
||||
<InputPrompt {...props} />,
|
||||
);
|
||||
stdin.write('\x12');
|
||||
await wait();
|
||||
expect(stdout.lastFrame()).toContain('(r:)');
|
||||
|
||||
Reference in New Issue
Block a user