mirror of
https://github.com/QwenLM/qwen-code.git
synced 2025-12-19 09:33:53 +00:00
fix: try to fix test case failures on Windows
This commit is contained in:
@@ -127,9 +127,11 @@ interface AppProps {
|
||||
|
||||
export const AppWrapper = (props: AppProps) => {
|
||||
const kittyProtocolStatus = useKittyKeyboardProtocol();
|
||||
const nodeMajorVersion = parseInt(process.versions.node.split('.')[0], 10);
|
||||
return (
|
||||
<KeypressProvider
|
||||
kittyProtocolEnabled={kittyProtocolStatus.enabled}
|
||||
pasteWorkaround={process.platform === 'win32' || nodeMajorVersion < 20}
|
||||
config={props.config}
|
||||
>
|
||||
<SessionStatsProvider>
|
||||
|
||||
@@ -66,11 +66,16 @@ describe('KeypressContext - Kitty Protocol', () => {
|
||||
const wrapper = ({
|
||||
children,
|
||||
kittyProtocolEnabled = true,
|
||||
pasteWorkaround = false,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
kittyProtocolEnabled?: boolean;
|
||||
pasteWorkaround?: boolean;
|
||||
}) => (
|
||||
<KeypressProvider kittyProtocolEnabled={kittyProtocolEnabled}>
|
||||
<KeypressProvider
|
||||
kittyProtocolEnabled={kittyProtocolEnabled}
|
||||
pasteWorkaround={pasteWorkaround}
|
||||
>
|
||||
{children}
|
||||
</KeypressProvider>
|
||||
);
|
||||
@@ -389,17 +394,15 @@ describe('KeypressContext - Kitty Protocol', () => {
|
||||
});
|
||||
|
||||
describe('paste mode markers', () => {
|
||||
beforeEach(() => {
|
||||
// Force passthrough mode for raw keypress testing
|
||||
vi.stubEnv('PASTE_WORKAROUND', '1');
|
||||
});
|
||||
// These tests use pasteWorkaround=true to force passthrough mode for raw keypress testing
|
||||
|
||||
it('should handle complete paste sequence with markers', async () => {
|
||||
const keyHandler = vi.fn();
|
||||
const pastedText = 'pasted content';
|
||||
|
||||
const { result } = renderHook(() => useKeypressContext(), {
|
||||
wrapper,
|
||||
wrapper: ({ children }) =>
|
||||
wrapper({ children, pasteWorkaround: true }),
|
||||
});
|
||||
|
||||
act(() => {
|
||||
@@ -429,7 +432,8 @@ describe('KeypressContext - Kitty Protocol', () => {
|
||||
const keyHandler = vi.fn();
|
||||
|
||||
const { result } = renderHook(() => useKeypressContext(), {
|
||||
wrapper,
|
||||
wrapper: ({ children }) =>
|
||||
wrapper({ children, pasteWorkaround: true }),
|
||||
});
|
||||
|
||||
act(() => {
|
||||
@@ -459,7 +463,8 @@ describe('KeypressContext - Kitty Protocol', () => {
|
||||
const keyHandler = vi.fn();
|
||||
|
||||
const { result } = renderHook(() => useKeypressContext(), {
|
||||
wrapper,
|
||||
wrapper: ({ children }) =>
|
||||
wrapper({ children, pasteWorkaround: true }),
|
||||
});
|
||||
|
||||
act(() => {
|
||||
@@ -515,7 +520,8 @@ describe('KeypressContext - Kitty Protocol', () => {
|
||||
const keyHandler = vi.fn();
|
||||
|
||||
const { result } = renderHook(() => useKeypressContext(), {
|
||||
wrapper,
|
||||
wrapper: ({ children }) =>
|
||||
wrapper({ children, pasteWorkaround: true }),
|
||||
});
|
||||
|
||||
act(() => {
|
||||
@@ -554,7 +560,8 @@ describe('KeypressContext - Kitty Protocol', () => {
|
||||
const keyHandler = vi.fn();
|
||||
|
||||
const { result } = renderHook(() => useKeypressContext(), {
|
||||
wrapper,
|
||||
wrapper: ({ children }) =>
|
||||
wrapper({ children, pasteWorkaround: true }),
|
||||
});
|
||||
|
||||
act(() => {
|
||||
@@ -658,7 +665,8 @@ describe('KeypressContext - Kitty Protocol', () => {
|
||||
const keyHandler = vi.fn();
|
||||
|
||||
const { result } = renderHook(() => useKeypressContext(), {
|
||||
wrapper,
|
||||
wrapper: ({ children }) =>
|
||||
wrapper({ children, pasteWorkaround: true }),
|
||||
});
|
||||
|
||||
act(() => {
|
||||
@@ -689,7 +697,8 @@ describe('KeypressContext - Kitty Protocol', () => {
|
||||
const multilineContent = 'line1\nline2\nline3';
|
||||
|
||||
const { result } = renderHook(() => useKeypressContext(), {
|
||||
wrapper,
|
||||
wrapper: ({ children }) =>
|
||||
wrapper({ children, pasteWorkaround: true }),
|
||||
});
|
||||
|
||||
act(() => {
|
||||
@@ -721,7 +730,8 @@ describe('KeypressContext - Kitty Protocol', () => {
|
||||
const keyHandler = vi.fn();
|
||||
|
||||
const { result } = renderHook(() => useKeypressContext(), {
|
||||
wrapper,
|
||||
wrapper: ({ children }) =>
|
||||
wrapper({ children, pasteWorkaround: true }),
|
||||
});
|
||||
|
||||
act(() => {
|
||||
@@ -754,7 +764,7 @@ describe('KeypressContext - Kitty Protocol', () => {
|
||||
const keyHandler = vi.fn();
|
||||
|
||||
const { result } = renderHook(() => useKeypressContext(), {
|
||||
wrapper,
|
||||
wrapper: ({ children }) => wrapper({ children, pasteWorkaround: true }),
|
||||
});
|
||||
|
||||
act(() => {
|
||||
@@ -789,17 +799,14 @@ describe('KeypressContext - Kitty Protocol', () => {
|
||||
});
|
||||
|
||||
describe('Raw keypress pipeline', () => {
|
||||
beforeEach(() => {
|
||||
// Force passthrough mode for raw keypress testing
|
||||
vi.stubEnv('PASTE_WORKAROUND', '1');
|
||||
});
|
||||
// These tests use pasteWorkaround=true to force passthrough mode for raw keypress testing
|
||||
|
||||
it('should buffer input data and wait for timeout', () => {
|
||||
vi.useFakeTimers();
|
||||
const keyHandler = vi.fn();
|
||||
|
||||
const { result } = renderHook(() => useKeypressContext(), {
|
||||
wrapper,
|
||||
wrapper: ({ children }) => wrapper({ children, pasteWorkaround: true }),
|
||||
});
|
||||
|
||||
act(() => {
|
||||
@@ -829,7 +836,7 @@ describe('KeypressContext - Kitty Protocol', () => {
|
||||
const keyHandler = vi.fn();
|
||||
|
||||
const { result } = renderHook(() => useKeypressContext(), {
|
||||
wrapper,
|
||||
wrapper: ({ children }) => wrapper({ children, pasteWorkaround: true }),
|
||||
});
|
||||
|
||||
act(() => {
|
||||
@@ -892,7 +899,7 @@ describe('KeypressContext - Kitty Protocol', () => {
|
||||
const keyHandler = vi.fn();
|
||||
|
||||
const { result } = renderHook(() => useKeypressContext(), {
|
||||
wrapper,
|
||||
wrapper: ({ children }) => wrapper({ children, pasteWorkaround: true }),
|
||||
});
|
||||
|
||||
act(() => {
|
||||
@@ -934,7 +941,7 @@ describe('KeypressContext - Kitty Protocol', () => {
|
||||
const keyHandler = vi.fn();
|
||||
|
||||
const { result } = renderHook(() => useKeypressContext(), {
|
||||
wrapper,
|
||||
wrapper: ({ children }) => wrapper({ children, pasteWorkaround: true }),
|
||||
});
|
||||
|
||||
act(() => {
|
||||
@@ -987,7 +994,7 @@ describe('KeypressContext - Kitty Protocol', () => {
|
||||
const keyHandler = vi.fn();
|
||||
|
||||
const { result } = renderHook(() => useKeypressContext(), {
|
||||
wrapper,
|
||||
wrapper: ({ children }) => wrapper({ children, pasteWorkaround: true }),
|
||||
});
|
||||
|
||||
act(() => {
|
||||
@@ -1036,7 +1043,7 @@ describe('KeypressContext - Kitty Protocol', () => {
|
||||
const keyHandler = vi.fn();
|
||||
|
||||
const { result } = renderHook(() => useKeypressContext(), {
|
||||
wrapper,
|
||||
wrapper: ({ children }) => wrapper({ children, pasteWorkaround: true }),
|
||||
});
|
||||
|
||||
act(() => {
|
||||
|
||||
@@ -69,10 +69,12 @@ export function useKeypressContext() {
|
||||
export function KeypressProvider({
|
||||
children,
|
||||
kittyProtocolEnabled,
|
||||
pasteWorkaround = false,
|
||||
config,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
children?: React.ReactNode;
|
||||
kittyProtocolEnabled: boolean;
|
||||
pasteWorkaround?: boolean;
|
||||
config?: Config;
|
||||
}) {
|
||||
const { stdin, setRawMode } = useStdin();
|
||||
@@ -97,18 +99,8 @@ export function KeypressProvider({
|
||||
|
||||
const keypressStream = new PassThrough();
|
||||
let usePassthrough = false;
|
||||
const nodeMajorVersion = parseInt(process.versions.node.split('.')[0], 10);
|
||||
const isWindows = process.platform === 'win32';
|
||||
// On Windows, Node's readline keypress stream often loses bracketed paste
|
||||
// boundaries, causing multi-line pastes to be delivered as plain Return
|
||||
// key events. This leads to accidental submits on Enter within pasted text.
|
||||
// Force passthrough on Windows to parse raw bytes and detect ESC[200~...201~.
|
||||
if (
|
||||
nodeMajorVersion < 20 ||
|
||||
isWindows ||
|
||||
process.env['PASTE_WORKAROUND'] === '1' ||
|
||||
process.env['PASTE_WORKAROUND'] === 'true'
|
||||
) {
|
||||
// Use passthrough mode when pasteWorkaround is enabled,
|
||||
if (pasteWorkaround) {
|
||||
usePassthrough = true;
|
||||
}
|
||||
|
||||
@@ -500,7 +492,14 @@ export function KeypressProvider({
|
||||
pasteBuffer = Buffer.alloc(0);
|
||||
}
|
||||
};
|
||||
}, [stdin, setRawMode, kittyProtocolEnabled, config, subscribers]);
|
||||
}, [
|
||||
stdin,
|
||||
setRawMode,
|
||||
kittyProtocolEnabled,
|
||||
pasteWorkaround,
|
||||
config,
|
||||
subscribers,
|
||||
]);
|
||||
|
||||
return (
|
||||
<KeypressContext.Provider value={{ subscribe, unsubscribe }}>
|
||||
|
||||
@@ -105,7 +105,28 @@ describe('useKeypress', () => {
|
||||
let originalNodeVersion: string;
|
||||
|
||||
const wrapper = ({ children }: { children: React.ReactNode }) =>
|
||||
React.createElement(KeypressProvider, null, children);
|
||||
React.createElement(
|
||||
KeypressProvider,
|
||||
{
|
||||
kittyProtocolEnabled: false,
|
||||
pasteWoraround: false,
|
||||
},
|
||||
children,
|
||||
);
|
||||
|
||||
const wrapperWithWindowsWorkaround = ({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}) =>
|
||||
React.createElement(
|
||||
KeypressProvider,
|
||||
{
|
||||
kittyProtocolEnabled: false,
|
||||
pasteWoraround: true,
|
||||
},
|
||||
children,
|
||||
);
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
@@ -187,21 +208,17 @@ describe('useKeypress', () => {
|
||||
description: 'Modern Node (>= v20)',
|
||||
setup: () => setNodeVersion('20.0.0'),
|
||||
isLegacy: false,
|
||||
pasteWoraround: false,
|
||||
},
|
||||
{
|
||||
description: 'Legacy Node (< v20)',
|
||||
setup: () => setNodeVersion('18.0.0'),
|
||||
isLegacy: true,
|
||||
},
|
||||
{
|
||||
description: 'Workaround Env Var',
|
||||
description: 'PasteWorkaround Environment Variable',
|
||||
setup: () => {
|
||||
setNodeVersion('20.0.0');
|
||||
vi.stubEnv('PASTE_WORKAROUND', 'true');
|
||||
},
|
||||
isLegacy: true,
|
||||
isLegacy: false,
|
||||
pasteWoraround: true,
|
||||
},
|
||||
])('in $description', ({ setup, isLegacy }) => {
|
||||
])('in $description', ({ setup, isLegacy, pasteWoraround }) => {
|
||||
beforeEach(() => {
|
||||
setup();
|
||||
stdin.setLegacy(isLegacy);
|
||||
@@ -209,7 +226,7 @@ describe('useKeypress', () => {
|
||||
|
||||
it('should process a paste as a single event', async () => {
|
||||
renderHook(() => useKeypress(onKeypress, { isActive: true }), {
|
||||
wrapper,
|
||||
wrapper: pasteWoraround ? wrapperWithWindowsWorkaround : wrapper,
|
||||
});
|
||||
const pasteText = 'hello world';
|
||||
act(() => stdin.paste(pasteText));
|
||||
@@ -230,7 +247,7 @@ describe('useKeypress', () => {
|
||||
|
||||
it('should handle keypress interspersed with pastes', async () => {
|
||||
renderHook(() => useKeypress(onKeypress, { isActive: true }), {
|
||||
wrapper,
|
||||
wrapper: pasteWoraround ? wrapperWithWindowsWorkaround : wrapper,
|
||||
});
|
||||
|
||||
const keyA = { name: 'a', sequence: 'a' };
|
||||
@@ -266,7 +283,9 @@ describe('useKeypress', () => {
|
||||
it('should emit partial paste content if unmounted mid-paste', async () => {
|
||||
const { unmount } = renderHook(
|
||||
() => useKeypress(onKeypress, { isActive: true }),
|
||||
{ wrapper },
|
||||
{
|
||||
wrapper: pasteWoraround ? wrapperWithWindowsWorkaround : wrapper,
|
||||
},
|
||||
);
|
||||
const pasteText = 'incomplete paste';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user