| |
| |
| |
| |
| |
|
|
| import { vi, beforeEach, afterEach } from 'vitest'; |
| import { format } from 'node:util'; |
| import { coreEvents, debugLogger } from '@google/gemini-cli-core'; |
| import { themeManager } from './src/ui/themes/theme-manager.js'; |
| import { mockInkSpinner } from './src/test-utils/mockSpinner.js'; |
|
|
| |
| mockInkSpinner(); |
|
|
| |
| if (process.env.CI !== undefined) { |
| delete process.env.CI; |
| } |
|
|
| global.IS_REACT_ACT_ENVIRONMENT = true; |
|
|
| |
| coreEvents.setMaxListeners(100); |
|
|
| |
| if (process.env.NO_COLOR !== undefined) { |
| delete process.env.NO_COLOR; |
| } |
|
|
| |
| process.env.FORCE_COLOR = '3'; |
|
|
| |
| process.env.FORCE_GENERIC_KEYBINDING_HINTS = 'true'; |
|
|
| |
| process.env.TERM_PROGRAM = 'generic'; |
|
|
| |
| process.env.COLORTERM = 'truecolor'; |
|
|
| |
| if (process.stdout) { |
| process.stdout.getColorDepth = () => 24; |
| } |
|
|
| import './src/test-utils/customMatchers.js'; |
|
|
| let consoleErrorSpy: vi.SpyInstance; |
| let actWarnings: Array<{ message: string; stack: string }> = []; |
|
|
| let logSpy: vi.SpyInstance; |
| let warnSpy: vi.SpyInstance; |
| let errorSpy: vi.SpyInstance; |
| let debugSpy: vi.SpyInstance; |
|
|
| beforeEach(() => { |
| |
| themeManager.resetForTesting(); |
|
|
| |
| logSpy = vi.spyOn(debugLogger, 'log').mockImplementation(() => {}); |
| warnSpy = vi.spyOn(debugLogger, 'warn').mockImplementation((...args) => { |
| console.warn(...args); |
| }); |
| errorSpy = vi.spyOn(debugLogger, 'error').mockImplementation((...args) => { |
| console.error(...args); |
| }); |
| debugSpy = vi.spyOn(debugLogger, 'debug').mockImplementation(() => {}); |
|
|
| actWarnings = []; |
| consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation((...args) => { |
| const firstArg = args[0]; |
| if ( |
| typeof firstArg === 'string' && |
| firstArg.includes('was not wrapped in act(...)') |
| ) { |
| const stackLines = (new Error().stack || '').split('\n'); |
| let lastReactFrameIndex = -1; |
|
|
| |
| for (let i = 0; i < stackLines.length; i++) { |
| if (stackLines[i].includes('react-reconciler')) { |
| lastReactFrameIndex = i; |
| } |
| } |
|
|
| |
| |
| const relevantStack = |
| lastReactFrameIndex !== -1 |
| ? stackLines.slice(lastReactFrameIndex + 1).join('\n') |
| : stackLines.slice(1).join('\n'); |
|
|
| if ( |
| relevantStack.includes('OverflowContext.tsx') || |
| relevantStack.includes('useTimedMessage.ts') || |
| relevantStack.includes('useInlineEditBuffer.ts') |
| ) { |
| return; |
| } |
|
|
| actWarnings.push({ |
| message: format(...args), |
| stack: relevantStack, |
| }); |
| } |
| }); |
| }); |
|
|
| afterEach(() => { |
| consoleErrorSpy.mockRestore(); |
|
|
| logSpy?.mockRestore(); |
| warnSpy?.mockRestore(); |
| errorSpy?.mockRestore(); |
| debugSpy?.mockRestore(); |
|
|
| vi.unstubAllEnvs(); |
| if (actWarnings.length > 0) { |
| const messages = actWarnings |
| .map(({ message, stack }) => `${message}\n${stack}`) |
| .join('\n\n'); |
| throw new Error(`Failing test due to "act(...)" warnings:\n${messages}`); |
| } |
| }); |
|
|