From 800353b609e7c04051ff2ac4bd57ec3f0f5ec2d6 Mon Sep 17 00:00:00 2001 From: Taylor Mullen Date: Mon, 14 Jul 2025 00:33:17 -0700 Subject: [PATCH] WIP Test fixes --- packages/cli/src/config/config.test.ts | 9 ++++++ .../cli/src/ui/hooks/slashCommandProcessor.ts | 7 ++-- packages/cli/src/ui/hooks/useGeminiStream.ts | 22 +++++++++++-- .../cli/src/ui/hooks/useShellHistory.test.ts | 5 +-- packages/core/src/code_assist/oauth2.test.ts | 32 +++++++++++-------- packages/core/src/config/storage.ts | 7 +++- packages/core/src/utils/editCorrector.test.ts | 1 + 7 files changed, 60 insertions(+), 23 deletions(-) diff --git a/packages/cli/src/config/config.test.ts b/packages/cli/src/config/config.test.ts index 08a85e4de4..4507719f49 100644 --- a/packages/cli/src/config/config.test.ts +++ b/packages/cli/src/config/config.test.ts @@ -11,6 +11,15 @@ import { Settings } from './settings.js'; import { Extension } from './extension.js'; import * as ServerConfig from '@google/gemini-cli-core'; +vi.mock('fs', async (importOriginal) => { + const actualFs = await importOriginal(); + return { + ...actualFs, + mkdirSync: vi.fn(), + writeFileSync: vi.fn(), + }; +}); + vi.mock('os', async (importOriginal) => { const actualOs = await importOriginal(); return { diff --git a/packages/cli/src/ui/hooks/slashCommandProcessor.ts b/packages/cli/src/ui/hooks/slashCommandProcessor.ts index cf83c2347c..caa7013708 100644 --- a/packages/cli/src/ui/hooks/slashCommandProcessor.ts +++ b/packages/cli/src/ui/hooks/slashCommandProcessor.ts @@ -221,7 +221,7 @@ export const useSlashCommandProcessor = ( } catch (_err) { return []; } - }, [config]); + }, [storage]); // Define legacy commands // This list contains all commands that have NOT YET been migrated to the @@ -934,8 +934,8 @@ export const useSlashCommandProcessor = ( } }, action: async (_mainCommand, subCommand, _args) => { - const checkpointDir = config?.getProjectTempDir() - ? path.join(config.getProjectTempDir(), 'checkpoints') + const checkpointDir = storage?.getProjectTempDir() + ? path.join(storage.getProjectTempDir(), 'checkpoints') : undefined; if (!checkpointDir) { @@ -1052,6 +1052,7 @@ export const useSlashCommandProcessor = ( setPendingCompressionItem, clearItems, refreshStatic, + storage, ]); const handleSlashCommand = useCallback( diff --git a/packages/cli/src/ui/hooks/useGeminiStream.ts b/packages/cli/src/ui/hooks/useGeminiStream.ts index 21d57b3bbd..e488257caa 100644 --- a/packages/cli/src/ui/hooks/useGeminiStream.ts +++ b/packages/cli/src/ui/hooks/useGeminiStream.ts @@ -25,6 +25,7 @@ import { UnauthorizedError, UserPromptEvent, DEFAULT_GEMINI_FLASH_MODEL, + Storage, } from '@google/gemini-cli-core'; import { type Part, type PartListUnion } from '@google/genai'; import { @@ -111,6 +112,13 @@ export const useGeminiStream = ( return new GitService(config.getProjectRoot()); }, [config]); + const storage = useMemo(() => { + if (!config.getProjectRoot()) { + return; + } + return new Storage(config.getProjectRoot()); + }, [config]); + const [toolCalls, scheduleToolCalls, markToolsAsSubmitted] = useReactToolScheduler( async (completedToolCallsFromScheduler) => { @@ -769,8 +777,8 @@ export const useGeminiStream = ( ); if (restorableToolCalls.length > 0) { - const checkpointDir = config.getProjectTempDir() - ? path.join(config.getProjectTempDir(), 'checkpoints') + const checkpointDir = storage?.getProjectTempDir() + ? path.join(storage.getProjectTempDir(), 'checkpoints') : undefined; if (!checkpointDir) { @@ -854,7 +862,15 @@ export const useGeminiStream = ( } }; saveRestorableToolCalls(); - }, [toolCalls, config, onDebugMessage, gitService, history, geminiClient]); + }, [ + toolCalls, + config, + onDebugMessage, + gitService, + history, + geminiClient, + storage, + ]); return { streamingState, diff --git a/packages/cli/src/ui/hooks/useShellHistory.test.ts b/packages/cli/src/ui/hooks/useShellHistory.test.ts index 8d03049738..365a4f3cdc 100644 --- a/packages/cli/src/ui/hooks/useShellHistory.test.ts +++ b/packages/cli/src/ui/hooks/useShellHistory.test.ts @@ -4,15 +4,16 @@ * SPDX-License-Identifier: Apache-2.0 */ +import * as os from 'os'; +vi.mock('os'); + import { renderHook, act, waitFor } from '@testing-library/react'; import { useShellHistory } from './useShellHistory.js'; import * as fs from 'fs/promises'; import * as path from 'path'; -import * as os from 'os'; import * as crypto from 'crypto'; vi.mock('fs/promises'); -vi.mock('os'); vi.mock('crypto'); const MOCKED_PROJECT_ROOT = '/test/project'; diff --git a/packages/core/src/code_assist/oauth2.test.ts b/packages/core/src/code_assist/oauth2.test.ts index 4a1e5a20d6..12061b95f9 100644 --- a/packages/core/src/code_assist/oauth2.test.ts +++ b/packages/core/src/code_assist/oauth2.test.ts @@ -4,20 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { describe, it, expect, vi, beforeEach, afterEach, Mock } from 'vitest'; -import { getOauthClient } from './oauth2.js'; -import { UserAccountManager } from '../utils/userAccountManager.js'; -import { OAuth2Client, Compute } from 'google-auth-library'; -import * as fs from 'fs'; -import * as path from 'path'; -import http from 'http'; -import open from 'open'; -import crypto from 'crypto'; import * as os from 'os'; -import { AuthType } from '../core/contentGenerator.js'; -import { Config } from '../config/config.js'; -import readline from 'node:readline'; - vi.mock('os', async (importOriginal) => { const os = await importOriginal(); return { @@ -26,6 +13,20 @@ vi.mock('os', async (importOriginal) => { }; }); +import { describe, it, expect, vi, beforeEach, afterEach, Mock } from 'vitest'; +import { getOauthClient } from './oauth2.js'; +import { UserAccountManager } from '../utils/userAccountManager.js'; +import { Storage } from '../config/storage.js'; +import { OAuth2Client, Compute } from 'google-auth-library'; +import * as fs from 'fs'; +import * as path from 'path'; +import http from 'http'; +import open from 'open'; +import crypto from 'crypto'; +import { AuthType } from '../core/contentGenerator.js'; +import { Config } from '../config/config.js'; +import readline from 'node:readline'; + vi.mock('google-auth-library'); vi.mock('http'); vi.mock('open'); @@ -170,7 +171,10 @@ describe('oauth2', () => { }); // Verify the getCachedGoogleAccount function works - expect(getCachedGoogleAccount()).toBe('test-google-account@gmail.com'); + const userAccountManager = new UserAccountManager(new Storage(tempHomeDir)); + expect(userAccountManager.getCachedGoogleAccount()).toBe( + 'test-google-account@gmail.com', + ); }); it('should perform login with user code', async () => { diff --git a/packages/core/src/config/storage.ts b/packages/core/src/config/storage.ts index f84b22f9a4..201651e75a 100644 --- a/packages/core/src/config/storage.ts +++ b/packages/core/src/config/storage.ts @@ -28,7 +28,12 @@ export class Storage { } getGlobalGeminiDir(): string { - const geminiDir = path.join(os.homedir(), GEMINI_DIR); + const homeDir = os.homedir(); + if (!homeDir) { + // This is a fallback for testing environments where homedir is not defined. + return path.join(os.tmpdir(), '.gemini'); + } + const geminiDir = path.join(homeDir, GEMINI_DIR); return geminiDir; } diff --git a/packages/core/src/utils/editCorrector.test.ts b/packages/core/src/utils/editCorrector.test.ts index cf9008ef81..5df768051c 100644 --- a/packages/core/src/utils/editCorrector.test.ts +++ b/packages/core/src/utils/editCorrector.test.ts @@ -27,6 +27,7 @@ let mockSendMessageStream: any; vi.mock('fs', () => ({ statSync: vi.fn(), + mkdirSync: vi.fn(), })); vi.mock('../core/client.js', () => ({