mirror of
https://github.com/QwenLM/qwen-code.git
synced 2025-12-19 09:33:53 +00:00
test: sync test files with code changes for IDE detection
- Update detect-ide.test.ts to remove ideProcessInfo parameter (now optional) - Update process-utils.test.ts to match simplified Windows process detection logic - Remove tests for removed IDE detection strategies (Strategy 1-4) - All tests now passing (13 tests in detect-ide.test.ts, 6 tests in process-utils.test.ts)
This commit is contained in:
@@ -8,9 +8,6 @@ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
||||
import { detectIde, IDE_DEFINITIONS } from './detect-ide.js';
|
||||
|
||||
describe('detectIde', () => {
|
||||
const ideProcessInfo = { pid: 123, command: 'some/path/to/code' };
|
||||
const ideProcessInfoNoCode = { pid: 123, command: 'some/path/to/fork' };
|
||||
|
||||
// Clear all IDE-related environment variables before each test
|
||||
beforeEach(() => {
|
||||
vi.stubEnv('__COG_BASHRC_SOURCED', '');
|
||||
@@ -29,73 +26,65 @@ describe('detectIde', () => {
|
||||
|
||||
it('should return undefined if TERM_PROGRAM is not vscode', () => {
|
||||
vi.stubEnv('TERM_PROGRAM', '');
|
||||
expect(detectIde(ideProcessInfo)).toBeUndefined();
|
||||
expect(detectIde()).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should detect Devin', () => {
|
||||
vi.stubEnv('TERM_PROGRAM', 'vscode');
|
||||
vi.stubEnv('__COG_BASHRC_SOURCED', '1');
|
||||
expect(detectIde(ideProcessInfo)).toBe(IDE_DEFINITIONS.devin);
|
||||
expect(detectIde()).toBe(IDE_DEFINITIONS.devin);
|
||||
});
|
||||
|
||||
it('should detect Replit', () => {
|
||||
vi.stubEnv('TERM_PROGRAM', 'vscode');
|
||||
vi.stubEnv('REPLIT_USER', 'testuser');
|
||||
expect(detectIde(ideProcessInfo)).toBe(IDE_DEFINITIONS.replit);
|
||||
expect(detectIde()).toBe(IDE_DEFINITIONS.replit);
|
||||
});
|
||||
|
||||
it('should detect Cursor', () => {
|
||||
vi.stubEnv('TERM_PROGRAM', 'vscode');
|
||||
vi.stubEnv('CURSOR_TRACE_ID', 'some-id');
|
||||
expect(detectIde(ideProcessInfo)).toBe(IDE_DEFINITIONS.cursor);
|
||||
expect(detectIde()).toBe(IDE_DEFINITIONS.cursor);
|
||||
});
|
||||
|
||||
it('should detect Codespaces', () => {
|
||||
vi.stubEnv('TERM_PROGRAM', 'vscode');
|
||||
vi.stubEnv('CODESPACES', 'true');
|
||||
expect(detectIde(ideProcessInfo)).toBe(IDE_DEFINITIONS.codespaces);
|
||||
expect(detectIde()).toBe(IDE_DEFINITIONS.codespaces);
|
||||
});
|
||||
|
||||
it('should detect Cloud Shell via EDITOR_IN_CLOUD_SHELL', () => {
|
||||
vi.stubEnv('TERM_PROGRAM', 'vscode');
|
||||
vi.stubEnv('EDITOR_IN_CLOUD_SHELL', 'true');
|
||||
expect(detectIde(ideProcessInfo)).toBe(IDE_DEFINITIONS.cloudshell);
|
||||
expect(detectIde()).toBe(IDE_DEFINITIONS.cloudshell);
|
||||
});
|
||||
|
||||
it('should detect Cloud Shell via CLOUD_SHELL', () => {
|
||||
vi.stubEnv('TERM_PROGRAM', 'vscode');
|
||||
vi.stubEnv('CLOUD_SHELL', 'true');
|
||||
expect(detectIde(ideProcessInfo)).toBe(IDE_DEFINITIONS.cloudshell);
|
||||
expect(detectIde()).toBe(IDE_DEFINITIONS.cloudshell);
|
||||
});
|
||||
|
||||
it('should detect Trae', () => {
|
||||
vi.stubEnv('TERM_PROGRAM', 'vscode');
|
||||
vi.stubEnv('TERM_PRODUCT', 'Trae');
|
||||
expect(detectIde(ideProcessInfo)).toBe(IDE_DEFINITIONS.trae);
|
||||
expect(detectIde()).toBe(IDE_DEFINITIONS.trae);
|
||||
});
|
||||
|
||||
it('should detect Firebase Studio via MONOSPACE_ENV', () => {
|
||||
vi.stubEnv('TERM_PROGRAM', 'vscode');
|
||||
vi.stubEnv('MONOSPACE_ENV', 'true');
|
||||
expect(detectIde(ideProcessInfo)).toBe(IDE_DEFINITIONS.firebasestudio);
|
||||
expect(detectIde()).toBe(IDE_DEFINITIONS.firebasestudio);
|
||||
});
|
||||
|
||||
it('should detect VSCode when no other IDE is detected and command includes "code"', () => {
|
||||
it('should detect VSCodeFork when no other IDE is detected and no process info provided', () => {
|
||||
vi.stubEnv('TERM_PROGRAM', 'vscode');
|
||||
vi.stubEnv('MONOSPACE_ENV', '');
|
||||
expect(detectIde(ideProcessInfo)).toBe(IDE_DEFINITIONS.vscode);
|
||||
});
|
||||
|
||||
it('should detect VSCodeFork when no other IDE is detected and command does not include "code"', () => {
|
||||
vi.stubEnv('TERM_PROGRAM', 'vscode');
|
||||
vi.stubEnv('MONOSPACE_ENV', '');
|
||||
expect(detectIde(ideProcessInfoNoCode)).toBe(IDE_DEFINITIONS.vscodefork);
|
||||
expect(detectIde()).toBe(IDE_DEFINITIONS.vscodefork);
|
||||
});
|
||||
});
|
||||
|
||||
describe('detectIde with ideInfoFromFile', () => {
|
||||
const ideProcessInfo = { pid: 123, command: 'some/path/to/code' };
|
||||
|
||||
beforeEach(() => {
|
||||
vi.stubEnv('__COG_BASHRC_SOURCED', '');
|
||||
vi.stubEnv('REPLIT_USER', '');
|
||||
@@ -116,22 +105,22 @@ describe('detectIde with ideInfoFromFile', () => {
|
||||
name: 'custom-ide',
|
||||
displayName: 'Custom IDE',
|
||||
};
|
||||
expect(detectIde(ideProcessInfo, ideInfoFromFile)).toEqual(ideInfoFromFile);
|
||||
expect(detectIde(undefined, ideInfoFromFile)).toEqual(ideInfoFromFile);
|
||||
});
|
||||
|
||||
it('should fall back to env detection if name is missing', () => {
|
||||
const ideInfoFromFile = { displayName: 'Custom IDE' };
|
||||
vi.stubEnv('TERM_PROGRAM', 'vscode');
|
||||
expect(detectIde(ideProcessInfo, ideInfoFromFile)).toBe(
|
||||
IDE_DEFINITIONS.vscode,
|
||||
expect(detectIde(undefined, ideInfoFromFile)).toBe(
|
||||
IDE_DEFINITIONS.vscodefork,
|
||||
);
|
||||
});
|
||||
|
||||
it('should fall back to env detection if displayName is missing', () => {
|
||||
const ideInfoFromFile = { name: 'custom-ide' };
|
||||
vi.stubEnv('TERM_PROGRAM', 'vscode');
|
||||
expect(detectIde(ideProcessInfo, ideInfoFromFile)).toBe(
|
||||
IDE_DEFINITIONS.vscode,
|
||||
expect(detectIde(undefined, ideInfoFromFile)).toBe(
|
||||
IDE_DEFINITIONS.vscodefork,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -63,7 +63,7 @@ describe('getIdeProcessInfo', () => {
|
||||
});
|
||||
|
||||
describe('on Windows', () => {
|
||||
it('should find known IDE process in the chain', async () => {
|
||||
it('should return great-grandparent process using heuristic', async () => {
|
||||
(os.platform as Mock).mockReturnValue('win32');
|
||||
|
||||
const processes = [
|
||||
@@ -101,88 +101,10 @@ describe('getIdeProcessInfo', () => {
|
||||
});
|
||||
|
||||
const result = await getIdeProcessInfo();
|
||||
// Strategy 1: Should find code.exe (known IDE process) in the chain
|
||||
// Process chain: 1000 (node.exe) -> 900 (powershell.exe) -> 800 (code.exe) -> 700 (wininit.exe)
|
||||
// The function should identify code.exe as the IDE process
|
||||
expect(result).toEqual({ pid: 800, command: 'code.exe' });
|
||||
});
|
||||
|
||||
it('should find shell parent when shell exists in chain', async () => {
|
||||
(os.platform as Mock).mockReturnValue('win32');
|
||||
|
||||
const processes = [
|
||||
{
|
||||
ProcessId: 1000,
|
||||
ParentProcessId: 900,
|
||||
Name: 'node.exe',
|
||||
CommandLine: 'node.exe',
|
||||
},
|
||||
{
|
||||
ProcessId: 900,
|
||||
ParentProcessId: 800,
|
||||
Name: 'cmd.exe',
|
||||
CommandLine: 'cmd.exe',
|
||||
},
|
||||
{
|
||||
ProcessId: 800,
|
||||
ParentProcessId: 700,
|
||||
Name: 'explorer.exe',
|
||||
CommandLine: 'explorer.exe',
|
||||
},
|
||||
{
|
||||
ProcessId: 700,
|
||||
ParentProcessId: 0,
|
||||
Name: 'wininit.exe',
|
||||
CommandLine: 'wininit.exe',
|
||||
},
|
||||
];
|
||||
|
||||
mockedExec.mockImplementation((file: string, _args: string[]) => {
|
||||
if (file === 'powershell') {
|
||||
return Promise.resolve({ stdout: JSON.stringify(processes) });
|
||||
}
|
||||
return Promise.resolve({ stdout: '' });
|
||||
});
|
||||
|
||||
const result = await getIdeProcessInfo();
|
||||
// Strategy 3: Should find cmd.exe and return its parent (explorer.exe)
|
||||
expect(result).toEqual({ pid: 800, command: 'explorer.exe' });
|
||||
});
|
||||
|
||||
it('should handle Git Bash with missing parent by finding IDE in process table', async () => {
|
||||
(os.platform as Mock).mockReturnValue('win32');
|
||||
|
||||
const processes = [
|
||||
{
|
||||
ProcessId: 1000,
|
||||
ParentProcessId: 900,
|
||||
Name: 'node.exe',
|
||||
CommandLine: 'node.exe',
|
||||
},
|
||||
{
|
||||
ProcessId: 900,
|
||||
ParentProcessId: 12345, // Parent doesn't exist in process table
|
||||
Name: 'bash.exe',
|
||||
CommandLine: 'bash.exe',
|
||||
},
|
||||
{
|
||||
ProcessId: 800,
|
||||
ParentProcessId: 0,
|
||||
Name: 'code.exe',
|
||||
CommandLine: 'code.exe',
|
||||
},
|
||||
];
|
||||
|
||||
mockedExec.mockImplementation((file: string, _args: string[]) => {
|
||||
if (file === 'powershell') {
|
||||
return Promise.resolve({ stdout: JSON.stringify(processes) });
|
||||
}
|
||||
return Promise.resolve({ stdout: '' });
|
||||
});
|
||||
|
||||
const result = await getIdeProcessInfo();
|
||||
// Strategy 2: Git Bash with missing parent should find code.exe in process table
|
||||
expect(result).toEqual({ pid: 800, command: 'code.exe' });
|
||||
// ancestors = [1000, 900, 800, 700], length = 4
|
||||
// Heuristic: return ancestors[length-3] = ancestors[1] = 900 (powershell.exe)
|
||||
expect(result).toEqual({ pid: 900, command: 'powershell.exe' });
|
||||
});
|
||||
|
||||
it('should handle empty process list gracefully', async () => {
|
||||
@@ -201,5 +123,36 @@ describe('getIdeProcessInfo', () => {
|
||||
const result = await getIdeProcessInfo();
|
||||
expect(result).toEqual({ pid: 1000, command: '' });
|
||||
});
|
||||
|
||||
it('should return last ancestor if chain is too short', async () => {
|
||||
(os.platform as Mock).mockReturnValue('win32');
|
||||
|
||||
const processes = [
|
||||
{
|
||||
ProcessId: 1000,
|
||||
ParentProcessId: 900,
|
||||
Name: 'node.exe',
|
||||
CommandLine: 'node.exe',
|
||||
},
|
||||
{
|
||||
ProcessId: 900,
|
||||
ParentProcessId: 0,
|
||||
Name: 'explorer.exe',
|
||||
CommandLine: 'explorer.exe',
|
||||
},
|
||||
];
|
||||
|
||||
mockedExec.mockImplementation((file: string, _args: string[]) => {
|
||||
if (file === 'powershell') {
|
||||
return Promise.resolve({ stdout: JSON.stringify(processes) });
|
||||
}
|
||||
return Promise.resolve({ stdout: '' });
|
||||
});
|
||||
|
||||
const result = await getIdeProcessInfo();
|
||||
// ancestors = [1000, 900], length = 2 (< 3)
|
||||
// Heuristic: return ancestors[length-1] = ancestors[1] = 900 (explorer.exe)
|
||||
expect(result).toEqual({ pid: 900, command: 'explorer.exe' });
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user