mirror of
https://github.com/QwenLM/qwen-code.git
synced 2025-12-20 16:57:46 +00:00
refactor(ide): Improve IDE detection discovery (#6765)
This commit is contained in:
90
packages/core/src/ide/process-utils.test.ts
Normal file
90
packages/core/src/ide/process-utils.test.ts
Normal file
@@ -0,0 +1,90 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2025 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import {
|
||||
describe,
|
||||
it,
|
||||
expect,
|
||||
vi,
|
||||
afterEach,
|
||||
beforeEach,
|
||||
type Mock,
|
||||
} from 'vitest';
|
||||
import { getIdeProcessInfo } from './process-utils.js';
|
||||
import os from 'node:os';
|
||||
|
||||
const mockedExec = vi.hoisted(() => vi.fn());
|
||||
vi.mock('node:util', () => ({
|
||||
promisify: vi.fn().mockReturnValue(mockedExec),
|
||||
}));
|
||||
vi.mock('node:os', () => ({
|
||||
default: {
|
||||
platform: vi.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
describe('getIdeProcessInfo', () => {
|
||||
beforeEach(() => {
|
||||
Object.defineProperty(process, 'pid', { value: 1000, configurable: true });
|
||||
mockedExec.mockReset();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
describe('on Unix', () => {
|
||||
it('should traverse up to find the shell and return grandparent process info', async () => {
|
||||
(os.platform as Mock).mockReturnValue('linux');
|
||||
// process (1000) -> shell (800) -> IDE (700)
|
||||
mockedExec
|
||||
.mockResolvedValueOnce({ stdout: '800 /bin/bash' }) // pid 1000 -> ppid 800 (shell)
|
||||
.mockResolvedValueOnce({ stdout: '700 /usr/lib/vscode/code' }) // pid 800 -> ppid 700 (IDE)
|
||||
.mockResolvedValueOnce({ stdout: '700 /usr/lib/vscode/code' }); // get command for pid 700
|
||||
|
||||
const result = await getIdeProcessInfo();
|
||||
|
||||
expect(result).toEqual({ pid: 700, command: '/usr/lib/vscode/code' });
|
||||
});
|
||||
|
||||
it('should return parent process info if grandparent lookup fails', async () => {
|
||||
(os.platform as Mock).mockReturnValue('linux');
|
||||
mockedExec
|
||||
.mockResolvedValueOnce({ stdout: '800 /bin/bash' }) // pid 1000 -> ppid 800 (shell)
|
||||
.mockRejectedValueOnce(new Error('ps failed')) // lookup for ppid of 800 fails
|
||||
.mockResolvedValueOnce({ stdout: '800 /bin/bash' }); // get command for pid 800
|
||||
|
||||
const result = await getIdeProcessInfo();
|
||||
expect(result).toEqual({ pid: 800, command: '/bin/bash' });
|
||||
});
|
||||
});
|
||||
|
||||
describe('on Windows', () => {
|
||||
it('should traverse up and find the great-grandchild of the root process', async () => {
|
||||
(os.platform as Mock).mockReturnValue('win32');
|
||||
const processInfoMap = new Map([
|
||||
[1000, { stdout: 'ParentProcessId=900\r\nCommandLine=node.exe\r\n' }],
|
||||
[
|
||||
900,
|
||||
{ stdout: 'ParentProcessId=800\r\nCommandLine=powershell.exe\r\n' },
|
||||
],
|
||||
[800, { stdout: 'ParentProcessId=700\r\nCommandLine=code.exe\r\n' }],
|
||||
[700, { stdout: 'ParentProcessId=0\r\nCommandLine=wininit.exe\r\n' }],
|
||||
]);
|
||||
mockedExec.mockImplementation((command: string) => {
|
||||
const pidMatch = command.match(/ProcessId=(\d+)/);
|
||||
if (pidMatch) {
|
||||
const pid = parseInt(pidMatch[1], 10);
|
||||
return Promise.resolve(processInfoMap.get(pid));
|
||||
}
|
||||
return Promise.reject(new Error('Invalid command for mock'));
|
||||
});
|
||||
|
||||
const result = await getIdeProcessInfo();
|
||||
expect(result).toEqual({ pid: 900, command: 'powershell.exe' });
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user