Introduce GEMINI_CLI_HOME for strict test isolation (#15907)

This commit is contained in:
N. Taylor Mullen
2026-01-06 20:09:39 -08:00
committed by GitHub
parent a26463b056
commit 7956eb239e
54 changed files with 455 additions and 148 deletions

View File

@@ -48,6 +48,7 @@ vi.mock('node:path', async () => {
vi.mock('@google/gemini-cli-core', () => ({
GEMINI_DIR: '.gemini',
homedir: () => '/mock/home',
Storage: {
getGlobalTempDir: () => '/mock/temp',
},

View File

@@ -12,13 +12,17 @@ import { theme } from '../semantic-colors.js';
import { StreamingState } from '../types.js';
import { UpdateNotification } from './UpdateNotification.js';
import { GEMINI_DIR, Storage, debugLogger } from '@google/gemini-cli-core';
import {
GEMINI_DIR,
Storage,
debugLogger,
homedir,
} from '@google/gemini-cli-core';
import * as fs from 'node:fs/promises';
import os from 'node:os';
import path from 'node:path';
const settingsPath = path.join(os.homedir(), GEMINI_DIR, 'settings.json');
const settingsPath = path.join(homedir(), GEMINI_DIR, 'settings.json');
const screenReaderNudgeFilePath = path.join(
Storage.getGlobalTempDir(),

View File

@@ -74,6 +74,7 @@ vi.mock('node:process', () => {
exit: mockProcessExit,
platform: 'sunos',
cwd: () => '/fake/dir',
env: {},
} as unknown as NodeJS.Process;
return {
...mockProcess,

View File

@@ -30,6 +30,15 @@ vi.mock('os', async (importOriginal) => {
};
});
vi.mock('@google/gemini-cli-core', async (importOriginal) => {
const actual =
await importOriginal<typeof import('@google/gemini-cli-core')>();
return {
...actual,
homedir: () => os.homedir(),
};
});
vi.mock('../../config/extensions/update.js', () => ({
checkForAllExtensionUpdates: vi.fn(),
updateExtension: vi.fn(),

View File

@@ -28,9 +28,16 @@ const mockedIsWorkspaceTrusted = vi.hoisted(() => vi.fn());
const mockedUseSettings = vi.hoisted(() => vi.fn());
// Mock modules
vi.mock('node:process', () => ({
cwd: mockedCwd,
}));
vi.mock('node:process', () => {
const mockProcess = {
cwd: mockedCwd,
env: {},
};
return {
...mockProcess,
default: mockProcess,
};
});
vi.mock('node:path', async (importOriginal) => {
const actual = await importOriginal();

View File

@@ -27,6 +27,15 @@ vi.mock('node:os', async (importOriginal) => {
};
});
vi.mock('@google/gemini-cli-core', async (importOriginal) => {
const actual =
await importOriginal<typeof import('@google/gemini-cli-core')>();
return {
...actual,
homedir: () => os.homedir(),
};
});
const validCustomTheme: CustomTheme = {
type: 'custom',
name: 'MyCustomTheme',

View File

@@ -18,7 +18,6 @@ import { ShadesOfPurple } from './shades-of-purple.js';
import { XCode } from './xcode.js';
import * as fs from 'node:fs';
import * as path from 'node:path';
import * as os from 'node:os';
import type { Theme, ThemeType, CustomTheme } from './theme.js';
import { createCustomTheme, validateCustomTheme } from './theme.js';
import type { SemanticColors } from './semantic-tokens.js';
@@ -26,7 +25,7 @@ import { ANSI } from './ansi.js';
import { ANSILight } from './ansi-light.js';
import { NoColorTheme } from './no-color.js';
import process from 'node:process';
import { debugLogger } from '@google/gemini-cli-core';
import { debugLogger, homedir } from '@google/gemini-cli-core';
export interface ThemeDisplay {
name: string;
@@ -255,7 +254,7 @@ class ThemeManager {
}
// 2. Perform security check.
const homeDir = path.resolve(os.homedir());
const homeDir = path.resolve(homedir());
if (!canonicalPath.startsWith(homeDir)) {
debugLogger.warn(
`Theme file at "${themePath}" is outside your home directory. ` +

View File

@@ -16,6 +16,7 @@ vi.mock('@google/gemini-cli-core', async (importOriginal) => {
await importOriginal<typeof import('@google/gemini-cli-core')>();
return {
...original,
homedir: () => mockHomeDir,
loadServerHierarchicalMemory: vi.fn().mockResolvedValue({
memoryContent: 'mock memory',
fileCount: 10,

View File

@@ -4,10 +4,10 @@
* SPDX-License-Identifier: Apache-2.0
*/
import * as os from 'node:os';
import * as path from 'node:path';
import * as fs from 'node:fs';
import { opendir } from 'node:fs/promises';
import { homedir } from '@google/gemini-cli-core';
const MAX_SUGGESTIONS = 50;
const MATCH_BUFFER_MULTIPLIER = 3;
@@ -18,9 +18,9 @@ export function expandHomeDir(p: string): string {
}
let expandedPath = p;
if (p.toLowerCase().startsWith('%userprofile%')) {
expandedPath = os.homedir() + p.substring('%userprofile%'.length);
expandedPath = homedir() + p.substring('%userprofile%'.length);
} else if (p === '~' || p.startsWith('~/')) {
expandedPath = os.homedir() + p.substring(1);
expandedPath = homedir() + p.substring(1);
}
return path.normalize(expandedPath);
}
@@ -56,7 +56,7 @@ function parsePartialPath(partialPath: string): ParsedPath {
!partialPath.includes('/') &&
!partialPath.includes(path.sep)
) {
searchDir = os.homedir();
searchDir = homedir();
filter = partialPath.substring(1);
}
}

View File

@@ -42,6 +42,15 @@ vi.mock('node:os', () => ({
platform: mocks.platform,
}));
vi.mock('@google/gemini-cli-core', async (importOriginal) => {
const actual =
await importOriginal<typeof import('@google/gemini-cli-core')>();
return {
...actual,
homedir: mocks.homedir,
};
});
vi.mock('./terminalCapabilityManager.js', () => ({
terminalCapabilityManager: {
isKittyProtocolEnabled: vi.fn().mockReturnValue(false),

View File

@@ -30,7 +30,7 @@ import { exec } from 'node:child_process';
import { promisify } from 'node:util';
import { terminalCapabilityManager } from './terminalCapabilityManager.js';
import { debugLogger } from '@google/gemini-cli-core';
import { debugLogger, homedir } from '@google/gemini-cli-core';
export const VSCODE_SHIFT_ENTER_SEQUENCE = '\\\r\n';
@@ -124,7 +124,7 @@ function getVSCodeStyleConfigDir(appName: string): string | null {
if (platform === 'darwin') {
return path.join(
os.homedir(),
homedir(),
'Library',
'Application Support',
appName,
@@ -136,7 +136,7 @@ function getVSCodeStyleConfigDir(appName: string): string | null {
}
return path.join(process.env['APPDATA'], appName, 'User');
} else {
return path.join(os.homedir(), '.config', appName, 'User');
return path.join(homedir(), '.config', appName, 'User');
}
}