|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; |
|
|
import * as os from 'os'; |
|
|
import { loadCliConfig } from './config.js'; |
|
|
import { Settings } from './settings.js'; |
|
|
import { Extension } from './extension.js'; |
|
|
import * as ServerConfig from '@google/gemini-cli-core'; |
|
|
|
|
|
vi.mock('os', async (importOriginal) => { |
|
|
const actualOs = await importOriginal<typeof os>(); |
|
|
return { |
|
|
...actualOs, |
|
|
homedir: vi.fn(() => '/mock/home/user'), |
|
|
}; |
|
|
}); |
|
|
|
|
|
vi.mock('open', () => ({ |
|
|
default: vi.fn(), |
|
|
})); |
|
|
|
|
|
vi.mock('read-package-up', () => ({ |
|
|
readPackageUp: vi.fn(() => |
|
|
Promise.resolve({ packageJson: { version: 'test-version' } }), |
|
|
), |
|
|
})); |
|
|
|
|
|
vi.mock('@google/gemini-cli-core', async () => { |
|
|
const actualServer = await vi.importActual<typeof ServerConfig>( |
|
|
'@google/gemini-cli-core', |
|
|
); |
|
|
return { |
|
|
...actualServer, |
|
|
loadEnvironment: vi.fn(), |
|
|
loadServerHierarchicalMemory: vi.fn( |
|
|
(cwd, debug, fileService, extensionPaths) => |
|
|
Promise.resolve({ |
|
|
memoryContent: extensionPaths?.join(',') || '', |
|
|
fileCount: extensionPaths?.length || 0, |
|
|
}), |
|
|
), |
|
|
}; |
|
|
}); |
|
|
|
|
|
describe('loadCliConfig', () => { |
|
|
const originalArgv = process.argv; |
|
|
const originalEnv = { ...process.env }; |
|
|
|
|
|
beforeEach(() => { |
|
|
vi.resetAllMocks(); |
|
|
vi.mocked(os.homedir).mockReturnValue('/mock/home/user'); |
|
|
process.env.GEMINI_API_KEY = 'test-api-key'; |
|
|
}); |
|
|
|
|
|
afterEach(() => { |
|
|
process.argv = originalArgv; |
|
|
process.env = originalEnv; |
|
|
vi.restoreAllMocks(); |
|
|
}); |
|
|
|
|
|
it('should set showMemoryUsage to true when --memory flag is present', async () => { |
|
|
process.argv = ['node', 'script.js', '--show_memory_usage']; |
|
|
const settings: Settings = {}; |
|
|
const config = await loadCliConfig(settings, [], 'test-session'); |
|
|
expect(config.getShowMemoryUsage()).toBe(true); |
|
|
}); |
|
|
|
|
|
it('should set showMemoryUsage to false when --memory flag is not present', async () => { |
|
|
process.argv = ['node', 'script.js']; |
|
|
const settings: Settings = {}; |
|
|
const config = await loadCliConfig(settings, [], 'test-session'); |
|
|
expect(config.getShowMemoryUsage()).toBe(false); |
|
|
}); |
|
|
|
|
|
it('should set showMemoryUsage to false by default from settings if CLI flag is not present', async () => { |
|
|
process.argv = ['node', 'script.js']; |
|
|
const settings: Settings = { showMemoryUsage: false }; |
|
|
const config = await loadCliConfig(settings, [], 'test-session'); |
|
|
expect(config.getShowMemoryUsage()).toBe(false); |
|
|
}); |
|
|
|
|
|
it('should prioritize CLI flag over settings for showMemoryUsage (CLI true, settings false)', async () => { |
|
|
process.argv = ['node', 'script.js', '--show_memory_usage']; |
|
|
const settings: Settings = { showMemoryUsage: false }; |
|
|
const config = await loadCliConfig(settings, [], 'test-session'); |
|
|
expect(config.getShowMemoryUsage()).toBe(true); |
|
|
}); |
|
|
}); |
|
|
|
|
|
describe('loadCliConfig telemetry', () => { |
|
|
const originalArgv = process.argv; |
|
|
const originalEnv = { ...process.env }; |
|
|
|
|
|
beforeEach(() => { |
|
|
vi.resetAllMocks(); |
|
|
vi.mocked(os.homedir).mockReturnValue('/mock/home/user'); |
|
|
process.env.GEMINI_API_KEY = 'test-api-key'; |
|
|
}); |
|
|
|
|
|
afterEach(() => { |
|
|
process.argv = originalArgv; |
|
|
process.env = originalEnv; |
|
|
vi.restoreAllMocks(); |
|
|
}); |
|
|
|
|
|
it('should set telemetry to false by default when no flag or setting is present', async () => { |
|
|
process.argv = ['node', 'script.js']; |
|
|
const settings: Settings = {}; |
|
|
const config = await loadCliConfig(settings, [], 'test-session'); |
|
|
expect(config.getTelemetryEnabled()).toBe(false); |
|
|
}); |
|
|
|
|
|
it('should set telemetry to true when --telemetry flag is present', async () => { |
|
|
process.argv = ['node', 'script.js', '--telemetry']; |
|
|
const settings: Settings = {}; |
|
|
const config = await loadCliConfig(settings, [], 'test-session'); |
|
|
expect(config.getTelemetryEnabled()).toBe(true); |
|
|
}); |
|
|
|
|
|
it('should set telemetry to false when --no-telemetry flag is present', async () => { |
|
|
process.argv = ['node', 'script.js', '--no-telemetry']; |
|
|
const settings: Settings = {}; |
|
|
const config = await loadCliConfig(settings, [], 'test-session'); |
|
|
expect(config.getTelemetryEnabled()).toBe(false); |
|
|
}); |
|
|
|
|
|
it('should use telemetry value from settings if CLI flag is not present (settings true)', async () => { |
|
|
process.argv = ['node', 'script.js']; |
|
|
const settings: Settings = { telemetry: { enabled: true } }; |
|
|
const config = await loadCliConfig(settings, [], 'test-session'); |
|
|
expect(config.getTelemetryEnabled()).toBe(true); |
|
|
}); |
|
|
|
|
|
it('should use telemetry value from settings if CLI flag is not present (settings false)', async () => { |
|
|
process.argv = ['node', 'script.js']; |
|
|
const settings: Settings = { telemetry: { enabled: false } }; |
|
|
const config = await loadCliConfig(settings, [], 'test-session'); |
|
|
expect(config.getTelemetryEnabled()).toBe(false); |
|
|
}); |
|
|
|
|
|
it('should prioritize --telemetry CLI flag (true) over settings (false)', async () => { |
|
|
process.argv = ['node', 'script.js', '--telemetry']; |
|
|
const settings: Settings = { telemetry: { enabled: false } }; |
|
|
const config = await loadCliConfig(settings, [], 'test-session'); |
|
|
expect(config.getTelemetryEnabled()).toBe(true); |
|
|
}); |
|
|
|
|
|
it('should prioritize --no-telemetry CLI flag (false) over settings (true)', async () => { |
|
|
process.argv = ['node', 'script.js', '--no-telemetry']; |
|
|
const settings: Settings = { telemetry: { enabled: true } }; |
|
|
const config = await loadCliConfig(settings, [], 'test-session'); |
|
|
expect(config.getTelemetryEnabled()).toBe(false); |
|
|
}); |
|
|
|
|
|
it('should use telemetry OTLP endpoint from settings if CLI flag is not present', async () => { |
|
|
process.argv = ['node', 'script.js']; |
|
|
const settings: Settings = { |
|
|
telemetry: { otlpEndpoint: 'http://settings.example.com' }, |
|
|
}; |
|
|
const config = await loadCliConfig(settings, [], 'test-session'); |
|
|
expect(config.getTelemetryOtlpEndpoint()).toBe( |
|
|
'http://settings.example.com', |
|
|
); |
|
|
}); |
|
|
|
|
|
it('should prioritize --telemetry-otlp-endpoint CLI flag over settings', async () => { |
|
|
process.argv = [ |
|
|
'node', |
|
|
'script.js', |
|
|
'--telemetry-otlp-endpoint', |
|
|
'http://cli.example.com', |
|
|
]; |
|
|
const settings: Settings = { |
|
|
telemetry: { otlpEndpoint: 'http://settings.example.com' }, |
|
|
}; |
|
|
const config = await loadCliConfig(settings, [], 'test-session'); |
|
|
expect(config.getTelemetryOtlpEndpoint()).toBe('http://cli.example.com'); |
|
|
}); |
|
|
|
|
|
it('should use default endpoint if no OTLP endpoint is provided via CLI or settings', async () => { |
|
|
process.argv = ['node', 'script.js']; |
|
|
const settings: Settings = { telemetry: { enabled: true } }; |
|
|
const config = await loadCliConfig(settings, [], 'test-session'); |
|
|
expect(config.getTelemetryOtlpEndpoint()).toBe('http://localhost:4317'); |
|
|
}); |
|
|
|
|
|
it('should use telemetry target from settings if CLI flag is not present', async () => { |
|
|
process.argv = ['node', 'script.js']; |
|
|
const settings: Settings = { |
|
|
telemetry: { target: ServerConfig.DEFAULT_TELEMETRY_TARGET }, |
|
|
}; |
|
|
const config = await loadCliConfig(settings, [], 'test-session'); |
|
|
expect(config.getTelemetryTarget()).toBe( |
|
|
ServerConfig.DEFAULT_TELEMETRY_TARGET, |
|
|
); |
|
|
}); |
|
|
|
|
|
it('should prioritize --telemetry-target CLI flag over settings', async () => { |
|
|
process.argv = ['node', 'script.js', '--telemetry-target', 'gcp']; |
|
|
const settings: Settings = { |
|
|
telemetry: { target: ServerConfig.DEFAULT_TELEMETRY_TARGET }, |
|
|
}; |
|
|
const config = await loadCliConfig(settings, [], 'test-session'); |
|
|
expect(config.getTelemetryTarget()).toBe('gcp'); |
|
|
}); |
|
|
|
|
|
it('should use default target if no target is provided via CLI or settings', async () => { |
|
|
process.argv = ['node', 'script.js']; |
|
|
const settings: Settings = { telemetry: { enabled: true } }; |
|
|
const config = await loadCliConfig(settings, [], 'test-session'); |
|
|
expect(config.getTelemetryTarget()).toBe( |
|
|
ServerConfig.DEFAULT_TELEMETRY_TARGET, |
|
|
); |
|
|
}); |
|
|
|
|
|
it('should use telemetry log prompts from settings if CLI flag is not present', async () => { |
|
|
process.argv = ['node', 'script.js']; |
|
|
const settings: Settings = { telemetry: { logPrompts: false } }; |
|
|
const config = await loadCliConfig(settings, [], 'test-session'); |
|
|
expect(config.getTelemetryLogPromptsEnabled()).toBe(false); |
|
|
}); |
|
|
|
|
|
it('should prioritize --telemetry-log-prompts CLI flag (true) over settings (false)', async () => { |
|
|
process.argv = ['node', 'script.js', '--telemetry-log-prompts']; |
|
|
const settings: Settings = { telemetry: { logPrompts: false } }; |
|
|
const config = await loadCliConfig(settings, [], 'test-session'); |
|
|
expect(config.getTelemetryLogPromptsEnabled()).toBe(true); |
|
|
}); |
|
|
|
|
|
it('should prioritize --no-telemetry-log-prompts CLI flag (false) over settings (true)', async () => { |
|
|
process.argv = ['node', 'script.js', '--no-telemetry-log-prompts']; |
|
|
const settings: Settings = { telemetry: { logPrompts: true } }; |
|
|
const config = await loadCliConfig(settings, [], 'test-session'); |
|
|
expect(config.getTelemetryLogPromptsEnabled()).toBe(false); |
|
|
}); |
|
|
|
|
|
it('should use default log prompts (true) if no value is provided via CLI or settings', async () => { |
|
|
process.argv = ['node', 'script.js']; |
|
|
const settings: Settings = { telemetry: { enabled: true } }; |
|
|
const config = await loadCliConfig(settings, [], 'test-session'); |
|
|
expect(config.getTelemetryLogPromptsEnabled()).toBe(true); |
|
|
}); |
|
|
}); |
|
|
|
|
|
describe('Hierarchical Memory Loading (config.ts) - Placeholder Suite', () => { |
|
|
beforeEach(() => { |
|
|
vi.resetAllMocks(); |
|
|
vi.mocked(os.homedir).mockReturnValue('/mock/home/user'); |
|
|
|
|
|
}); |
|
|
|
|
|
afterEach(() => { |
|
|
vi.restoreAllMocks(); |
|
|
}); |
|
|
|
|
|
it('should pass extension context file paths to loadServerHierarchicalMemory', async () => { |
|
|
process.argv = ['node', 'script.js']; |
|
|
const settings: Settings = {}; |
|
|
const extensions: Extension[] = [ |
|
|
{ |
|
|
config: { |
|
|
name: 'ext1', |
|
|
version: '1.0.0', |
|
|
}, |
|
|
contextFiles: ['/path/to/ext1/GEMINI.md'], |
|
|
}, |
|
|
{ |
|
|
config: { |
|
|
name: 'ext2', |
|
|
version: '1.0.0', |
|
|
}, |
|
|
contextFiles: [], |
|
|
}, |
|
|
{ |
|
|
config: { |
|
|
name: 'ext3', |
|
|
version: '1.0.0', |
|
|
}, |
|
|
contextFiles: [ |
|
|
'/path/to/ext3/context1.md', |
|
|
'/path/to/ext3/context2.md', |
|
|
], |
|
|
}, |
|
|
]; |
|
|
await loadCliConfig(settings, extensions, 'session-id'); |
|
|
expect(ServerConfig.loadServerHierarchicalMemory).toHaveBeenCalledWith( |
|
|
expect.any(String), |
|
|
false, |
|
|
expect.any(Object), |
|
|
[ |
|
|
'/path/to/ext1/GEMINI.md', |
|
|
'/path/to/ext3/context1.md', |
|
|
'/path/to/ext3/context2.md', |
|
|
], |
|
|
); |
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}); |
|
|
|
|
|
describe('mergeMcpServers', () => { |
|
|
it('should not modify the original settings object', async () => { |
|
|
const settings: Settings = { |
|
|
mcpServers: { |
|
|
'test-server': { |
|
|
url: 'http://localhost:8080', |
|
|
}, |
|
|
}, |
|
|
}; |
|
|
const extensions: Extension[] = [ |
|
|
{ |
|
|
config: { |
|
|
name: 'ext1', |
|
|
version: '1.0.0', |
|
|
mcpServers: { |
|
|
'ext1-server': { |
|
|
url: 'http://localhost:8081', |
|
|
}, |
|
|
}, |
|
|
}, |
|
|
contextFiles: [], |
|
|
}, |
|
|
]; |
|
|
const originalSettings = JSON.parse(JSON.stringify(settings)); |
|
|
await loadCliConfig(settings, extensions, 'test-session'); |
|
|
expect(settings).toEqual(originalSettings); |
|
|
}); |
|
|
}); |
|
|
|