mirror of
https://github.com/google-gemini/gemini-cli
synced 2026-05-24 09:38:34 +00:00
refactor(cli): integrate real config loading into async test utils (#23040)
This commit is contained in:
parent
7de0616229
commit
23264ced9a
103 changed files with 1806 additions and 1541 deletions
|
|
@ -29,7 +29,7 @@ describe('Model Steering Integration', () => {
|
|||
configOverrides: { modelSteering: true },
|
||||
});
|
||||
await rig.initialize();
|
||||
rig.render();
|
||||
await rig.render();
|
||||
await rig.waitForIdle();
|
||||
|
||||
rig.setToolPolicy('list_directory', PolicyDecision.ASK_USER);
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
*/
|
||||
|
||||
import { describe, it, afterEach, expect } from 'vitest';
|
||||
import { act } from 'react';
|
||||
import { AppRig } from './AppRig.js';
|
||||
import path from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
|
@ -31,7 +30,7 @@ describe('AppRig', () => {
|
|||
configOverrides: { modelSteering: true },
|
||||
});
|
||||
await rig.initialize();
|
||||
rig.render();
|
||||
await rig.render();
|
||||
await rig.waitForIdle();
|
||||
|
||||
// Set breakpoints on the canonical tool names
|
||||
|
|
@ -69,12 +68,7 @@ describe('AppRig', () => {
|
|||
);
|
||||
rig = new AppRig({ fakeResponsesPath });
|
||||
await rig.initialize();
|
||||
await act(async () => {
|
||||
rig!.render();
|
||||
// Allow async initializations (like banners) to settle within the act boundary
|
||||
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||
});
|
||||
|
||||
await rig.render();
|
||||
// Wait for initial render
|
||||
await rig.waitForIdle();
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import os from 'node:os';
|
|||
import path from 'node:path';
|
||||
import fs from 'node:fs';
|
||||
import { AppContainer } from '../ui/AppContainer.js';
|
||||
import { renderWithProviders } from './render.js';
|
||||
import { renderWithProviders, type RenderInstance } from './render.js';
|
||||
import {
|
||||
makeFakeConfig,
|
||||
type Config,
|
||||
|
|
@ -155,7 +155,7 @@ export interface PendingConfirmation {
|
|||
}
|
||||
|
||||
export class AppRig {
|
||||
private renderResult: ReturnType<typeof renderWithProviders> | undefined;
|
||||
private renderResult: RenderInstance | undefined;
|
||||
private config: Config | undefined;
|
||||
private settings: LoadedSettings | undefined;
|
||||
private testDir: string;
|
||||
|
|
@ -393,12 +393,12 @@ export class AppRig {
|
|||
return isAnyToolActive || isAwaitingConfirmation;
|
||||
}
|
||||
|
||||
render() {
|
||||
async render() {
|
||||
if (!this.config || !this.settings)
|
||||
throw new Error('AppRig not initialized');
|
||||
|
||||
act(() => {
|
||||
this.renderResult = renderWithProviders(
|
||||
await act(async () => {
|
||||
this.renderResult = await renderWithProviders(
|
||||
<AppContainer
|
||||
config={this.config!}
|
||||
version="test-version"
|
||||
|
|
|
|||
|
|
@ -16,8 +16,6 @@ import { vi } from 'vitest';
|
|||
import stripAnsi from 'strip-ansi';
|
||||
import type React from 'react';
|
||||
import { act, useState } from 'react';
|
||||
import os from 'node:os';
|
||||
import path from 'node:path';
|
||||
import type { LoadedSettings } from '../config/settings.js';
|
||||
import { KeypressProvider } from '../ui/contexts/KeypressContext.js';
|
||||
import { SettingsContext } from '../ui/contexts/SettingsContext.js';
|
||||
|
|
@ -44,7 +42,7 @@ import {
|
|||
type OverflowState,
|
||||
} from '../ui/contexts/OverflowContext.js';
|
||||
|
||||
import { makeFakeConfig, type Config } from '@google/gemini-cli-core';
|
||||
import { type Config } from '@google/gemini-cli-core';
|
||||
import { FakePersistentState } from './persistentStateFake.js';
|
||||
import { AppContext, type AppState } from '../ui/contexts/AppContext.js';
|
||||
import { createMockSettings } from './settings.js';
|
||||
|
|
@ -53,6 +51,7 @@ import { themeManager, DEFAULT_THEME } from '../ui/themes/theme-manager.js';
|
|||
import { DefaultLight } from '../ui/themes/builtin/light/default-light.js';
|
||||
import { pickDefaultThemeName } from '../ui/themes/theme.js';
|
||||
import { generateSvgForTerminal } from './svg.js';
|
||||
import { loadCliConfig, type CliArgs } from '../config/config.js';
|
||||
|
||||
export const persistentStateMock = new FakePersistentState();
|
||||
|
||||
|
|
@ -66,7 +65,9 @@ if (process.env['NODE_ENV'] === 'test') {
|
|||
}
|
||||
|
||||
vi.mock('../utils/persistentState.js', () => ({
|
||||
persistentState: persistentStateMock,
|
||||
get persistentState() {
|
||||
return persistentStateMock;
|
||||
},
|
||||
}));
|
||||
|
||||
vi.mock('../ui/utils/terminalUtils.js', () => ({
|
||||
|
|
@ -486,50 +487,6 @@ export const simulateClick = async (
|
|||
});
|
||||
};
|
||||
|
||||
let mockConfigInternal: Config | undefined;
|
||||
|
||||
const getMockConfigInternal = (): Config => {
|
||||
if (!mockConfigInternal) {
|
||||
mockConfigInternal = makeFakeConfig({
|
||||
targetDir: os.tmpdir(),
|
||||
enableEventDrivenScheduler: true,
|
||||
});
|
||||
}
|
||||
return mockConfigInternal;
|
||||
};
|
||||
|
||||
const configProxy = new Proxy({} as Config, {
|
||||
get(_target, prop) {
|
||||
if (prop === 'getTargetDir') {
|
||||
return () =>
|
||||
path.join(
|
||||
path.parse(process.cwd()).root,
|
||||
'Users',
|
||||
'test',
|
||||
'project',
|
||||
'foo',
|
||||
'bar',
|
||||
'and',
|
||||
'some',
|
||||
'more',
|
||||
'directories',
|
||||
'to',
|
||||
'make',
|
||||
'it',
|
||||
'long',
|
||||
);
|
||||
}
|
||||
if (prop === 'getUseBackgroundColor') {
|
||||
return () => true;
|
||||
}
|
||||
const internal = getMockConfigInternal();
|
||||
if (prop in internal) {
|
||||
return internal[prop as keyof typeof internal];
|
||||
}
|
||||
throw new Error(`mockConfig does not have property ${String(prop)}`);
|
||||
},
|
||||
});
|
||||
|
||||
export const mockSettings = createMockSettings();
|
||||
|
||||
// A minimal mock UIState to satisfy the context provider.
|
||||
|
|
@ -639,7 +596,7 @@ const ContextCapture: React.FC<{ children: React.ReactNode }> = ({
|
|||
return <>{children}</>;
|
||||
};
|
||||
|
||||
export const renderWithProviders = (
|
||||
export const renderWithProviders = async (
|
||||
component: React.ReactElement,
|
||||
{
|
||||
shellFocus = true,
|
||||
|
|
@ -647,8 +604,7 @@ export const renderWithProviders = (
|
|||
uiState: providedUiState,
|
||||
width,
|
||||
mouseEventsEnabled = false,
|
||||
|
||||
config = configProxy as unknown as Config,
|
||||
config,
|
||||
uiActions,
|
||||
persistentState,
|
||||
appState = mockAppState,
|
||||
|
|
@ -666,13 +622,15 @@ export const renderWithProviders = (
|
|||
};
|
||||
appState?: AppState;
|
||||
} = {},
|
||||
): RenderInstance & {
|
||||
simulateClick: (
|
||||
col: number,
|
||||
row: number,
|
||||
button?: 0 | 1 | 2,
|
||||
) => Promise<void>;
|
||||
} => {
|
||||
): Promise<
|
||||
RenderInstance & {
|
||||
simulateClick: (
|
||||
col: number,
|
||||
row: number,
|
||||
button?: 0 | 1 | 2,
|
||||
) => Promise<void>;
|
||||
}
|
||||
> => {
|
||||
const baseState: UIState = new Proxy(
|
||||
{ ...baseMockUiState, ...providedUiState },
|
||||
{
|
||||
|
|
@ -701,8 +659,15 @@ export const renderWithProviders = (
|
|||
persistentStateMock.mockClear();
|
||||
|
||||
const terminalWidth = width ?? baseState.terminalWidth;
|
||||
const finalSettings = settings;
|
||||
const finalConfig = config;
|
||||
|
||||
if (!config) {
|
||||
config = await loadCliConfig(
|
||||
settings.merged,
|
||||
'random-session-id',
|
||||
{} as unknown as CliArgs,
|
||||
{ cwd: '/' },
|
||||
);
|
||||
}
|
||||
|
||||
const mainAreaWidth = terminalWidth;
|
||||
|
||||
|
|
@ -732,8 +697,8 @@ export const renderWithProviders = (
|
|||
|
||||
const wrapWithProviders = (comp: React.ReactElement) => (
|
||||
<AppContext.Provider value={appState}>
|
||||
<ConfigContext.Provider value={finalConfig}>
|
||||
<SettingsContext.Provider value={finalSettings}>
|
||||
<ConfigContext.Provider value={config}>
|
||||
<SettingsContext.Provider value={settings}>
|
||||
<UIStateContext.Provider value={finalUiState}>
|
||||
<VimModeProvider>
|
||||
<ShellFocusContext.Provider value={shellFocus}>
|
||||
|
|
@ -744,7 +709,7 @@ export const renderWithProviders = (
|
|||
<UIActionsContext.Provider value={finalUIActions}>
|
||||
<OverflowProvider>
|
||||
<ToolActionsProvider
|
||||
config={finalConfig}
|
||||
config={config}
|
||||
toolCalls={allToolCalls}
|
||||
>
|
||||
<AskUserActionsProvider
|
||||
|
|
@ -863,7 +828,7 @@ export function renderHook<Result, Props>(
|
|||
return { result, rerender, unmount, waitUntilReady, generateSvg };
|
||||
}
|
||||
|
||||
export function renderHookWithProviders<Result, Props>(
|
||||
export async function renderHookWithProviders<Result, Props>(
|
||||
renderCallback: (props: Props) => Result,
|
||||
options: {
|
||||
initialProps?: Props;
|
||||
|
|
@ -876,13 +841,13 @@ export function renderHookWithProviders<Result, Props>(
|
|||
mouseEventsEnabled?: boolean;
|
||||
config?: Config;
|
||||
} = {},
|
||||
): {
|
||||
): Promise<{
|
||||
result: { current: Result };
|
||||
rerender: (props?: Props) => void;
|
||||
unmount: () => void;
|
||||
waitUntilReady: () => Promise<void>;
|
||||
generateSvg: () => string;
|
||||
} {
|
||||
}> {
|
||||
const result = { current: undefined as unknown as Result };
|
||||
|
||||
let setPropsFn: ((props: Props) => void) | undefined;
|
||||
|
|
@ -901,8 +866,8 @@ export function renderHookWithProviders<Result, Props>(
|
|||
|
||||
let renderResult: ReturnType<typeof render>;
|
||||
|
||||
act(() => {
|
||||
renderResult = renderWithProviders(
|
||||
await act(async () => {
|
||||
renderResult = await renderWithProviders(
|
||||
<Wrapper>
|
||||
{}
|
||||
<TestComponent initialProps={options.initialProps as Props} />
|
||||
|
|
|
|||
|
|
@ -94,11 +94,10 @@ describe('App', () => {
|
|||
};
|
||||
|
||||
it('should render main content and composer when not quitting', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<App />,
|
||||
{
|
||||
uiState: mockUIState,
|
||||
config: makeFakeConfig({ useAlternateBuffer: false }),
|
||||
settings: createMockSettings({ ui: { useAlternateBuffer: false } }),
|
||||
},
|
||||
);
|
||||
|
|
@ -116,11 +115,10 @@ describe('App', () => {
|
|||
quittingMessages: [{ id: 1, type: 'user', text: 'test' }],
|
||||
} as UIState;
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<App />,
|
||||
{
|
||||
uiState: quittingUIState,
|
||||
config: makeFakeConfig({ useAlternateBuffer: false }),
|
||||
settings: createMockSettings({ ui: { useAlternateBuffer: false } }),
|
||||
},
|
||||
);
|
||||
|
|
@ -138,11 +136,10 @@ describe('App', () => {
|
|||
pendingHistoryItems: [{ type: 'user', text: 'pending item' }],
|
||||
} as UIState;
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<App />,
|
||||
{
|
||||
uiState: quittingUIState,
|
||||
config: makeFakeConfig({ useAlternateBuffer: true }),
|
||||
settings: createMockSettings({ ui: { useAlternateBuffer: true } }),
|
||||
},
|
||||
);
|
||||
|
|
@ -159,11 +156,10 @@ describe('App', () => {
|
|||
dialogsVisible: true,
|
||||
} as UIState;
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<App />,
|
||||
{
|
||||
uiState: dialogUIState,
|
||||
config: makeFakeConfig({ useAlternateBuffer: true }),
|
||||
settings: createMockSettings({ ui: { useAlternateBuffer: true } }),
|
||||
},
|
||||
);
|
||||
|
|
@ -187,11 +183,10 @@ describe('App', () => {
|
|||
[stateKey]: true,
|
||||
} as UIState;
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<App />,
|
||||
{
|
||||
uiState,
|
||||
config: makeFakeConfig({ useAlternateBuffer: true }),
|
||||
settings: createMockSettings({ ui: { useAlternateBuffer: true } }),
|
||||
},
|
||||
);
|
||||
|
|
@ -205,11 +200,10 @@ describe('App', () => {
|
|||
it('should render ScreenReaderAppLayout when screen reader is enabled', async () => {
|
||||
(useIsScreenReaderEnabled as Mock).mockReturnValue(true);
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<App />,
|
||||
{
|
||||
uiState: mockUIState,
|
||||
config: makeFakeConfig({ useAlternateBuffer: true }),
|
||||
settings: createMockSettings({ ui: { useAlternateBuffer: true } }),
|
||||
},
|
||||
);
|
||||
|
|
@ -225,11 +219,10 @@ describe('App', () => {
|
|||
it('should render DefaultAppLayout when screen reader is not enabled', async () => {
|
||||
(useIsScreenReaderEnabled as Mock).mockReturnValue(false);
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<App />,
|
||||
{
|
||||
uiState: mockUIState,
|
||||
config: makeFakeConfig({ useAlternateBuffer: true }),
|
||||
settings: createMockSettings({ ui: { useAlternateBuffer: true } }),
|
||||
},
|
||||
);
|
||||
|
|
@ -281,7 +274,7 @@ describe('App', () => {
|
|||
vi.spyOn(configWithExperiment, 'isTrustedFolder').mockReturnValue(true);
|
||||
vi.spyOn(configWithExperiment, 'getIdeMode').mockReturnValue(false);
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<App />,
|
||||
{
|
||||
uiState: stateWithConfirmingTool,
|
||||
|
|
@ -302,11 +295,10 @@ describe('App', () => {
|
|||
describe('Snapshots', () => {
|
||||
it('renders default layout correctly', async () => {
|
||||
(useIsScreenReaderEnabled as Mock).mockReturnValue(false);
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<App />,
|
||||
{
|
||||
uiState: mockUIState,
|
||||
config: makeFakeConfig({ useAlternateBuffer: true }),
|
||||
settings: createMockSettings({ ui: { useAlternateBuffer: true } }),
|
||||
},
|
||||
);
|
||||
|
|
@ -317,11 +309,10 @@ describe('App', () => {
|
|||
|
||||
it('renders screen reader layout correctly', async () => {
|
||||
(useIsScreenReaderEnabled as Mock).mockReturnValue(true);
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<App />,
|
||||
{
|
||||
uiState: mockUIState,
|
||||
config: makeFakeConfig({ useAlternateBuffer: true }),
|
||||
settings: createMockSettings({ ui: { useAlternateBuffer: true } }),
|
||||
},
|
||||
);
|
||||
|
|
@ -335,11 +326,10 @@ describe('App', () => {
|
|||
...mockUIState,
|
||||
dialogsVisible: true,
|
||||
} as UIState;
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<App />,
|
||||
{
|
||||
uiState: dialogUIState,
|
||||
config: makeFakeConfig({ useAlternateBuffer: true }),
|
||||
settings: createMockSettings({ ui: { useAlternateBuffer: true } }),
|
||||
},
|
||||
);
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ describe('IdeIntegrationNudge', () => {
|
|||
});
|
||||
|
||||
it('renders correctly with default options', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<IdeIntegrationNudge {...defaultProps} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -68,7 +68,7 @@ describe('IdeIntegrationNudge', () => {
|
|||
|
||||
it('handles "Yes" selection', async () => {
|
||||
const onComplete = vi.fn();
|
||||
const { stdin, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { stdin, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<IdeIntegrationNudge {...defaultProps} onComplete={onComplete} />,
|
||||
);
|
||||
|
||||
|
|
@ -89,7 +89,7 @@ describe('IdeIntegrationNudge', () => {
|
|||
|
||||
it('handles "No" selection', async () => {
|
||||
const onComplete = vi.fn();
|
||||
const { stdin, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { stdin, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<IdeIntegrationNudge {...defaultProps} onComplete={onComplete} />,
|
||||
);
|
||||
|
||||
|
|
@ -115,7 +115,7 @@ describe('IdeIntegrationNudge', () => {
|
|||
|
||||
it('handles "Dismiss" selection', async () => {
|
||||
const onComplete = vi.fn();
|
||||
const { stdin, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { stdin, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<IdeIntegrationNudge {...defaultProps} onComplete={onComplete} />,
|
||||
);
|
||||
|
||||
|
|
@ -146,7 +146,7 @@ describe('IdeIntegrationNudge', () => {
|
|||
|
||||
it('handles Escape key press', async () => {
|
||||
const onComplete = vi.fn();
|
||||
const { stdin, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { stdin, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<IdeIntegrationNudge {...defaultProps} onComplete={onComplete} />,
|
||||
);
|
||||
|
||||
|
|
@ -173,9 +173,10 @@ describe('IdeIntegrationNudge', () => {
|
|||
vi.stubEnv('GEMINI_CLI_IDE_WORKSPACE_PATH', '/tmp');
|
||||
|
||||
const onComplete = vi.fn();
|
||||
const { lastFrame, stdin, waitUntilReady, unmount } = renderWithProviders(
|
||||
<IdeIntegrationNudge {...defaultProps} onComplete={onComplete} />,
|
||||
);
|
||||
const { lastFrame, stdin, waitUntilReady, unmount } =
|
||||
await renderWithProviders(
|
||||
<IdeIntegrationNudge {...defaultProps} onComplete={onComplete} />,
|
||||
);
|
||||
|
||||
await waitUntilReady();
|
||||
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ describe('AuthDialog', () => {
|
|||
for (const [key, value] of Object.entries(env)) {
|
||||
vi.stubEnv(key, value as string);
|
||||
}
|
||||
const { waitUntilReady, unmount } = renderWithProviders(
|
||||
const { waitUntilReady, unmount } = await renderWithProviders(
|
||||
<AuthDialog {...props} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -161,7 +161,7 @@ describe('AuthDialog', () => {
|
|||
|
||||
it('filters auth types when enforcedType is set', async () => {
|
||||
props.settings.merged.security.auth.enforcedType = AuthType.USE_GEMINI;
|
||||
const { waitUntilReady, unmount } = renderWithProviders(
|
||||
const { waitUntilReady, unmount } = await renderWithProviders(
|
||||
<AuthDialog {...props} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -173,7 +173,7 @@ describe('AuthDialog', () => {
|
|||
|
||||
it('sets initial index to 0 when enforcedType is set', async () => {
|
||||
props.settings.merged.security.auth.enforcedType = AuthType.USE_GEMINI;
|
||||
const { waitUntilReady, unmount } = renderWithProviders(
|
||||
const { waitUntilReady, unmount } = await renderWithProviders(
|
||||
<AuthDialog {...props} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -213,7 +213,7 @@ describe('AuthDialog', () => {
|
|||
},
|
||||
])('selects initial auth type $desc', async ({ setup, expected }) => {
|
||||
setup();
|
||||
const { waitUntilReady, unmount } = renderWithProviders(
|
||||
const { waitUntilReady, unmount } = await renderWithProviders(
|
||||
<AuthDialog {...props} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -226,7 +226,7 @@ describe('AuthDialog', () => {
|
|||
describe('handleAuthSelect', () => {
|
||||
it('calls onAuthError if validation fails', async () => {
|
||||
mockedValidateAuthMethod.mockReturnValue('Invalid method');
|
||||
const { waitUntilReady, unmount } = renderWithProviders(
|
||||
const { waitUntilReady, unmount } = await renderWithProviders(
|
||||
<AuthDialog {...props} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -245,7 +245,7 @@ describe('AuthDialog', () => {
|
|||
|
||||
it('sets auth context with requiresRestart: true for LOGIN_WITH_GOOGLE', async () => {
|
||||
mockedValidateAuthMethod.mockReturnValue(null);
|
||||
const { waitUntilReady, unmount } = renderWithProviders(
|
||||
const { waitUntilReady, unmount } = await renderWithProviders(
|
||||
<AuthDialog {...props} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -261,7 +261,7 @@ describe('AuthDialog', () => {
|
|||
|
||||
it('sets auth context with empty object for other auth types', async () => {
|
||||
mockedValidateAuthMethod.mockReturnValue(null);
|
||||
const { waitUntilReady, unmount } = renderWithProviders(
|
||||
const { waitUntilReady, unmount } = await renderWithProviders(
|
||||
<AuthDialog {...props} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -278,7 +278,7 @@ describe('AuthDialog', () => {
|
|||
vi.stubEnv('GEMINI_API_KEY', 'test-key-from-env');
|
||||
// props.settings.merged.security.auth.selectedType is undefined here, simulating initial setup
|
||||
|
||||
const { waitUntilReady, unmount } = renderWithProviders(
|
||||
const { waitUntilReady, unmount } = await renderWithProviders(
|
||||
<AuthDialog {...props} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -297,7 +297,7 @@ describe('AuthDialog', () => {
|
|||
vi.stubEnv('GEMINI_API_KEY', ''); // Empty string
|
||||
// props.settings.merged.security.auth.selectedType is undefined here
|
||||
|
||||
const { waitUntilReady, unmount } = renderWithProviders(
|
||||
const { waitUntilReady, unmount } = await renderWithProviders(
|
||||
<AuthDialog {...props} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -316,7 +316,7 @@ describe('AuthDialog', () => {
|
|||
// process.env['GEMINI_API_KEY'] is not set
|
||||
// props.settings.merged.security.auth.selectedType is undefined here, simulating initial setup
|
||||
|
||||
const { waitUntilReady, unmount } = renderWithProviders(
|
||||
const { waitUntilReady, unmount } = await renderWithProviders(
|
||||
<AuthDialog {...props} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -337,7 +337,7 @@ describe('AuthDialog', () => {
|
|||
props.settings.merged.security.auth.selectedType =
|
||||
AuthType.LOGIN_WITH_GOOGLE;
|
||||
|
||||
const { waitUntilReady, unmount } = renderWithProviders(
|
||||
const { waitUntilReady, unmount } = await renderWithProviders(
|
||||
<AuthDialog {...props} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -360,7 +360,7 @@ describe('AuthDialog', () => {
|
|||
vi.mocked(props.config.isBrowserLaunchSuppressed).mockReturnValue(true);
|
||||
mockedValidateAuthMethod.mockReturnValue(null);
|
||||
|
||||
const { waitUntilReady, unmount } = renderWithProviders(
|
||||
const { waitUntilReady, unmount } = await renderWithProviders(
|
||||
<AuthDialog {...props} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -383,7 +383,7 @@ describe('AuthDialog', () => {
|
|||
|
||||
it('displays authError when provided', async () => {
|
||||
props.authError = 'Something went wrong';
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<AuthDialog {...props} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -429,7 +429,7 @@ describe('AuthDialog', () => {
|
|||
},
|
||||
])('$desc', async ({ setup, expectations }) => {
|
||||
setup();
|
||||
const { waitUntilReady, unmount } = renderWithProviders(
|
||||
const { waitUntilReady, unmount } = await renderWithProviders(
|
||||
<AuthDialog {...props} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -442,7 +442,7 @@ describe('AuthDialog', () => {
|
|||
|
||||
describe('Snapshots', () => {
|
||||
it('renders correctly with default props', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<AuthDialog {...props} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -452,7 +452,7 @@ describe('AuthDialog', () => {
|
|||
|
||||
it('renders correctly with auth error', async () => {
|
||||
props.authError = 'Something went wrong';
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<AuthDialog {...props} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -462,7 +462,7 @@ describe('AuthDialog', () => {
|
|||
|
||||
it('renders correctly with enforced auth type', async () => {
|
||||
props.settings.merged.security.auth.enforcedType = AuthType.USE_GEMINI;
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<AuthDialog {...props} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ describe('BannedAccountDialog', () => {
|
|||
});
|
||||
|
||||
it('renders the suspension message from accountSuspensionInfo', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<BannedAccountDialog
|
||||
accountSuspensionInfo={DEFAULT_SUSPENSION_INFO}
|
||||
onExit={onExit}
|
||||
|
|
@ -89,7 +89,7 @@ describe('BannedAccountDialog', () => {
|
|||
});
|
||||
|
||||
it('renders menu options with appeal link text from response', async () => {
|
||||
const { waitUntilReady, unmount } = renderWithProviders(
|
||||
const { waitUntilReady, unmount } = await renderWithProviders(
|
||||
<BannedAccountDialog
|
||||
accountSuspensionInfo={DEFAULT_SUSPENSION_INFO}
|
||||
onExit={onExit}
|
||||
|
|
@ -109,7 +109,7 @@ describe('BannedAccountDialog', () => {
|
|||
const infoWithoutUrl: AccountSuspensionInfo = {
|
||||
message: 'Account suspended.',
|
||||
};
|
||||
const { waitUntilReady, unmount } = renderWithProviders(
|
||||
const { waitUntilReady, unmount } = await renderWithProviders(
|
||||
<BannedAccountDialog
|
||||
accountSuspensionInfo={infoWithoutUrl}
|
||||
onExit={onExit}
|
||||
|
|
@ -129,7 +129,7 @@ describe('BannedAccountDialog', () => {
|
|||
message: 'Account suspended.',
|
||||
appealUrl: 'https://example.com/appeal',
|
||||
};
|
||||
const { waitUntilReady, unmount } = renderWithProviders(
|
||||
const { waitUntilReady, unmount } = await renderWithProviders(
|
||||
<BannedAccountDialog
|
||||
accountSuspensionInfo={infoWithoutLinkText}
|
||||
onExit={onExit}
|
||||
|
|
@ -143,7 +143,7 @@ describe('BannedAccountDialog', () => {
|
|||
});
|
||||
|
||||
it('opens browser when appeal option is selected', async () => {
|
||||
const { waitUntilReady, unmount } = renderWithProviders(
|
||||
const { waitUntilReady, unmount } = await renderWithProviders(
|
||||
<BannedAccountDialog
|
||||
accountSuspensionInfo={DEFAULT_SUSPENSION_INFO}
|
||||
onExit={onExit}
|
||||
|
|
@ -162,7 +162,7 @@ describe('BannedAccountDialog', () => {
|
|||
|
||||
it('shows URL when browser cannot be launched', async () => {
|
||||
mockedShouldLaunchBrowser.mockReturnValue(false);
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<BannedAccountDialog
|
||||
accountSuspensionInfo={DEFAULT_SUSPENSION_INFO}
|
||||
onExit={onExit}
|
||||
|
|
@ -180,7 +180,7 @@ describe('BannedAccountDialog', () => {
|
|||
});
|
||||
|
||||
it('calls onExit when "Exit" is selected', async () => {
|
||||
const { waitUntilReady, unmount } = renderWithProviders(
|
||||
const { waitUntilReady, unmount } = await renderWithProviders(
|
||||
<BannedAccountDialog
|
||||
accountSuspensionInfo={DEFAULT_SUSPENSION_INFO}
|
||||
onExit={onExit}
|
||||
|
|
@ -196,7 +196,7 @@ describe('BannedAccountDialog', () => {
|
|||
});
|
||||
|
||||
it('calls onChangeAuth when "Change authentication" is selected', async () => {
|
||||
const { waitUntilReady, unmount } = renderWithProviders(
|
||||
const { waitUntilReady, unmount } = await renderWithProviders(
|
||||
<BannedAccountDialog
|
||||
accountSuspensionInfo={DEFAULT_SUSPENSION_INFO}
|
||||
onExit={onExit}
|
||||
|
|
@ -212,7 +212,7 @@ describe('BannedAccountDialog', () => {
|
|||
});
|
||||
|
||||
it('exits on escape key', async () => {
|
||||
const { waitUntilReady, unmount } = renderWithProviders(
|
||||
const { waitUntilReady, unmount } = await renderWithProviders(
|
||||
<BannedAccountDialog
|
||||
accountSuspensionInfo={DEFAULT_SUSPENSION_INFO}
|
||||
onExit={onExit}
|
||||
|
|
@ -227,7 +227,7 @@ describe('BannedAccountDialog', () => {
|
|||
});
|
||||
|
||||
it('renders snapshot correctly', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<BannedAccountDialog
|
||||
accountSuspensionInfo={DEFAULT_SUSPENSION_INFO}
|
||||
onExit={onExit}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ describe('AboutBox', () => {
|
|||
};
|
||||
|
||||
it('renders with required props', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<AboutBox {...defaultProps} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -46,7 +46,7 @@ describe('AboutBox', () => {
|
|||
['tier', 'Enterprise', 'Tier'],
|
||||
])('renders optional prop %s', async (prop, value, label) => {
|
||||
const props = { ...defaultProps, [prop]: value };
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<AboutBox {...props} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -58,7 +58,7 @@ describe('AboutBox', () => {
|
|||
|
||||
it('renders Auth Method with email when userEmail is provided', async () => {
|
||||
const props = { ...defaultProps, userEmail: 'test@example.com' };
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<AboutBox {...props} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -69,7 +69,7 @@ describe('AboutBox', () => {
|
|||
|
||||
it('renders Auth Method correctly when not oauth', async () => {
|
||||
const props = { ...defaultProps, selectedAuthType: 'api-key' };
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<AboutBox {...props} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ describe('AdminSettingsChangedDialog', () => {
|
|||
});
|
||||
|
||||
it('renders correctly', async () => {
|
||||
const { lastFrame, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady } = await renderWithProviders(
|
||||
<AdminSettingsChangedDialog />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -25,7 +25,7 @@ describe('AdminSettingsChangedDialog', () => {
|
|||
});
|
||||
|
||||
it('restarts on "r" key press', async () => {
|
||||
const { stdin, waitUntilReady } = renderWithProviders(
|
||||
const { stdin, waitUntilReady } = await renderWithProviders(
|
||||
<AdminSettingsChangedDialog />,
|
||||
{
|
||||
uiActions: {
|
||||
|
|
@ -43,7 +43,7 @@ describe('AdminSettingsChangedDialog', () => {
|
|||
});
|
||||
|
||||
it.each(['r', 'R'])('restarts on "%s" key press', async (key) => {
|
||||
const { stdin, waitUntilReady } = renderWithProviders(
|
||||
const { stdin, waitUntilReady } = await renderWithProviders(
|
||||
<AdminSettingsChangedDialog />,
|
||||
{
|
||||
uiActions: {
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ describe('AgentConfigDialog', () => {
|
|||
settings: LoadedSettings,
|
||||
definition: AgentDefinition = createMockAgentDefinition(),
|
||||
) => {
|
||||
const result = renderWithProviders(
|
||||
const result = await renderWithProviders(
|
||||
<AgentConfigDialog
|
||||
agentName="test-agent"
|
||||
displayName="Test Agent"
|
||||
|
|
@ -323,7 +323,7 @@ describe('AgentConfigDialog', () => {
|
|||
const settings = createMockSettings();
|
||||
// Agent config has about 6 base items + 2 per tool
|
||||
// Render with very small height (20)
|
||||
const { lastFrame, unmount } = renderWithProviders(
|
||||
const { lastFrame, unmount } = await renderWithProviders(
|
||||
<AgentConfigDialog
|
||||
agentName="test-agent"
|
||||
displayName="Test Agent"
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ describe('AlternateBufferQuittingDisplay', () => {
|
|||
|
||||
it('renders with active and pending tool messages', async () => {
|
||||
persistentStateMock.setData({ tipsShown: 0 });
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<AlternateBufferQuittingDisplay />,
|
||||
{
|
||||
uiState: {
|
||||
|
|
@ -125,7 +125,7 @@ describe('AlternateBufferQuittingDisplay', () => {
|
|||
|
||||
it('renders with empty history and no pending items', async () => {
|
||||
persistentStateMock.setData({ tipsShown: 0 });
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<AlternateBufferQuittingDisplay />,
|
||||
{
|
||||
uiState: {
|
||||
|
|
@ -142,7 +142,7 @@ describe('AlternateBufferQuittingDisplay', () => {
|
|||
|
||||
it('renders with history but no pending items', async () => {
|
||||
persistentStateMock.setData({ tipsShown: 0 });
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<AlternateBufferQuittingDisplay />,
|
||||
{
|
||||
uiState: {
|
||||
|
|
@ -159,7 +159,7 @@ describe('AlternateBufferQuittingDisplay', () => {
|
|||
|
||||
it('renders with pending items but no history', async () => {
|
||||
persistentStateMock.setData({ tipsShown: 0 });
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<AlternateBufferQuittingDisplay />,
|
||||
{
|
||||
uiState: {
|
||||
|
|
@ -195,7 +195,7 @@ describe('AlternateBufferQuittingDisplay', () => {
|
|||
],
|
||||
},
|
||||
];
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<AlternateBufferQuittingDisplay />,
|
||||
{
|
||||
uiState: {
|
||||
|
|
@ -220,7 +220,7 @@ describe('AlternateBufferQuittingDisplay', () => {
|
|||
{ id: 1, type: 'user', text: 'Hello Gemini' },
|
||||
{ id: 2, type: 'gemini', text: 'Hello User!' },
|
||||
];
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<AlternateBufferQuittingDisplay />,
|
||||
{
|
||||
uiState: {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ import {
|
|||
} from '../../test-utils/render.js';
|
||||
import { AppHeader } from './AppHeader.js';
|
||||
import { describe, it, expect, vi } from 'vitest';
|
||||
import { makeFakeConfig } from '@google/gemini-cli-core';
|
||||
import crypto from 'node:crypto';
|
||||
|
||||
vi.mock('../utils/terminalSetup.js', () => ({
|
||||
|
|
@ -19,7 +18,6 @@ vi.mock('../utils/terminalSetup.js', () => ({
|
|||
|
||||
describe('<AppHeader />', () => {
|
||||
it('should render the banner with default text', async () => {
|
||||
const mockConfig = makeFakeConfig();
|
||||
const uiState = {
|
||||
history: [],
|
||||
bannerData: {
|
||||
|
|
@ -29,10 +27,9 @@ describe('<AppHeader />', () => {
|
|||
bannerVisible: true,
|
||||
};
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<AppHeader version="1.0.0" />,
|
||||
{
|
||||
config: mockConfig,
|
||||
uiState,
|
||||
},
|
||||
);
|
||||
|
|
@ -44,7 +41,6 @@ describe('<AppHeader />', () => {
|
|||
});
|
||||
|
||||
it('should render the banner with warning text', async () => {
|
||||
const mockConfig = makeFakeConfig();
|
||||
const uiState = {
|
||||
history: [],
|
||||
bannerData: {
|
||||
|
|
@ -54,10 +50,9 @@ describe('<AppHeader />', () => {
|
|||
bannerVisible: true,
|
||||
};
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<AppHeader version="1.0.0" />,
|
||||
{
|
||||
config: mockConfig,
|
||||
uiState,
|
||||
},
|
||||
);
|
||||
|
|
@ -69,7 +64,6 @@ describe('<AppHeader />', () => {
|
|||
});
|
||||
|
||||
it('should not render the banner when no flags are set', async () => {
|
||||
const mockConfig = makeFakeConfig();
|
||||
const uiState = {
|
||||
history: [],
|
||||
bannerData: {
|
||||
|
|
@ -78,10 +72,9 @@ describe('<AppHeader />', () => {
|
|||
},
|
||||
};
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<AppHeader version="1.0.0" />,
|
||||
{
|
||||
config: mockConfig,
|
||||
uiState,
|
||||
},
|
||||
);
|
||||
|
|
@ -93,7 +86,6 @@ describe('<AppHeader />', () => {
|
|||
});
|
||||
|
||||
it('should not render the default banner if shown count is 5 or more', async () => {
|
||||
const mockConfig = makeFakeConfig();
|
||||
const uiState = {
|
||||
history: [],
|
||||
bannerData: {
|
||||
|
|
@ -111,10 +103,9 @@ describe('<AppHeader />', () => {
|
|||
},
|
||||
});
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<AppHeader version="1.0.0" />,
|
||||
{
|
||||
config: mockConfig,
|
||||
uiState,
|
||||
},
|
||||
);
|
||||
|
|
@ -126,7 +117,6 @@ describe('<AppHeader />', () => {
|
|||
});
|
||||
|
||||
it('should increment the version count when default banner is displayed', async () => {
|
||||
const mockConfig = makeFakeConfig();
|
||||
const uiState = {
|
||||
history: [],
|
||||
bannerData: {
|
||||
|
|
@ -139,10 +129,9 @@ describe('<AppHeader />', () => {
|
|||
// and interfering with the expected persistentState.set call.
|
||||
persistentStateMock.setData({ tipsShown: 10 });
|
||||
|
||||
const { waitUntilReady, unmount } = renderWithProviders(
|
||||
const { waitUntilReady, unmount } = await renderWithProviders(
|
||||
<AppHeader version="1.0.0" />,
|
||||
{
|
||||
config: mockConfig,
|
||||
uiState,
|
||||
},
|
||||
);
|
||||
|
|
@ -161,7 +150,6 @@ describe('<AppHeader />', () => {
|
|||
});
|
||||
|
||||
it('should render banner text with unescaped newlines', async () => {
|
||||
const mockConfig = makeFakeConfig();
|
||||
const uiState = {
|
||||
history: [],
|
||||
bannerData: {
|
||||
|
|
@ -171,10 +159,9 @@ describe('<AppHeader />', () => {
|
|||
bannerVisible: true,
|
||||
};
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<AppHeader version="1.0.0" />,
|
||||
{
|
||||
config: mockConfig,
|
||||
uiState,
|
||||
},
|
||||
);
|
||||
|
|
@ -185,7 +172,6 @@ describe('<AppHeader />', () => {
|
|||
});
|
||||
|
||||
it('should render Tips when tipsShown is less than 10', async () => {
|
||||
const mockConfig = makeFakeConfig();
|
||||
const uiState = {
|
||||
history: [],
|
||||
bannerData: {
|
||||
|
|
@ -197,10 +183,9 @@ describe('<AppHeader />', () => {
|
|||
|
||||
persistentStateMock.setData({ tipsShown: 5 });
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<AppHeader version="1.0.0" />,
|
||||
{
|
||||
config: mockConfig,
|
||||
uiState,
|
||||
},
|
||||
);
|
||||
|
|
@ -212,7 +197,6 @@ describe('<AppHeader />', () => {
|
|||
});
|
||||
|
||||
it('should NOT render Tips when tipsShown is 10 or more', async () => {
|
||||
const mockConfig = makeFakeConfig();
|
||||
const uiState = {
|
||||
bannerData: {
|
||||
defaultText: '',
|
||||
|
|
@ -222,10 +206,9 @@ describe('<AppHeader />', () => {
|
|||
|
||||
persistentStateMock.setData({ tipsShown: 10 });
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<AppHeader version="1.0.0" />,
|
||||
{
|
||||
config: mockConfig,
|
||||
uiState,
|
||||
},
|
||||
);
|
||||
|
|
@ -238,7 +221,6 @@ describe('<AppHeader />', () => {
|
|||
it('should show tips until they have been shown 10 times (persistence flow)', async () => {
|
||||
persistentStateMock.setData({ tipsShown: 9 });
|
||||
|
||||
const mockConfig = makeFakeConfig();
|
||||
const uiState = {
|
||||
history: [],
|
||||
bannerData: {
|
||||
|
|
@ -249,8 +231,7 @@ describe('<AppHeader />', () => {
|
|||
};
|
||||
|
||||
// First session
|
||||
const session1 = renderWithProviders(<AppHeader version="1.0.0" />, {
|
||||
config: mockConfig,
|
||||
const session1 = await renderWithProviders(<AppHeader version="1.0.0" />, {
|
||||
uiState,
|
||||
});
|
||||
await session1.waitUntilReady();
|
||||
|
|
@ -260,9 +241,10 @@ describe('<AppHeader />', () => {
|
|||
session1.unmount();
|
||||
|
||||
// Second session - state is persisted in the fake
|
||||
const session2 = renderWithProviders(<AppHeader version="1.0.0" />, {
|
||||
config: mockConfig,
|
||||
});
|
||||
const session2 = await renderWithProviders(
|
||||
<AppHeader version="1.0.0" />,
|
||||
{},
|
||||
);
|
||||
await session2.waitUntilReady();
|
||||
|
||||
expect(session2.lastFrame()).not.toContain('Tips');
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ describe('AppHeader Icon Rendering', () => {
|
|||
it('renders the default icon in standard terminals', async () => {
|
||||
vi.mocked(isAppleTerminal).mockReturnValue(false);
|
||||
|
||||
const result = renderWithProviders(<AppHeader version="1.0.0" />);
|
||||
const result = await renderWithProviders(<AppHeader version="1.0.0" />);
|
||||
await result.waitUntilReady();
|
||||
|
||||
await expect(result).toMatchSvgSnapshot();
|
||||
|
|
@ -41,7 +41,7 @@ describe('AppHeader Icon Rendering', () => {
|
|||
it('renders the symmetric icon in Apple Terminal', async () => {
|
||||
vi.mocked(isAppleTerminal).mockReturnValue(true);
|
||||
|
||||
const result = renderWithProviders(<AppHeader version="1.0.0" />);
|
||||
const result = await renderWithProviders(<AppHeader version="1.0.0" />);
|
||||
await result.waitUntilReady();
|
||||
|
||||
await expect(result).toMatchSvgSnapshot();
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ describe('AskUserDialog', () => {
|
|||
];
|
||||
|
||||
it('renders question and options', async () => {
|
||||
const { lastFrame, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady } = await renderWithProviders(
|
||||
<AskUserDialog
|
||||
questions={authQuestion}
|
||||
onSubmit={vi.fn()}
|
||||
|
|
@ -140,7 +140,7 @@ describe('AskUserDialog', () => {
|
|||
])('Submission: $name', ({ name, questions, actions, expectedSubmit }) => {
|
||||
it(`submits correct values for ${name}`, async () => {
|
||||
const onSubmit = vi.fn();
|
||||
const { stdin } = renderWithProviders(
|
||||
const { stdin } = await renderWithProviders(
|
||||
<AskUserDialog
|
||||
questions={questions}
|
||||
onSubmit={onSubmit}
|
||||
|
|
@ -172,7 +172,7 @@ describe('AskUserDialog', () => {
|
|||
},
|
||||
] as Question[];
|
||||
|
||||
const { stdin, lastFrame, waitUntilReady } = renderWithProviders(
|
||||
const { stdin, lastFrame, waitUntilReady } = await renderWithProviders(
|
||||
<AskUserDialog
|
||||
questions={questions}
|
||||
onSubmit={vi.fn()}
|
||||
|
|
@ -196,7 +196,7 @@ describe('AskUserDialog', () => {
|
|||
|
||||
it('handles custom option in single select with inline typing', async () => {
|
||||
const onSubmit = vi.fn();
|
||||
const { stdin, lastFrame, waitUntilReady } = renderWithProviders(
|
||||
const { stdin, lastFrame, waitUntilReady } = await renderWithProviders(
|
||||
<AskUserDialog
|
||||
questions={authQuestion}
|
||||
onSubmit={onSubmit}
|
||||
|
|
@ -245,7 +245,7 @@ describe('AskUserDialog', () => {
|
|||
];
|
||||
|
||||
const onSubmit = vi.fn();
|
||||
const { stdin, lastFrame, waitUntilReady } = renderWithProviders(
|
||||
const { stdin, lastFrame, waitUntilReady } = await renderWithProviders(
|
||||
<AskUserDialog
|
||||
questions={authQuestionWithOther}
|
||||
onSubmit={onSubmit}
|
||||
|
|
@ -307,7 +307,7 @@ describe('AskUserDialog', () => {
|
|||
},
|
||||
];
|
||||
|
||||
const { lastFrame, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady } = await renderWithProviders(
|
||||
<AskUserDialog
|
||||
questions={questions}
|
||||
onSubmit={vi.fn()}
|
||||
|
|
@ -341,7 +341,7 @@ describe('AskUserDialog', () => {
|
|||
);
|
||||
|
||||
it('navigates to custom option when typing unbound characters (Type-to-Jump)', async () => {
|
||||
const { stdin, lastFrame, waitUntilReady } = renderWithProviders(
|
||||
const { stdin, lastFrame, waitUntilReady } = await renderWithProviders(
|
||||
<AskUserDialog
|
||||
questions={authQuestion}
|
||||
onSubmit={vi.fn()}
|
||||
|
|
@ -397,7 +397,7 @@ describe('AskUserDialog', () => {
|
|||
},
|
||||
];
|
||||
|
||||
const { lastFrame, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady } = await renderWithProviders(
|
||||
<AskUserDialog
|
||||
questions={multiQuestions}
|
||||
onSubmit={vi.fn()}
|
||||
|
|
@ -412,7 +412,7 @@ describe('AskUserDialog', () => {
|
|||
});
|
||||
|
||||
it('hides progress header for single question', async () => {
|
||||
const { lastFrame, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady } = await renderWithProviders(
|
||||
<AskUserDialog
|
||||
questions={authQuestion}
|
||||
onSubmit={vi.fn()}
|
||||
|
|
@ -427,7 +427,7 @@ describe('AskUserDialog', () => {
|
|||
});
|
||||
|
||||
it('shows keyboard hints', async () => {
|
||||
const { lastFrame, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady } = await renderWithProviders(
|
||||
<AskUserDialog
|
||||
questions={authQuestion}
|
||||
onSubmit={vi.fn()}
|
||||
|
|
@ -461,7 +461,7 @@ describe('AskUserDialog', () => {
|
|||
},
|
||||
];
|
||||
|
||||
const { stdin, lastFrame, waitUntilReady } = renderWithProviders(
|
||||
const { stdin, lastFrame, waitUntilReady } = await renderWithProviders(
|
||||
<AskUserDialog
|
||||
questions={multiQuestions}
|
||||
onSubmit={vi.fn()}
|
||||
|
|
@ -508,7 +508,7 @@ describe('AskUserDialog', () => {
|
|||
];
|
||||
|
||||
const onSubmit = vi.fn();
|
||||
const { stdin, lastFrame, waitUntilReady } = renderWithProviders(
|
||||
const { stdin, lastFrame, waitUntilReady } = await renderWithProviders(
|
||||
<AskUserDialog
|
||||
questions={multiQuestions}
|
||||
onSubmit={onSubmit}
|
||||
|
|
@ -582,7 +582,7 @@ describe('AskUserDialog', () => {
|
|||
},
|
||||
];
|
||||
|
||||
const { lastFrame, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady } = await renderWithProviders(
|
||||
<AskUserDialog
|
||||
questions={multiQuestions}
|
||||
onSubmit={vi.fn()}
|
||||
|
|
@ -614,7 +614,7 @@ describe('AskUserDialog', () => {
|
|||
},
|
||||
];
|
||||
|
||||
const { stdin, lastFrame, waitUntilReady } = renderWithProviders(
|
||||
const { stdin, lastFrame, waitUntilReady } = await renderWithProviders(
|
||||
<AskUserDialog
|
||||
questions={multiQuestions}
|
||||
onSubmit={vi.fn()}
|
||||
|
|
@ -664,7 +664,7 @@ describe('AskUserDialog', () => {
|
|||
},
|
||||
];
|
||||
|
||||
const { stdin, lastFrame, waitUntilReady } = renderWithProviders(
|
||||
const { stdin, lastFrame, waitUntilReady } = await renderWithProviders(
|
||||
<AskUserDialog
|
||||
questions={multiQuestions}
|
||||
onSubmit={vi.fn()}
|
||||
|
|
@ -703,7 +703,7 @@ describe('AskUserDialog', () => {
|
|||
];
|
||||
|
||||
const onSubmit = vi.fn();
|
||||
const { stdin } = renderWithProviders(
|
||||
const { stdin } = await renderWithProviders(
|
||||
<AskUserDialog
|
||||
questions={multiQuestions}
|
||||
onSubmit={onSubmit}
|
||||
|
|
@ -736,7 +736,7 @@ describe('AskUserDialog', () => {
|
|||
},
|
||||
];
|
||||
|
||||
const { lastFrame, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady } = await renderWithProviders(
|
||||
<AskUserDialog
|
||||
questions={textQuestion}
|
||||
onSubmit={vi.fn()}
|
||||
|
|
@ -759,7 +759,7 @@ describe('AskUserDialog', () => {
|
|||
},
|
||||
];
|
||||
|
||||
const { lastFrame, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady } = await renderWithProviders(
|
||||
<AskUserDialog
|
||||
questions={textQuestion}
|
||||
onSubmit={vi.fn()}
|
||||
|
|
@ -782,7 +782,7 @@ describe('AskUserDialog', () => {
|
|||
},
|
||||
];
|
||||
|
||||
const { stdin, lastFrame, waitUntilReady } = renderWithProviders(
|
||||
const { stdin, lastFrame, waitUntilReady } = await renderWithProviders(
|
||||
<AskUserDialog
|
||||
questions={textQuestion}
|
||||
onSubmit={vi.fn()}
|
||||
|
|
@ -820,7 +820,7 @@ describe('AskUserDialog', () => {
|
|||
},
|
||||
];
|
||||
|
||||
const { lastFrame, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady } = await renderWithProviders(
|
||||
<AskUserDialog
|
||||
questions={textQuestion}
|
||||
onSubmit={vi.fn()}
|
||||
|
|
@ -853,7 +853,7 @@ describe('AskUserDialog', () => {
|
|||
},
|
||||
];
|
||||
|
||||
const { stdin, lastFrame, waitUntilReady } = renderWithProviders(
|
||||
const { stdin, lastFrame, waitUntilReady } = await renderWithProviders(
|
||||
<AskUserDialog
|
||||
questions={mixedQuestions}
|
||||
onSubmit={vi.fn()}
|
||||
|
|
@ -903,7 +903,7 @@ describe('AskUserDialog', () => {
|
|||
];
|
||||
|
||||
const onSubmit = vi.fn();
|
||||
const { stdin, lastFrame, waitUntilReady } = renderWithProviders(
|
||||
const { stdin, lastFrame, waitUntilReady } = await renderWithProviders(
|
||||
<AskUserDialog
|
||||
questions={mixedQuestions}
|
||||
onSubmit={onSubmit}
|
||||
|
|
@ -959,7 +959,7 @@ describe('AskUserDialog', () => {
|
|||
];
|
||||
|
||||
const onSubmit = vi.fn();
|
||||
const { stdin } = renderWithProviders(
|
||||
const { stdin } = await renderWithProviders(
|
||||
<AskUserDialog
|
||||
questions={textQuestion}
|
||||
onSubmit={onSubmit}
|
||||
|
|
@ -986,7 +986,7 @@ describe('AskUserDialog', () => {
|
|||
];
|
||||
|
||||
const onCancel = vi.fn();
|
||||
const { stdin, lastFrame, waitUntilReady } = renderWithProviders(
|
||||
const { stdin, lastFrame, waitUntilReady } = await renderWithProviders(
|
||||
<AskUserDialog
|
||||
questions={textQuestion}
|
||||
onSubmit={vi.fn()}
|
||||
|
|
@ -1036,7 +1036,7 @@ describe('AskUserDialog', () => {
|
|||
},
|
||||
];
|
||||
|
||||
const { stdin, lastFrame, waitUntilReady } = renderWithProviders(
|
||||
const { stdin, lastFrame, waitUntilReady } = await renderWithProviders(
|
||||
<AskUserDialog
|
||||
questions={multiQuestions}
|
||||
onSubmit={vi.fn()}
|
||||
|
|
@ -1102,7 +1102,7 @@ describe('AskUserDialog', () => {
|
|||
];
|
||||
|
||||
const onSubmit = vi.fn();
|
||||
const { stdin, lastFrame, waitUntilReady } = renderWithProviders(
|
||||
const { stdin, lastFrame, waitUntilReady } = await renderWithProviders(
|
||||
<AskUserDialog
|
||||
questions={multiQuestions}
|
||||
onSubmit={onSubmit}
|
||||
|
|
@ -1154,7 +1154,7 @@ describe('AskUserDialog', () => {
|
|||
},
|
||||
];
|
||||
|
||||
const { lastFrame, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady } = await renderWithProviders(
|
||||
<AskUserDialog
|
||||
questions={questions}
|
||||
onSubmit={vi.fn()}
|
||||
|
|
@ -1184,7 +1184,7 @@ describe('AskUserDialog', () => {
|
|||
},
|
||||
];
|
||||
|
||||
const { lastFrame, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady } = await renderWithProviders(
|
||||
<AskUserDialog
|
||||
questions={questions}
|
||||
onSubmit={vi.fn()}
|
||||
|
|
@ -1217,7 +1217,7 @@ describe('AskUserDialog', () => {
|
|||
},
|
||||
];
|
||||
|
||||
const { lastFrame, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady } = await renderWithProviders(
|
||||
<AskUserDialog
|
||||
questions={questions}
|
||||
onSubmit={vi.fn()}
|
||||
|
|
@ -1248,7 +1248,7 @@ describe('AskUserDialog', () => {
|
|||
},
|
||||
];
|
||||
|
||||
const { lastFrame, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady } = await renderWithProviders(
|
||||
<AskUserDialog
|
||||
questions={questions}
|
||||
onSubmit={vi.fn()}
|
||||
|
|
@ -1287,7 +1287,7 @@ describe('AskUserDialog', () => {
|
|||
availableTerminalHeight: 5, // Small height to force scroll arrows
|
||||
} as UIState;
|
||||
|
||||
const { lastFrame, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady } = await renderWithProviders(
|
||||
<UIStateContext.Provider value={mockUIState}>
|
||||
<AskUserDialog
|
||||
questions={questions}
|
||||
|
|
@ -1326,7 +1326,7 @@ describe('AskUserDialog', () => {
|
|||
availableTerminalHeight: 5,
|
||||
} as UIState;
|
||||
|
||||
const { lastFrame, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady } = await renderWithProviders(
|
||||
<UIStateContext.Provider value={mockUIState}>
|
||||
<AskUserDialog
|
||||
questions={questions}
|
||||
|
|
@ -1365,7 +1365,7 @@ describe('AskUserDialog', () => {
|
|||
},
|
||||
];
|
||||
|
||||
const { stdin, lastFrame, waitUntilReady } = renderWithProviders(
|
||||
const { stdin, lastFrame, waitUntilReady } = await renderWithProviders(
|
||||
<AskUserDialog
|
||||
questions={questions}
|
||||
onSubmit={vi.fn()}
|
||||
|
|
@ -1399,7 +1399,7 @@ describe('AskUserDialog', () => {
|
|||
},
|
||||
];
|
||||
|
||||
const { stdin, lastFrame, waitUntilReady } = renderWithProviders(
|
||||
const { stdin, lastFrame, waitUntilReady } = await renderWithProviders(
|
||||
<AskUserDialog
|
||||
questions={questions}
|
||||
onSubmit={vi.fn()}
|
||||
|
|
@ -1432,7 +1432,7 @@ describe('AskUserDialog', () => {
|
|||
];
|
||||
|
||||
const onSubmit = vi.fn();
|
||||
const { stdin } = renderWithProviders(
|
||||
const { stdin } = await renderWithProviders(
|
||||
<AskUserDialog
|
||||
questions={questions}
|
||||
onSubmit={onSubmit}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ describe('Banner', () => {
|
|||
['info mode', false, 'Info Message'],
|
||||
['multi-line warning', true, 'Title Line\\nBody Line 1\\nBody Line 2'],
|
||||
])('renders in %s', async (_, isWarning, text) => {
|
||||
const renderResult = renderWithProviders(
|
||||
const renderResult = await renderWithProviders(
|
||||
<Banner bannerText={text} isWarning={isWarning} width={80} />,
|
||||
);
|
||||
await renderResult.waitUntilReady();
|
||||
|
|
@ -24,7 +24,7 @@ describe('Banner', () => {
|
|||
|
||||
it('handles newlines in text', async () => {
|
||||
const text = 'Line 1\\nLine 2';
|
||||
const renderResult = renderWithProviders(
|
||||
const renderResult = await renderWithProviders(
|
||||
<Banner bannerText={text} isWarning={false} width={80} />,
|
||||
);
|
||||
await renderResult.waitUntilReady();
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ describe('Key Bubbling Regression', () => {
|
|||
];
|
||||
|
||||
it('does not navigate when pressing "j" or "k" in a focused text input', async () => {
|
||||
const { stdin, lastFrame } = renderWithProviders(
|
||||
const { stdin, lastFrame } = await renderWithProviders(
|
||||
<AskUserDialog
|
||||
questions={choiceQuestion}
|
||||
onSubmit={vi.fn()}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,9 @@ describe('<CliSpinner />', () => {
|
|||
|
||||
it('should increment debugNumAnimatedComponents on mount and decrement on unmount', async () => {
|
||||
expect(debugState.debugNumAnimatedComponents).toBe(0);
|
||||
const { waitUntilReady, unmount } = renderWithProviders(<CliSpinner />);
|
||||
const { waitUntilReady, unmount } = await renderWithProviders(
|
||||
<CliSpinner />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
expect(debugState.debugNumAnimatedComponents).toBe(1);
|
||||
unmount();
|
||||
|
|
@ -26,7 +28,7 @@ describe('<CliSpinner />', () => {
|
|||
|
||||
it('should not render when showSpinner is false', async () => {
|
||||
const settings = createMockSettings({ ui: { showSpinner: false } });
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<CliSpinner />,
|
||||
{ settings },
|
||||
);
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ describe('ColorsDisplay', () => {
|
|||
|
||||
it('renders correctly', async () => {
|
||||
const mockTheme = themeManager.getActiveTheme();
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ColorsDisplay activeTheme={mockTheme} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ describe('ConfigInitDisplay', () => {
|
|||
});
|
||||
|
||||
it('renders initial state', async () => {
|
||||
const { lastFrame, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady } = await renderWithProviders(
|
||||
<ConfigInitDisplay />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -59,7 +59,7 @@ describe('ConfigInitDisplay', () => {
|
|||
return coreEvents;
|
||||
});
|
||||
|
||||
const { lastFrame } = renderWithProviders(<ConfigInitDisplay />);
|
||||
const { lastFrame } = await renderWithProviders(<ConfigInitDisplay />);
|
||||
|
||||
// Wait for listener to be registered
|
||||
await waitFor(() => {
|
||||
|
|
@ -97,7 +97,7 @@ describe('ConfigInitDisplay', () => {
|
|||
return coreEvents;
|
||||
});
|
||||
|
||||
const { lastFrame } = renderWithProviders(<ConfigInitDisplay />);
|
||||
const { lastFrame } = await renderWithProviders(<ConfigInitDisplay />);
|
||||
|
||||
await waitFor(() => {
|
||||
if (!listener) throw new Error('Listener not registered yet');
|
||||
|
|
@ -133,7 +133,7 @@ describe('ConfigInitDisplay', () => {
|
|||
return coreEvents;
|
||||
});
|
||||
|
||||
const { lastFrame } = renderWithProviders(<ConfigInitDisplay />);
|
||||
const { lastFrame } = await renderWithProviders(<ConfigInitDisplay />);
|
||||
|
||||
await waitFor(() => {
|
||||
if (!listener) throw new Error('Listener not registered yet');
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ vi.mock('@google/gemini-cli-core', async (importOriginal) => {
|
|||
|
||||
describe('ContextUsageDisplay', () => {
|
||||
it('renders correct percentage used', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ContextUsageDisplay
|
||||
promptTokenCount={5000}
|
||||
model="gemini-pro"
|
||||
|
|
@ -33,7 +33,7 @@ describe('ContextUsageDisplay', () => {
|
|||
});
|
||||
|
||||
it('renders correctly when usage is 0%', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ContextUsageDisplay
|
||||
promptTokenCount={0}
|
||||
model="gemini-pro"
|
||||
|
|
@ -47,7 +47,7 @@ describe('ContextUsageDisplay', () => {
|
|||
});
|
||||
|
||||
it('renders abbreviated label when terminal width is small', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ContextUsageDisplay
|
||||
promptTokenCount={2000}
|
||||
model="gemini-pro"
|
||||
|
|
@ -63,7 +63,7 @@ describe('ContextUsageDisplay', () => {
|
|||
});
|
||||
|
||||
it('renders 80% correctly', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ContextUsageDisplay
|
||||
promptTokenCount={8000}
|
||||
model="gemini-pro"
|
||||
|
|
@ -77,7 +77,7 @@ describe('ContextUsageDisplay', () => {
|
|||
});
|
||||
|
||||
it('renders 100% when full', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ContextUsageDisplay
|
||||
promptTokenCount={10000}
|
||||
model="gemini-pro"
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ vi.mock('./shared/ScrollableList.js', () => ({
|
|||
|
||||
describe('DetailedMessagesDisplay', () => {
|
||||
it('renders nothing when messages are empty', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<DetailedMessagesDisplay
|
||||
messages={[]}
|
||||
maxHeight={10}
|
||||
|
|
@ -54,7 +54,7 @@ describe('DetailedMessagesDisplay', () => {
|
|||
{ type: 'debug', content: 'Debug message', count: 1 },
|
||||
];
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<DetailedMessagesDisplay
|
||||
messages={messages}
|
||||
maxHeight={20}
|
||||
|
|
@ -77,7 +77,7 @@ describe('DetailedMessagesDisplay', () => {
|
|||
{ type: 'error', content: 'Error message', count: 1 },
|
||||
];
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<DetailedMessagesDisplay
|
||||
messages={messages}
|
||||
maxHeight={20}
|
||||
|
|
@ -98,7 +98,7 @@ describe('DetailedMessagesDisplay', () => {
|
|||
{ type: 'error', content: 'Error message', count: 1 },
|
||||
];
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<DetailedMessagesDisplay
|
||||
messages={messages}
|
||||
maxHeight={20}
|
||||
|
|
@ -119,7 +119,7 @@ describe('DetailedMessagesDisplay', () => {
|
|||
{ type: 'log', content: 'Repeated message', count: 5 },
|
||||
];
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<DetailedMessagesDisplay
|
||||
messages={messages}
|
||||
maxHeight={10}
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ describe('DialogManager', () => {
|
|||
};
|
||||
|
||||
it('renders nothing by default', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<DialogManager {...defaultProps} />,
|
||||
{ uiState: baseUiState as Partial<UIState> as UIState },
|
||||
);
|
||||
|
|
@ -197,7 +197,7 @@ describe('DialogManager', () => {
|
|||
it.each(testCases)(
|
||||
'renders %s when state is %o',
|
||||
async (uiStateOverride, expectedComponent) => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<DialogManager {...defaultProps} />,
|
||||
{
|
||||
uiState: {
|
||||
|
|
|
|||
|
|
@ -51,11 +51,11 @@ describe('EditorSettingsDialog', () => {
|
|||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
const renderWithProvider = (ui: React.ReactElement) =>
|
||||
const renderWithProvider = async (ui: React.ReactElement) =>
|
||||
renderWithProviders(ui);
|
||||
|
||||
it('renders correctly', async () => {
|
||||
const { lastFrame, waitUntilReady } = renderWithProvider(
|
||||
const { lastFrame, waitUntilReady } = await renderWithProvider(
|
||||
<EditorSettingsDialog
|
||||
onSelect={vi.fn()}
|
||||
settings={mockSettings}
|
||||
|
|
@ -68,7 +68,7 @@ describe('EditorSettingsDialog', () => {
|
|||
|
||||
it('calls onSelect when an editor is selected', async () => {
|
||||
const onSelect = vi.fn();
|
||||
const { lastFrame, waitUntilReady } = renderWithProvider(
|
||||
const { lastFrame, waitUntilReady } = await renderWithProvider(
|
||||
<EditorSettingsDialog
|
||||
onSelect={onSelect}
|
||||
settings={mockSettings}
|
||||
|
|
@ -81,7 +81,7 @@ describe('EditorSettingsDialog', () => {
|
|||
});
|
||||
|
||||
it('switches focus between editor and scope sections on Tab', async () => {
|
||||
const { lastFrame, stdin, waitUntilReady } = renderWithProvider(
|
||||
const { lastFrame, stdin, waitUntilReady } = await renderWithProvider(
|
||||
<EditorSettingsDialog
|
||||
onSelect={vi.fn()}
|
||||
settings={mockSettings}
|
||||
|
|
@ -127,7 +127,7 @@ describe('EditorSettingsDialog', () => {
|
|||
|
||||
it('calls onExit when Escape is pressed', async () => {
|
||||
const onExit = vi.fn();
|
||||
const { stdin, waitUntilReady } = renderWithProvider(
|
||||
const { stdin, waitUntilReady } = await renderWithProvider(
|
||||
<EditorSettingsDialog
|
||||
onSelect={vi.fn()}
|
||||
settings={mockSettings}
|
||||
|
|
@ -162,7 +162,7 @@ describe('EditorSettingsDialog', () => {
|
|||
},
|
||||
} as unknown as LoadedSettings;
|
||||
|
||||
const { lastFrame, waitUntilReady } = renderWithProvider(
|
||||
const { lastFrame, waitUntilReady } = await renderWithProvider(
|
||||
<EditorSettingsDialog
|
||||
onSelect={vi.fn()}
|
||||
settings={settingsWithOtherScope}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ describe('EmptyWalletDialog', () => {
|
|||
|
||||
describe('rendering', () => {
|
||||
it('should match snapshot with fallback available', async () => {
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithProviders(
|
||||
<EmptyWalletDialog
|
||||
failedModel="gemini-2.5-pro"
|
||||
fallbackModel="gemini-3-flash-preview"
|
||||
|
|
@ -45,7 +45,7 @@ describe('EmptyWalletDialog', () => {
|
|||
});
|
||||
|
||||
it('should match snapshot without fallback', async () => {
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithProviders(
|
||||
<EmptyWalletDialog
|
||||
failedModel="gemini-2.5-pro"
|
||||
onChoice={mockOnChoice}
|
||||
|
|
@ -58,7 +58,7 @@ describe('EmptyWalletDialog', () => {
|
|||
});
|
||||
|
||||
it('should display the model name and usage limit message', async () => {
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithProviders(
|
||||
<EmptyWalletDialog
|
||||
failedModel="gemini-2.5-pro"
|
||||
onChoice={mockOnChoice}
|
||||
|
|
@ -73,7 +73,7 @@ describe('EmptyWalletDialog', () => {
|
|||
});
|
||||
|
||||
it('should display purchase prompt and credits update notice', async () => {
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithProviders(
|
||||
<EmptyWalletDialog
|
||||
failedModel="gemini-2.5-pro"
|
||||
onChoice={mockOnChoice}
|
||||
|
|
@ -90,7 +90,7 @@ describe('EmptyWalletDialog', () => {
|
|||
});
|
||||
|
||||
it('should display reset time when provided', async () => {
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithProviders(
|
||||
<EmptyWalletDialog
|
||||
failedModel="gemini-2.5-pro"
|
||||
resetTime="3:45 PM"
|
||||
|
|
@ -106,7 +106,7 @@ describe('EmptyWalletDialog', () => {
|
|||
});
|
||||
|
||||
it('should not display reset time when not provided', async () => {
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithProviders(
|
||||
<EmptyWalletDialog
|
||||
failedModel="gemini-2.5-pro"
|
||||
onChoice={mockOnChoice}
|
||||
|
|
@ -120,7 +120,7 @@ describe('EmptyWalletDialog', () => {
|
|||
});
|
||||
|
||||
it('should display slash command hints', async () => {
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithProviders(
|
||||
<EmptyWalletDialog
|
||||
failedModel="gemini-2.5-pro"
|
||||
onChoice={mockOnChoice}
|
||||
|
|
@ -139,7 +139,7 @@ describe('EmptyWalletDialog', () => {
|
|||
describe('onChoice handling', () => {
|
||||
it('should call onGetCredits and onChoice when get_credits is selected', async () => {
|
||||
// get_credits is the first item, so just press Enter
|
||||
const { unmount, stdin, waitUntilReady } = renderWithProviders(
|
||||
const { unmount, stdin, waitUntilReady } = await renderWithProviders(
|
||||
<EmptyWalletDialog
|
||||
failedModel="gemini-2.5-pro"
|
||||
onChoice={mockOnChoice}
|
||||
|
|
@ -158,7 +158,7 @@ describe('EmptyWalletDialog', () => {
|
|||
});
|
||||
|
||||
it('should call onChoice without onGetCredits when onGetCredits is not provided', async () => {
|
||||
const { unmount, stdin, waitUntilReady } = renderWithProviders(
|
||||
const { unmount, stdin, waitUntilReady } = await renderWithProviders(
|
||||
<EmptyWalletDialog
|
||||
failedModel="gemini-2.5-pro"
|
||||
onChoice={mockOnChoice}
|
||||
|
|
@ -177,7 +177,7 @@ describe('EmptyWalletDialog', () => {
|
|||
it('should call onChoice with use_fallback when selected', async () => {
|
||||
// With fallback: items are [get_credits, use_fallback, stop]
|
||||
// use_fallback is the second item: Down + Enter
|
||||
const { unmount, stdin, waitUntilReady } = renderWithProviders(
|
||||
const { unmount, stdin, waitUntilReady } = await renderWithProviders(
|
||||
<EmptyWalletDialog
|
||||
failedModel="gemini-2.5-pro"
|
||||
fallbackModel="gemini-3-flash-preview"
|
||||
|
|
@ -198,7 +198,7 @@ describe('EmptyWalletDialog', () => {
|
|||
it('should call onChoice with stop when selected', async () => {
|
||||
// Without fallback: items are [get_credits, stop]
|
||||
// stop is the second item: Down + Enter
|
||||
const { unmount, stdin, waitUntilReady } = renderWithProviders(
|
||||
const { unmount, stdin, waitUntilReady } = await renderWithProviders(
|
||||
<EmptyWalletDialog
|
||||
failedModel="gemini-2.5-pro"
|
||||
onChoice={mockOnChoice}
|
||||
|
|
|
|||
|
|
@ -139,7 +139,7 @@ Implement a comprehensive authentication system with multiple providers.
|
|||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
const renderDialog = (options?: { useAlternateBuffer?: boolean }) => {
|
||||
const renderDialog = async (options?: { useAlternateBuffer?: boolean }) => {
|
||||
const useAlternateBuffer = options?.useAlternateBuffer ?? true;
|
||||
return renderWithProviders(
|
||||
<ExitPlanModeDialog
|
||||
|
|
@ -176,7 +176,9 @@ Implement a comprehensive authentication system with multiple providers.
|
|||
'useAlternateBuffer: $useAlternateBuffer',
|
||||
({ useAlternateBuffer }) => {
|
||||
it('renders correctly with plan content', async () => {
|
||||
const { lastFrame } = renderDialog({ useAlternateBuffer });
|
||||
const { lastFrame } = await act(async () =>
|
||||
renderDialog({ useAlternateBuffer }),
|
||||
);
|
||||
|
||||
// Advance timers to pass the debounce period
|
||||
await act(async () => {
|
||||
|
|
@ -199,7 +201,9 @@ Implement a comprehensive authentication system with multiple providers.
|
|||
});
|
||||
|
||||
it('calls onApprove with AUTO_EDIT when first option is selected', async () => {
|
||||
const { stdin, lastFrame } = renderDialog({ useAlternateBuffer });
|
||||
const { stdin, lastFrame } = await act(async () =>
|
||||
renderDialog({ useAlternateBuffer }),
|
||||
);
|
||||
|
||||
await act(async () => {
|
||||
vi.runAllTimers();
|
||||
|
|
@ -217,7 +221,9 @@ Implement a comprehensive authentication system with multiple providers.
|
|||
});
|
||||
|
||||
it('calls onApprove with DEFAULT when second option is selected', async () => {
|
||||
const { stdin, lastFrame } = renderDialog({ useAlternateBuffer });
|
||||
const { stdin, lastFrame } = await act(async () =>
|
||||
renderDialog({ useAlternateBuffer }),
|
||||
);
|
||||
|
||||
await act(async () => {
|
||||
vi.runAllTimers();
|
||||
|
|
@ -236,7 +242,9 @@ Implement a comprehensive authentication system with multiple providers.
|
|||
});
|
||||
|
||||
it('calls onFeedback when feedback is typed and submitted', async () => {
|
||||
const { stdin, lastFrame } = renderDialog({ useAlternateBuffer });
|
||||
const { stdin, lastFrame } = await act(async () =>
|
||||
renderDialog({ useAlternateBuffer }),
|
||||
);
|
||||
|
||||
await act(async () => {
|
||||
vi.runAllTimers();
|
||||
|
|
@ -267,7 +275,9 @@ Implement a comprehensive authentication system with multiple providers.
|
|||
});
|
||||
|
||||
it('calls onCancel when Esc is pressed', async () => {
|
||||
const { stdin, lastFrame } = renderDialog({ useAlternateBuffer });
|
||||
const { stdin, lastFrame } = await act(async () =>
|
||||
renderDialog({ useAlternateBuffer }),
|
||||
);
|
||||
|
||||
await act(async () => {
|
||||
vi.runAllTimers();
|
||||
|
|
@ -293,7 +303,9 @@ Implement a comprehensive authentication system with multiple providers.
|
|||
error: 'File not found',
|
||||
});
|
||||
|
||||
const { lastFrame } = renderDialog({ useAlternateBuffer });
|
||||
const { lastFrame } = await act(async () =>
|
||||
renderDialog({ useAlternateBuffer }),
|
||||
);
|
||||
|
||||
await act(async () => {
|
||||
vi.runAllTimers();
|
||||
|
|
@ -309,7 +321,9 @@ Implement a comprehensive authentication system with multiple providers.
|
|||
it('displays error state when plan file is empty', async () => {
|
||||
vi.mocked(validatePlanContent).mockResolvedValue('Plan file is empty.');
|
||||
|
||||
const { lastFrame } = renderDialog({ useAlternateBuffer });
|
||||
const { lastFrame } = await act(async () =>
|
||||
renderDialog({ useAlternateBuffer }),
|
||||
);
|
||||
|
||||
await act(async () => {
|
||||
vi.runAllTimers();
|
||||
|
|
@ -328,7 +342,9 @@ Implement a comprehensive authentication system with multiple providers.
|
|||
returnDisplay: 'Read file',
|
||||
});
|
||||
|
||||
const { lastFrame } = renderDialog({ useAlternateBuffer });
|
||||
const { lastFrame } = await act(async () =>
|
||||
renderDialog({ useAlternateBuffer }),
|
||||
);
|
||||
|
||||
await act(async () => {
|
||||
vi.runAllTimers();
|
||||
|
|
@ -344,7 +360,9 @@ Implement a comprehensive authentication system with multiple providers.
|
|||
});
|
||||
|
||||
it('allows number key quick selection', async () => {
|
||||
const { stdin, lastFrame } = renderDialog({ useAlternateBuffer });
|
||||
const { stdin, lastFrame } = await act(async () =>
|
||||
renderDialog({ useAlternateBuffer }),
|
||||
);
|
||||
|
||||
await act(async () => {
|
||||
vi.runAllTimers();
|
||||
|
|
@ -363,7 +381,9 @@ Implement a comprehensive authentication system with multiple providers.
|
|||
});
|
||||
|
||||
it('clears feedback text when Ctrl+C is pressed while editing', async () => {
|
||||
const { stdin, lastFrame } = renderDialog({ useAlternateBuffer });
|
||||
const { stdin, lastFrame } = await act(async () =>
|
||||
renderDialog({ useAlternateBuffer }),
|
||||
);
|
||||
|
||||
await act(async () => {
|
||||
vi.runAllTimers();
|
||||
|
|
@ -420,7 +440,7 @@ Implement a comprehensive authentication system with multiple providers.
|
|||
return <>{children}</>;
|
||||
};
|
||||
|
||||
const { stdin, lastFrame } = renderWithProviders(
|
||||
const { stdin, lastFrame } = await renderWithProviders(
|
||||
<BubbleListener>
|
||||
<ExitPlanModeDialog
|
||||
planPath={mockPlanFullPath}
|
||||
|
|
@ -491,7 +511,9 @@ Implement a comprehensive authentication system with multiple providers.
|
|||
});
|
||||
|
||||
it('does not submit empty feedback when Enter is pressed', async () => {
|
||||
const { stdin, lastFrame } = renderDialog({ useAlternateBuffer });
|
||||
const { stdin, lastFrame } = await act(async () =>
|
||||
renderDialog({ useAlternateBuffer }),
|
||||
);
|
||||
|
||||
await act(async () => {
|
||||
vi.runAllTimers();
|
||||
|
|
@ -518,7 +540,9 @@ Implement a comprehensive authentication system with multiple providers.
|
|||
});
|
||||
|
||||
it('allows arrow navigation while typing feedback to change selection', async () => {
|
||||
const { stdin, lastFrame } = renderDialog({ useAlternateBuffer });
|
||||
const { stdin, lastFrame } = await act(async () =>
|
||||
renderDialog({ useAlternateBuffer }),
|
||||
);
|
||||
|
||||
await act(async () => {
|
||||
vi.runAllTimers();
|
||||
|
|
@ -550,7 +574,9 @@ Implement a comprehensive authentication system with multiple providers.
|
|||
});
|
||||
|
||||
it('automatically submits feedback when Ctrl+X is used to edit the plan', async () => {
|
||||
const { stdin, lastFrame } = renderDialog({ useAlternateBuffer });
|
||||
const { stdin, lastFrame } = await act(async () =>
|
||||
renderDialog({ useAlternateBuffer }),
|
||||
);
|
||||
|
||||
await act(async () => {
|
||||
vi.runAllTimers();
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ describe('FolderTrustDialog', () => {
|
|||
});
|
||||
|
||||
it('should render the dialog with title and description', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<FolderTrustDialog onSelect={vi.fn()} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -72,7 +72,7 @@ describe('FolderTrustDialog', () => {
|
|||
discoveryErrors: [],
|
||||
securityWarnings: [],
|
||||
};
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithProviders(
|
||||
<FolderTrustDialog
|
||||
onSelect={vi.fn()}
|
||||
discoveryResults={discoveryResults}
|
||||
|
|
@ -103,7 +103,7 @@ describe('FolderTrustDialog', () => {
|
|||
discoveryErrors: [],
|
||||
securityWarnings: [],
|
||||
};
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithProviders(
|
||||
<FolderTrustDialog
|
||||
onSelect={vi.fn()}
|
||||
discoveryResults={discoveryResults}
|
||||
|
|
@ -135,7 +135,7 @@ describe('FolderTrustDialog', () => {
|
|||
discoveryErrors: [],
|
||||
securityWarnings: [],
|
||||
};
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithProviders(
|
||||
<FolderTrustDialog
|
||||
onSelect={vi.fn()}
|
||||
discoveryResults={discoveryResults}
|
||||
|
|
@ -165,7 +165,7 @@ describe('FolderTrustDialog', () => {
|
|||
securityWarnings: [],
|
||||
};
|
||||
|
||||
const { lastFrame, unmount } = renderWithProviders(
|
||||
const { lastFrame, unmount } = await renderWithProviders(
|
||||
<FolderTrustDialog
|
||||
onSelect={vi.fn()}
|
||||
discoveryResults={discoveryResults}
|
||||
|
|
@ -192,7 +192,7 @@ describe('FolderTrustDialog', () => {
|
|||
// because it's handled in AppContainer.
|
||||
// But we can re-render with constrainHeight: false.
|
||||
const { lastFrame: lastFrameExpanded, unmount: unmountExpanded } =
|
||||
renderWithProviders(
|
||||
await renderWithProviders(
|
||||
<FolderTrustDialog
|
||||
onSelect={vi.fn()}
|
||||
discoveryResults={discoveryResults}
|
||||
|
|
@ -217,9 +217,10 @@ describe('FolderTrustDialog', () => {
|
|||
|
||||
it('should display exit message and call process.exit and not call onSelect when escape is pressed', async () => {
|
||||
const onSelect = vi.fn();
|
||||
const { lastFrame, stdin, waitUntilReady, unmount } = renderWithProviders(
|
||||
<FolderTrustDialog onSelect={onSelect} isRestarting={false} />,
|
||||
);
|
||||
const { lastFrame, stdin, waitUntilReady, unmount } =
|
||||
await renderWithProviders(
|
||||
<FolderTrustDialog onSelect={onSelect} isRestarting={false} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
||||
await act(async () => {
|
||||
|
|
@ -245,7 +246,7 @@ describe('FolderTrustDialog', () => {
|
|||
});
|
||||
|
||||
it('should display restart message when isRestarting is true', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<FolderTrustDialog onSelect={vi.fn()} isRestarting={true} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -259,7 +260,7 @@ describe('FolderTrustDialog', () => {
|
|||
const relaunchApp = vi
|
||||
.spyOn(processUtils, 'relaunchApp')
|
||||
.mockResolvedValue(undefined);
|
||||
const { waitUntilReady, unmount } = renderWithProviders(
|
||||
const { waitUntilReady, unmount } = await renderWithProviders(
|
||||
<FolderTrustDialog onSelect={vi.fn()} isRestarting={true} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -274,7 +275,7 @@ describe('FolderTrustDialog', () => {
|
|||
const relaunchApp = vi
|
||||
.spyOn(processUtils, 'relaunchApp')
|
||||
.mockResolvedValue(undefined);
|
||||
const { waitUntilReady, unmount } = renderWithProviders(
|
||||
const { waitUntilReady, unmount } = await renderWithProviders(
|
||||
<FolderTrustDialog onSelect={vi.fn()} isRestarting={true} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -288,7 +289,7 @@ describe('FolderTrustDialog', () => {
|
|||
});
|
||||
|
||||
it('should not call process.exit when "r" is pressed and isRestarting is false', async () => {
|
||||
const { stdin, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { stdin, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<FolderTrustDialog onSelect={vi.fn()} isRestarting={false} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -307,7 +308,7 @@ describe('FolderTrustDialog', () => {
|
|||
describe('directory display', () => {
|
||||
it('should correctly display the folder name for a nested directory', async () => {
|
||||
mockedCwd.mockReturnValue('/home/user/project');
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<FolderTrustDialog onSelect={vi.fn()} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -317,7 +318,7 @@ describe('FolderTrustDialog', () => {
|
|||
|
||||
it('should correctly display the parent folder name for a nested directory', async () => {
|
||||
mockedCwd.mockReturnValue('/home/user/project');
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<FolderTrustDialog onSelect={vi.fn()} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -327,7 +328,7 @@ describe('FolderTrustDialog', () => {
|
|||
|
||||
it('should correctly display an empty parent folder name for a directory directly under root', async () => {
|
||||
mockedCwd.mockReturnValue('/project');
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<FolderTrustDialog onSelect={vi.fn()} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -347,7 +348,7 @@ describe('FolderTrustDialog', () => {
|
|||
discoveryErrors: [],
|
||||
securityWarnings: [],
|
||||
};
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithProviders(
|
||||
<FolderTrustDialog
|
||||
onSelect={vi.fn()}
|
||||
discoveryResults={discoveryResults}
|
||||
|
|
@ -385,7 +386,7 @@ describe('FolderTrustDialog', () => {
|
|||
discoveryErrors: [],
|
||||
securityWarnings: ['Dangerous setting detected!'],
|
||||
};
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithProviders(
|
||||
<FolderTrustDialog
|
||||
onSelect={vi.fn()}
|
||||
discoveryResults={discoveryResults}
|
||||
|
|
@ -409,7 +410,7 @@ describe('FolderTrustDialog', () => {
|
|||
discoveryErrors: ['Failed to load custom commands'],
|
||||
securityWarnings: [],
|
||||
};
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithProviders(
|
||||
<FolderTrustDialog
|
||||
onSelect={vi.fn()}
|
||||
discoveryResults={discoveryResults}
|
||||
|
|
@ -433,7 +434,7 @@ describe('FolderTrustDialog', () => {
|
|||
discoveryErrors: [],
|
||||
securityWarnings: [],
|
||||
};
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithProviders(
|
||||
<FolderTrustDialog
|
||||
onSelect={vi.fn()}
|
||||
discoveryResults={discoveryResults}
|
||||
|
|
@ -469,7 +470,7 @@ describe('FolderTrustDialog', () => {
|
|||
securityWarnings: [`${ansiRed}warning-with-ansi${ansiReset}`],
|
||||
};
|
||||
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithProviders(
|
||||
<FolderTrustDialog
|
||||
onSelect={vi.fn()}
|
||||
discoveryResults={discoveryResults}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import { describe, it, expect, vi, afterEach, beforeEach } from 'vitest';
|
|||
import { renderWithProviders } from '../../test-utils/render.js';
|
||||
import { Footer } from './Footer.js';
|
||||
import { createMockSettings } from '../../test-utils/settings.js';
|
||||
import { type Config } from '@google/gemini-cli-core';
|
||||
import path from 'node:path';
|
||||
|
||||
// Normalize paths to POSIX slashes for stable cross-platform snapshots.
|
||||
|
|
@ -16,7 +17,11 @@ const normalizeFrame = (frame: string | undefined) => {
|
|||
return frame.replace(/\\/g, '/');
|
||||
};
|
||||
|
||||
let mockIsDevelopment = false;
|
||||
const { mocks } = vi.hoisted(() => ({
|
||||
mocks: {
|
||||
isDevelopment: false,
|
||||
},
|
||||
}));
|
||||
|
||||
vi.mock('../../utils/installationInfo.js', async (importOriginal) => {
|
||||
const original =
|
||||
|
|
@ -24,7 +29,7 @@ vi.mock('../../utils/installationInfo.js', async (importOriginal) => {
|
|||
return {
|
||||
...original,
|
||||
get isDevelopment() {
|
||||
return mockIsDevelopment;
|
||||
return mocks.isDevelopment;
|
||||
},
|
||||
};
|
||||
});
|
||||
|
|
@ -45,11 +50,34 @@ vi.mock('@google/gemini-cli-core', async (importOriginal) => {
|
|||
|
||||
const defaultProps = {
|
||||
model: 'gemini-pro',
|
||||
targetDir:
|
||||
'/Users/test/project/foo/bar/and/some/more/directories/to/make/it/long',
|
||||
targetDir: path.join(
|
||||
path.parse(process.cwd()).root,
|
||||
'Users',
|
||||
'test',
|
||||
'project',
|
||||
'foo',
|
||||
'bar',
|
||||
'and',
|
||||
'some',
|
||||
'more',
|
||||
'directories',
|
||||
'to',
|
||||
'make',
|
||||
'it',
|
||||
'long',
|
||||
),
|
||||
branchName: 'main',
|
||||
};
|
||||
|
||||
const mockConfig = {
|
||||
getTargetDir: () => defaultProps.targetDir,
|
||||
getDebugMode: () => false,
|
||||
getModel: () => defaultProps.model,
|
||||
getIdeMode: () => false,
|
||||
isTrustedFolder: () => true,
|
||||
getExtensionRegistryURI: () => undefined,
|
||||
} as unknown as Config;
|
||||
|
||||
const mockSessionStats = {
|
||||
sessionId: 'test-session-id',
|
||||
sessionStartTime: new Date(),
|
||||
|
|
@ -110,9 +138,10 @@ describe('<Footer />', () => {
|
|||
});
|
||||
|
||||
it('renders the component', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: {
|
||||
branchName: defaultProps.branchName,
|
||||
|
|
@ -127,9 +156,10 @@ describe('<Footer />', () => {
|
|||
|
||||
describe('path display', () => {
|
||||
it('should display a shortened path on a narrow terminal', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 79,
|
||||
uiState: { sessionStats: mockSessionStats },
|
||||
},
|
||||
|
|
@ -143,9 +173,10 @@ describe('<Footer />', () => {
|
|||
});
|
||||
|
||||
it('should use wide layout at 80 columns', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 80,
|
||||
uiState: { sessionStats: mockSessionStats },
|
||||
},
|
||||
|
|
@ -158,9 +189,10 @@ describe('<Footer />', () => {
|
|||
});
|
||||
|
||||
it('should not truncate high-priority items on narrow terminals (regression)', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 60,
|
||||
uiState: {
|
||||
sessionStats: mockSessionStats,
|
||||
|
|
@ -190,9 +222,10 @@ describe('<Footer />', () => {
|
|||
});
|
||||
|
||||
it('displays the branch name when provided', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: {
|
||||
branchName: defaultProps.branchName,
|
||||
|
|
@ -206,9 +239,10 @@ describe('<Footer />', () => {
|
|||
});
|
||||
|
||||
it('does not display the branch name when not provided', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: { branchName: undefined, sessionStats: mockSessionStats },
|
||||
},
|
||||
|
|
@ -219,9 +253,10 @@ describe('<Footer />', () => {
|
|||
});
|
||||
|
||||
it('displays the model name and context percentage', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: {
|
||||
currentModel: defaultProps.model,
|
||||
|
|
@ -246,9 +281,10 @@ describe('<Footer />', () => {
|
|||
});
|
||||
|
||||
it('displays the usage indicator when usage is low', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: {
|
||||
sessionStats: mockSessionStats,
|
||||
|
|
@ -274,9 +310,10 @@ describe('<Footer />', () => {
|
|||
});
|
||||
|
||||
it('hides the usage indicator when usage is not near limit', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: {
|
||||
sessionStats: mockSessionStats,
|
||||
|
|
@ -302,9 +339,10 @@ describe('<Footer />', () => {
|
|||
});
|
||||
|
||||
it('displays "Limit reached" message when remaining is 0', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: {
|
||||
sessionStats: mockSessionStats,
|
||||
|
|
@ -330,9 +368,10 @@ describe('<Footer />', () => {
|
|||
});
|
||||
|
||||
it('displays the model name and abbreviated context used label on narrow terminals', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 99,
|
||||
uiState: { sessionStats: mockSessionStats },
|
||||
settings: createMockSettings({
|
||||
|
|
@ -353,9 +392,10 @@ describe('<Footer />', () => {
|
|||
|
||||
describe('sandbox and trust info', () => {
|
||||
it('should display untrusted when isTrustedFolder is false', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: { isTrustedFolder: false, sessionStats: mockSessionStats },
|
||||
},
|
||||
|
|
@ -367,9 +407,10 @@ describe('<Footer />', () => {
|
|||
|
||||
it('should display custom sandbox info when SANDBOX env is set', async () => {
|
||||
vi.stubEnv('SANDBOX', 'gemini-cli-test-sandbox');
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: {
|
||||
isTrustedFolder: undefined,
|
||||
|
|
@ -386,9 +427,10 @@ describe('<Footer />', () => {
|
|||
it('should display macOS Seatbelt info when SANDBOX is sandbox-exec', async () => {
|
||||
vi.stubEnv('SANDBOX', 'sandbox-exec');
|
||||
vi.stubEnv('SEATBELT_PROFILE', 'test-profile');
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: { isTrustedFolder: true, sessionStats: mockSessionStats },
|
||||
},
|
||||
|
|
@ -402,9 +444,10 @@ describe('<Footer />', () => {
|
|||
it('should display "no sandbox" when SANDBOX is not set and folder is trusted', async () => {
|
||||
// Clear any SANDBOX env var that might be set.
|
||||
vi.stubEnv('SANDBOX', '');
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: { isTrustedFolder: true, sessionStats: mockSessionStats },
|
||||
},
|
||||
|
|
@ -417,9 +460,10 @@ describe('<Footer />', () => {
|
|||
|
||||
it('should prioritize untrusted message over sandbox info', async () => {
|
||||
vi.stubEnv('SANDBOX', 'gemini-cli-test-sandbox');
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: { isTrustedFolder: false, sessionStats: mockSessionStats },
|
||||
},
|
||||
|
|
@ -434,9 +478,10 @@ describe('<Footer />', () => {
|
|||
|
||||
describe('footer configuration filtering (golden snapshots)', () => {
|
||||
it('renders complete footer with all sections visible (baseline)', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: { sessionStats: mockSessionStats },
|
||||
settings: createMockSettings({
|
||||
|
|
@ -456,7 +501,7 @@ describe('<Footer />', () => {
|
|||
});
|
||||
|
||||
it('renders footer with all optional sections hidden (minimal footer)', async () => {
|
||||
const { lastFrame, unmount } = renderWithProviders(<Footer />, {
|
||||
const { lastFrame, unmount } = await renderWithProviders(<Footer />, {
|
||||
width: 120,
|
||||
uiState: { sessionStats: mockSessionStats },
|
||||
settings: createMockSettings({
|
||||
|
|
@ -478,9 +523,10 @@ describe('<Footer />', () => {
|
|||
});
|
||||
|
||||
it('renders footer with only model info hidden (partial filtering)', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: { sessionStats: mockSessionStats },
|
||||
settings: createMockSettings({
|
||||
|
|
@ -500,9 +546,10 @@ describe('<Footer />', () => {
|
|||
});
|
||||
|
||||
it('renders footer with CWD and model info hidden to test alignment (only sandbox visible)', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: { sessionStats: mockSessionStats },
|
||||
settings: createMockSettings({
|
||||
|
|
@ -524,9 +571,10 @@ describe('<Footer />', () => {
|
|||
});
|
||||
|
||||
it('hides the context percentage when hideContextPercentage is true', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: { sessionStats: mockSessionStats },
|
||||
settings: createMockSettings({
|
||||
|
|
@ -544,9 +592,10 @@ describe('<Footer />', () => {
|
|||
unmount();
|
||||
});
|
||||
it('shows the context percentage when hideContextPercentage is false', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: { sessionStats: mockSessionStats },
|
||||
settings: createMockSettings({
|
||||
|
|
@ -564,9 +613,10 @@ describe('<Footer />', () => {
|
|||
unmount();
|
||||
});
|
||||
it('renders complete footer in narrow terminal (baseline narrow)', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 79,
|
||||
uiState: { sessionStats: mockSessionStats },
|
||||
settings: createMockSettings({
|
||||
|
|
@ -588,7 +638,7 @@ describe('<Footer />', () => {
|
|||
|
||||
describe('Footer Token Formatting', () => {
|
||||
const renderWithTokens = async (tokens: number) => {
|
||||
const result = renderWithProviders(<Footer />, {
|
||||
const result = await renderWithProviders(<Footer />, {
|
||||
width: 120,
|
||||
uiState: {
|
||||
sessionStats: {
|
||||
|
|
@ -656,17 +706,18 @@ describe('<Footer />', () => {
|
|||
|
||||
describe('error summary visibility', () => {
|
||||
beforeEach(() => {
|
||||
mockIsDevelopment = false;
|
||||
mocks.isDevelopment = false;
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
mockIsDevelopment = false;
|
||||
mocks.isDevelopment = false;
|
||||
});
|
||||
|
||||
it('hides error summary in low verbosity mode out of dev mode', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: {
|
||||
sessionStats: mockSessionStats,
|
||||
|
|
@ -682,10 +733,11 @@ describe('<Footer />', () => {
|
|||
});
|
||||
|
||||
it('shows error summary in low verbosity mode in dev mode', async () => {
|
||||
mockIsDevelopment = true;
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
mocks.isDevelopment = true;
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: {
|
||||
sessionStats: mockSessionStats,
|
||||
|
|
@ -702,9 +754,10 @@ describe('<Footer />', () => {
|
|||
});
|
||||
|
||||
it('shows error summary in full verbosity mode', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: {
|
||||
sessionStats: mockSessionStats,
|
||||
|
|
@ -723,9 +776,10 @@ describe('<Footer />', () => {
|
|||
|
||||
describe('Footer Custom Items', () => {
|
||||
it('renders items in the specified order', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: {
|
||||
currentModel: 'gemini-pro',
|
||||
|
|
@ -750,9 +804,10 @@ describe('<Footer />', () => {
|
|||
});
|
||||
|
||||
it('renders multiple items with proper alignment', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: {
|
||||
sessionStats: mockSessionStats,
|
||||
|
|
@ -786,7 +841,7 @@ describe('<Footer />', () => {
|
|||
});
|
||||
|
||||
it('handles empty items array', async () => {
|
||||
const { lastFrame, unmount } = renderWithProviders(<Footer />, {
|
||||
const { lastFrame, unmount } = await renderWithProviders(<Footer />, {
|
||||
width: 120,
|
||||
uiState: { sessionStats: mockSessionStats },
|
||||
settings: createMockSettings({
|
||||
|
|
@ -807,9 +862,10 @@ describe('<Footer />', () => {
|
|||
});
|
||||
|
||||
it('does not render items that are conditionally hidden', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: {
|
||||
sessionStats: mockSessionStats,
|
||||
|
|
@ -837,9 +893,10 @@ describe('<Footer />', () => {
|
|||
|
||||
describe('fallback mode display', () => {
|
||||
it('should display Flash model when in fallback mode, not the configured Pro model', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: {
|
||||
sessionStats: mockSessionStats,
|
||||
|
|
@ -856,9 +913,10 @@ describe('<Footer />', () => {
|
|||
});
|
||||
|
||||
it('should display Pro model when NOT in fallback mode', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: {
|
||||
sessionStats: mockSessionStats,
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ describe('<FooterConfigDialog />', () => {
|
|||
|
||||
it('renders correctly with default settings', async () => {
|
||||
const settings = createMockSettings();
|
||||
const renderResult = renderWithProviders(
|
||||
const renderResult = await renderWithProviders(
|
||||
<FooterConfigDialog onClose={mockOnClose} />,
|
||||
{ settings },
|
||||
);
|
||||
|
|
@ -37,7 +37,7 @@ describe('<FooterConfigDialog />', () => {
|
|||
|
||||
it('toggles an item when enter is pressed', async () => {
|
||||
const settings = createMockSettings();
|
||||
const { lastFrame, stdin, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, stdin, waitUntilReady } = await renderWithProviders(
|
||||
<FooterConfigDialog onClose={mockOnClose} />,
|
||||
{ settings },
|
||||
);
|
||||
|
|
@ -62,7 +62,7 @@ describe('<FooterConfigDialog />', () => {
|
|||
|
||||
it('reorders items with arrow keys', async () => {
|
||||
const settings = createMockSettings();
|
||||
const { lastFrame, stdin, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, stdin, waitUntilReady } = await renderWithProviders(
|
||||
<FooterConfigDialog onClose={mockOnClose} />,
|
||||
{ settings },
|
||||
);
|
||||
|
|
@ -93,7 +93,7 @@ describe('<FooterConfigDialog />', () => {
|
|||
|
||||
it('closes on Esc', async () => {
|
||||
const settings = createMockSettings();
|
||||
const { stdin, waitUntilReady } = renderWithProviders(
|
||||
const { stdin, waitUntilReady } = await renderWithProviders(
|
||||
<FooterConfigDialog onClose={mockOnClose} />,
|
||||
{ settings },
|
||||
);
|
||||
|
|
@ -110,7 +110,7 @@ describe('<FooterConfigDialog />', () => {
|
|||
|
||||
it('highlights the active item in the preview', async () => {
|
||||
const settings = createMockSettings();
|
||||
const renderResult = renderWithProviders(
|
||||
const renderResult = await renderWithProviders(
|
||||
<FooterConfigDialog onClose={mockOnClose} />,
|
||||
{ settings },
|
||||
);
|
||||
|
|
@ -148,7 +148,7 @@ describe('<FooterConfigDialog />', () => {
|
|||
|
||||
it('shows an empty preview when all items are deselected', async () => {
|
||||
const settings = createMockSettings();
|
||||
const { lastFrame, stdin, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, stdin, waitUntilReady } = await renderWithProviders(
|
||||
<FooterConfigDialog onClose={mockOnClose} />,
|
||||
{ settings },
|
||||
);
|
||||
|
|
@ -178,7 +178,7 @@ describe('<FooterConfigDialog />', () => {
|
|||
|
||||
it('moves item correctly after trying to move up at the top', async () => {
|
||||
const settings = createMockSettings();
|
||||
const { lastFrame, stdin, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, stdin, waitUntilReady } = await renderWithProviders(
|
||||
<FooterConfigDialog onClose={mockOnClose} />,
|
||||
{ settings },
|
||||
);
|
||||
|
|
@ -217,7 +217,7 @@ describe('<FooterConfigDialog />', () => {
|
|||
|
||||
it('updates the preview when Show footer labels is toggled off', async () => {
|
||||
const settings = createMockSettings();
|
||||
const renderResult = renderWithProviders(
|
||||
const renderResult = await renderWithProviders(
|
||||
<FooterConfigDialog onClose={mockOnClose} />,
|
||||
{ settings },
|
||||
);
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ useSessionStatsMock.mockReturnValue({
|
|||
|
||||
describe('Gradient Crash Regression Tests', () => {
|
||||
it('<Header /> should not crash when theme.ui.gradient is empty', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Header version="1.0.0" nightly={false} />,
|
||||
{
|
||||
width: 120,
|
||||
|
|
@ -84,7 +84,7 @@ describe('Gradient Crash Regression Tests', () => {
|
|||
});
|
||||
|
||||
it('<ModelDialog /> should not crash when theme.ui.gradient is empty', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ModelDialog onClose={async () => {}} />,
|
||||
{
|
||||
width: 120,
|
||||
|
|
@ -96,7 +96,7 @@ describe('Gradient Crash Regression Tests', () => {
|
|||
});
|
||||
|
||||
it('<Banner /> should not crash when theme.ui.gradient is empty', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Banner bannerText="Test Banner" isWarning={false} width={80} />,
|
||||
{
|
||||
width: 120,
|
||||
|
|
@ -108,7 +108,7 @@ describe('Gradient Crash Regression Tests', () => {
|
|||
});
|
||||
|
||||
it('<Footer /> should not crash when theme.ui.gradient has only one color (or empty) and nightly is true', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
width: 120,
|
||||
|
|
@ -127,7 +127,7 @@ describe('Gradient Crash Regression Tests', () => {
|
|||
});
|
||||
|
||||
it('<StatsDisplay /> should not crash when theme.ui.gradient is empty', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<StatsDisplay duration="1s" title="My Stats" />,
|
||||
{
|
||||
width: 120,
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ describe('<HistoryItemDisplay />', () => {
|
|||
type: MessageType.USER,
|
||||
text: 'Hello',
|
||||
};
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<HistoryItemDisplay {...baseItem} item={item} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -53,7 +53,7 @@ describe('<HistoryItemDisplay />', () => {
|
|||
type: 'hint',
|
||||
text: 'Try using ripgrep first',
|
||||
};
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<HistoryItemDisplay {...baseItem} item={item} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -67,7 +67,7 @@ describe('<HistoryItemDisplay />', () => {
|
|||
type: MessageType.USER,
|
||||
text: '/theme',
|
||||
};
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<HistoryItemDisplay {...baseItem} item={item} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -83,7 +83,7 @@ describe('<HistoryItemDisplay />', () => {
|
|||
type: MessageType.INFO,
|
||||
text: '⚡ Line 1\n⚡ Line 2\n⚡ Line 3',
|
||||
};
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<HistoryItemDisplay {...baseItem} item={item} />,
|
||||
{
|
||||
config: makeFakeConfig({ useAlternateBuffer }),
|
||||
|
|
@ -114,7 +114,7 @@ describe('<HistoryItemDisplay />', () => {
|
|||
},
|
||||
],
|
||||
};
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<HistoryItemDisplay {...baseItem} item={item} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -128,7 +128,7 @@ describe('<HistoryItemDisplay />', () => {
|
|||
type: MessageType.STATS,
|
||||
duration: '1s',
|
||||
};
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<SessionStatsProvider>
|
||||
<HistoryItemDisplay {...baseItem} item={item} />
|
||||
</SessionStatsProvider>,
|
||||
|
|
@ -150,7 +150,7 @@ describe('<HistoryItemDisplay />', () => {
|
|||
gcpProject: 'test-project',
|
||||
ideClient: 'test-ide',
|
||||
};
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<HistoryItemDisplay {...baseItem} item={item} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -163,7 +163,7 @@ describe('<HistoryItemDisplay />', () => {
|
|||
...baseItem,
|
||||
type: 'model_stats',
|
||||
};
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<SessionStatsProvider>
|
||||
<HistoryItemDisplay {...baseItem} item={item} />
|
||||
</SessionStatsProvider>,
|
||||
|
|
@ -180,7 +180,7 @@ describe('<HistoryItemDisplay />', () => {
|
|||
...baseItem,
|
||||
type: 'tool_stats',
|
||||
};
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<SessionStatsProvider>
|
||||
<HistoryItemDisplay {...baseItem} item={item} />
|
||||
</SessionStatsProvider>,
|
||||
|
|
@ -198,7 +198,7 @@ describe('<HistoryItemDisplay />', () => {
|
|||
type: 'quit',
|
||||
duration: '1s',
|
||||
};
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<SessionStatsProvider>
|
||||
<HistoryItemDisplay {...baseItem} item={item} />
|
||||
</SessionStatsProvider>,
|
||||
|
|
@ -215,7 +215,7 @@ describe('<HistoryItemDisplay />', () => {
|
|||
text: 'Hello, \u001b[31mred\u001b[0m world!',
|
||||
};
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<HistoryItemDisplay
|
||||
item={historyItem}
|
||||
terminalWidth={80}
|
||||
|
|
@ -253,7 +253,7 @@ describe('<HistoryItemDisplay />', () => {
|
|||
],
|
||||
};
|
||||
|
||||
const { waitUntilReady, unmount } = renderWithProviders(
|
||||
const { waitUntilReady, unmount } = await renderWithProviders(
|
||||
<HistoryItemDisplay
|
||||
item={historyItem}
|
||||
terminalWidth={80}
|
||||
|
|
@ -279,7 +279,7 @@ describe('<HistoryItemDisplay />', () => {
|
|||
type: 'thinking',
|
||||
thought: { subject: 'Thinking', description: 'test' },
|
||||
};
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<HistoryItemDisplay {...baseItem} item={item} />,
|
||||
{
|
||||
settings: createMockSettings({ ui: { inlineThinkingMode: 'full' } }),
|
||||
|
|
@ -297,7 +297,7 @@ describe('<HistoryItemDisplay />', () => {
|
|||
type: 'thinking',
|
||||
thought: { subject: 'Thinking', description: 'test' },
|
||||
};
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<HistoryItemDisplay {...baseItem} item={item} isFirstThinking={true} />,
|
||||
{
|
||||
settings: createMockSettings({ ui: { inlineThinkingMode: 'full' } }),
|
||||
|
|
@ -315,7 +315,7 @@ describe('<HistoryItemDisplay />', () => {
|
|||
type: 'thinking',
|
||||
thought: { subject: 'Thinking', description: 'test' },
|
||||
};
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<HistoryItemDisplay {...baseItem} item={item} />,
|
||||
{
|
||||
settings: createMockSettings({ ui: { inlineThinkingMode: 'off' } }),
|
||||
|
|
@ -343,18 +343,19 @@ describe('<HistoryItemDisplay />', () => {
|
|||
type: 'gemini',
|
||||
text: longCode,
|
||||
};
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
<HistoryItemDisplay
|
||||
item={item}
|
||||
isPending={false}
|
||||
terminalWidth={80}
|
||||
availableTerminalHeight={10}
|
||||
/>,
|
||||
{
|
||||
config: makeFakeConfig({ useAlternateBuffer }),
|
||||
settings: createMockSettings({ ui: { useAlternateBuffer } }),
|
||||
},
|
||||
);
|
||||
const { lastFrame, waitUntilReady, unmount } =
|
||||
await renderWithProviders(
|
||||
<HistoryItemDisplay
|
||||
item={item}
|
||||
isPending={false}
|
||||
terminalWidth={80}
|
||||
availableTerminalHeight={10}
|
||||
/>,
|
||||
{
|
||||
config: makeFakeConfig({ useAlternateBuffer }),
|
||||
settings: createMockSettings({ ui: { useAlternateBuffer } }),
|
||||
},
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
||||
expect(lastFrame()).toMatchSnapshot();
|
||||
|
|
@ -367,19 +368,20 @@ describe('<HistoryItemDisplay />', () => {
|
|||
type: 'gemini',
|
||||
text: longCode,
|
||||
};
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
<HistoryItemDisplay
|
||||
item={item}
|
||||
isPending={false}
|
||||
terminalWidth={80}
|
||||
availableTerminalHeight={10}
|
||||
availableTerminalHeightGemini={Number.MAX_SAFE_INTEGER}
|
||||
/>,
|
||||
{
|
||||
config: makeFakeConfig({ useAlternateBuffer }),
|
||||
settings: createMockSettings({ ui: { useAlternateBuffer } }),
|
||||
},
|
||||
);
|
||||
const { lastFrame, waitUntilReady, unmount } =
|
||||
await renderWithProviders(
|
||||
<HistoryItemDisplay
|
||||
item={item}
|
||||
isPending={false}
|
||||
terminalWidth={80}
|
||||
availableTerminalHeight={10}
|
||||
availableTerminalHeightGemini={Number.MAX_SAFE_INTEGER}
|
||||
/>,
|
||||
{
|
||||
config: makeFakeConfig({ useAlternateBuffer }),
|
||||
settings: createMockSettings({ ui: { useAlternateBuffer } }),
|
||||
},
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
||||
expect(lastFrame()).toMatchSnapshot();
|
||||
|
|
@ -392,18 +394,19 @@ describe('<HistoryItemDisplay />', () => {
|
|||
type: 'gemini_content',
|
||||
text: longCode,
|
||||
};
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
<HistoryItemDisplay
|
||||
item={item}
|
||||
isPending={false}
|
||||
terminalWidth={80}
|
||||
availableTerminalHeight={10}
|
||||
/>,
|
||||
{
|
||||
config: makeFakeConfig({ useAlternateBuffer }),
|
||||
settings: createMockSettings({ ui: { useAlternateBuffer } }),
|
||||
},
|
||||
);
|
||||
const { lastFrame, waitUntilReady, unmount } =
|
||||
await renderWithProviders(
|
||||
<HistoryItemDisplay
|
||||
item={item}
|
||||
isPending={false}
|
||||
terminalWidth={80}
|
||||
availableTerminalHeight={10}
|
||||
/>,
|
||||
{
|
||||
config: makeFakeConfig({ useAlternateBuffer }),
|
||||
settings: createMockSettings({ ui: { useAlternateBuffer } }),
|
||||
},
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
||||
expect(lastFrame()).toMatchSnapshot();
|
||||
|
|
@ -416,19 +419,20 @@ describe('<HistoryItemDisplay />', () => {
|
|||
type: 'gemini_content',
|
||||
text: longCode,
|
||||
};
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
<HistoryItemDisplay
|
||||
item={item}
|
||||
isPending={false}
|
||||
terminalWidth={80}
|
||||
availableTerminalHeight={10}
|
||||
availableTerminalHeightGemini={Number.MAX_SAFE_INTEGER}
|
||||
/>,
|
||||
{
|
||||
config: makeFakeConfig({ useAlternateBuffer }),
|
||||
settings: createMockSettings({ ui: { useAlternateBuffer } }),
|
||||
},
|
||||
);
|
||||
const { lastFrame, waitUntilReady, unmount } =
|
||||
await renderWithProviders(
|
||||
<HistoryItemDisplay
|
||||
item={item}
|
||||
isPending={false}
|
||||
terminalWidth={80}
|
||||
availableTerminalHeight={10}
|
||||
availableTerminalHeightGemini={Number.MAX_SAFE_INTEGER}
|
||||
/>,
|
||||
{
|
||||
config: makeFakeConfig({ useAlternateBuffer }),
|
||||
settings: createMockSettings({ ui: { useAlternateBuffer } }),
|
||||
},
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
||||
expect(lastFrame()).toMatchSnapshot();
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ describe('HooksDialog', () => {
|
|||
|
||||
describe('snapshots', () => {
|
||||
it('renders empty hooks dialog', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<HooksDialog hooks={[]} onClose={vi.fn()} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -45,7 +45,7 @@ describe('HooksDialog', () => {
|
|||
|
||||
it('renders single hook with security warning, source, and tips', async () => {
|
||||
const hooks = [createMockHook('test-hook', 'before-tool', true)];
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<HooksDialog hooks={hooks} onClose={vi.fn()} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -59,7 +59,7 @@ describe('HooksDialog', () => {
|
|||
createMockHook('hook2', 'before-tool', false),
|
||||
createMockHook('hook3', 'after-agent', true),
|
||||
];
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<HooksDialog hooks={hooks} onClose={vi.fn()} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -80,7 +80,7 @@ describe('HooksDialog', () => {
|
|||
},
|
||||
}),
|
||||
];
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<HooksDialog hooks={hooks} onClose={vi.fn()} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -100,7 +100,7 @@ describe('HooksDialog', () => {
|
|||
enabled: true,
|
||||
},
|
||||
];
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<HooksDialog hooks={hooks} onClose={vi.fn()} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -112,7 +112,7 @@ describe('HooksDialog', () => {
|
|||
describe('keyboard interaction', () => {
|
||||
it('should call onClose when escape key is pressed', async () => {
|
||||
const onClose = vi.fn();
|
||||
const { waitUntilReady, stdin, unmount } = renderWithProviders(
|
||||
const { waitUntilReady, stdin, unmount } = await renderWithProviders(
|
||||
<HooksDialog hooks={[]} onClose={onClose} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -137,7 +137,7 @@ describe('HooksDialog', () => {
|
|||
createMockHook('hook1', 'before-tool', true),
|
||||
createMockHook('hook2', 'after-tool', false),
|
||||
];
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<HooksDialog hooks={hooks} onClose={vi.fn()} maxVisibleHooks={10} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -149,7 +149,7 @@ describe('HooksDialog', () => {
|
|||
|
||||
it('should show scroll down indicator when there are more hooks than maxVisibleHooks', async () => {
|
||||
const hooks = createManyHooks(15);
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<HooksDialog hooks={hooks} onClose={vi.fn()} maxVisibleHooks={5} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -160,9 +160,10 @@ describe('HooksDialog', () => {
|
|||
|
||||
it('should scroll down when down arrow is pressed', async () => {
|
||||
const hooks = createManyHooks(15);
|
||||
const { lastFrame, waitUntilReady, stdin, unmount } = renderWithProviders(
|
||||
<HooksDialog hooks={hooks} onClose={vi.fn()} maxVisibleHooks={5} />,
|
||||
);
|
||||
const { lastFrame, waitUntilReady, stdin, unmount } =
|
||||
await renderWithProviders(
|
||||
<HooksDialog hooks={hooks} onClose={vi.fn()} maxVisibleHooks={5} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
||||
// Initially should not show up indicator
|
||||
|
|
@ -180,9 +181,10 @@ describe('HooksDialog', () => {
|
|||
|
||||
it('should scroll up when up arrow is pressed after scrolling down', async () => {
|
||||
const hooks = createManyHooks(15);
|
||||
const { lastFrame, waitUntilReady, stdin, unmount } = renderWithProviders(
|
||||
<HooksDialog hooks={hooks} onClose={vi.fn()} maxVisibleHooks={5} />,
|
||||
);
|
||||
const { lastFrame, waitUntilReady, stdin, unmount } =
|
||||
await renderWithProviders(
|
||||
<HooksDialog hooks={hooks} onClose={vi.fn()} maxVisibleHooks={5} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
||||
// Scroll down twice
|
||||
|
|
@ -207,9 +209,10 @@ describe('HooksDialog', () => {
|
|||
|
||||
it('should not scroll beyond the end', async () => {
|
||||
const hooks = createManyHooks(10);
|
||||
const { lastFrame, waitUntilReady, stdin, unmount } = renderWithProviders(
|
||||
<HooksDialog hooks={hooks} onClose={vi.fn()} maxVisibleHooks={5} />,
|
||||
);
|
||||
const { lastFrame, waitUntilReady, stdin, unmount } =
|
||||
await renderWithProviders(
|
||||
<HooksDialog hooks={hooks} onClose={vi.fn()} maxVisibleHooks={5} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
||||
// Scroll down many times past the end
|
||||
|
|
@ -229,9 +232,10 @@ describe('HooksDialog', () => {
|
|||
|
||||
it('should not scroll above the beginning', async () => {
|
||||
const hooks = createManyHooks(10);
|
||||
const { lastFrame, waitUntilReady, stdin, unmount } = renderWithProviders(
|
||||
<HooksDialog hooks={hooks} onClose={vi.fn()} maxVisibleHooks={5} />,
|
||||
);
|
||||
const { lastFrame, waitUntilReady, stdin, unmount } =
|
||||
await renderWithProviders(
|
||||
<HooksDialog hooks={hooks} onClose={vi.fn()} maxVisibleHooks={5} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
||||
// Try to scroll up when already at top
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ describe('IdeTrustChangeDialog', () => {
|
|||
});
|
||||
|
||||
it('renders the correct message for CONNECTION_CHANGE', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<IdeTrustChangeDialog reason="CONNECTION_CHANGE" />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -31,7 +31,7 @@ describe('IdeTrustChangeDialog', () => {
|
|||
});
|
||||
|
||||
it('renders the correct message for TRUST_CHANGE', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<IdeTrustChangeDialog reason="TRUST_CHANGE" />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -48,7 +48,7 @@ describe('IdeTrustChangeDialog', () => {
|
|||
const debugLoggerWarnSpy = vi
|
||||
.spyOn(debugLogger, 'warn')
|
||||
.mockImplementation(() => {});
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<IdeTrustChangeDialog reason="NONE" />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -65,7 +65,7 @@ describe('IdeTrustChangeDialog', () => {
|
|||
const relaunchAppSpy = vi
|
||||
.spyOn(processUtils, 'relaunchApp')
|
||||
.mockResolvedValue(undefined);
|
||||
const { stdin, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { stdin, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<IdeTrustChangeDialog reason="NONE" />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -83,7 +83,7 @@ describe('IdeTrustChangeDialog', () => {
|
|||
const relaunchAppSpy = vi
|
||||
.spyOn(processUtils, 'relaunchApp')
|
||||
.mockResolvedValue(undefined);
|
||||
const { stdin, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { stdin, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<IdeTrustChangeDialog reason="CONNECTION_CHANGE" />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -101,7 +101,7 @@ describe('IdeTrustChangeDialog', () => {
|
|||
const relaunchAppSpy = vi
|
||||
.spyOn(processUtils, 'relaunchApp')
|
||||
.mockResolvedValue(undefined);
|
||||
const { stdin, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { stdin, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<IdeTrustChangeDialog reason="CONNECTION_CHANGE" />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -36,7 +36,7 @@ vi.mock('../hooks/useTerminalSize.js', () => ({
|
|||
|
||||
const useTerminalSizeMock = vi.mocked(useTerminalSize.useTerminalSize);
|
||||
|
||||
const renderWithContext = (
|
||||
const renderWithContext = async (
|
||||
ui: React.ReactElement,
|
||||
streamingStateValue: StreamingState,
|
||||
width = 120,
|
||||
|
|
@ -55,7 +55,7 @@ describe('<LoadingIndicator />', () => {
|
|||
};
|
||||
|
||||
it('should render blank when streamingState is Idle and no loading phrase or thought', async () => {
|
||||
const { lastFrame, waitUntilReady } = renderWithContext(
|
||||
const { lastFrame, waitUntilReady } = await renderWithContext(
|
||||
<LoadingIndicator elapsedTime={5} />,
|
||||
StreamingState.Idle,
|
||||
);
|
||||
|
|
@ -64,7 +64,7 @@ describe('<LoadingIndicator />', () => {
|
|||
});
|
||||
|
||||
it('should render spinner, phrase, and time when streamingState is Responding', async () => {
|
||||
const { lastFrame, waitUntilReady } = renderWithContext(
|
||||
const { lastFrame, waitUntilReady } = await renderWithContext(
|
||||
<LoadingIndicator {...defaultProps} />,
|
||||
StreamingState.Responding,
|
||||
);
|
||||
|
|
@ -80,7 +80,7 @@ describe('<LoadingIndicator />', () => {
|
|||
currentLoadingPhrase: 'Confirm action',
|
||||
elapsedTime: 10,
|
||||
};
|
||||
const { lastFrame, waitUntilReady } = renderWithContext(
|
||||
const { lastFrame, waitUntilReady } = await renderWithContext(
|
||||
<LoadingIndicator {...props} />,
|
||||
StreamingState.WaitingForConfirmation,
|
||||
);
|
||||
|
|
@ -97,7 +97,7 @@ describe('<LoadingIndicator />', () => {
|
|||
currentLoadingPhrase: 'Processing data...',
|
||||
elapsedTime: 3,
|
||||
};
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithContext(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithContext(
|
||||
<LoadingIndicator {...props} />,
|
||||
StreamingState.Responding,
|
||||
);
|
||||
|
|
@ -111,7 +111,7 @@ describe('<LoadingIndicator />', () => {
|
|||
currentLoadingPhrase: 'Working...',
|
||||
elapsedTime: 60,
|
||||
};
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithContext(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithContext(
|
||||
<LoadingIndicator {...props} />,
|
||||
StreamingState.Responding,
|
||||
);
|
||||
|
|
@ -125,7 +125,7 @@ describe('<LoadingIndicator />', () => {
|
|||
currentLoadingPhrase: 'Working...',
|
||||
elapsedTime: 125,
|
||||
};
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithContext(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithContext(
|
||||
<LoadingIndicator {...props} />,
|
||||
StreamingState.Responding,
|
||||
);
|
||||
|
|
@ -136,7 +136,7 @@ describe('<LoadingIndicator />', () => {
|
|||
|
||||
it('should render rightContent when provided', async () => {
|
||||
const rightContent = <Text>Extra Info</Text>;
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithContext(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithContext(
|
||||
<LoadingIndicator {...defaultProps} rightContent={rightContent} />,
|
||||
StreamingState.Responding,
|
||||
);
|
||||
|
|
@ -178,7 +178,7 @@ describe('<LoadingIndicator />', () => {
|
|||
);
|
||||
};
|
||||
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithProviders(
|
||||
<TestWrapper />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -232,7 +232,7 @@ describe('<LoadingIndicator />', () => {
|
|||
currentLoadingPhrase: 'Loading...',
|
||||
elapsedTime: 5,
|
||||
};
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithContext(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithContext(
|
||||
<LoadingIndicator {...props} />,
|
||||
StreamingState.Responding,
|
||||
);
|
||||
|
|
@ -250,7 +250,7 @@ describe('<LoadingIndicator />', () => {
|
|||
},
|
||||
elapsedTime: 5,
|
||||
};
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithContext(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithContext(
|
||||
<LoadingIndicator {...props} />,
|
||||
StreamingState.Responding,
|
||||
);
|
||||
|
|
@ -274,7 +274,7 @@ describe('<LoadingIndicator />', () => {
|
|||
},
|
||||
elapsedTime: 5,
|
||||
};
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithContext(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithContext(
|
||||
<LoadingIndicator {...props} />,
|
||||
StreamingState.Responding,
|
||||
);
|
||||
|
|
@ -293,7 +293,7 @@ describe('<LoadingIndicator />', () => {
|
|||
currentLoadingPhrase: 'This should not be displayed',
|
||||
elapsedTime: 5,
|
||||
};
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithContext(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithContext(
|
||||
<LoadingIndicator {...props} />,
|
||||
StreamingState.Responding,
|
||||
);
|
||||
|
|
@ -306,7 +306,7 @@ describe('<LoadingIndicator />', () => {
|
|||
});
|
||||
|
||||
it('should not display thought indicator for non-thought loading phrases', async () => {
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithContext(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithContext(
|
||||
<LoadingIndicator
|
||||
currentLoadingPhrase="some random tip..."
|
||||
elapsedTime={3}
|
||||
|
|
@ -319,7 +319,7 @@ describe('<LoadingIndicator />', () => {
|
|||
});
|
||||
|
||||
it('should truncate long primary text instead of wrapping', async () => {
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithContext(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithContext(
|
||||
<LoadingIndicator
|
||||
{...defaultProps}
|
||||
currentLoadingPhrase={
|
||||
|
|
@ -337,7 +337,7 @@ describe('<LoadingIndicator />', () => {
|
|||
|
||||
describe('responsive layout', () => {
|
||||
it('should render on a single line on a wide terminal', async () => {
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithContext(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithContext(
|
||||
<LoadingIndicator
|
||||
{...defaultProps}
|
||||
rightContent={<Text>Right</Text>}
|
||||
|
|
@ -356,7 +356,7 @@ describe('<LoadingIndicator />', () => {
|
|||
});
|
||||
|
||||
it('should render on multiple lines on a narrow terminal', async () => {
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithContext(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithContext(
|
||||
<LoadingIndicator
|
||||
{...defaultProps}
|
||||
rightContent={<Text>Right</Text>}
|
||||
|
|
@ -382,7 +382,7 @@ describe('<LoadingIndicator />', () => {
|
|||
});
|
||||
|
||||
it('should use wide layout at 80 columns', async () => {
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithContext(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithContext(
|
||||
<LoadingIndicator {...defaultProps} />,
|
||||
StreamingState.Responding,
|
||||
80,
|
||||
|
|
@ -393,7 +393,7 @@ describe('<LoadingIndicator />', () => {
|
|||
});
|
||||
|
||||
it('should use narrow layout at 79 columns', async () => {
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithContext(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithContext(
|
||||
<LoadingIndicator {...defaultProps} />,
|
||||
StreamingState.Responding,
|
||||
79,
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ describe('LogoutConfirmationDialog', () => {
|
|||
});
|
||||
|
||||
it('should render the dialog with title, description, and hint', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<LogoutConfirmationDialog onSelect={vi.fn()} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -37,7 +37,7 @@ describe('LogoutConfirmationDialog', () => {
|
|||
});
|
||||
|
||||
it('should render RadioButtonSelect with Login and Exit options', async () => {
|
||||
const { waitUntilReady, unmount } = renderWithProviders(
|
||||
const { waitUntilReady, unmount } = await renderWithProviders(
|
||||
<LogoutConfirmationDialog onSelect={vi.fn()} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -54,7 +54,7 @@ describe('LogoutConfirmationDialog', () => {
|
|||
|
||||
it('should call onSelect with LOGIN when Login is selected', async () => {
|
||||
const onSelect = vi.fn();
|
||||
const { waitUntilReady, unmount } = renderWithProviders(
|
||||
const { waitUntilReady, unmount } = await renderWithProviders(
|
||||
<LogoutConfirmationDialog onSelect={onSelect} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -71,7 +71,7 @@ describe('LogoutConfirmationDialog', () => {
|
|||
|
||||
it('should call onSelect with EXIT when Exit is selected', async () => {
|
||||
const onSelect = vi.fn();
|
||||
const { waitUntilReady, unmount } = renderWithProviders(
|
||||
const { waitUntilReady, unmount } = await renderWithProviders(
|
||||
<LogoutConfirmationDialog onSelect={onSelect} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -88,7 +88,7 @@ describe('LogoutConfirmationDialog', () => {
|
|||
|
||||
it('should call onSelect with EXIT when escape key is pressed', async () => {
|
||||
const onSelect = vi.fn();
|
||||
const { stdin, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { stdin, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<LogoutConfirmationDialog onSelect={onSelect} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ describe('LoopDetectionConfirmation', () => {
|
|||
const onComplete = vi.fn();
|
||||
|
||||
it('renders correctly', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<LoopDetectionConfirmation onComplete={onComplete} />,
|
||||
{ width: 101 },
|
||||
);
|
||||
|
|
@ -22,7 +22,7 @@ describe('LoopDetectionConfirmation', () => {
|
|||
});
|
||||
|
||||
it('contains the expected options', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<LoopDetectionConfirmation onComplete={onComplete} />,
|
||||
{ width: 100 },
|
||||
);
|
||||
|
|
|
|||
|
|
@ -350,7 +350,7 @@ describe('MainContent', () => {
|
|||
});
|
||||
|
||||
it('renders in normal buffer mode', async () => {
|
||||
const { lastFrame, unmount } = renderWithProviders(<MainContent />, {
|
||||
const { lastFrame, unmount } = await renderWithProviders(<MainContent />, {
|
||||
uiState: defaultMockUiState as Partial<UIState>,
|
||||
});
|
||||
await waitFor(() => expect(lastFrame()).toContain('AppHeader(full)'));
|
||||
|
|
@ -364,7 +364,7 @@ describe('MainContent', () => {
|
|||
|
||||
it('renders in alternate buffer mode', async () => {
|
||||
vi.mocked(useAlternateBuffer).mockReturnValue(true);
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<MainContent />,
|
||||
{
|
||||
uiState: defaultMockUiState as Partial<UIState>,
|
||||
|
|
@ -382,7 +382,7 @@ describe('MainContent', () => {
|
|||
it('renders minimal header in minimal mode (alternate buffer)', async () => {
|
||||
vi.mocked(useAlternateBuffer).mockReturnValue(true);
|
||||
|
||||
const { lastFrame, unmount } = renderWithProviders(<MainContent />, {
|
||||
const { lastFrame, unmount } = await renderWithProviders(<MainContent />, {
|
||||
uiState: {
|
||||
...defaultMockUiState,
|
||||
cleanUiDetailsVisible: false,
|
||||
|
|
@ -417,7 +417,7 @@ describe('MainContent', () => {
|
|||
);
|
||||
};
|
||||
|
||||
const { lastFrame } = renderWithProviders(<ToggleHarness />, {
|
||||
const { lastFrame } = await renderWithProviders(<ToggleHarness />, {
|
||||
uiState: {
|
||||
...defaultMockUiState,
|
||||
cleanUiDetailsVisible: false,
|
||||
|
|
@ -439,7 +439,7 @@ describe('MainContent', () => {
|
|||
|
||||
it('always renders full header details in normal buffer mode', async () => {
|
||||
vi.mocked(useAlternateBuffer).mockReturnValue(false);
|
||||
const { lastFrame } = renderWithProviders(<MainContent />, {
|
||||
const { lastFrame } = await renderWithProviders(<MainContent />, {
|
||||
uiState: {
|
||||
...defaultMockUiState,
|
||||
cleanUiDetailsVisible: false,
|
||||
|
|
@ -452,7 +452,7 @@ describe('MainContent', () => {
|
|||
|
||||
it('does not constrain height in alternate buffer mode', async () => {
|
||||
vi.mocked(useAlternateBuffer).mockReturnValue(true);
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<MainContent />,
|
||||
{
|
||||
uiState: defaultMockUiState as Partial<UIState>,
|
||||
|
|
@ -479,7 +479,7 @@ describe('MainContent', () => {
|
|||
staticAreaMaxItemHeight: 5,
|
||||
};
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<MainContent />,
|
||||
{
|
||||
uiState: uiState as Partial<UIState>,
|
||||
|
|
@ -507,7 +507,7 @@ describe('MainContent', () => {
|
|||
staticAreaMaxItemHeight: 5,
|
||||
};
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<MainContent />,
|
||||
{
|
||||
uiState: uiState as unknown as Partial<UIState>,
|
||||
|
|
@ -564,7 +564,7 @@ describe('MainContent', () => {
|
|||
],
|
||||
};
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<MainContent />,
|
||||
{
|
||||
uiState: uiState as Partial<UIState>,
|
||||
|
|
@ -626,7 +626,7 @@ describe('MainContent', () => {
|
|||
],
|
||||
};
|
||||
|
||||
const renderResult = renderWithProviders(<MainContent />, {
|
||||
const renderResult = await renderWithProviders(<MainContent />, {
|
||||
uiState: uiState as Partial<UIState>,
|
||||
});
|
||||
await renderResult.waitUntilReady();
|
||||
|
|
@ -732,16 +732,14 @@ describe('MainContent', () => {
|
|||
bannerVisible: false,
|
||||
};
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
<MainContent />,
|
||||
{
|
||||
const { lastFrame, waitUntilReady, unmount } =
|
||||
await renderWithProviders(<MainContent />, {
|
||||
uiState: uiState as Partial<UIState>,
|
||||
config: makeFakeConfig({ useAlternateBuffer: isAlternateBuffer }),
|
||||
settings: createMockSettings({
|
||||
ui: { useAlternateBuffer: isAlternateBuffer },
|
||||
}),
|
||||
},
|
||||
);
|
||||
});
|
||||
await waitUntilReady();
|
||||
|
||||
const output = lastFrame();
|
||||
|
|
|
|||
|
|
@ -108,10 +108,13 @@ describe('<ModelDialog />', () => {
|
|||
},
|
||||
});
|
||||
|
||||
const result = renderWithProviders(<ModelDialog onClose={mockOnClose} />, {
|
||||
config: configValue,
|
||||
settings,
|
||||
});
|
||||
const result = await renderWithProviders(
|
||||
<ModelDialog onClose={mockOnClose} />,
|
||||
{
|
||||
config: configValue,
|
||||
settings,
|
||||
},
|
||||
);
|
||||
await result.waitUntilReady();
|
||||
return result;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ describe('NewAgentsNotification', () => {
|
|||
const onSelect = vi.fn();
|
||||
|
||||
it('renders agent list', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = render(
|
||||
const { lastFrame, waitUntilReady, unmount } = await render(
|
||||
<NewAgentsNotification agents={mockAgents} onSelect={onSelect} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -68,7 +68,7 @@ describe('NewAgentsNotification', () => {
|
|||
inputConfig: { inputSchema: {} },
|
||||
}));
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = render(
|
||||
const { lastFrame, waitUntilReady, unmount } = await render(
|
||||
<NewAgentsNotification agents={manyAgents} onSelect={onSelect} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -86,7 +86,7 @@ describe('NewAgentsNotification', () => {
|
|||
}),
|
||||
);
|
||||
|
||||
const { lastFrame, stdin, unmount } = render(
|
||||
const { lastFrame, stdin, unmount } = await render(
|
||||
<NewAgentsNotification agents={mockAgents} onSelect={asyncOnSelect} />,
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -63,6 +63,14 @@ vi.mock('node:path', async () => {
|
|||
vi.mock('@google/gemini-cli-core', async (importOriginal) => {
|
||||
const actual =
|
||||
await importOriginal<typeof import('@google/gemini-cli-core')>();
|
||||
const MockStorage = vi.fn().mockImplementation(() => ({
|
||||
getExtensionsDir: () => '/mock/home/.gemini/extensions',
|
||||
}));
|
||||
Object.assign(MockStorage, {
|
||||
getGlobalTempDir: () => '/mock/temp',
|
||||
getGlobalSettingsPath: () => '/mock/home/.gemini/settings.json',
|
||||
getGlobalGeminiDir: () => '/mock/home/.gemini',
|
||||
});
|
||||
return {
|
||||
...actual,
|
||||
GEMINI_DIR: '.gemini',
|
||||
|
|
@ -71,11 +79,7 @@ vi.mock('@google/gemini-cli-core', async (importOriginal) => {
|
|||
Low: 'low',
|
||||
High: 'high',
|
||||
},
|
||||
Storage: {
|
||||
...actual.Storage,
|
||||
getGlobalTempDir: () => '/mock/temp',
|
||||
getGlobalSettingsPath: () => '/mock/home/.gemini/settings.json',
|
||||
},
|
||||
Storage: MockStorage,
|
||||
};
|
||||
});
|
||||
|
||||
|
|
@ -107,7 +111,7 @@ describe('Notifications', () => {
|
|||
});
|
||||
|
||||
it('renders nothing when no notifications', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Notifications />,
|
||||
{
|
||||
settings,
|
||||
|
|
@ -133,7 +137,7 @@ describe('Notifications', () => {
|
|||
version: '1.0.0',
|
||||
} as AppState;
|
||||
mockUseAppContext.mockReturnValue(appState);
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Notifications />,
|
||||
{
|
||||
appState,
|
||||
|
|
@ -159,11 +163,14 @@ describe('Notifications', () => {
|
|||
} as AppState;
|
||||
mockUseAppContext.mockReturnValue(appState);
|
||||
|
||||
const { waitUntilReady, unmount } = renderWithProviders(<Notifications />, {
|
||||
appState,
|
||||
settings,
|
||||
width: 100,
|
||||
});
|
||||
const { waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Notifications />,
|
||||
{
|
||||
appState,
|
||||
settings,
|
||||
width: 100,
|
||||
},
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
||||
expect(persistentStateMock.set).toHaveBeenCalledWith(
|
||||
|
|
@ -192,7 +199,7 @@ describe('Notifications', () => {
|
|||
startupWarningCounts: { 'low-1': 3 },
|
||||
});
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Notifications />,
|
||||
{
|
||||
appState,
|
||||
|
|
@ -221,14 +228,12 @@ describe('Notifications', () => {
|
|||
} as AppState;
|
||||
mockUseAppContext.mockReturnValue(appState);
|
||||
|
||||
const { lastFrame, stdin, waitUntilReady, unmount } = renderWithProviders(
|
||||
<Notifications />,
|
||||
{
|
||||
const { lastFrame, stdin, waitUntilReady, unmount } =
|
||||
await renderWithProviders(<Notifications />, {
|
||||
appState,
|
||||
settings,
|
||||
width: 100,
|
||||
},
|
||||
);
|
||||
});
|
||||
await waitUntilReady();
|
||||
expect(lastFrame()).toContain('High priority 1');
|
||||
|
||||
|
|
@ -248,7 +253,7 @@ describe('Notifications', () => {
|
|||
updateInfo: null,
|
||||
} as unknown as UIState;
|
||||
mockUseUIState.mockReturnValue(uiState);
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Notifications />,
|
||||
{
|
||||
uiState,
|
||||
|
|
@ -268,7 +273,7 @@ describe('Notifications', () => {
|
|||
updateInfo: null,
|
||||
} as unknown as UIState;
|
||||
mockUseUIState.mockReturnValue(uiState);
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Notifications />,
|
||||
{
|
||||
uiState,
|
||||
|
|
@ -288,7 +293,7 @@ describe('Notifications', () => {
|
|||
updateInfo: { message: 'Update available' },
|
||||
} as unknown as UIState;
|
||||
mockUseUIState.mockReturnValue(uiState);
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Notifications />,
|
||||
{
|
||||
uiState,
|
||||
|
|
@ -306,7 +311,7 @@ describe('Notifications', () => {
|
|||
persistentStateMock.setData({ hasSeenScreenReaderNudge: false });
|
||||
mockFsAccess.mockRejectedValue(new Error('No legacy file'));
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Notifications />,
|
||||
{
|
||||
settings,
|
||||
|
|
@ -330,29 +335,24 @@ describe('Notifications', () => {
|
|||
persistentStateMock.setData({ hasSeenScreenReaderNudge: undefined });
|
||||
mockFsAccess.mockResolvedValue(undefined);
|
||||
|
||||
const { waitUntilReady, unmount } = renderWithProviders(<Notifications />, {
|
||||
settings,
|
||||
width: 100,
|
||||
});
|
||||
|
||||
await act(async () => {
|
||||
await waitUntilReady();
|
||||
await waitFor(() => {
|
||||
expect(persistentStateMock.set).toHaveBeenCalledWith(
|
||||
'hasSeenScreenReaderNudge',
|
||||
true,
|
||||
);
|
||||
expect(mockFsUnlink).toHaveBeenCalled();
|
||||
await renderWithProviders(<Notifications />, {
|
||||
settings,
|
||||
width: 100,
|
||||
});
|
||||
});
|
||||
unmount();
|
||||
|
||||
await waitFor(() => {
|
||||
expect(persistentStateMock.get('hasSeenScreenReaderNudge')).toBe(true);
|
||||
});
|
||||
expect(mockFsUnlink).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('does not render screen reader nudge when already seen in persistent state', async () => {
|
||||
mockUseIsScreenReaderEnabled.mockReturnValue(true);
|
||||
persistentStateMock.setData({ hasSeenScreenReaderNudge: true });
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Notifications />,
|
||||
{
|
||||
settings,
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ describe('OverageMenuDialog', () => {
|
|||
|
||||
describe('rendering', () => {
|
||||
it('should match snapshot with fallback available', async () => {
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithProviders(
|
||||
<OverageMenuDialog
|
||||
failedModel="gemini-2.5-pro"
|
||||
fallbackModel="gemini-3-flash-preview"
|
||||
|
|
@ -45,7 +45,7 @@ describe('OverageMenuDialog', () => {
|
|||
});
|
||||
|
||||
it('should match snapshot without fallback', async () => {
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithProviders(
|
||||
<OverageMenuDialog
|
||||
failedModel="gemini-2.5-pro"
|
||||
creditBalance={500}
|
||||
|
|
@ -59,7 +59,7 @@ describe('OverageMenuDialog', () => {
|
|||
});
|
||||
|
||||
it('should display the credit balance', async () => {
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithProviders(
|
||||
<OverageMenuDialog
|
||||
failedModel="gemini-2.5-pro"
|
||||
creditBalance={200}
|
||||
|
|
@ -75,7 +75,7 @@ describe('OverageMenuDialog', () => {
|
|||
});
|
||||
|
||||
it('should display the model name', async () => {
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithProviders(
|
||||
<OverageMenuDialog
|
||||
failedModel="gemini-2.5-pro"
|
||||
creditBalance={100}
|
||||
|
|
@ -91,7 +91,7 @@ describe('OverageMenuDialog', () => {
|
|||
});
|
||||
|
||||
it('should display reset time when provided', async () => {
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithProviders(
|
||||
<OverageMenuDialog
|
||||
failedModel="gemini-2.5-pro"
|
||||
resetTime="3:45 PM"
|
||||
|
|
@ -108,7 +108,7 @@ describe('OverageMenuDialog', () => {
|
|||
});
|
||||
|
||||
it('should not display reset time when not provided', async () => {
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithProviders(
|
||||
<OverageMenuDialog
|
||||
failedModel="gemini-2.5-pro"
|
||||
creditBalance={100}
|
||||
|
|
@ -123,7 +123,7 @@ describe('OverageMenuDialog', () => {
|
|||
});
|
||||
|
||||
it('should display slash command hints', async () => {
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithProviders(
|
||||
<OverageMenuDialog
|
||||
failedModel="gemini-2.5-pro"
|
||||
creditBalance={100}
|
||||
|
|
@ -143,7 +143,7 @@ describe('OverageMenuDialog', () => {
|
|||
describe('onChoice handling', () => {
|
||||
it('should call onChoice with use_credits when selected', async () => {
|
||||
// use_credits is the first item, so just press Enter
|
||||
const { unmount, stdin, waitUntilReady } = renderWithProviders(
|
||||
const { unmount, stdin, waitUntilReady } = await renderWithProviders(
|
||||
<OverageMenuDialog
|
||||
failedModel="gemini-2.5-pro"
|
||||
creditBalance={100}
|
||||
|
|
@ -162,7 +162,7 @@ describe('OverageMenuDialog', () => {
|
|||
|
||||
it('should call onChoice with manage when selected', async () => {
|
||||
// manage is the second item: Down + Enter
|
||||
const { unmount, stdin, waitUntilReady } = renderWithProviders(
|
||||
const { unmount, stdin, waitUntilReady } = await renderWithProviders(
|
||||
<OverageMenuDialog
|
||||
failedModel="gemini-2.5-pro"
|
||||
creditBalance={100}
|
||||
|
|
@ -183,7 +183,7 @@ describe('OverageMenuDialog', () => {
|
|||
it('should call onChoice with use_fallback when selected', async () => {
|
||||
// With fallback: items are [use_credits, manage, use_fallback, stop]
|
||||
// use_fallback is the third item: Down x2 + Enter
|
||||
const { unmount, stdin, waitUntilReady } = renderWithProviders(
|
||||
const { unmount, stdin, waitUntilReady } = await renderWithProviders(
|
||||
<OverageMenuDialog
|
||||
failedModel="gemini-2.5-pro"
|
||||
fallbackModel="gemini-3-flash-preview"
|
||||
|
|
@ -206,7 +206,7 @@ describe('OverageMenuDialog', () => {
|
|||
it('should call onChoice with stop when selected', async () => {
|
||||
// Without fallback: items are [use_credits, manage, stop]
|
||||
// stop is the third item: Down x2 + Enter
|
||||
const { unmount, stdin, waitUntilReady } = renderWithProviders(
|
||||
const { unmount, stdin, waitUntilReady } = await renderWithProviders(
|
||||
<OverageMenuDialog
|
||||
failedModel="gemini-2.5-pro"
|
||||
creditBalance={100}
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ describe('PermissionsModifyTrustDialog', () => {
|
|||
});
|
||||
|
||||
it('should render the main dialog with current trust level', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<PermissionsModifyTrustDialog onExit={vi.fn()} addItem={vi.fn()} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -96,7 +96,7 @@ describe('PermissionsModifyTrustDialog', () => {
|
|||
commitTrustLevelChange: mockCommitTrustLevelChange,
|
||||
isFolderTrustEnabled: true,
|
||||
});
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<PermissionsModifyTrustDialog onExit={vi.fn()} addItem={vi.fn()} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -120,7 +120,7 @@ describe('PermissionsModifyTrustDialog', () => {
|
|||
commitTrustLevelChange: mockCommitTrustLevelChange,
|
||||
isFolderTrustEnabled: true,
|
||||
});
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<PermissionsModifyTrustDialog onExit={vi.fn()} addItem={vi.fn()} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -134,7 +134,7 @@ describe('PermissionsModifyTrustDialog', () => {
|
|||
});
|
||||
|
||||
it('should render the labels with folder names', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<PermissionsModifyTrustDialog onExit={vi.fn()} addItem={vi.fn()} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -148,9 +148,10 @@ describe('PermissionsModifyTrustDialog', () => {
|
|||
|
||||
it('should call onExit when escape is pressed', async () => {
|
||||
const onExit = vi.fn();
|
||||
const { stdin, lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
<PermissionsModifyTrustDialog onExit={onExit} addItem={vi.fn()} />,
|
||||
);
|
||||
const { stdin, lastFrame, waitUntilReady, unmount } =
|
||||
await renderWithProviders(
|
||||
<PermissionsModifyTrustDialog onExit={onExit} addItem={vi.fn()} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
||||
await waitFor(() => expect(lastFrame()).not.toContain('Loading...'));
|
||||
|
|
@ -186,9 +187,10 @@ describe('PermissionsModifyTrustDialog', () => {
|
|||
});
|
||||
|
||||
const onExit = vi.fn();
|
||||
const { stdin, lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
<PermissionsModifyTrustDialog onExit={onExit} addItem={vi.fn()} />,
|
||||
);
|
||||
const { stdin, lastFrame, waitUntilReady, unmount } =
|
||||
await renderWithProviders(
|
||||
<PermissionsModifyTrustDialog onExit={onExit} addItem={vi.fn()} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
||||
await waitFor(() => expect(lastFrame()).not.toContain('Loading...'));
|
||||
|
|
@ -220,9 +222,10 @@ describe('PermissionsModifyTrustDialog', () => {
|
|||
});
|
||||
|
||||
const onExit = vi.fn();
|
||||
const { stdin, lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
<PermissionsModifyTrustDialog onExit={onExit} addItem={vi.fn()} />,
|
||||
);
|
||||
const { stdin, lastFrame, waitUntilReady, unmount } =
|
||||
await renderWithProviders(
|
||||
<PermissionsModifyTrustDialog onExit={onExit} addItem={vi.fn()} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
||||
await waitFor(() => expect(lastFrame()).not.toContain('Loading...'));
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ describe('PolicyUpdateDialog', () => {
|
|||
});
|
||||
|
||||
it('renders correctly and matches snapshot', async () => {
|
||||
const { lastFrame, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady } = await renderWithProviders(
|
||||
<PolicyUpdateDialog
|
||||
config={mockConfig}
|
||||
request={mockRequest}
|
||||
|
|
@ -75,7 +75,7 @@ describe('PolicyUpdateDialog', () => {
|
|||
});
|
||||
|
||||
it('handles ACCEPT correctly', async () => {
|
||||
const { stdin } = renderWithProviders(
|
||||
const { stdin } = await renderWithProviders(
|
||||
<PolicyUpdateDialog
|
||||
config={mockConfig}
|
||||
request={mockRequest}
|
||||
|
|
@ -98,7 +98,7 @@ describe('PolicyUpdateDialog', () => {
|
|||
});
|
||||
|
||||
it('handles IGNORE correctly', async () => {
|
||||
const { stdin } = renderWithProviders(
|
||||
const { stdin } = await renderWithProviders(
|
||||
<PolicyUpdateDialog
|
||||
config={mockConfig}
|
||||
request={mockRequest}
|
||||
|
|
@ -122,7 +122,7 @@ describe('PolicyUpdateDialog', () => {
|
|||
});
|
||||
|
||||
it('calls onClose when Escape key is pressed', async () => {
|
||||
const { stdin } = renderWithProviders(
|
||||
const { stdin } = await renderWithProviders(
|
||||
<PolicyUpdateDialog
|
||||
config={mockConfig}
|
||||
request={mockRequest}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ describe('RewindConfirmation', () => {
|
|||
details: [{ fileName: 'test.ts', diff: '' }],
|
||||
};
|
||||
const onConfirm = vi.fn();
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<RewindConfirmation
|
||||
stats={stats}
|
||||
onConfirm={onConfirm}
|
||||
|
|
@ -40,7 +40,7 @@ describe('RewindConfirmation', () => {
|
|||
|
||||
it('renders correctly without stats', async () => {
|
||||
const onConfirm = vi.fn();
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<RewindConfirmation
|
||||
stats={null}
|
||||
onConfirm={onConfirm}
|
||||
|
|
@ -58,7 +58,7 @@ describe('RewindConfirmation', () => {
|
|||
|
||||
it('calls onConfirm with Cancel on Escape', async () => {
|
||||
const onConfirm = vi.fn();
|
||||
const { stdin, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { stdin, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<RewindConfirmation
|
||||
stats={null}
|
||||
onConfirm={onConfirm}
|
||||
|
|
@ -81,7 +81,7 @@ describe('RewindConfirmation', () => {
|
|||
it('renders timestamp when provided', async () => {
|
||||
const onConfirm = vi.fn();
|
||||
const timestamp = new Date().toISOString();
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<RewindConfirmation
|
||||
stats={null}
|
||||
onConfirm={onConfirm}
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ describe('RewindViewer', () => {
|
|||
const conversation = createConversation([
|
||||
{ type: 'user', content: 'Hello', id: '1', timestamp: '1' },
|
||||
]);
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<RewindViewer
|
||||
conversation={conversation}
|
||||
onExit={vi.fn()}
|
||||
|
|
@ -130,7 +130,7 @@ describe('RewindViewer', () => {
|
|||
const conversation = createConversation(messages as MessageRecord[]);
|
||||
const onExit = vi.fn();
|
||||
const onRewind = vi.fn();
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<RewindViewer
|
||||
conversation={conversation}
|
||||
onExit={onExit}
|
||||
|
|
@ -154,13 +154,14 @@ describe('RewindViewer', () => {
|
|||
]);
|
||||
const onExit = vi.fn();
|
||||
const onRewind = vi.fn();
|
||||
const { lastFrame, stdin, waitUntilReady, unmount } = renderWithProviders(
|
||||
<RewindViewer
|
||||
conversation={conversation}
|
||||
onExit={onExit}
|
||||
onRewind={onRewind}
|
||||
/>,
|
||||
);
|
||||
const { lastFrame, stdin, waitUntilReady, unmount } =
|
||||
await renderWithProviders(
|
||||
<RewindViewer
|
||||
conversation={conversation}
|
||||
onExit={onExit}
|
||||
onRewind={onRewind}
|
||||
/>,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
||||
// Initial state
|
||||
|
|
@ -188,13 +189,14 @@ describe('RewindViewer', () => {
|
|||
{ type: 'user', content: 'Q2', id: '2', timestamp: '1' },
|
||||
{ type: 'user', content: 'Q3', id: '3', timestamp: '1' },
|
||||
]);
|
||||
const { lastFrame, stdin, waitUntilReady, unmount } = renderWithProviders(
|
||||
<RewindViewer
|
||||
conversation={conversation}
|
||||
onExit={vi.fn()}
|
||||
onRewind={vi.fn()}
|
||||
/>,
|
||||
);
|
||||
const { lastFrame, stdin, waitUntilReady, unmount } =
|
||||
await renderWithProviders(
|
||||
<RewindViewer
|
||||
conversation={conversation}
|
||||
onExit={vi.fn()}
|
||||
onRewind={vi.fn()}
|
||||
/>,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
||||
act(() => {
|
||||
|
|
@ -220,13 +222,14 @@ describe('RewindViewer', () => {
|
|||
{ type: 'user', content: 'Q2', id: '2', timestamp: '1' },
|
||||
{ type: 'user', content: 'Q3', id: '3', timestamp: '1' },
|
||||
]);
|
||||
const { lastFrame, stdin, waitUntilReady, unmount } = renderWithProviders(
|
||||
<RewindViewer
|
||||
conversation={conversation}
|
||||
onExit={vi.fn()}
|
||||
onRewind={vi.fn()}
|
||||
/>,
|
||||
);
|
||||
const { lastFrame, stdin, waitUntilReady, unmount } =
|
||||
await renderWithProviders(
|
||||
<RewindViewer
|
||||
conversation={conversation}
|
||||
onExit={vi.fn()}
|
||||
onRewind={vi.fn()}
|
||||
/>,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
||||
// Up from first -> Last
|
||||
|
|
@ -297,13 +300,14 @@ describe('RewindViewer', () => {
|
|||
{ type: 'user', content: 'Original Prompt', id: '1', timestamp: '1' },
|
||||
]);
|
||||
const onRewind = vi.fn();
|
||||
const { lastFrame, stdin, waitUntilReady, unmount } = renderWithProviders(
|
||||
<RewindViewer
|
||||
conversation={conversation}
|
||||
onExit={vi.fn()}
|
||||
onRewind={onRewind}
|
||||
/>,
|
||||
);
|
||||
const { lastFrame, stdin, waitUntilReady, unmount } =
|
||||
await renderWithProviders(
|
||||
<RewindViewer
|
||||
conversation={conversation}
|
||||
onExit={vi.fn()}
|
||||
onRewind={onRewind}
|
||||
/>,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
||||
// Select
|
||||
|
|
@ -354,13 +358,14 @@ describe('RewindViewer', () => {
|
|||
},
|
||||
]);
|
||||
const onRewind = vi.fn();
|
||||
const { lastFrame, stdin, waitUntilReady, unmount } = renderWithProviders(
|
||||
<RewindViewer
|
||||
conversation={conversation}
|
||||
onExit={vi.fn()}
|
||||
onRewind={onRewind}
|
||||
/>,
|
||||
);
|
||||
const { lastFrame, stdin, waitUntilReady, unmount } =
|
||||
await renderWithProviders(
|
||||
<RewindViewer
|
||||
conversation={conversation}
|
||||
onExit={vi.fn()}
|
||||
onRewind={onRewind}
|
||||
/>,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
||||
expect(lastFrame()).toMatchSnapshot();
|
||||
|
|
@ -398,7 +403,7 @@ describe('RewindViewer', () => {
|
|||
const onExit = vi.fn();
|
||||
const onRewind = vi.fn();
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<RewindViewer
|
||||
conversation={conversation}
|
||||
onExit={onExit}
|
||||
|
|
@ -421,7 +426,7 @@ describe('RewindViewer', () => {
|
|||
lastFrame: lastFrame2,
|
||||
waitUntilReady: waitUntilReady2,
|
||||
unmount: unmount2,
|
||||
} = renderWithProviders(
|
||||
} = await renderWithProviders(
|
||||
<RewindViewer
|
||||
conversation={conversation}
|
||||
onExit={onExit}
|
||||
|
|
@ -446,7 +451,7 @@ it('renders accessible screen reader view when screen reader is enabled', async
|
|||
const onExit = vi.fn();
|
||||
const onRewind = vi.fn();
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<RewindViewer
|
||||
conversation={conversation}
|
||||
onExit={onExit}
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ const renderWithMockedStats = async (
|
|||
startNewPrompt: vi.fn(),
|
||||
});
|
||||
|
||||
const result = renderWithProviders(
|
||||
const result = await renderWithProviders(
|
||||
<SessionSummaryDisplay duration="1h 23m 45s" />,
|
||||
{
|
||||
width: 100,
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|||
import { SettingsDialog } from './SettingsDialog.js';
|
||||
import { SettingScope } from '../../config/settings.js';
|
||||
import { createMockSettings } from '../../test-utils/settings.js';
|
||||
import { makeFakeConfig } from '@google/gemini-cli-core';
|
||||
import { act } from 'react';
|
||||
import { TEST_ONLY } from '../../utils/settingsUtils.js';
|
||||
import {
|
||||
|
|
@ -228,7 +229,7 @@ const TOOLS_SHELL_FAKE_SCHEMA: SettingsSchemaType = {
|
|||
} as unknown as SettingsSchemaType;
|
||||
|
||||
// Helper function to render SettingsDialog with standard wrapper
|
||||
const renderDialog = (
|
||||
const renderDialog = async (
|
||||
settings: ReturnType<typeof createMockSettings>,
|
||||
onSelect: ReturnType<typeof vi.fn>,
|
||||
options?: {
|
||||
|
|
@ -244,6 +245,7 @@ const renderDialog = (
|
|||
/>,
|
||||
{
|
||||
settings,
|
||||
config: makeFakeConfig(),
|
||||
uiState: { terminalBackgroundColor: undefined },
|
||||
},
|
||||
);
|
||||
|
|
@ -268,7 +270,7 @@ describe('SettingsDialog', () => {
|
|||
const settings = createMockSettings();
|
||||
const onSelect = vi.fn();
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderDialog(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderDialog(
|
||||
settings,
|
||||
onSelect,
|
||||
);
|
||||
|
|
@ -286,7 +288,7 @@ describe('SettingsDialog', () => {
|
|||
const settings = createMockSettings();
|
||||
const onSelect = vi.fn();
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderDialog(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderDialog(
|
||||
settings,
|
||||
onSelect,
|
||||
{
|
||||
|
|
@ -307,7 +309,7 @@ describe('SettingsDialog', () => {
|
|||
const settings = createMockSettings();
|
||||
const onSelect = vi.fn();
|
||||
|
||||
const renderResult = renderDialog(settings, onSelect);
|
||||
const renderResult = await renderDialog(settings, onSelect);
|
||||
await renderResult.waitUntilReady();
|
||||
|
||||
await expect(renderResult).toMatchSvgSnapshot();
|
||||
|
|
@ -319,7 +321,7 @@ describe('SettingsDialog', () => {
|
|||
const onSelect = vi.fn();
|
||||
|
||||
// Render with a fixed height of 25 rows
|
||||
const { lastFrame, waitUntilReady, unmount } = renderDialog(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderDialog(
|
||||
settings,
|
||||
onSelect,
|
||||
{
|
||||
|
|
@ -346,7 +348,7 @@ describe('SettingsDialog', () => {
|
|||
const settings = createMockSettings();
|
||||
const onSelect = vi.fn();
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderDialog(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderDialog(
|
||||
settings,
|
||||
onSelect,
|
||||
);
|
||||
|
|
@ -379,7 +381,7 @@ describe('SettingsDialog', () => {
|
|||
const settings = createMockSettings();
|
||||
const onSelect = vi.fn();
|
||||
|
||||
const { stdin, unmount, lastFrame, waitUntilReady } = renderDialog(
|
||||
const { stdin, unmount, lastFrame, waitUntilReady } = await renderDialog(
|
||||
settings,
|
||||
onSelect,
|
||||
);
|
||||
|
|
@ -414,7 +416,7 @@ describe('SettingsDialog', () => {
|
|||
it('should allow j and k characters to be typed in search without triggering navigation', async () => {
|
||||
const settings = createMockSettings();
|
||||
const onSelect = vi.fn();
|
||||
const { lastFrame, stdin, waitUntilReady, unmount } = renderDialog(
|
||||
const { lastFrame, stdin, waitUntilReady, unmount } = await renderDialog(
|
||||
settings,
|
||||
onSelect,
|
||||
);
|
||||
|
|
@ -440,7 +442,7 @@ describe('SettingsDialog', () => {
|
|||
const settings = createMockSettings();
|
||||
const onSelect = vi.fn();
|
||||
|
||||
const { stdin, unmount, lastFrame, waitUntilReady } = renderDialog(
|
||||
const { stdin, unmount, lastFrame, waitUntilReady } = await renderDialog(
|
||||
settings,
|
||||
onSelect,
|
||||
);
|
||||
|
|
@ -467,7 +469,7 @@ describe('SettingsDialog', () => {
|
|||
const setValueSpy = vi.spyOn(settings, 'setValue');
|
||||
const onSelect = vi.fn();
|
||||
|
||||
const { stdin, unmount, lastFrame, waitUntilReady } = renderDialog(
|
||||
const { stdin, unmount, lastFrame, waitUntilReady } = await renderDialog(
|
||||
settings,
|
||||
onSelect,
|
||||
);
|
||||
|
|
@ -520,7 +522,7 @@ describe('SettingsDialog', () => {
|
|||
|
||||
const onSelect = vi.fn();
|
||||
|
||||
const { stdin, unmount, waitUntilReady } = renderDialog(
|
||||
const { stdin, unmount, waitUntilReady } = await renderDialog(
|
||||
settings,
|
||||
onSelect,
|
||||
);
|
||||
|
|
@ -552,7 +554,7 @@ describe('SettingsDialog', () => {
|
|||
const settings = createMockSettings();
|
||||
const onSelect = vi.fn();
|
||||
|
||||
const { stdin, unmount, waitUntilReady } = renderDialog(
|
||||
const { stdin, unmount, waitUntilReady } = await renderDialog(
|
||||
settings,
|
||||
onSelect,
|
||||
);
|
||||
|
|
@ -575,7 +577,7 @@ describe('SettingsDialog', () => {
|
|||
const settings = createMockSettings();
|
||||
const onSelect = vi.fn();
|
||||
|
||||
const { stdin, unmount, waitUntilReady } = renderDialog(
|
||||
const { stdin, unmount, waitUntilReady } = await renderDialog(
|
||||
settings,
|
||||
onSelect,
|
||||
);
|
||||
|
|
@ -596,7 +598,7 @@ describe('SettingsDialog', () => {
|
|||
const settings = createMockSettings();
|
||||
const onSelect = vi.fn();
|
||||
|
||||
const { lastFrame, unmount, waitUntilReady } = renderDialog(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderDialog(
|
||||
settings,
|
||||
onSelect,
|
||||
);
|
||||
|
|
@ -623,9 +625,13 @@ describe('SettingsDialog', () => {
|
|||
const settings = createMockSettings();
|
||||
const onRestartRequest = vi.fn();
|
||||
|
||||
const { unmount, waitUntilReady } = renderDialog(settings, vi.fn(), {
|
||||
onRestartRequest,
|
||||
});
|
||||
const { unmount, waitUntilReady } = await renderDialog(
|
||||
settings,
|
||||
vi.fn(),
|
||||
{
|
||||
onRestartRequest,
|
||||
},
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
||||
// This test would need to trigger a restart-required setting change
|
||||
|
|
@ -638,7 +644,7 @@ describe('SettingsDialog', () => {
|
|||
const settings = createMockSettings();
|
||||
const onRestartRequest = vi.fn();
|
||||
|
||||
const { stdin, unmount, waitUntilReady } = renderDialog(
|
||||
const { stdin, unmount, waitUntilReady } = await renderDialog(
|
||||
settings,
|
||||
vi.fn(),
|
||||
{
|
||||
|
|
@ -663,7 +669,7 @@ describe('SettingsDialog', () => {
|
|||
const settings = createMockSettings();
|
||||
const onSelect = vi.fn();
|
||||
|
||||
const { lastFrame, unmount, waitUntilReady } = renderDialog(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderDialog(
|
||||
settings,
|
||||
onSelect,
|
||||
);
|
||||
|
|
@ -690,7 +696,7 @@ describe('SettingsDialog', () => {
|
|||
const settings = createMockSettings({ vimMode: true });
|
||||
const onSelect = vi.fn();
|
||||
|
||||
const { stdin, unmount, waitUntilReady } = renderDialog(
|
||||
const { stdin, unmount, waitUntilReady } = await renderDialog(
|
||||
settings,
|
||||
onSelect,
|
||||
);
|
||||
|
|
@ -727,7 +733,7 @@ describe('SettingsDialog', () => {
|
|||
});
|
||||
const onSelect = vi.fn();
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderDialog(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderDialog(
|
||||
settings,
|
||||
onSelect,
|
||||
);
|
||||
|
|
@ -745,7 +751,7 @@ describe('SettingsDialog', () => {
|
|||
const settings = createMockSettings();
|
||||
const onSelect = vi.fn();
|
||||
|
||||
const { stdin, unmount, waitUntilReady } = renderDialog(
|
||||
const { stdin, unmount, waitUntilReady } = await renderDialog(
|
||||
settings,
|
||||
onSelect,
|
||||
);
|
||||
|
|
@ -773,7 +779,7 @@ describe('SettingsDialog', () => {
|
|||
const settings = createMockSettings();
|
||||
const onSelect = vi.fn();
|
||||
|
||||
const { stdin, unmount, waitUntilReady } = renderDialog(
|
||||
const { stdin, unmount, waitUntilReady } = await renderDialog(
|
||||
settings,
|
||||
onSelect,
|
||||
);
|
||||
|
|
@ -812,7 +818,7 @@ describe('SettingsDialog', () => {
|
|||
});
|
||||
const onSelect = vi.fn();
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderDialog(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderDialog(
|
||||
settings,
|
||||
onSelect,
|
||||
);
|
||||
|
|
@ -828,7 +834,7 @@ describe('SettingsDialog', () => {
|
|||
const settings = createMockSettings();
|
||||
const onSelect = vi.fn();
|
||||
|
||||
const { stdin, unmount, waitUntilReady } = renderDialog(
|
||||
const { stdin, unmount, waitUntilReady } = await renderDialog(
|
||||
settings,
|
||||
onSelect,
|
||||
);
|
||||
|
|
@ -848,7 +854,7 @@ describe('SettingsDialog', () => {
|
|||
const settings = createMockSettings();
|
||||
const onSelect = vi.fn();
|
||||
|
||||
const { lastFrame, unmount, waitUntilReady } = renderDialog(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderDialog(
|
||||
settings,
|
||||
onSelect,
|
||||
);
|
||||
|
|
@ -871,7 +877,10 @@ describe('SettingsDialog', () => {
|
|||
const settings = createMockSettings();
|
||||
const onSelect = vi.fn();
|
||||
|
||||
const { unmount, waitUntilReady } = renderDialog(settings, onSelect);
|
||||
const { unmount, waitUntilReady } = await renderDialog(
|
||||
settings,
|
||||
onSelect,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
||||
// Restart prompt should be cleared when switching scopes
|
||||
|
|
@ -890,7 +899,7 @@ describe('SettingsDialog', () => {
|
|||
});
|
||||
const onSelect = vi.fn();
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderDialog(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderDialog(
|
||||
settings,
|
||||
onSelect,
|
||||
);
|
||||
|
|
@ -917,7 +926,7 @@ describe('SettingsDialog', () => {
|
|||
});
|
||||
const onSelect = vi.fn();
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderDialog(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderDialog(
|
||||
settings,
|
||||
onSelect,
|
||||
);
|
||||
|
|
@ -968,7 +977,7 @@ describe('SettingsDialog', () => {
|
|||
|
||||
const onSelect = vi.fn();
|
||||
|
||||
const { stdin, unmount } = renderDialog(settings, onSelect);
|
||||
const { stdin, unmount } = await renderDialog(settings, onSelect);
|
||||
|
||||
for (let i = 0; i < toggleCount; i++) {
|
||||
act(() => {
|
||||
|
|
@ -998,7 +1007,7 @@ describe('SettingsDialog', () => {
|
|||
const settings = createMockSettings();
|
||||
const onSelect = vi.fn();
|
||||
|
||||
const { stdin, unmount, waitUntilReady } = renderDialog(
|
||||
const { stdin, unmount, waitUntilReady } = await renderDialog(
|
||||
settings,
|
||||
onSelect,
|
||||
);
|
||||
|
|
@ -1026,7 +1035,7 @@ describe('SettingsDialog', () => {
|
|||
const settings = createMockSettings({ vimMode: true });
|
||||
const onSelect = vi.fn();
|
||||
|
||||
const { stdin, unmount, waitUntilReady } = renderDialog(
|
||||
const { stdin, unmount, waitUntilReady } = await renderDialog(
|
||||
settings,
|
||||
onSelect,
|
||||
);
|
||||
|
|
@ -1046,7 +1055,7 @@ describe('SettingsDialog', () => {
|
|||
const settings = createMockSettings();
|
||||
const onSelect = vi.fn();
|
||||
|
||||
const { stdin, unmount, waitUntilReady } = renderDialog(
|
||||
const { stdin, unmount, waitUntilReady } = await renderDialog(
|
||||
settings,
|
||||
onSelect,
|
||||
);
|
||||
|
|
@ -1069,7 +1078,7 @@ describe('SettingsDialog', () => {
|
|||
const settings = createMockSettings();
|
||||
const onSelect = vi.fn();
|
||||
|
||||
const { lastFrame, unmount, waitUntilReady } = renderDialog(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderDialog(
|
||||
settings,
|
||||
onSelect,
|
||||
);
|
||||
|
|
@ -1103,7 +1112,7 @@ describe('SettingsDialog', () => {
|
|||
});
|
||||
const onSelect = vi.fn();
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderDialog(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderDialog(
|
||||
settings,
|
||||
onSelect,
|
||||
);
|
||||
|
|
@ -1119,7 +1128,7 @@ describe('SettingsDialog', () => {
|
|||
const onSelect = vi.fn();
|
||||
|
||||
// Should not crash even if some settings are missing definitions
|
||||
const { lastFrame, waitUntilReady, unmount } = renderDialog(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderDialog(
|
||||
settings,
|
||||
onSelect,
|
||||
);
|
||||
|
|
@ -1135,7 +1144,7 @@ describe('SettingsDialog', () => {
|
|||
const settings = createMockSettings();
|
||||
const onSelect = vi.fn();
|
||||
|
||||
const { lastFrame, unmount, waitUntilReady } = renderDialog(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderDialog(
|
||||
settings,
|
||||
onSelect,
|
||||
);
|
||||
|
|
@ -1164,7 +1173,7 @@ describe('SettingsDialog', () => {
|
|||
const settings = createMockSettings();
|
||||
const onSelect = vi.fn();
|
||||
|
||||
const { stdin, unmount, waitUntilReady } = renderDialog(
|
||||
const { stdin, unmount, waitUntilReady } = await renderDialog(
|
||||
settings,
|
||||
onSelect,
|
||||
);
|
||||
|
|
@ -1201,7 +1210,7 @@ describe('SettingsDialog', () => {
|
|||
const settings = createMockSettings({ vimMode: true });
|
||||
const onSelect = vi.fn();
|
||||
|
||||
const { stdin, unmount, waitUntilReady } = renderDialog(
|
||||
const { stdin, unmount, waitUntilReady } = await renderDialog(
|
||||
settings,
|
||||
onSelect,
|
||||
);
|
||||
|
|
@ -1237,7 +1246,7 @@ describe('SettingsDialog', () => {
|
|||
const settings = createMockSettings();
|
||||
const onRestartRequest = vi.fn();
|
||||
|
||||
const { stdin, unmount, waitUntilReady } = renderDialog(
|
||||
const { stdin, unmount, waitUntilReady } = await renderDialog(
|
||||
settings,
|
||||
vi.fn(),
|
||||
{
|
||||
|
|
@ -1265,7 +1274,7 @@ describe('SettingsDialog', () => {
|
|||
const settings = createMockSettings();
|
||||
const onRestartRequest = vi.fn();
|
||||
|
||||
const { stdin, lastFrame, unmount, waitUntilReady } = renderDialog(
|
||||
const { stdin, lastFrame, unmount, waitUntilReady } = await renderDialog(
|
||||
settings,
|
||||
vi.fn(),
|
||||
{
|
||||
|
|
@ -1317,7 +1326,7 @@ describe('SettingsDialog', () => {
|
|||
vi.mocked(getSettingsSchema).mockReturnValue(TOOLS_SHELL_FAKE_SCHEMA);
|
||||
const settings = createMockSettings();
|
||||
|
||||
const { stdin, lastFrame, unmount, waitUntilReady } = renderDialog(
|
||||
const { stdin, lastFrame, unmount, waitUntilReady } = await renderDialog(
|
||||
settings,
|
||||
vi.fn(),
|
||||
);
|
||||
|
|
@ -1361,9 +1370,9 @@ describe('SettingsDialog', () => {
|
|||
});
|
||||
const onSelect = vi.fn();
|
||||
|
||||
const { stdin, unmount, waitUntilReady } = renderWithProviders(
|
||||
const { stdin, unmount, waitUntilReady } = await renderWithProviders(
|
||||
<SettingsDialog onSelect={onSelect} />,
|
||||
{ settings },
|
||||
{ settings, config: makeFakeConfig() },
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
||||
|
|
@ -1434,7 +1443,7 @@ describe('SettingsDialog', () => {
|
|||
const settings = createMockSettings();
|
||||
const setValueSpy = vi.spyOn(settings, 'setValue');
|
||||
|
||||
const { stdin, unmount } = renderDialog(settings, vi.fn());
|
||||
const { stdin, unmount } = await renderDialog(settings, vi.fn());
|
||||
|
||||
await act(async () => {
|
||||
stdin.write(TerminalKeys.ENTER as string); // Start editing first array setting
|
||||
|
|
@ -1460,7 +1469,7 @@ describe('SettingsDialog', () => {
|
|||
const settings = createMockSettings();
|
||||
const setValueSpy = vi.spyOn(settings, 'setValue');
|
||||
|
||||
const { stdin, unmount } = renderDialog(settings, vi.fn());
|
||||
const { stdin, unmount } = await renderDialog(settings, vi.fn());
|
||||
|
||||
await act(async () => {
|
||||
stdin.write(TerminalKeys.DOWN_ARROW as string); // Move to second array setting
|
||||
|
|
@ -1490,7 +1499,7 @@ describe('SettingsDialog', () => {
|
|||
const settings = createMockSettings();
|
||||
const onSelect = vi.fn();
|
||||
|
||||
const { lastFrame, stdin, unmount, waitUntilReady } = renderDialog(
|
||||
const { lastFrame, stdin, unmount, waitUntilReady } = await renderDialog(
|
||||
settings,
|
||||
onSelect,
|
||||
);
|
||||
|
|
@ -1520,7 +1529,7 @@ describe('SettingsDialog', () => {
|
|||
const settings = createMockSettings();
|
||||
const onSelect = vi.fn();
|
||||
|
||||
const { lastFrame, stdin, unmount, waitUntilReady } = renderDialog(
|
||||
const { lastFrame, stdin, unmount, waitUntilReady } = await renderDialog(
|
||||
settings,
|
||||
onSelect,
|
||||
);
|
||||
|
|
@ -1543,7 +1552,7 @@ describe('SettingsDialog', () => {
|
|||
const settings = createMockSettings();
|
||||
const onSelect = vi.fn();
|
||||
|
||||
const { lastFrame, stdin, unmount, waitUntilReady } = renderDialog(
|
||||
const { lastFrame, stdin, unmount, waitUntilReady } = await renderDialog(
|
||||
settings,
|
||||
onSelect,
|
||||
);
|
||||
|
|
@ -1576,7 +1585,7 @@ describe('SettingsDialog', () => {
|
|||
const settings = createMockSettings();
|
||||
const onSelect = vi.fn();
|
||||
|
||||
const { lastFrame, stdin, unmount, waitUntilReady } = renderDialog(
|
||||
const { lastFrame, stdin, unmount, waitUntilReady } = await renderDialog(
|
||||
settings,
|
||||
onSelect,
|
||||
);
|
||||
|
|
@ -1609,7 +1618,7 @@ describe('SettingsDialog', () => {
|
|||
const settings = createMockSettings();
|
||||
const onSelect = vi.fn();
|
||||
|
||||
const { lastFrame, stdin, unmount, waitUntilReady } = renderDialog(
|
||||
const { lastFrame, stdin, unmount, waitUntilReady } = await renderDialog(
|
||||
settings,
|
||||
onSelect,
|
||||
);
|
||||
|
|
@ -1863,7 +1872,7 @@ describe('SettingsDialog', () => {
|
|||
});
|
||||
const onSelect = vi.fn();
|
||||
|
||||
const renderResult = renderDialog(settings, onSelect);
|
||||
const renderResult = await renderDialog(settings, onSelect);
|
||||
await renderResult.waitUntilReady();
|
||||
|
||||
if (stdinActions) {
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ describe('ShortcutsHelp', () => {
|
|||
value: platform.value,
|
||||
});
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ShortcutsHelp />,
|
||||
{
|
||||
width,
|
||||
|
|
@ -56,7 +56,7 @@ describe('ShortcutsHelp', () => {
|
|||
);
|
||||
|
||||
it('always shows Tab focus UI shortcut', async () => {
|
||||
const rendered = renderWithProviders(<ShortcutsHelp />);
|
||||
const rendered = await renderWithProviders(<ShortcutsHelp />);
|
||||
await rendered.waitUntilReady();
|
||||
expect(rendered.lastFrame()).toContain('Tab focus UI');
|
||||
rendered.unmount();
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ vi.mock('../contexts/SessionContext.js', async (importOriginal) => {
|
|||
|
||||
const useSessionStatsMock = vi.mocked(SessionContext.useSessionStats);
|
||||
|
||||
const renderWithMockedStats = (metrics: SessionMetrics) => {
|
||||
const renderWithMockedStats = async (metrics: SessionMetrics) => {
|
||||
useSessionStatsMock.mockReturnValue({
|
||||
stats: {
|
||||
sessionId: 'test-session-id',
|
||||
|
|
@ -39,7 +39,9 @@ const renderWithMockedStats = (metrics: SessionMetrics) => {
|
|||
startNewPrompt: vi.fn(),
|
||||
});
|
||||
|
||||
return renderWithProviders(<StatsDisplay duration="1s" />, { width: 100 });
|
||||
return renderWithProviders(<StatsDisplay duration="1s" />, {
|
||||
width: 100,
|
||||
});
|
||||
};
|
||||
|
||||
// Helper to create metrics with default zero values
|
||||
|
|
@ -79,7 +81,8 @@ describe('<StatsDisplay />', () => {
|
|||
it('renders only the Performance section in its zero state', async () => {
|
||||
const zeroMetrics = createTestMetrics();
|
||||
|
||||
const { lastFrame, waitUntilReady } = renderWithMockedStats(zeroMetrics);
|
||||
const { lastFrame, waitUntilReady } =
|
||||
await renderWithMockedStats(zeroMetrics);
|
||||
await waitUntilReady();
|
||||
const output = lastFrame();
|
||||
|
||||
|
|
@ -120,7 +123,7 @@ describe('<StatsDisplay />', () => {
|
|||
},
|
||||
});
|
||||
|
||||
const { lastFrame, waitUntilReady } = renderWithMockedStats(metrics);
|
||||
const { lastFrame, waitUntilReady } = await renderWithMockedStats(metrics);
|
||||
await waitUntilReady();
|
||||
const output = lastFrame();
|
||||
|
||||
|
|
@ -176,7 +179,7 @@ describe('<StatsDisplay />', () => {
|
|||
},
|
||||
});
|
||||
|
||||
const { lastFrame, waitUntilReady } = renderWithMockedStats(metrics);
|
||||
const { lastFrame, waitUntilReady } = await renderWithMockedStats(metrics);
|
||||
await waitUntilReady();
|
||||
const output = lastFrame();
|
||||
|
||||
|
|
@ -218,7 +221,8 @@ describe('<StatsDisplay />', () => {
|
|||
},
|
||||
});
|
||||
|
||||
const { lastFrame, waitUntilReady } = renderWithMockedStats(metrics);
|
||||
const { lastFrame, waitUntilReady } =
|
||||
await renderWithMockedStats(metrics);
|
||||
await waitUntilReady();
|
||||
const output = lastFrame();
|
||||
|
||||
|
|
@ -247,7 +251,8 @@ describe('<StatsDisplay />', () => {
|
|||
},
|
||||
});
|
||||
|
||||
const { lastFrame, waitUntilReady } = renderWithMockedStats(metrics);
|
||||
const { lastFrame, waitUntilReady } =
|
||||
await renderWithMockedStats(metrics);
|
||||
await waitUntilReady();
|
||||
const output = lastFrame();
|
||||
|
||||
|
|
@ -272,7 +277,8 @@ describe('<StatsDisplay />', () => {
|
|||
byName: {},
|
||||
},
|
||||
});
|
||||
const { lastFrame, waitUntilReady } = renderWithMockedStats(metrics);
|
||||
const { lastFrame, waitUntilReady } =
|
||||
await renderWithMockedStats(metrics);
|
||||
await waitUntilReady();
|
||||
expect(lastFrame()).toMatchSnapshot();
|
||||
});
|
||||
|
|
@ -293,7 +299,8 @@ describe('<StatsDisplay />', () => {
|
|||
byName: {},
|
||||
},
|
||||
});
|
||||
const { lastFrame, waitUntilReady } = renderWithMockedStats(metrics);
|
||||
const { lastFrame, waitUntilReady } =
|
||||
await renderWithMockedStats(metrics);
|
||||
await waitUntilReady();
|
||||
expect(lastFrame()).toMatchSnapshot();
|
||||
});
|
||||
|
|
@ -314,7 +321,8 @@ describe('<StatsDisplay />', () => {
|
|||
byName: {},
|
||||
},
|
||||
});
|
||||
const { lastFrame, waitUntilReady } = renderWithMockedStats(metrics);
|
||||
const { lastFrame, waitUntilReady } =
|
||||
await renderWithMockedStats(metrics);
|
||||
await waitUntilReady();
|
||||
expect(lastFrame()).toMatchSnapshot();
|
||||
});
|
||||
|
|
@ -342,7 +350,8 @@ describe('<StatsDisplay />', () => {
|
|||
},
|
||||
});
|
||||
|
||||
const { lastFrame, waitUntilReady } = renderWithMockedStats(metrics);
|
||||
const { lastFrame, waitUntilReady } =
|
||||
await renderWithMockedStats(metrics);
|
||||
await waitUntilReady();
|
||||
const output = lastFrame();
|
||||
|
||||
|
|
@ -369,7 +378,8 @@ describe('<StatsDisplay />', () => {
|
|||
},
|
||||
});
|
||||
|
||||
const { lastFrame, waitUntilReady } = renderWithMockedStats(metrics);
|
||||
const { lastFrame, waitUntilReady } =
|
||||
await renderWithMockedStats(metrics);
|
||||
await waitUntilReady();
|
||||
const output = lastFrame();
|
||||
|
||||
|
|
@ -382,7 +392,8 @@ describe('<StatsDisplay />', () => {
|
|||
const zeroMetrics = createTestMetrics();
|
||||
|
||||
it('renders the default title when no title prop is provided', async () => {
|
||||
const { lastFrame, waitUntilReady } = renderWithMockedStats(zeroMetrics);
|
||||
const { lastFrame, waitUntilReady } =
|
||||
await renderWithMockedStats(zeroMetrics);
|
||||
await waitUntilReady();
|
||||
const output = lastFrame();
|
||||
expect(output).toContain('Session Stats');
|
||||
|
|
@ -404,7 +415,7 @@ describe('<StatsDisplay />', () => {
|
|||
startNewPrompt: vi.fn(),
|
||||
});
|
||||
|
||||
const { lastFrame, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady } = await renderWithProviders(
|
||||
<StatsDisplay duration="1s" title="Agent powering down. Goodbye!" />,
|
||||
{ width: 100 },
|
||||
);
|
||||
|
|
@ -466,7 +477,7 @@ describe('<StatsDisplay />', () => {
|
|||
startNewPrompt: vi.fn(),
|
||||
});
|
||||
|
||||
const { lastFrame, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady } = await renderWithProviders(
|
||||
<StatsDisplay duration="1s" quotas={quotas} />,
|
||||
{ width: 100 },
|
||||
);
|
||||
|
|
@ -514,7 +525,7 @@ describe('<StatsDisplay />', () => {
|
|||
startNewPrompt: vi.fn(),
|
||||
});
|
||||
|
||||
const { lastFrame, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady } = await renderWithProviders(
|
||||
<StatsDisplay
|
||||
duration="1s"
|
||||
quotas={quotas}
|
||||
|
|
@ -570,7 +581,7 @@ describe('<StatsDisplay />', () => {
|
|||
startNewPrompt: vi.fn(),
|
||||
});
|
||||
|
||||
const { lastFrame, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady } = await renderWithProviders(
|
||||
<StatsDisplay duration="1s" quotas={quotas} />,
|
||||
{ width: 100 },
|
||||
);
|
||||
|
|
@ -603,7 +614,7 @@ describe('<StatsDisplay />', () => {
|
|||
startNewPrompt: vi.fn(),
|
||||
});
|
||||
|
||||
const { lastFrame, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady } = await renderWithProviders(
|
||||
<StatsDisplay
|
||||
duration="1s"
|
||||
selectedAuthType="oauth"
|
||||
|
|
@ -636,7 +647,7 @@ describe('<StatsDisplay />', () => {
|
|||
startNewPrompt: vi.fn(),
|
||||
});
|
||||
|
||||
const { lastFrame, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady } = await renderWithProviders(
|
||||
<StatsDisplay duration="1s" selectedAuthType="Google API Key" />,
|
||||
{ width: 100 },
|
||||
);
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ describe('StickyHeader', () => {
|
|||
it.each([true, false])(
|
||||
'renders children with isFirst=%s',
|
||||
async (isFirst) => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<StickyHeader
|
||||
isFirst={isFirst}
|
||||
width={80}
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ describe('ThemeDialog Snapshots', () => {
|
|||
async (isDev) => {
|
||||
mockIsDevelopment.value = isDev;
|
||||
const settings = createMockSettings();
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ThemeDialog {...baseProps} settings={settings} />,
|
||||
{ settings },
|
||||
);
|
||||
|
|
@ -64,10 +64,11 @@ describe('ThemeDialog Snapshots', () => {
|
|||
|
||||
it('should render correctly in scope selector mode', async () => {
|
||||
const settings = createMockSettings();
|
||||
const { lastFrame, stdin, waitUntilReady, unmount } = renderWithProviders(
|
||||
<ThemeDialog {...baseProps} settings={settings} />,
|
||||
{ settings },
|
||||
);
|
||||
const { lastFrame, stdin, waitUntilReady, unmount } =
|
||||
await renderWithProviders(
|
||||
<ThemeDialog {...baseProps} settings={settings} />,
|
||||
{ settings },
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
||||
// Press Tab to switch to scope selector mode
|
||||
|
|
@ -85,7 +86,7 @@ describe('ThemeDialog Snapshots', () => {
|
|||
it('should call onCancel when ESC is pressed', async () => {
|
||||
const mockOnCancel = vi.fn();
|
||||
const settings = createMockSettings();
|
||||
const { stdin, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { stdin, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ThemeDialog
|
||||
{...baseProps}
|
||||
onCancel={mockOnCancel}
|
||||
|
|
@ -112,7 +113,7 @@ describe('ThemeDialog Snapshots', () => {
|
|||
|
||||
it('should call onSelect when a theme is selected', async () => {
|
||||
const settings = createMockSettings();
|
||||
const { stdin, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { stdin, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ThemeDialog {...baseProps} settings={settings} />,
|
||||
{
|
||||
settings,
|
||||
|
|
@ -148,7 +149,7 @@ describe('Initial Theme Selection', () => {
|
|||
|
||||
it('should default to a light theme when terminal background is light and no theme is set', async () => {
|
||||
const settings = createMockSettings(); // No theme set
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ThemeDialog {...baseProps} settings={settings} />,
|
||||
{
|
||||
settings,
|
||||
|
|
@ -165,7 +166,7 @@ describe('Initial Theme Selection', () => {
|
|||
|
||||
it('should default to a dark theme when terminal background is dark and no theme is set', async () => {
|
||||
const settings = createMockSettings(); // No theme set
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ThemeDialog {...baseProps} settings={settings} />,
|
||||
{
|
||||
settings,
|
||||
|
|
@ -181,7 +182,7 @@ describe('Initial Theme Selection', () => {
|
|||
|
||||
it('should use the theme from settings even if terminal background suggests a different theme type', async () => {
|
||||
const settings = createMockSettings({ ui: { theme: 'DefaultLight' } }); // Light theme set
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ThemeDialog {...baseProps} settings={settings} />,
|
||||
{
|
||||
settings,
|
||||
|
|
@ -207,7 +208,7 @@ describe('Hint Visibility', () => {
|
|||
|
||||
it('should show hint when theme background matches terminal background', async () => {
|
||||
const settings = createMockSettings({ ui: { theme: 'Default' } });
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ThemeDialog {...baseProps} settings={settings} />,
|
||||
{
|
||||
settings,
|
||||
|
|
@ -222,7 +223,7 @@ describe('Hint Visibility', () => {
|
|||
|
||||
it('should not show hint when theme background does not match terminal background', async () => {
|
||||
const settings = createMockSettings({ ui: { theme: 'Default' } });
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ThemeDialog {...baseProps} settings={settings} />,
|
||||
{
|
||||
settings,
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import { type UIState } from '../contexts/UIStateContext.js';
|
|||
import { type TextBuffer } from './shared/text-buffer.js';
|
||||
import { type HistoryItem } from '../types.js';
|
||||
|
||||
const renderToastDisplay = (uiState: Partial<UIState> = {}) =>
|
||||
const renderToastDisplay = async (uiState: Partial<UIState> = {}) =>
|
||||
renderWithProviders(<ToastDisplay />, {
|
||||
uiState: {
|
||||
buffer: { text: '' } as TextBuffer,
|
||||
|
|
@ -112,13 +112,13 @@ describe('ToastDisplay', () => {
|
|||
});
|
||||
|
||||
it('renders nothing by default', async () => {
|
||||
const { lastFrame, waitUntilReady } = renderToastDisplay();
|
||||
const { lastFrame, waitUntilReady } = await renderToastDisplay();
|
||||
await waitUntilReady();
|
||||
expect(lastFrame({ allowEmpty: true })).toBe('');
|
||||
});
|
||||
|
||||
it('renders Ctrl+C prompt', async () => {
|
||||
const { lastFrame, waitUntilReady } = renderToastDisplay({
|
||||
const { lastFrame, waitUntilReady } = await renderToastDisplay({
|
||||
ctrlCPressedOnce: true,
|
||||
});
|
||||
await waitUntilReady();
|
||||
|
|
@ -126,7 +126,7 @@ describe('ToastDisplay', () => {
|
|||
});
|
||||
|
||||
it('renders warning message', async () => {
|
||||
const { lastFrame, waitUntilReady } = renderToastDisplay({
|
||||
const { lastFrame, waitUntilReady } = await renderToastDisplay({
|
||||
transientMessage: {
|
||||
text: 'This is a warning',
|
||||
type: TransientMessageType.Warning,
|
||||
|
|
@ -137,7 +137,7 @@ describe('ToastDisplay', () => {
|
|||
});
|
||||
|
||||
it('renders hint message', async () => {
|
||||
const { lastFrame, waitUntilReady } = renderToastDisplay({
|
||||
const { lastFrame, waitUntilReady } = await renderToastDisplay({
|
||||
transientMessage: {
|
||||
text: 'This is a hint',
|
||||
type: TransientMessageType.Hint,
|
||||
|
|
@ -148,7 +148,7 @@ describe('ToastDisplay', () => {
|
|||
});
|
||||
|
||||
it('renders Ctrl+D prompt', async () => {
|
||||
const { lastFrame, waitUntilReady } = renderToastDisplay({
|
||||
const { lastFrame, waitUntilReady } = await renderToastDisplay({
|
||||
ctrlDPressedOnce: true,
|
||||
});
|
||||
await waitUntilReady();
|
||||
|
|
@ -156,7 +156,7 @@ describe('ToastDisplay', () => {
|
|||
});
|
||||
|
||||
it('renders Escape prompt when buffer is empty', async () => {
|
||||
const { lastFrame, waitUntilReady } = renderToastDisplay({
|
||||
const { lastFrame, waitUntilReady } = await renderToastDisplay({
|
||||
showEscapePrompt: true,
|
||||
history: [{ id: 1, type: 'user', text: 'test' }] as HistoryItem[],
|
||||
});
|
||||
|
|
@ -165,7 +165,7 @@ describe('ToastDisplay', () => {
|
|||
});
|
||||
|
||||
it('renders Escape prompt when buffer is NOT empty', async () => {
|
||||
const { lastFrame, waitUntilReady } = renderToastDisplay({
|
||||
const { lastFrame, waitUntilReady } = await renderToastDisplay({
|
||||
showEscapePrompt: true,
|
||||
buffer: { text: 'some text' } as TextBuffer,
|
||||
});
|
||||
|
|
@ -174,7 +174,7 @@ describe('ToastDisplay', () => {
|
|||
});
|
||||
|
||||
it('renders Queue Error Message', async () => {
|
||||
const { lastFrame, waitUntilReady } = renderToastDisplay({
|
||||
const { lastFrame, waitUntilReady } = await renderToastDisplay({
|
||||
queueErrorMessage: 'Queue Error',
|
||||
});
|
||||
await waitUntilReady();
|
||||
|
|
@ -182,7 +182,7 @@ describe('ToastDisplay', () => {
|
|||
});
|
||||
|
||||
it('renders expansion hint when showIsExpandableHint is true', async () => {
|
||||
const { lastFrame, waitUntilReady } = renderToastDisplay({
|
||||
const { lastFrame, waitUntilReady } = await renderToastDisplay({
|
||||
showIsExpandableHint: true,
|
||||
constrainHeight: true,
|
||||
});
|
||||
|
|
@ -193,7 +193,7 @@ describe('ToastDisplay', () => {
|
|||
});
|
||||
|
||||
it('renders collapse hint when showIsExpandableHint is true and constrainHeight is false', async () => {
|
||||
const { lastFrame, waitUntilReady } = renderToastDisplay({
|
||||
const { lastFrame, waitUntilReady } = await renderToastDisplay({
|
||||
showIsExpandableHint: true,
|
||||
constrainHeight: false,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ describe('ToolConfirmationQueue', () => {
|
|||
total: 3,
|
||||
};
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ToolConfirmationQueue
|
||||
confirmingTool={confirmingTool as unknown as ConfirmingToolState}
|
||||
/>,
|
||||
|
|
@ -117,7 +117,7 @@ describe('ToolConfirmationQueue', () => {
|
|||
total: 1,
|
||||
};
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ToolConfirmationQueue
|
||||
confirmingTool={confirmingTool as unknown as ConfirmingToolState}
|
||||
/>,
|
||||
|
|
@ -156,7 +156,7 @@ describe('ToolConfirmationQueue', () => {
|
|||
total: 1,
|
||||
};
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Box flexDirection="column" height={30}>
|
||||
<ToolConfirmationQueue
|
||||
confirmingTool={confirmingTool as unknown as ConfirmingToolState}
|
||||
|
|
@ -210,7 +210,7 @@ describe('ToolConfirmationQueue', () => {
|
|||
};
|
||||
|
||||
// Use a small availableTerminalHeight to force truncation
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ToolConfirmationQueue
|
||||
confirmingTool={confirmingTool as unknown as ConfirmingToolState}
|
||||
/>,
|
||||
|
|
@ -265,7 +265,7 @@ describe('ToolConfirmationQueue', () => {
|
|||
lastFrame,
|
||||
waitUntilReady,
|
||||
unmount = vi.fn(),
|
||||
} = renderWithProviders(
|
||||
} = await renderWithProviders(
|
||||
<ToolConfirmationQueue
|
||||
confirmingTool={confirmingTool as unknown as ConfirmingToolState}
|
||||
/>,
|
||||
|
|
@ -321,7 +321,7 @@ describe('ToolConfirmationQueue', () => {
|
|||
total: 1,
|
||||
};
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ToolConfirmationQueue
|
||||
confirmingTool={confirmingTool as unknown as ConfirmingToolState}
|
||||
/>,
|
||||
|
|
@ -360,7 +360,7 @@ describe('ToolConfirmationQueue', () => {
|
|||
total: 1,
|
||||
};
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ToolConfirmationQueue
|
||||
confirmingTool={confirmingTool as unknown as ConfirmingToolState}
|
||||
/>,
|
||||
|
|
@ -398,7 +398,7 @@ describe('ToolConfirmationQueue', () => {
|
|||
total: 1,
|
||||
};
|
||||
|
||||
const { lastFrame, unmount } = renderWithProviders(
|
||||
const { lastFrame, unmount } = await renderWithProviders(
|
||||
<ToolConfirmationQueue
|
||||
confirmingTool={confirmingTool as unknown as ConfirmingToolState}
|
||||
/>,
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ describe('<UserIdentity />', () => {
|
|||
} as unknown as ContentGeneratorConfig);
|
||||
vi.spyOn(mockConfig, 'getUserTierName').mockReturnValue(undefined);
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<UserIdentity config={mockConfig} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -51,7 +51,7 @@ describe('<UserIdentity />', () => {
|
|||
unmount();
|
||||
});
|
||||
|
||||
it('should render the user email on the very first frame (regression test)', () => {
|
||||
it('should render the user email on the very first frame (regression test)', async () => {
|
||||
const mockConfig = makeFakeConfig();
|
||||
vi.spyOn(mockConfig, 'getContentGeneratorConfig').mockReturnValue({
|
||||
authType: AuthType.LOGIN_WITH_GOOGLE,
|
||||
|
|
@ -59,7 +59,7 @@ describe('<UserIdentity />', () => {
|
|||
} as unknown as ContentGeneratorConfig);
|
||||
vi.spyOn(mockConfig, 'getUserTierName').mockReturnValue(undefined);
|
||||
|
||||
const { lastFrameRaw, unmount } = renderWithProviders(
|
||||
const { lastFrameRaw, unmount } = await renderWithProviders(
|
||||
<UserIdentity config={mockConfig} />,
|
||||
);
|
||||
|
||||
|
|
@ -85,7 +85,7 @@ describe('<UserIdentity />', () => {
|
|||
} as unknown as ContentGeneratorConfig);
|
||||
vi.spyOn(mockConfig, 'getUserTierName').mockReturnValue(undefined);
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<UserIdentity config={mockConfig} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -106,7 +106,7 @@ describe('<UserIdentity />', () => {
|
|||
} as unknown as ContentGeneratorConfig);
|
||||
vi.spyOn(mockConfig, 'getUserTierName').mockReturnValue('Premium Plan');
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<UserIdentity config={mockConfig} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -135,7 +135,7 @@ describe('<UserIdentity />', () => {
|
|||
{} as unknown as ContentGeneratorConfig,
|
||||
);
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<UserIdentity config={mockConfig} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -152,7 +152,7 @@ describe('<UserIdentity />', () => {
|
|||
} as unknown as ContentGeneratorConfig);
|
||||
vi.spyOn(mockConfig, 'getUserTierName').mockReturnValue(undefined);
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<UserIdentity config={mockConfig} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -172,7 +172,7 @@ describe('<UserIdentity />', () => {
|
|||
} as unknown as ContentGeneratorConfig);
|
||||
vi.spyOn(mockConfig, 'getUserTierName').mockReturnValue('Enterprise Tier');
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<UserIdentity config={mockConfig} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -191,7 +191,7 @@ describe('<UserIdentity />', () => {
|
|||
} as unknown as ContentGeneratorConfig);
|
||||
vi.spyOn(mockConfig, 'getUserTierName').mockReturnValue('Advanced Ultra');
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<UserIdentity config={mockConfig} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
|
|||
|
|
@ -18,20 +18,8 @@ Spinner Connecting to MCP servers... (0/5) - Waiting for: s1, s2, s3, +2 more
|
|||
"
|
||||
`;
|
||||
|
||||
exports[`ConfigInitDisplay > truncates list of waiting servers if too many 2`] = `
|
||||
"
|
||||
Spinner Connecting to MCP servers... (0/5) - Waiting for: s1, s2, s3, +2 more
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`ConfigInitDisplay > updates message on McpClientUpdate event 1`] = `
|
||||
"
|
||||
Spinner Connecting to MCP servers... (1/2) - Waiting for: server2
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`ConfigInitDisplay > updates message on McpClientUpdate event 2`] = `
|
||||
"
|
||||
Spinner Connecting to MCP servers... (1/2) - Waiting for: server2
|
||||
"
|
||||
`;
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ describe('<CompressionMessage />', () => {
|
|||
describe('pending state', () => {
|
||||
it('renders pending message when compression is in progress', async () => {
|
||||
const props = createCompressionProps({ isPending: true });
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<CompressionMessage {...props} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -48,7 +48,7 @@ describe('<CompressionMessage />', () => {
|
|||
newTokenCount: 50,
|
||||
compressionStatus: CompressionStatus.COMPRESSED,
|
||||
});
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<CompressionMessage {...props} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -73,9 +73,8 @@ describe('<CompressionMessage />', () => {
|
|||
newTokenCount: newTokens,
|
||||
compressionStatus: CompressionStatus.COMPRESSED,
|
||||
});
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
<CompressionMessage {...props} />,
|
||||
);
|
||||
const { lastFrame, waitUntilReady, unmount } =
|
||||
await renderWithProviders(<CompressionMessage {...props} />);
|
||||
await waitUntilReady();
|
||||
const output = lastFrame();
|
||||
|
||||
|
|
@ -99,7 +98,7 @@ describe('<CompressionMessage />', () => {
|
|||
compressionStatus:
|
||||
CompressionStatus.COMPRESSION_FAILED_INFLATED_TOKEN_COUNT,
|
||||
});
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<CompressionMessage {...props} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -120,7 +119,7 @@ describe('<CompressionMessage />', () => {
|
|||
compressionStatus:
|
||||
CompressionStatus.COMPRESSION_FAILED_INFLATED_TOKEN_COUNT,
|
||||
});
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<CompressionMessage {...props} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -159,9 +158,8 @@ describe('<CompressionMessage />', () => {
|
|||
newTokenCount: newTokens,
|
||||
compressionStatus: CompressionStatus.COMPRESSED,
|
||||
});
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
<CompressionMessage {...props} />,
|
||||
);
|
||||
const { lastFrame, waitUntilReady, unmount } =
|
||||
await renderWithProviders(<CompressionMessage {...props} />);
|
||||
await waitUntilReady();
|
||||
const output = lastFrame();
|
||||
|
||||
|
|
@ -184,9 +182,8 @@ describe('<CompressionMessage />', () => {
|
|||
compressionStatus:
|
||||
CompressionStatus.COMPRESSION_FAILED_INFLATED_TOKEN_COUNT,
|
||||
});
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
<CompressionMessage {...props} />,
|
||||
);
|
||||
const { lastFrame, waitUntilReady, unmount } =
|
||||
await renderWithProviders(<CompressionMessage {...props} />);
|
||||
await waitUntilReady();
|
||||
const output = lastFrame();
|
||||
|
||||
|
|
@ -212,9 +209,8 @@ describe('<CompressionMessage />', () => {
|
|||
compressionStatus:
|
||||
CompressionStatus.COMPRESSION_FAILED_INFLATED_TOKEN_COUNT,
|
||||
});
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
<CompressionMessage {...props} />,
|
||||
);
|
||||
const { lastFrame, waitUntilReady, unmount } =
|
||||
await renderWithProviders(<CompressionMessage {...props} />);
|
||||
await waitUntilReady();
|
||||
const output = lastFrame();
|
||||
|
||||
|
|
@ -232,7 +228,7 @@ describe('<CompressionMessage />', () => {
|
|||
isPending: false,
|
||||
compressionStatus: CompressionStatus.COMPRESSION_FAILED_EMPTY_SUMMARY,
|
||||
});
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<CompressionMessage {...props} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -251,7 +247,7 @@ describe('<CompressionMessage />', () => {
|
|||
compressionStatus:
|
||||
CompressionStatus.COMPRESSION_FAILED_TOKEN_COUNT_ERROR,
|
||||
});
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<CompressionMessage {...props} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
import { OverflowProvider } from '../../contexts/OverflowContext.js';
|
||||
import { renderWithProviders } from '../../../test-utils/render.js';
|
||||
import { createMockSettings } from '../../../test-utils/settings.js';
|
||||
import { makeFakeConfig } from '@google/gemini-cli-core';
|
||||
import { waitFor } from '../../../test-utils/async.js';
|
||||
import { DiffRenderer } from './DiffRenderer.js';
|
||||
import * as CodeColorizer from '../../utils/CodeColorizer.js';
|
||||
|
|
@ -36,7 +35,7 @@ index 0000000..e69de29
|
|||
@@ -0,0 +1 @@
|
||||
+print("hello world")
|
||||
`;
|
||||
renderWithProviders(
|
||||
await renderWithProviders(
|
||||
<OverflowProvider>
|
||||
<DiffRenderer
|
||||
diffContent={newFileDiffContent}
|
||||
|
|
@ -45,7 +44,6 @@ index 0000000..e69de29
|
|||
/>
|
||||
</OverflowProvider>,
|
||||
{
|
||||
config: makeFakeConfig({ useAlternateBuffer }),
|
||||
settings: createMockSettings({ ui: { useAlternateBuffer } }),
|
||||
},
|
||||
);
|
||||
|
|
@ -71,7 +69,7 @@ index 0000000..e69de29
|
|||
@@ -0,0 +1 @@
|
||||
+some content
|
||||
`;
|
||||
renderWithProviders(
|
||||
await renderWithProviders(
|
||||
<OverflowProvider>
|
||||
<DiffRenderer
|
||||
diffContent={newFileDiffContent}
|
||||
|
|
@ -80,7 +78,6 @@ index 0000000..e69de29
|
|||
/>
|
||||
</OverflowProvider>,
|
||||
{
|
||||
config: makeFakeConfig({ useAlternateBuffer }),
|
||||
settings: createMockSettings({ ui: { useAlternateBuffer } }),
|
||||
},
|
||||
);
|
||||
|
|
@ -106,12 +103,11 @@ index 0000000..e69de29
|
|||
@@ -0,0 +1 @@
|
||||
+some text content
|
||||
`;
|
||||
renderWithProviders(
|
||||
await renderWithProviders(
|
||||
<OverflowProvider>
|
||||
<DiffRenderer diffContent={newFileDiffContent} terminalWidth={80} />
|
||||
</OverflowProvider>,
|
||||
{
|
||||
config: makeFakeConfig({ useAlternateBuffer }),
|
||||
settings: createMockSettings({ ui: { useAlternateBuffer } }),
|
||||
},
|
||||
);
|
||||
|
|
@ -138,7 +134,7 @@ index 0000001..0000002 100644
|
|||
-old line
|
||||
+new line
|
||||
`;
|
||||
const { lastFrame } = renderWithProviders(
|
||||
const { lastFrame } = await renderWithProviders(
|
||||
<OverflowProvider>
|
||||
<DiffRenderer
|
||||
diffContent={existingFileDiffContent}
|
||||
|
|
@ -147,7 +143,6 @@ index 0000001..0000002 100644
|
|||
/>
|
||||
</OverflowProvider>,
|
||||
{
|
||||
config: makeFakeConfig({ useAlternateBuffer }),
|
||||
settings: createMockSettings({ ui: { useAlternateBuffer } }),
|
||||
},
|
||||
);
|
||||
|
|
@ -172,7 +167,7 @@ index 1234567..1234567 100644
|
|||
--- a/file.txt
|
||||
+++ b/file.txt
|
||||
`;
|
||||
const { lastFrame } = renderWithProviders(
|
||||
const { lastFrame } = await renderWithProviders(
|
||||
<OverflowProvider>
|
||||
<DiffRenderer
|
||||
diffContent={noChangeDiff}
|
||||
|
|
@ -181,7 +176,6 @@ index 1234567..1234567 100644
|
|||
/>
|
||||
</OverflowProvider>,
|
||||
{
|
||||
config: makeFakeConfig({ useAlternateBuffer }),
|
||||
settings: createMockSettings({ ui: { useAlternateBuffer } }),
|
||||
},
|
||||
);
|
||||
|
|
@ -191,12 +185,11 @@ index 1234567..1234567 100644
|
|||
});
|
||||
|
||||
it('should handle empty diff content', async () => {
|
||||
const { lastFrame } = renderWithProviders(
|
||||
const { lastFrame } = await renderWithProviders(
|
||||
<OverflowProvider>
|
||||
<DiffRenderer diffContent="" terminalWidth={80} />
|
||||
</OverflowProvider>,
|
||||
{
|
||||
config: makeFakeConfig({ useAlternateBuffer }),
|
||||
settings: createMockSettings({ ui: { useAlternateBuffer } }),
|
||||
},
|
||||
);
|
||||
|
|
@ -220,7 +213,7 @@ index 123..456 100644
|
|||
context line 10
|
||||
context line 11
|
||||
`;
|
||||
const { lastFrame } = renderWithProviders(
|
||||
const { lastFrame } = await renderWithProviders(
|
||||
<OverflowProvider>
|
||||
<DiffRenderer
|
||||
diffContent={diffWithGap}
|
||||
|
|
@ -229,7 +222,6 @@ index 123..456 100644
|
|||
/>
|
||||
</OverflowProvider>,
|
||||
{
|
||||
config: makeFakeConfig({ useAlternateBuffer }),
|
||||
settings: createMockSettings({ ui: { useAlternateBuffer } }),
|
||||
},
|
||||
);
|
||||
|
|
@ -257,7 +249,7 @@ index abc..def 100644
|
|||
context line 14
|
||||
context line 15
|
||||
`;
|
||||
const { lastFrame } = renderWithProviders(
|
||||
const { lastFrame } = await renderWithProviders(
|
||||
<OverflowProvider>
|
||||
<DiffRenderer
|
||||
diffContent={diffWithSmallGap}
|
||||
|
|
@ -266,7 +258,6 @@ index abc..def 100644
|
|||
/>
|
||||
</OverflowProvider>,
|
||||
{
|
||||
config: makeFakeConfig({ useAlternateBuffer }),
|
||||
settings: createMockSettings({ ui: { useAlternateBuffer } }),
|
||||
},
|
||||
);
|
||||
|
|
@ -309,7 +300,7 @@ index 123..789 100644
|
|||
])(
|
||||
'with terminalWidth $terminalWidth and height $height',
|
||||
async ({ terminalWidth, height }) => {
|
||||
const { lastFrame } = renderWithProviders(
|
||||
const { lastFrame } = await renderWithProviders(
|
||||
<OverflowProvider>
|
||||
<DiffRenderer
|
||||
diffContent={diffWithMultipleHunks}
|
||||
|
|
@ -319,7 +310,6 @@ index 123..789 100644
|
|||
/>
|
||||
</OverflowProvider>,
|
||||
{
|
||||
config: makeFakeConfig({ useAlternateBuffer }),
|
||||
settings: createMockSettings({ ui: { useAlternateBuffer } }),
|
||||
},
|
||||
);
|
||||
|
|
@ -347,7 +337,7 @@ fileDiff Index: file.txt
|
|||
+const anotherNew = 'test';
|
||||
\\ No newline at end of file
|
||||
`;
|
||||
const { lastFrame } = renderWithProviders(
|
||||
const { lastFrame } = await renderWithProviders(
|
||||
<OverflowProvider>
|
||||
<DiffRenderer
|
||||
diffContent={newFileDiff}
|
||||
|
|
@ -356,7 +346,6 @@ fileDiff Index: file.txt
|
|||
/>
|
||||
</OverflowProvider>,
|
||||
{
|
||||
config: makeFakeConfig({ useAlternateBuffer }),
|
||||
settings: createMockSettings({ ui: { useAlternateBuffer } }),
|
||||
},
|
||||
);
|
||||
|
|
@ -377,7 +366,7 @@ fileDiff Index: Dockerfile
|
|||
+RUN npm run build
|
||||
\\ No newline at end of file
|
||||
`;
|
||||
const { lastFrame } = renderWithProviders(
|
||||
const { lastFrame } = await renderWithProviders(
|
||||
<OverflowProvider>
|
||||
<DiffRenderer
|
||||
diffContent={newFileDiff}
|
||||
|
|
@ -386,7 +375,6 @@ fileDiff Index: Dockerfile
|
|||
/>
|
||||
</OverflowProvider>,
|
||||
{
|
||||
config: makeFakeConfig({ useAlternateBuffer }),
|
||||
settings: createMockSettings({ ui: { useAlternateBuffer } }),
|
||||
},
|
||||
);
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ describe('<GeminiMessage /> - Raw Markdown Display Snapshots', () => {
|
|||
])(
|
||||
'renders with renderMarkdown=$renderMarkdown $description',
|
||||
async ({ renderMarkdown }) => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<GeminiMessage {...baseProps} />,
|
||||
{
|
||||
uiState: { renderMarkdown, streamingState: StreamingState.Idle },
|
||||
|
|
@ -39,7 +39,7 @@ describe('<GeminiMessage /> - Raw Markdown Display Snapshots', () => {
|
|||
it.each([{ renderMarkdown: true }, { renderMarkdown: false }])(
|
||||
'renders pending state with renderMarkdown=$renderMarkdown',
|
||||
async ({ renderMarkdown }) => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<GeminiMessage {...baseProps} isPending={true} />,
|
||||
{
|
||||
uiState: { renderMarkdown, streamingState: StreamingState.Idle },
|
||||
|
|
@ -55,7 +55,7 @@ describe('<GeminiMessage /> - Raw Markdown Display Snapshots', () => {
|
|||
const terminalWidth = 20;
|
||||
const text =
|
||||
'This is a long line that should wrap correctly without truncation';
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<GeminiMessage
|
||||
text={text}
|
||||
isPending={false}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ describe('ToolConfirmationMessage Redirection', () => {
|
|||
rootCommands: ['echo'],
|
||||
};
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ToolConfirmationMessage
|
||||
callId="test-call-id"
|
||||
confirmationDetails={confirmationDetails}
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ describe('<ShellToolMessage />', () => {
|
|||
['SHELL_COMMAND_NAME', SHELL_COMMAND_NAME],
|
||||
['SHELL_TOOL_NAME', SHELL_TOOL_NAME],
|
||||
])('clicks inside the shell area sets focus for %s', async (_, name) => {
|
||||
const { lastFrame, simulateClick, unmount } = renderWithProviders(
|
||||
const { lastFrame, simulateClick, unmount } = await renderWithProviders(
|
||||
<ShellToolMessage {...baseProps} name={name} />,
|
||||
{ uiActions, mouseEventsEnabled: true },
|
||||
);
|
||||
|
|
@ -86,7 +86,7 @@ describe('<ShellToolMessage />', () => {
|
|||
return <ShellToolMessage {...baseProps} status={status} ptyId={1} />;
|
||||
};
|
||||
|
||||
const { lastFrame, unmount } = renderWithProviders(<Wrapper />, {
|
||||
const { lastFrame, unmount } = await renderWithProviders(<Wrapper />, {
|
||||
uiActions,
|
||||
uiState: {
|
||||
streamingState: StreamingState.Idle,
|
||||
|
|
@ -170,7 +170,7 @@ describe('<ShellToolMessage />', () => {
|
|||
},
|
||||
],
|
||||
])('%s', async (_, props, options) => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ShellToolMessage {...baseProps} {...props} />,
|
||||
{ uiActions, ...options },
|
||||
);
|
||||
|
|
@ -219,26 +219,29 @@ describe('<ShellToolMessage />', () => {
|
|||
focused,
|
||||
constrainHeight,
|
||||
) => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
<ShellToolMessage
|
||||
{...baseProps}
|
||||
resultDisplay={LONG_OUTPUT}
|
||||
renderOutputAsMarkdown={false}
|
||||
availableTerminalHeight={availableTerminalHeight}
|
||||
ptyId={1}
|
||||
status={CoreToolCallStatus.Executing}
|
||||
/>,
|
||||
{
|
||||
uiActions,
|
||||
config: makeFakeConfig({ useAlternateBuffer: true }),
|
||||
settings: createMockSettings({ ui: { useAlternateBuffer: true } }),
|
||||
uiState: {
|
||||
activePtyId: focused ? 1 : 2,
|
||||
embeddedShellFocused: focused,
|
||||
constrainHeight,
|
||||
const { lastFrame, waitUntilReady, unmount } =
|
||||
await renderWithProviders(
|
||||
<ShellToolMessage
|
||||
{...baseProps}
|
||||
resultDisplay={LONG_OUTPUT}
|
||||
renderOutputAsMarkdown={false}
|
||||
availableTerminalHeight={availableTerminalHeight}
|
||||
ptyId={1}
|
||||
status={CoreToolCallStatus.Executing}
|
||||
/>,
|
||||
{
|
||||
uiActions,
|
||||
config: makeFakeConfig({ useAlternateBuffer: true }),
|
||||
settings: createMockSettings({
|
||||
ui: { useAlternateBuffer: true },
|
||||
}),
|
||||
uiState: {
|
||||
activePtyId: focused ? 1 : 2,
|
||||
embeddedShellFocused: focused,
|
||||
constrainHeight,
|
||||
},
|
||||
},
|
||||
},
|
||||
);
|
||||
);
|
||||
|
||||
await waitUntilReady();
|
||||
const frame = lastFrame();
|
||||
|
|
@ -249,7 +252,7 @@ describe('<ShellToolMessage />', () => {
|
|||
);
|
||||
|
||||
it('fully expands in standard mode when availableTerminalHeight is undefined', async () => {
|
||||
const { lastFrame, unmount } = renderWithProviders(
|
||||
const { lastFrame, unmount } = await renderWithProviders(
|
||||
<ShellToolMessage
|
||||
{...baseProps}
|
||||
resultDisplay={LONG_OUTPUT}
|
||||
|
|
@ -273,7 +276,7 @@ describe('<ShellToolMessage />', () => {
|
|||
});
|
||||
|
||||
it('fully expands in alternate buffer mode when constrainHeight is false and isExpandable is true', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ShellToolMessage
|
||||
{...baseProps}
|
||||
resultDisplay={LONG_OUTPUT}
|
||||
|
|
@ -303,7 +306,7 @@ describe('<ShellToolMessage />', () => {
|
|||
});
|
||||
|
||||
it('stays constrained in alternate buffer mode when isExpandable is false even if constrainHeight is false', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ShellToolMessage
|
||||
{...baseProps}
|
||||
resultDisplay={LONG_OUTPUT}
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ describe('<SubagentGroupDisplay />', () => {
|
|||
},
|
||||
];
|
||||
|
||||
const renderSubagentGroup = (
|
||||
const renderSubagentGroup = async (
|
||||
toolCallsToRender: IndividualToolCallDisplay[],
|
||||
height?: number,
|
||||
) =>
|
||||
|
|
@ -78,12 +78,12 @@ describe('<SubagentGroupDisplay />', () => {
|
|||
);
|
||||
|
||||
it('renders nothing if there are no agent tool calls', async () => {
|
||||
const { lastFrame } = renderSubagentGroup([], 40);
|
||||
const { lastFrame } = await renderSubagentGroup([], 40);
|
||||
expect(lastFrame({ allowEmpty: true })).toBe('');
|
||||
});
|
||||
|
||||
it('renders collapsed view by default with correct agent counts and states', async () => {
|
||||
const { lastFrame, waitUntilReady } = renderSubagentGroup(
|
||||
const { lastFrame, waitUntilReady } = await renderSubagentGroup(
|
||||
mockToolCalls,
|
||||
40,
|
||||
);
|
||||
|
|
@ -92,7 +92,10 @@ describe('<SubagentGroupDisplay />', () => {
|
|||
});
|
||||
|
||||
it('expands when availableTerminalHeight is undefined', async () => {
|
||||
const { lastFrame, rerender } = renderSubagentGroup(mockToolCalls, 40);
|
||||
const { lastFrame, rerender } = await renderSubagentGroup(
|
||||
mockToolCalls,
|
||||
40,
|
||||
);
|
||||
|
||||
// Default collapsed view
|
||||
await waitFor(() => {
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import React from 'react';
|
|||
|
||||
describe('ThinkingMessage', () => {
|
||||
it('renders subject line with vertical rule and "Thinking..." header', async () => {
|
||||
const renderResult = renderWithProviders(
|
||||
const renderResult = await renderWithProviders(
|
||||
<ThinkingMessage
|
||||
thought={{ subject: 'Planning', description: 'test' }}
|
||||
terminalWidth={80}
|
||||
|
|
@ -30,7 +30,7 @@ describe('ThinkingMessage', () => {
|
|||
});
|
||||
|
||||
it('uses description when subject is empty', async () => {
|
||||
const renderResult = renderWithProviders(
|
||||
const renderResult = await renderWithProviders(
|
||||
<ThinkingMessage
|
||||
thought={{ subject: '', description: 'Processing details' }}
|
||||
terminalWidth={80}
|
||||
|
|
@ -48,7 +48,7 @@ describe('ThinkingMessage', () => {
|
|||
});
|
||||
|
||||
it('renders full mode with left border and full text', async () => {
|
||||
const renderResult = renderWithProviders(
|
||||
const renderResult = await renderWithProviders(
|
||||
<ThinkingMessage
|
||||
thought={{
|
||||
subject: 'Planning',
|
||||
|
|
@ -70,7 +70,7 @@ describe('ThinkingMessage', () => {
|
|||
});
|
||||
|
||||
it('renders "Thinking..." header when isFirstThinking is true', async () => {
|
||||
const renderResult = renderWithProviders(
|
||||
const renderResult = await renderWithProviders(
|
||||
<ThinkingMessage
|
||||
thought={{
|
||||
subject: 'Summary line',
|
||||
|
|
@ -92,7 +92,7 @@ describe('ThinkingMessage', () => {
|
|||
});
|
||||
|
||||
it('normalizes escaped newline tokens', async () => {
|
||||
const renderResult = renderWithProviders(
|
||||
const renderResult = await renderWithProviders(
|
||||
<ThinkingMessage
|
||||
thought={{
|
||||
subject: 'Matching the Blocks',
|
||||
|
|
@ -110,7 +110,7 @@ describe('ThinkingMessage', () => {
|
|||
});
|
||||
|
||||
it('renders empty state gracefully', async () => {
|
||||
const renderResult = renderWithProviders(
|
||||
const renderResult = await renderWithProviders(
|
||||
<ThinkingMessage
|
||||
thought={{ subject: '', description: '' }}
|
||||
terminalWidth={80}
|
||||
|
|
@ -124,7 +124,7 @@ describe('ThinkingMessage', () => {
|
|||
});
|
||||
|
||||
it('renders multiple thinking messages sequentially correctly', async () => {
|
||||
const renderResult = renderWithProviders(
|
||||
const renderResult = await renderWithProviders(
|
||||
<React.Fragment>
|
||||
<ThinkingMessage
|
||||
thought={{
|
||||
|
|
@ -161,7 +161,7 @@ describe('ThinkingMessage', () => {
|
|||
});
|
||||
|
||||
it('filters out progress dots and empty lines', async () => {
|
||||
const renderResult = renderWithProviders(
|
||||
const renderResult = await renderWithProviders(
|
||||
<ThinkingMessage
|
||||
thought={{ subject: '...', description: 'Thinking\n.\n..\n...\nDone' }}
|
||||
terminalWidth={80}
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ describe('ToolConfirmationMessage', () => {
|
|||
urls: ['https://example.com'],
|
||||
};
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ToolConfirmationMessage
|
||||
callId="test-call-id"
|
||||
confirmationDetails={confirmationDetails}
|
||||
|
|
@ -77,7 +77,7 @@ describe('ToolConfirmationMessage', () => {
|
|||
],
|
||||
};
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ToolConfirmationMessage
|
||||
callId="test-call-id"
|
||||
confirmationDetails={confirmationDetails}
|
||||
|
|
@ -101,7 +101,7 @@ describe('ToolConfirmationMessage', () => {
|
|||
urls: ['https://täst.com'],
|
||||
};
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ToolConfirmationMessage
|
||||
callId="test-call-id"
|
||||
confirmationDetails={confirmationDetails}
|
||||
|
|
@ -132,7 +132,7 @@ describe('ToolConfirmationMessage', () => {
|
|||
rootCommands: ['curl'],
|
||||
};
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ToolConfirmationMessage
|
||||
callId="test-call-id"
|
||||
confirmationDetails={confirmationDetails}
|
||||
|
|
@ -163,7 +163,7 @@ describe('ToolConfirmationMessage', () => {
|
|||
rootCommands: ['curl'],
|
||||
};
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ToolConfirmationMessage
|
||||
callId="test-call-id"
|
||||
confirmationDetails={confirmationDetails}
|
||||
|
|
@ -193,7 +193,7 @@ describe('ToolConfirmationMessage', () => {
|
|||
urls: ['https://еxample.com', 'https://täst.com'],
|
||||
};
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ToolConfirmationMessage
|
||||
callId="test-call-id"
|
||||
confirmationDetails={confirmationDetails}
|
||||
|
|
@ -223,7 +223,7 @@ describe('ToolConfirmationMessage', () => {
|
|||
commands: ['echo "hello"', 'ls -la', 'whoami'], // Multi-command list
|
||||
};
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ToolConfirmationMessage
|
||||
callId="test-call-id"
|
||||
confirmationDetails={confirmationDetails}
|
||||
|
|
@ -252,7 +252,7 @@ describe('ToolConfirmationMessage', () => {
|
|||
rootCommands: ['echo'],
|
||||
};
|
||||
|
||||
const result = renderWithProviders(
|
||||
const result = await renderWithProviders(
|
||||
<ToolConfirmationMessage
|
||||
callId="test-call-id"
|
||||
confirmationDetails={confirmationDetails}
|
||||
|
|
@ -336,16 +336,17 @@ describe('ToolConfirmationMessage', () => {
|
|||
getIdeMode: () => false,
|
||||
getDisableAlwaysAllow: () => false,
|
||||
} as unknown as Config;
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
<ToolConfirmationMessage
|
||||
callId="test-call-id"
|
||||
confirmationDetails={details}
|
||||
config={mockConfig}
|
||||
getPreferredEditor={vi.fn()}
|
||||
availableTerminalHeight={30}
|
||||
terminalWidth={80}
|
||||
/>,
|
||||
);
|
||||
const { lastFrame, waitUntilReady, unmount } =
|
||||
await renderWithProviders(
|
||||
<ToolConfirmationMessage
|
||||
callId="test-call-id"
|
||||
confirmationDetails={details}
|
||||
config={mockConfig}
|
||||
getPreferredEditor={vi.fn()}
|
||||
availableTerminalHeight={30}
|
||||
terminalWidth={80}
|
||||
/>,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
||||
expect(lastFrame()).toMatchSnapshot();
|
||||
|
|
@ -359,16 +360,17 @@ describe('ToolConfirmationMessage', () => {
|
|||
getDisableAlwaysAllow: () => false,
|
||||
} as unknown as Config;
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
<ToolConfirmationMessage
|
||||
callId="test-call-id"
|
||||
confirmationDetails={details}
|
||||
config={mockConfig}
|
||||
getPreferredEditor={vi.fn()}
|
||||
availableTerminalHeight={30}
|
||||
terminalWidth={80}
|
||||
/>,
|
||||
);
|
||||
const { lastFrame, waitUntilReady, unmount } =
|
||||
await renderWithProviders(
|
||||
<ToolConfirmationMessage
|
||||
callId="test-call-id"
|
||||
confirmationDetails={details}
|
||||
config={mockConfig}
|
||||
getPreferredEditor={vi.fn()}
|
||||
availableTerminalHeight={30}
|
||||
terminalWidth={80}
|
||||
/>,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
||||
expect(lastFrame()).toMatchSnapshot();
|
||||
|
|
@ -394,7 +396,7 @@ describe('ToolConfirmationMessage', () => {
|
|||
getIdeMode: () => false,
|
||||
getDisableAlwaysAllow: () => false,
|
||||
} as unknown as Config;
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ToolConfirmationMessage
|
||||
callId="test-call-id"
|
||||
confirmationDetails={editConfirmationDetails}
|
||||
|
|
@ -421,7 +423,7 @@ describe('ToolConfirmationMessage', () => {
|
|||
getIdeMode: () => false,
|
||||
getDisableAlwaysAllow: () => false,
|
||||
} as unknown as Config;
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ToolConfirmationMessage
|
||||
callId="test-call-id"
|
||||
confirmationDetails={editConfirmationDetails}
|
||||
|
|
@ -469,7 +471,7 @@ describe('ToolConfirmationMessage', () => {
|
|||
isDiffingEnabled: false,
|
||||
});
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ToolConfirmationMessage
|
||||
callId="test-call-id"
|
||||
confirmationDetails={editConfirmationDetails}
|
||||
|
|
@ -497,7 +499,7 @@ describe('ToolConfirmationMessage', () => {
|
|||
isDiffingEnabled: false,
|
||||
});
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ToolConfirmationMessage
|
||||
callId="test-call-id"
|
||||
confirmationDetails={editConfirmationDetails}
|
||||
|
|
@ -525,7 +527,7 @@ describe('ToolConfirmationMessage', () => {
|
|||
isDiffingEnabled: true,
|
||||
});
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ToolConfirmationMessage
|
||||
callId="test-call-id"
|
||||
confirmationDetails={editConfirmationDetails}
|
||||
|
|
@ -552,7 +554,7 @@ describe('ToolConfirmationMessage', () => {
|
|||
onConfirm: vi.fn(),
|
||||
};
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ToolConfirmationMessage
|
||||
callId="test-call-id"
|
||||
confirmationDetails={confirmationDetails}
|
||||
|
|
@ -598,7 +600,7 @@ describe('ToolConfirmationMessage', () => {
|
|||
onConfirm: vi.fn(),
|
||||
};
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ToolConfirmationMessage
|
||||
callId="test-call-id"
|
||||
confirmationDetails={confirmationDetails}
|
||||
|
|
@ -630,7 +632,7 @@ describe('ToolConfirmationMessage', () => {
|
|||
onConfirm: vi.fn(),
|
||||
};
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ToolConfirmationMessage
|
||||
callId="test-call-id"
|
||||
confirmationDetails={confirmationDetails}
|
||||
|
|
@ -675,7 +677,7 @@ describe('ToolConfirmationMessage', () => {
|
|||
urls: ['https://example.com'],
|
||||
};
|
||||
|
||||
const { stdin, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { stdin, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ToolConfirmationMessage
|
||||
callId="test-call-id"
|
||||
confirmationDetails={confirmationDetails}
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ describe('<ToolGroupMessage />', () => {
|
|||
it('renders single successful tool call', async () => {
|
||||
const toolCalls = [createToolCall()];
|
||||
const item = createItem(toolCalls);
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithProviders(
|
||||
<ToolGroupMessage {...baseProps} item={item} toolCalls={toolCalls} />,
|
||||
{
|
||||
config: baseMockConfig,
|
||||
|
|
@ -109,7 +109,7 @@ describe('<ToolGroupMessage />', () => {
|
|||
];
|
||||
const item = createItem(toolCalls);
|
||||
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithProviders(
|
||||
<ToolGroupMessage {...baseProps} item={item} toolCalls={toolCalls} />,
|
||||
{ config: baseMockConfig, settings: fullVerbositySettings },
|
||||
);
|
||||
|
|
@ -130,7 +130,7 @@ describe('<ToolGroupMessage />', () => {
|
|||
];
|
||||
const item = createItem(toolCalls);
|
||||
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithProviders(
|
||||
<ToolGroupMessage {...baseProps} item={item} toolCalls={toolCalls} />,
|
||||
{ config: baseMockConfig, settings: fullVerbositySettings },
|
||||
);
|
||||
|
|
@ -164,7 +164,7 @@ describe('<ToolGroupMessage />', () => {
|
|||
];
|
||||
const item = createItem(toolCalls);
|
||||
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithProviders(
|
||||
<ToolGroupMessage {...baseProps} item={item} toolCalls={toolCalls} />,
|
||||
{
|
||||
config: baseMockConfig,
|
||||
|
|
@ -205,7 +205,7 @@ describe('<ToolGroupMessage />', () => {
|
|||
];
|
||||
const item = createItem(toolCalls);
|
||||
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithProviders(
|
||||
<ToolGroupMessage {...baseProps} item={item} toolCalls={toolCalls} />,
|
||||
{
|
||||
config: baseMockConfig,
|
||||
|
|
@ -238,7 +238,7 @@ describe('<ToolGroupMessage />', () => {
|
|||
];
|
||||
const item = createItem(toolCalls);
|
||||
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithProviders(
|
||||
<ToolGroupMessage {...baseProps} item={item} toolCalls={toolCalls} />,
|
||||
{
|
||||
config: baseMockConfig,
|
||||
|
|
@ -282,7 +282,7 @@ describe('<ToolGroupMessage />', () => {
|
|||
];
|
||||
const item = createItem(toolCalls);
|
||||
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithProviders(
|
||||
<ToolGroupMessage {...baseProps} item={item} toolCalls={toolCalls} />,
|
||||
{
|
||||
config: baseMockConfig,
|
||||
|
|
@ -324,7 +324,7 @@ describe('<ToolGroupMessage />', () => {
|
|||
}),
|
||||
];
|
||||
const item = createItem(toolCalls);
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithProviders(
|
||||
<ToolGroupMessage
|
||||
{...baseProps}
|
||||
item={item}
|
||||
|
|
@ -358,7 +358,7 @@ describe('<ToolGroupMessage />', () => {
|
|||
}),
|
||||
];
|
||||
const item = createItem(toolCalls);
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithProviders(
|
||||
<ToolGroupMessage
|
||||
{...baseProps}
|
||||
item={item}
|
||||
|
|
@ -386,7 +386,7 @@ describe('<ToolGroupMessage />', () => {
|
|||
it('renders empty tool calls array', async () => {
|
||||
const toolCalls: IndividualToolCallDisplay[] = [];
|
||||
const item = createItem(toolCalls);
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithProviders(
|
||||
<ToolGroupMessage {...baseProps} item={item} toolCalls={toolCalls} />,
|
||||
{
|
||||
config: baseMockConfig,
|
||||
|
|
@ -423,7 +423,7 @@ describe('<ToolGroupMessage />', () => {
|
|||
}),
|
||||
];
|
||||
const item = createItem(toolCalls);
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithProviders(
|
||||
<Scrollable height={10} hasFocus={true} scrollToBottom={true}>
|
||||
<ToolGroupMessage {...baseProps} item={item} toolCalls={toolCalls} />
|
||||
</Scrollable>,
|
||||
|
|
@ -456,7 +456,7 @@ describe('<ToolGroupMessage />', () => {
|
|||
}),
|
||||
];
|
||||
const item = createItem(toolCalls);
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithProviders(
|
||||
<ToolGroupMessage {...baseProps} item={item} toolCalls={toolCalls} />,
|
||||
{
|
||||
config: baseMockConfig,
|
||||
|
|
@ -496,7 +496,7 @@ describe('<ToolGroupMessage />', () => {
|
|||
];
|
||||
const item2 = createItem(toolCalls2);
|
||||
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithProviders(
|
||||
<Scrollable height={6} hasFocus={true} scrollToBottom={true}>
|
||||
<ToolGroupMessage
|
||||
{...baseProps}
|
||||
|
|
@ -541,7 +541,7 @@ describe('<ToolGroupMessage />', () => {
|
|||
}),
|
||||
];
|
||||
const item = createItem(toolCalls);
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithProviders(
|
||||
<ToolGroupMessage {...baseProps} item={item} toolCalls={toolCalls} />,
|
||||
{
|
||||
config: baseMockConfig,
|
||||
|
|
@ -571,7 +571,7 @@ describe('<ToolGroupMessage />', () => {
|
|||
}),
|
||||
];
|
||||
const item = createItem(toolCalls);
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithProviders(
|
||||
<ToolGroupMessage {...baseProps} item={item} toolCalls={toolCalls} />,
|
||||
{
|
||||
config: baseMockConfig,
|
||||
|
|
@ -609,7 +609,7 @@ describe('<ToolGroupMessage />', () => {
|
|||
}),
|
||||
];
|
||||
const item = createItem(toolCalls);
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithProviders(
|
||||
<ToolGroupMessage
|
||||
{...baseProps}
|
||||
item={item}
|
||||
|
|
@ -676,10 +676,15 @@ describe('<ToolGroupMessage />', () => {
|
|||
];
|
||||
const item = createItem(toolCalls);
|
||||
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithProviders(
|
||||
<ToolGroupMessage {...baseProps} item={item} toolCalls={toolCalls} />,
|
||||
{ config: baseMockConfig, settings: fullVerbositySettings },
|
||||
);
|
||||
const { lastFrame, unmount, waitUntilReady } =
|
||||
await renderWithProviders(
|
||||
<ToolGroupMessage
|
||||
{...baseProps}
|
||||
item={item}
|
||||
toolCalls={toolCalls}
|
||||
/>,
|
||||
{ config: baseMockConfig, settings: fullVerbositySettings },
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
||||
if (shouldHide) {
|
||||
|
|
@ -706,7 +711,7 @@ describe('<ToolGroupMessage />', () => {
|
|||
];
|
||||
const item = createItem(toolCalls);
|
||||
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithProviders(
|
||||
<ToolGroupMessage {...baseProps} item={item} toolCalls={toolCalls} />,
|
||||
{ config: baseMockConfig, settings: fullVerbositySettings },
|
||||
);
|
||||
|
|
@ -729,7 +734,7 @@ describe('<ToolGroupMessage />', () => {
|
|||
];
|
||||
const item = createItem(toolCalls);
|
||||
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithProviders(
|
||||
<ToolGroupMessage
|
||||
{...baseProps}
|
||||
item={item}
|
||||
|
|
@ -756,7 +761,7 @@ describe('<ToolGroupMessage />', () => {
|
|||
];
|
||||
const item = createItem(toolCalls);
|
||||
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithProviders(
|
||||
<ToolGroupMessage
|
||||
{...baseProps}
|
||||
item={item}
|
||||
|
|
@ -779,7 +784,7 @@ describe('<ToolGroupMessage />', () => {
|
|||
const toolCalls: IndividualToolCallDisplay[] = [];
|
||||
const item = createItem(toolCalls);
|
||||
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithProviders(
|
||||
<ToolGroupMessage
|
||||
{...baseProps}
|
||||
item={item}
|
||||
|
|
@ -810,7 +815,7 @@ describe('<ToolGroupMessage />', () => {
|
|||
];
|
||||
const item = createItem(toolCalls);
|
||||
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithProviders(
|
||||
<ToolGroupMessage
|
||||
{...baseProps}
|
||||
item={item}
|
||||
|
|
@ -843,7 +848,7 @@ describe('<ToolGroupMessage />', () => {
|
|||
];
|
||||
const item = createItem(toolCalls);
|
||||
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithProviders(
|
||||
<ToolGroupMessage
|
||||
{...baseProps}
|
||||
item={item}
|
||||
|
|
@ -884,7 +889,7 @@ describe('<ToolGroupMessage />', () => {
|
|||
const initialItem = createItem(visibleTools);
|
||||
const hiddenItem = createItem(hiddenTools);
|
||||
|
||||
const firstRender = renderWithProviders(
|
||||
const firstRender = await renderWithProviders(
|
||||
<ToolGroupMessage
|
||||
{...baseProps}
|
||||
item={initialItem}
|
||||
|
|
@ -901,7 +906,7 @@ describe('<ToolGroupMessage />', () => {
|
|||
expect(firstRender.lastFrame()).toContain('visible-tool');
|
||||
firstRender.unmount();
|
||||
|
||||
const secondRender = renderWithProviders(
|
||||
const secondRender = await renderWithProviders(
|
||||
<ToolGroupMessage
|
||||
{...baseProps}
|
||||
item={hiddenItem}
|
||||
|
|
@ -938,7 +943,7 @@ describe('<ToolGroupMessage />', () => {
|
|||
const toolCalls = [visibleTool, ...hiddenTools];
|
||||
const item = createItem(toolCalls);
|
||||
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithProviders(
|
||||
<ToolGroupMessage
|
||||
{...baseProps}
|
||||
item={item}
|
||||
|
|
@ -964,7 +969,7 @@ describe('<ToolGroupMessage />', () => {
|
|||
const toolCalls: IndividualToolCallDisplay[] = [];
|
||||
const item = createItem(toolCalls);
|
||||
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithProviders(
|
||||
<ToolGroupMessage
|
||||
item={item}
|
||||
toolCalls={toolCalls}
|
||||
|
|
@ -1011,10 +1016,15 @@ describe('<ToolGroupMessage />', () => {
|
|||
];
|
||||
const item = createItem(toolCalls);
|
||||
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithProviders(
|
||||
<ToolGroupMessage {...baseProps} item={item} toolCalls={toolCalls} />,
|
||||
{ config: baseMockConfig, settings: fullVerbositySettings },
|
||||
);
|
||||
const { lastFrame, unmount, waitUntilReady } =
|
||||
await renderWithProviders(
|
||||
<ToolGroupMessage
|
||||
{...baseProps}
|
||||
item={item}
|
||||
toolCalls={toolCalls}
|
||||
/>,
|
||||
{ config: baseMockConfig, settings: fullVerbositySettings },
|
||||
);
|
||||
|
||||
await waitUntilReady();
|
||||
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ describe('<ToolMessage />', () => {
|
|||
};
|
||||
|
||||
// Helper to render with context
|
||||
const renderWithContext = (
|
||||
const renderWithContext = async (
|
||||
ui: React.ReactElement,
|
||||
streamingState: StreamingState,
|
||||
) =>
|
||||
|
|
@ -78,7 +78,7 @@ describe('<ToolMessage />', () => {
|
|||
});
|
||||
|
||||
it('renders basic tool information', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithContext(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithContext(
|
||||
<ToolMessage {...baseProps} />,
|
||||
StreamingState.Idle,
|
||||
);
|
||||
|
|
@ -91,7 +91,7 @@ describe('<ToolMessage />', () => {
|
|||
describe('JSON rendering', () => {
|
||||
it('pretty prints valid JSON', async () => {
|
||||
const testJSONstring = '{"a": 1, "b": [2, 3]}';
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithContext(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithContext(
|
||||
<ToolMessage
|
||||
{...baseProps}
|
||||
resultDisplay={testJSONstring}
|
||||
|
|
@ -113,7 +113,7 @@ describe('<ToolMessage />', () => {
|
|||
});
|
||||
|
||||
it('renders pretty JSON in ink frame', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithContext(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithContext(
|
||||
<ToolMessage {...baseProps} resultDisplay='{"a":1,"b":2}' />,
|
||||
StreamingState.Idle,
|
||||
);
|
||||
|
|
@ -127,7 +127,7 @@ describe('<ToolMessage />', () => {
|
|||
|
||||
it('uses JSON renderer even when renderOutputAsMarkdown=true is true', async () => {
|
||||
const testJSONstring = '{"a": 1, "b": [2, 3]}';
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithContext(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithContext(
|
||||
<ToolMessage
|
||||
{...baseProps}
|
||||
resultDisplay={testJSONstring}
|
||||
|
|
@ -149,7 +149,7 @@ describe('<ToolMessage />', () => {
|
|||
});
|
||||
it('falls back to plain text for malformed JSON', async () => {
|
||||
const testJSONstring = 'a": 1, "b": [2, 3]}';
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithContext(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithContext(
|
||||
<ToolMessage
|
||||
{...baseProps}
|
||||
resultDisplay={testJSONstring}
|
||||
|
|
@ -168,7 +168,7 @@ describe('<ToolMessage />', () => {
|
|||
|
||||
it('rejects mixed text + JSON renders as plain text', async () => {
|
||||
const testJSONstring = `{"result": "count": 42,"items": ["apple", "banana"]},"meta": {"timestamp": "2025-09-28T12:34:56Z"}}End.`;
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithContext(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithContext(
|
||||
<ToolMessage
|
||||
{...baseProps}
|
||||
resultDisplay={testJSONstring}
|
||||
|
|
@ -188,7 +188,7 @@ describe('<ToolMessage />', () => {
|
|||
it('rejects ANSI-tained JSON renders as plain text', async () => {
|
||||
const testJSONstring =
|
||||
'\u001b[32mOK\u001b[0m {"status": "success", "data": {"id": 123, "values": [10, 20, 30]}}';
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithContext(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithContext(
|
||||
<ToolMessage
|
||||
{...baseProps}
|
||||
resultDisplay={testJSONstring}
|
||||
|
|
@ -207,7 +207,7 @@ describe('<ToolMessage />', () => {
|
|||
|
||||
it('pretty printing 10kb JSON completes in <50ms', async () => {
|
||||
const large = '{"key": "' + 'x'.repeat(10000) + '"}';
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithContext(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithContext(
|
||||
<ToolMessage
|
||||
{...baseProps}
|
||||
resultDisplay={large}
|
||||
|
|
@ -226,7 +226,7 @@ describe('<ToolMessage />', () => {
|
|||
|
||||
describe('ToolStatusIndicator rendering', () => {
|
||||
it('shows ✓ for Success status', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithContext(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithContext(
|
||||
<ToolMessage {...baseProps} status={CoreToolCallStatus.Success} />,
|
||||
StreamingState.Idle,
|
||||
);
|
||||
|
|
@ -236,7 +236,7 @@ describe('<ToolMessage />', () => {
|
|||
});
|
||||
|
||||
it('shows o for Pending status', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithContext(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithContext(
|
||||
<ToolMessage {...baseProps} status={CoreToolCallStatus.Scheduled} />,
|
||||
StreamingState.Idle,
|
||||
);
|
||||
|
|
@ -246,7 +246,7 @@ describe('<ToolMessage />', () => {
|
|||
});
|
||||
|
||||
it('shows ? for Confirming status', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithContext(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithContext(
|
||||
<ToolMessage
|
||||
{...baseProps}
|
||||
status={CoreToolCallStatus.AwaitingApproval}
|
||||
|
|
@ -259,7 +259,7 @@ describe('<ToolMessage />', () => {
|
|||
});
|
||||
|
||||
it('shows - for Canceled status', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithContext(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithContext(
|
||||
<ToolMessage {...baseProps} status={CoreToolCallStatus.Cancelled} />,
|
||||
StreamingState.Idle,
|
||||
);
|
||||
|
|
@ -269,7 +269,7 @@ describe('<ToolMessage />', () => {
|
|||
});
|
||||
|
||||
it('shows x for Error status', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithContext(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithContext(
|
||||
<ToolMessage {...baseProps} status={CoreToolCallStatus.Error} />,
|
||||
StreamingState.Idle,
|
||||
);
|
||||
|
|
@ -279,7 +279,7 @@ describe('<ToolMessage />', () => {
|
|||
});
|
||||
|
||||
it('shows paused spinner for Executing status when streamingState is Idle', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithContext(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithContext(
|
||||
<ToolMessage {...baseProps} status={CoreToolCallStatus.Executing} />,
|
||||
StreamingState.Idle,
|
||||
);
|
||||
|
|
@ -289,7 +289,7 @@ describe('<ToolMessage />', () => {
|
|||
});
|
||||
|
||||
it('shows paused spinner for Executing status when streamingState is WaitingForConfirmation', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithContext(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithContext(
|
||||
<ToolMessage {...baseProps} status={CoreToolCallStatus.Executing} />,
|
||||
StreamingState.WaitingForConfirmation,
|
||||
);
|
||||
|
|
@ -299,7 +299,7 @@ describe('<ToolMessage />', () => {
|
|||
});
|
||||
|
||||
it('shows MockRespondingSpinner for Executing status when streamingState is Responding', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithContext(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithContext(
|
||||
<ToolMessage {...baseProps} status={CoreToolCallStatus.Executing} />,
|
||||
StreamingState.Responding, // Simulate app still responding
|
||||
);
|
||||
|
|
@ -317,7 +317,7 @@ describe('<ToolMessage />', () => {
|
|||
newContent: 'new',
|
||||
filePath: 'file.txt',
|
||||
};
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithContext(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithContext(
|
||||
<ToolMessage {...baseProps} resultDisplay={diffResult} />,
|
||||
StreamingState.Idle,
|
||||
);
|
||||
|
|
@ -332,7 +332,7 @@ describe('<ToolMessage />', () => {
|
|||
lastFrame: highEmphasisFrame,
|
||||
waitUntilReady: waitUntilReadyHigh,
|
||||
unmount: unmountHigh,
|
||||
} = renderWithContext(
|
||||
} = await renderWithContext(
|
||||
<ToolMessage {...baseProps} emphasis="high" />,
|
||||
StreamingState.Idle,
|
||||
);
|
||||
|
|
@ -345,7 +345,7 @@ describe('<ToolMessage />', () => {
|
|||
lastFrame: lowEmphasisFrame,
|
||||
waitUntilReady: waitUntilReadyLow,
|
||||
unmount: unmountLow,
|
||||
} = renderWithContext(
|
||||
} = await renderWithContext(
|
||||
<ToolMessage {...baseProps} emphasis="low" />,
|
||||
StreamingState.Idle,
|
||||
);
|
||||
|
|
@ -372,7 +372,7 @@ describe('<ToolMessage />', () => {
|
|||
},
|
||||
],
|
||||
];
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithContext(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithContext(
|
||||
<ToolMessage {...baseProps} resultDisplay={ansiResult} />,
|
||||
StreamingState.Idle,
|
||||
);
|
||||
|
|
@ -382,7 +382,7 @@ describe('<ToolMessage />', () => {
|
|||
});
|
||||
|
||||
it('renders McpProgressIndicator with percentage and message for executing tools', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithContext(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithContext(
|
||||
<ToolMessage
|
||||
{...baseProps}
|
||||
status={CoreToolCallStatus.Executing}
|
||||
|
|
@ -404,7 +404,7 @@ describe('<ToolMessage />', () => {
|
|||
});
|
||||
|
||||
it('renders only percentage when progressMessage is missing', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithContext(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithContext(
|
||||
<ToolMessage
|
||||
{...baseProps}
|
||||
status={CoreToolCallStatus.Executing}
|
||||
|
|
@ -424,7 +424,7 @@ describe('<ToolMessage />', () => {
|
|||
});
|
||||
|
||||
it('renders indeterminate progress when total is missing', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithContext(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithContext(
|
||||
<ToolMessage
|
||||
{...baseProps}
|
||||
status={CoreToolCallStatus.Executing}
|
||||
|
|
@ -449,7 +449,7 @@ describe('<ToolMessage />', () => {
|
|||
(_, i) => `Line ${i + 1}`,
|
||||
).join('\n');
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ToolMessage
|
||||
{...baseProps}
|
||||
kind={Kind.Agent}
|
||||
|
|
@ -486,7 +486,7 @@ describe('<ToolMessage />', () => {
|
|||
(_, i) => `Line ${i + 1}`,
|
||||
).join('\n');
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ToolMessage
|
||||
{...baseProps}
|
||||
kind={Kind.Agent}
|
||||
|
|
@ -516,7 +516,7 @@ describe('<ToolMessage />', () => {
|
|||
(_, i) => `Line ${i + 1}`,
|
||||
).join('\n');
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ToolMessage
|
||||
{...baseProps}
|
||||
kind={Kind.Read}
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ describe('Focus Hint', () => {
|
|||
|
||||
describe.each(testCases)('$componentName', ({ Component }) => {
|
||||
it('shows focus hint after delay even with NO output', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Component {...baseProps} resultDisplay={undefined} />,
|
||||
{ uiState: { streamingState: StreamingState.Idle } },
|
||||
);
|
||||
|
|
@ -88,7 +88,7 @@ describe('Focus Hint', () => {
|
|||
});
|
||||
|
||||
it('shows focus hint after delay with output', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Component {...baseProps} resultDisplay="Some output" />,
|
||||
{ uiState: { streamingState: StreamingState.Idle } },
|
||||
);
|
||||
|
|
@ -111,7 +111,7 @@ describe('Focus Hint', () => {
|
|||
|
||||
it('handles long descriptions by shrinking them to show the focus hint', async () => {
|
||||
const longDescription = 'A'.repeat(100);
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ToolMessage
|
||||
{...baseProps}
|
||||
description={longDescription}
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ describe('<ToolMessage /> - Raw Markdown Display Snapshots', () => {
|
|||
])(
|
||||
'renders with renderMarkdown=$renderMarkdown, useAlternateBuffer=$useAlternateBuffer $description',
|
||||
async ({ renderMarkdown, useAlternateBuffer, availableTerminalHeight }) => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<StreamingContext.Provider value={StreamingState.Idle}>
|
||||
<ToolMessage
|
||||
{...baseProps}
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ describe('ToolOverflowConsistencyChecks: ToolGroupMessage and ToolResultDisplay
|
|||
return null;
|
||||
};
|
||||
|
||||
const { unmount, waitUntilReady } = renderWithProviders(
|
||||
const { unmount, waitUntilReady } = await renderWithProviders(
|
||||
<>
|
||||
<StateCapture />
|
||||
<ToolGroupMessage
|
||||
|
|
@ -95,7 +95,7 @@ describe('ToolOverflowConsistencyChecks: ToolGroupMessage and ToolResultDisplay
|
|||
},
|
||||
];
|
||||
|
||||
const { lastFrame, unmount, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, unmount, waitUntilReady } = await renderWithProviders(
|
||||
<ToolGroupMessage
|
||||
item={{ id: 1, type: 'tool_group', tools: toolCalls }}
|
||||
toolCalls={toolCalls}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ describe('ToolResultDisplay', () => {
|
|||
},
|
||||
],
|
||||
];
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ToolResultDisplay
|
||||
resultDisplay={ansiResult}
|
||||
terminalWidth={80}
|
||||
|
|
@ -50,7 +50,7 @@ describe('ToolResultDisplay', () => {
|
|||
});
|
||||
|
||||
it('uses Scrollable for non-ANSI output in alternate buffer mode', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ToolResultDisplay
|
||||
resultDisplay="**Markdown content**"
|
||||
terminalWidth={80}
|
||||
|
|
@ -70,7 +70,7 @@ describe('ToolResultDisplay', () => {
|
|||
});
|
||||
|
||||
it('passes hasFocus prop to scrollable components', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ToolResultDisplay
|
||||
resultDisplay="Some result"
|
||||
terminalWidth={80}
|
||||
|
|
@ -88,7 +88,7 @@ describe('ToolResultDisplay', () => {
|
|||
});
|
||||
|
||||
it('renders string result as markdown by default', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ToolResultDisplay resultDisplay="**Some result**" terminalWidth={80} />,
|
||||
{
|
||||
config: makeFakeConfig({ useAlternateBuffer: false }),
|
||||
|
|
@ -103,7 +103,7 @@ describe('ToolResultDisplay', () => {
|
|||
});
|
||||
|
||||
it('renders string result as plain text when renderOutputAsMarkdown is false', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ToolResultDisplay
|
||||
resultDisplay="**Some result**"
|
||||
terminalWidth={80}
|
||||
|
|
@ -125,7 +125,7 @@ describe('ToolResultDisplay', () => {
|
|||
|
||||
it('truncates very long string results', { timeout: 20000 }, async () => {
|
||||
const longString = 'a'.repeat(1000005);
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ToolResultDisplay
|
||||
resultDisplay={longString}
|
||||
terminalWidth={80}
|
||||
|
|
@ -149,7 +149,7 @@ describe('ToolResultDisplay', () => {
|
|||
fileDiff: 'diff content',
|
||||
fileName: 'test.ts',
|
||||
};
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ToolResultDisplay
|
||||
resultDisplay={diffResult}
|
||||
terminalWidth={80}
|
||||
|
|
@ -182,7 +182,7 @@ describe('ToolResultDisplay', () => {
|
|||
},
|
||||
],
|
||||
];
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ToolResultDisplay
|
||||
resultDisplay={ansiResult as unknown as AnsiOutput}
|
||||
terminalWidth={80}
|
||||
|
|
@ -204,7 +204,7 @@ describe('ToolResultDisplay', () => {
|
|||
const todoResult = {
|
||||
todos: [],
|
||||
};
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ToolResultDisplay
|
||||
resultDisplay={todoResult}
|
||||
terminalWidth={80}
|
||||
|
|
@ -224,7 +224,7 @@ describe('ToolResultDisplay', () => {
|
|||
|
||||
it('does not fall back to plain text if availableHeight is set and not in alternate buffer', async () => {
|
||||
// availableHeight calculation: 20 - 1 - 5 = 14 > 3
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ToolResultDisplay
|
||||
resultDisplay="**Some result**"
|
||||
terminalWidth={80}
|
||||
|
|
@ -244,7 +244,7 @@ describe('ToolResultDisplay', () => {
|
|||
});
|
||||
|
||||
it('keeps markdown if in alternate buffer even with availableHeight', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ToolResultDisplay
|
||||
resultDisplay="**Some result**"
|
||||
terminalWidth={80}
|
||||
|
|
@ -326,7 +326,7 @@ describe('ToolResultDisplay', () => {
|
|||
},
|
||||
],
|
||||
];
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ToolResultDisplay
|
||||
resultDisplay={ansiResult}
|
||||
terminalWidth={80}
|
||||
|
|
@ -363,7 +363,7 @@ describe('ToolResultDisplay', () => {
|
|||
inverse: false,
|
||||
},
|
||||
]);
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ToolResultDisplay
|
||||
resultDisplay={ansiResult}
|
||||
terminalWidth={80}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import { makeFakeConfig, type AnsiOutput } from '@google/gemini-cli-core';
|
|||
describe('ToolResultDisplay Overflow', () => {
|
||||
it('shows the head of the content when overflowDirection is bottom (string)', async () => {
|
||||
const content = 'Line 1\nLine 2\nLine 3\nLine 4\nLine 5';
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ToolResultDisplay
|
||||
resultDisplay={content}
|
||||
terminalWidth={80}
|
||||
|
|
@ -40,7 +40,7 @@ describe('ToolResultDisplay Overflow', () => {
|
|||
|
||||
it('shows the tail of the content when overflowDirection is top (string default)', async () => {
|
||||
const content = 'Line 1\nLine 2\nLine 3\nLine 4\nLine 5';
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ToolResultDisplay
|
||||
resultDisplay={content}
|
||||
terminalWidth={80}
|
||||
|
|
@ -78,7 +78,7 @@ describe('ToolResultDisplay Overflow', () => {
|
|||
inverse: false,
|
||||
},
|
||||
]);
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<ToolResultDisplay
|
||||
resultDisplay={ansiResult}
|
||||
terminalWidth={80}
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ describe('ToolMessage Sticky Header Regression', () => {
|
|||
);
|
||||
};
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Box height={terminalHeight}>
|
||||
<TestComponent />
|
||||
</Box>,
|
||||
|
|
@ -181,7 +181,7 @@ describe('ToolMessage Sticky Header Regression', () => {
|
|||
);
|
||||
};
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Box height={terminalHeight}>
|
||||
<TestComponent />
|
||||
</Box>,
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ vi.mock('../../utils/commandUtils.js', () => ({
|
|||
|
||||
describe('UserMessage', () => {
|
||||
it('renders normal user message with correct prefix', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<UserMessage text="Hello Gemini" width={80} />,
|
||||
{ width: 80 },
|
||||
);
|
||||
|
|
@ -27,7 +27,7 @@ describe('UserMessage', () => {
|
|||
});
|
||||
|
||||
it('renders slash command message', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<UserMessage text="/help" width={80} />,
|
||||
{ width: 80 },
|
||||
);
|
||||
|
|
@ -40,7 +40,7 @@ describe('UserMessage', () => {
|
|||
|
||||
it('renders multiline user message', async () => {
|
||||
const message = 'Line 1\nLine 2';
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<UserMessage text={message} width={80} />,
|
||||
{ width: 80 },
|
||||
);
|
||||
|
|
@ -53,7 +53,7 @@ describe('UserMessage', () => {
|
|||
|
||||
it('transforms image paths in user message', async () => {
|
||||
const message = 'Check out this image: @/path/to/my-image.png';
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<UserMessage text={message} width={80} />,
|
||||
{ width: 80 },
|
||||
);
|
||||
|
|
|
|||
|
|
@ -75,7 +75,9 @@ describe('BaseSelectionList', () => {
|
|||
...props,
|
||||
};
|
||||
|
||||
const result = renderWithProviders(<BaseSelectionList {...defaultProps} />);
|
||||
const result = await renderWithProviders(
|
||||
<BaseSelectionList {...defaultProps} />,
|
||||
);
|
||||
await result.waitUntilReady();
|
||||
return result;
|
||||
};
|
||||
|
|
@ -310,7 +312,7 @@ describe('BaseSelectionList', () => {
|
|||
);
|
||||
|
||||
const { rerender, lastFrame, waitUntilReady, unmount } =
|
||||
renderWithProviders(<BaseSelectionList {...componentProps} />);
|
||||
await renderWithProviders(<BaseSelectionList {...componentProps} />);
|
||||
await waitUntilReady();
|
||||
|
||||
// Function to simulate the activeIndex changing over time
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ describe('BaseSettingsDialog', () => {
|
|||
...props,
|
||||
};
|
||||
|
||||
const result = renderWithProviders(
|
||||
const result = await renderWithProviders(
|
||||
<BaseSettingsDialog {...defaultProps} />,
|
||||
);
|
||||
await result.waitUntilReady();
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ describe('DescriptiveRadioButtonSelect', () => {
|
|||
onSelect: mockOnSelect,
|
||||
...props,
|
||||
};
|
||||
const result = renderWithProviders(
|
||||
const result = await renderWithProviders(
|
||||
<DescriptiveRadioButtonSelect {...defaultProps} />,
|
||||
);
|
||||
await result.waitUntilReady();
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ const NUMERIC_OPTIONS: readonly SettingEnumOption[] = [
|
|||
|
||||
describe('<EnumSelector />', () => {
|
||||
it('renders with string options and matches snapshot', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<EnumSelector
|
||||
options={LANGUAGE_OPTIONS}
|
||||
currentValue="en"
|
||||
|
|
@ -39,7 +39,7 @@ describe('<EnumSelector />', () => {
|
|||
});
|
||||
|
||||
it('renders with numeric options and matches snapshot', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<EnumSelector
|
||||
options={NUMERIC_OPTIONS}
|
||||
currentValue={2}
|
||||
|
|
@ -53,7 +53,7 @@ describe('<EnumSelector />', () => {
|
|||
});
|
||||
|
||||
it('renders inactive state and matches snapshot', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<EnumSelector
|
||||
options={LANGUAGE_OPTIONS}
|
||||
currentValue="zh"
|
||||
|
|
@ -70,7 +70,7 @@ describe('<EnumSelector />', () => {
|
|||
const singleOption: readonly SettingEnumOption[] = [
|
||||
{ label: 'Only Option', value: 'only' },
|
||||
];
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<EnumSelector
|
||||
options={singleOption}
|
||||
currentValue="only"
|
||||
|
|
@ -84,7 +84,7 @@ describe('<EnumSelector />', () => {
|
|||
});
|
||||
|
||||
it('renders nothing when no options are provided', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<EnumSelector
|
||||
options={[]}
|
||||
currentValue=""
|
||||
|
|
@ -98,7 +98,7 @@ describe('<EnumSelector />', () => {
|
|||
});
|
||||
|
||||
it('handles currentValue not found in options', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<EnumSelector
|
||||
options={LANGUAGE_OPTIONS}
|
||||
currentValue="invalid"
|
||||
|
|
@ -114,7 +114,7 @@ describe('<EnumSelector />', () => {
|
|||
|
||||
it('updates when currentValue changes externally', async () => {
|
||||
const { rerender, lastFrame, waitUntilReady, unmount } =
|
||||
renderWithProviders(
|
||||
await renderWithProviders(
|
||||
<EnumSelector
|
||||
options={LANGUAGE_OPTIONS}
|
||||
currentValue="en"
|
||||
|
|
@ -141,7 +141,7 @@ describe('<EnumSelector />', () => {
|
|||
});
|
||||
|
||||
it('shows navigation arrows when multiple options available', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<EnumSelector
|
||||
options={LANGUAGE_OPTIONS}
|
||||
currentValue="en"
|
||||
|
|
@ -159,7 +159,7 @@ describe('<EnumSelector />', () => {
|
|||
const singleOption: readonly SettingEnumOption[] = [
|
||||
{ label: 'Only Option', value: 'only' },
|
||||
];
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<EnumSelector
|
||||
options={singleOption}
|
||||
currentValue="only"
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ describe('<HalfLinePaddedBox />', () => {
|
|||
it('renders standard background and blocks when not iTerm2', async () => {
|
||||
vi.mocked(isITerm2).mockReturnValue(false);
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<HalfLinePaddedBox backgroundBaseColor="blue" backgroundOpacity={0.5}>
|
||||
<Text>Content</Text>
|
||||
</HalfLinePaddedBox>,
|
||||
|
|
@ -44,7 +44,7 @@ describe('<HalfLinePaddedBox />', () => {
|
|||
it('renders iTerm2-specific blocks when iTerm2 is detected', async () => {
|
||||
vi.mocked(isITerm2).mockReturnValue(true);
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<HalfLinePaddedBox backgroundBaseColor="blue" backgroundOpacity={0.5}>
|
||||
<Text>Content</Text>
|
||||
</HalfLinePaddedBox>,
|
||||
|
|
@ -58,7 +58,7 @@ describe('<HalfLinePaddedBox />', () => {
|
|||
});
|
||||
|
||||
it('renders nothing when useBackgroundColor is false', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<HalfLinePaddedBox
|
||||
backgroundBaseColor="blue"
|
||||
backgroundOpacity={0.5}
|
||||
|
|
@ -78,7 +78,7 @@ describe('<HalfLinePaddedBox />', () => {
|
|||
it('renders nothing when screen reader is enabled', async () => {
|
||||
mockUseIsScreenReaderEnabled.mockReturnValue(true);
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<HalfLinePaddedBox backgroundBaseColor="blue" backgroundOpacity={0.5}>
|
||||
<Text>Content</Text>
|
||||
</HalfLinePaddedBox>,
|
||||
|
|
|
|||
|
|
@ -288,7 +288,7 @@ describe('<MaxSizedBox />', () => {
|
|||
{ length: 20 },
|
||||
(_, i) => `- Step ${i + 1}: Do something important`,
|
||||
).join('\n');
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<MaxSizedBox maxWidth={80} maxHeight={5} overflowDirection="bottom">
|
||||
<MarkdownDisplay
|
||||
text={`## Plan\n\n${markdownContent}`}
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ describe('RadioButtonSelect', () => {
|
|||
{ label: 'Option 3', value: 'three', disabled: true, key: 'three' },
|
||||
];
|
||||
|
||||
const renderComponent = (
|
||||
const renderComponent = async (
|
||||
props: Partial<RadioButtonSelectProps<string>> = {},
|
||||
) => {
|
||||
const defaultProps: RadioButtonSelectProps<string> = {
|
||||
|
|
@ -86,7 +86,7 @@ describe('RadioButtonSelect', () => {
|
|||
});
|
||||
|
||||
describe('Prop forwarding to BaseSelectionList', () => {
|
||||
it('should forward all props correctly when provided', () => {
|
||||
it('should forward all props correctly when provided', async () => {
|
||||
const props = {
|
||||
items: ITEMS,
|
||||
initialIndex: 1,
|
||||
|
|
@ -98,7 +98,7 @@ describe('RadioButtonSelect', () => {
|
|||
showNumbers: false,
|
||||
};
|
||||
|
||||
renderComponent(props);
|
||||
await renderComponent(props);
|
||||
|
||||
expect(BaseSelectionList).toHaveBeenCalledTimes(1);
|
||||
expect(BaseSelectionList).toHaveBeenCalledWith(
|
||||
|
|
@ -110,8 +110,8 @@ describe('RadioButtonSelect', () => {
|
|||
);
|
||||
});
|
||||
|
||||
it('should use default props if not provided', () => {
|
||||
renderComponent({
|
||||
it('should use default props if not provided', async () => {
|
||||
await renderComponent({
|
||||
items: ITEMS,
|
||||
onSelect: mockOnSelect,
|
||||
});
|
||||
|
|
@ -137,8 +137,8 @@ describe('RadioButtonSelect', () => {
|
|||
numberColor: 'MOCK_NUMBER_COLOR',
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
renderComponent();
|
||||
beforeEach(async () => {
|
||||
await renderComponent();
|
||||
renderItem = extractRenderItem();
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ describe('<Scrollable />', () => {
|
|||
});
|
||||
|
||||
it('renders children', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Scrollable hasFocus={false} height={5}>
|
||||
<Text>Hello World</Text>
|
||||
</Scrollable>,
|
||||
|
|
@ -40,7 +40,7 @@ describe('<Scrollable />', () => {
|
|||
});
|
||||
|
||||
it('renders multiple children', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Scrollable hasFocus={false} height={5}>
|
||||
<Text>Line 1</Text>
|
||||
<Text>Line 2</Text>
|
||||
|
|
@ -55,7 +55,7 @@ describe('<Scrollable />', () => {
|
|||
});
|
||||
|
||||
it('matches snapshot', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Scrollable hasFocus={false} height={5}>
|
||||
<Text>Line 1</Text>
|
||||
<Text>Line 2</Text>
|
||||
|
|
@ -77,7 +77,7 @@ describe('<Scrollable />', () => {
|
|||
},
|
||||
);
|
||||
|
||||
const { waitUntilReady, unmount } = renderWithProviders(
|
||||
const { waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Scrollable hasFocus={true} height={5}>
|
||||
<Text>Line 1</Text>
|
||||
<Text>Line 2</Text>
|
||||
|
|
@ -105,7 +105,7 @@ describe('<Scrollable />', () => {
|
|||
// Initial state with scrollToBottom={true}
|
||||
unmount();
|
||||
const { waitUntilReady: waitUntilReady2, unmount: unmount2 } =
|
||||
renderWithProviders(
|
||||
await renderWithProviders(
|
||||
<Scrollable hasFocus={true} height={5} scrollToBottom={true}>
|
||||
<Text>Line 1</Text>
|
||||
<Text>Line 2</Text>
|
||||
|
|
@ -197,7 +197,7 @@ describe('<Scrollable />', () => {
|
|||
},
|
||||
);
|
||||
|
||||
const { stdin, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { stdin, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Scrollable hasFocus={true} height={5}>
|
||||
<Box height={scrollHeight}>
|
||||
<Text>Content</Text>
|
||||
|
|
|
|||
|
|
@ -132,10 +132,10 @@ describe('ScrollableList Demo Behavior', () => {
|
|||
let lastFrame: (options?: { allowEmpty?: boolean }) => string | undefined;
|
||||
let waitUntilReady: () => Promise<void>;
|
||||
|
||||
let result: ReturnType<typeof renderWithProviders>;
|
||||
let result: Awaited<ReturnType<typeof renderWithProviders>>;
|
||||
|
||||
await act(async () => {
|
||||
result = renderWithProviders(
|
||||
result = await renderWithProviders(
|
||||
<TestComponent
|
||||
onAddItem={(add) => {
|
||||
addItem = add;
|
||||
|
|
@ -245,9 +245,9 @@ describe('ScrollableList Demo Behavior', () => {
|
|||
|
||||
let lastFrame: () => string | undefined;
|
||||
let waitUntilReady: () => Promise<void>;
|
||||
let result: ReturnType<typeof renderWithProviders>;
|
||||
let result: Awaited<ReturnType<typeof renderWithProviders>>;
|
||||
await act(async () => {
|
||||
result = renderWithProviders(<StickyTestComponent />);
|
||||
result = await renderWithProviders(<StickyTestComponent />);
|
||||
lastFrame = result.lastFrame;
|
||||
waitUntilReady = result.waitUntilReady;
|
||||
});
|
||||
|
|
@ -313,9 +313,9 @@ describe('ScrollableList Demo Behavior', () => {
|
|||
title: `Item ${i}`,
|
||||
}));
|
||||
|
||||
let result: ReturnType<typeof renderWithProviders>;
|
||||
let result: Awaited<ReturnType<typeof renderWithProviders>>;
|
||||
await act(async () => {
|
||||
result = renderWithProviders(
|
||||
result = await renderWithProviders(
|
||||
<Box flexDirection="column" width={80} height={10}>
|
||||
<ScrollableList
|
||||
ref={(ref) => {
|
||||
|
|
@ -417,9 +417,9 @@ describe('ScrollableList Demo Behavior', () => {
|
|||
let lastFrame: (options?: { allowEmpty?: boolean }) => string | undefined;
|
||||
let waitUntilReady: () => Promise<void>;
|
||||
|
||||
let result: ReturnType<typeof renderWithProviders>;
|
||||
let result: Awaited<ReturnType<typeof renderWithProviders>>;
|
||||
await act(async () => {
|
||||
result = renderWithProviders(
|
||||
result = await renderWithProviders(
|
||||
<Box width={100} height={20}>
|
||||
<ScrollableList
|
||||
data={items}
|
||||
|
|
@ -480,9 +480,9 @@ describe('ScrollableList Demo Behavior', () => {
|
|||
);
|
||||
};
|
||||
|
||||
let result: ReturnType<typeof renderWithProviders>;
|
||||
let result: Awaited<ReturnType<typeof renderWithProviders>>;
|
||||
await act(async () => {
|
||||
result = renderWithProviders(<TestComp />);
|
||||
result = await renderWithProviders(<TestComp />);
|
||||
});
|
||||
|
||||
await result!.waitUntilReady();
|
||||
|
|
@ -601,9 +601,9 @@ describe('ScrollableList Demo Behavior', () => {
|
|||
);
|
||||
};
|
||||
|
||||
let result: ReturnType<typeof renderWithProviders>;
|
||||
let result: Awaited<ReturnType<typeof renderWithProviders>>;
|
||||
await act(async () => {
|
||||
result = renderWithProviders(<TestComp />);
|
||||
result = await renderWithProviders(<TestComp />);
|
||||
});
|
||||
|
||||
await result!.waitUntilReady();
|
||||
|
|
@ -671,9 +671,9 @@ describe('ScrollableList Demo Behavior', () => {
|
|||
);
|
||||
};
|
||||
|
||||
let result: ReturnType<typeof renderWithProviders>;
|
||||
let result: Awaited<ReturnType<typeof renderWithProviders>>;
|
||||
await act(async () => {
|
||||
result = renderWithProviders(<TestComp />);
|
||||
result = await renderWithProviders(<TestComp />);
|
||||
});
|
||||
|
||||
await result!.waitUntilReady();
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ describe('SearchableList', () => {
|
|||
mockOnClose = vi.fn();
|
||||
});
|
||||
|
||||
const renderList = (
|
||||
const renderList = async (
|
||||
props: Partial<SearchableListProps<GenericListItem>> = {},
|
||||
) => {
|
||||
const defaultProps: SearchableListProps<GenericListItem> = {
|
||||
|
|
@ -95,7 +95,7 @@ describe('SearchableList', () => {
|
|||
};
|
||||
|
||||
it('should render all items initially', async () => {
|
||||
const { lastFrame, waitUntilReady } = renderList();
|
||||
const { lastFrame, waitUntilReady } = await renderList();
|
||||
await waitUntilReady();
|
||||
const frame = lastFrame();
|
||||
|
||||
|
|
@ -109,7 +109,7 @@ describe('SearchableList', () => {
|
|||
});
|
||||
|
||||
it('should reset selection to top when items change if resetSelectionOnItemsChange is true', async () => {
|
||||
const { lastFrame, stdin, waitUntilReady } = renderList({
|
||||
const { lastFrame, stdin, waitUntilReady } = await renderList({
|
||||
resetSelectionOnItemsChange: true,
|
||||
});
|
||||
await waitUntilReady();
|
||||
|
|
@ -150,7 +150,7 @@ describe('SearchableList', () => {
|
|||
});
|
||||
|
||||
it('should filter items based on search query', async () => {
|
||||
const { lastFrame, stdin } = renderList();
|
||||
const { lastFrame, stdin } = await renderList();
|
||||
|
||||
await React.act(async () => {
|
||||
stdin.write('Two');
|
||||
|
|
@ -165,7 +165,7 @@ describe('SearchableList', () => {
|
|||
});
|
||||
|
||||
it('should show "No items found." when no items match', async () => {
|
||||
const { lastFrame, stdin } = renderList();
|
||||
const { lastFrame, stdin } = await renderList();
|
||||
|
||||
await React.act(async () => {
|
||||
stdin.write('xyz123');
|
||||
|
|
@ -178,7 +178,7 @@ describe('SearchableList', () => {
|
|||
});
|
||||
|
||||
it('should handle selection with Enter', async () => {
|
||||
const { stdin } = renderList();
|
||||
const { stdin } = await renderList();
|
||||
|
||||
await React.act(async () => {
|
||||
stdin.write('\r'); // Enter
|
||||
|
|
@ -190,7 +190,7 @@ describe('SearchableList', () => {
|
|||
});
|
||||
|
||||
it('should handle navigation and selection', async () => {
|
||||
const { stdin } = renderList();
|
||||
const { stdin } = await renderList();
|
||||
|
||||
await React.act(async () => {
|
||||
stdin.write('\u001B[B'); // Down arrow
|
||||
|
|
@ -206,7 +206,7 @@ describe('SearchableList', () => {
|
|||
});
|
||||
|
||||
it('should handle close with Esc', async () => {
|
||||
const { stdin } = renderList();
|
||||
const { stdin } = await renderList();
|
||||
|
||||
await React.act(async () => {
|
||||
stdin.write('\u001B'); // Esc
|
||||
|
|
@ -218,7 +218,7 @@ describe('SearchableList', () => {
|
|||
});
|
||||
|
||||
it('should match snapshot', async () => {
|
||||
const { lastFrame, waitUntilReady } = renderList();
|
||||
const { lastFrame, waitUntilReady } = await renderList();
|
||||
await waitUntilReady();
|
||||
expect(lastFrame()).toMatchSnapshot();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ describe('<SectionHeader />', () => {
|
|||
width: 40,
|
||||
},
|
||||
])('$description', async ({ title, subtitle, width }) => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<SectionHeader title={title} subtitle={subtitle} />,
|
||||
{ width },
|
||||
);
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ const MOCK_TABS: Tab[] = [
|
|||
describe('TabHeader', () => {
|
||||
describe('rendering', () => {
|
||||
it('renders null for single tab', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<TabHeader
|
||||
tabs={[{ key: '0', header: 'Only Tab' }]}
|
||||
currentIndex={0}
|
||||
|
|
@ -29,7 +29,7 @@ describe('TabHeader', () => {
|
|||
});
|
||||
|
||||
it('renders all tab headers', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<TabHeader tabs={MOCK_TABS} currentIndex={0} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -42,7 +42,7 @@ describe('TabHeader', () => {
|
|||
});
|
||||
|
||||
it('renders separators between tabs', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<TabHeader tabs={MOCK_TABS} currentIndex={0} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -57,7 +57,7 @@ describe('TabHeader', () => {
|
|||
|
||||
describe('arrows', () => {
|
||||
it('shows arrows by default', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<TabHeader tabs={MOCK_TABS} currentIndex={0} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -69,7 +69,7 @@ describe('TabHeader', () => {
|
|||
});
|
||||
|
||||
it('hides arrows when showArrows is false', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<TabHeader tabs={MOCK_TABS} currentIndex={0} showArrows={false} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -83,7 +83,7 @@ describe('TabHeader', () => {
|
|||
|
||||
describe('status icons', () => {
|
||||
it('shows status icons by default', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<TabHeader tabs={MOCK_TABS} currentIndex={0} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -95,7 +95,7 @@ describe('TabHeader', () => {
|
|||
});
|
||||
|
||||
it('hides status icons when showStatusIcons is false', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<TabHeader tabs={MOCK_TABS} currentIndex={0} showStatusIcons={false} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -107,7 +107,7 @@ describe('TabHeader', () => {
|
|||
});
|
||||
|
||||
it('shows checkmark for completed tabs', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<TabHeader
|
||||
tabs={MOCK_TABS}
|
||||
currentIndex={0}
|
||||
|
|
@ -130,7 +130,7 @@ describe('TabHeader', () => {
|
|||
{ key: '0', header: 'Tab 1' },
|
||||
{ key: '1', header: 'Review', isSpecial: true },
|
||||
];
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<TabHeader tabs={tabsWithSpecial} currentIndex={0} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -146,7 +146,7 @@ describe('TabHeader', () => {
|
|||
{ key: '0', header: 'Tab 1', statusIcon: '★' },
|
||||
{ key: '1', header: 'Tab 2' },
|
||||
];
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<TabHeader tabs={tabsWithCustomIcon} currentIndex={0} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -158,7 +158,7 @@ describe('TabHeader', () => {
|
|||
|
||||
it('uses custom renderStatusIcon when provided', async () => {
|
||||
const renderStatusIcon = () => '•';
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<TabHeader
|
||||
tabs={MOCK_TABS}
|
||||
currentIndex={0}
|
||||
|
|
@ -178,7 +178,7 @@ describe('TabHeader', () => {
|
|||
{ key: '0', header: 'ThisIsAVeryLongHeaderThatShouldBeTruncated' },
|
||||
{ key: '1', header: 'AnotherVeryLongHeader' },
|
||||
];
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<TabHeader tabs={longTabs} currentIndex={0} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -197,7 +197,7 @@ describe('TabHeader', () => {
|
|||
|
||||
it('falls back to default when renderStatusIcon returns undefined', async () => {
|
||||
const renderStatusIcon = () => undefined;
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<TabHeader
|
||||
tabs={MOCK_TABS}
|
||||
currentIndex={0}
|
||||
|
|
|
|||
|
|
@ -3241,9 +3241,9 @@ describe('Transformation Utilities', () => {
|
|||
},
|
||||
])(
|
||||
'should invalidate cache when line content changes $desc',
|
||||
({ actFn, expected }) => {
|
||||
async ({ actFn, expected }) => {
|
||||
const viewport = { width: 80, height: 24 };
|
||||
const { result } = renderHookWithProviders(() =>
|
||||
const { result } = await renderHookWithProviders(() =>
|
||||
useTextBuffer({
|
||||
initialText: 'original line',
|
||||
viewport,
|
||||
|
|
@ -3262,9 +3262,9 @@ describe('Transformation Utilities', () => {
|
|||
},
|
||||
);
|
||||
|
||||
it('should invalidate cache when viewport width changes', () => {
|
||||
it('should invalidate cache when viewport width changes', async () => {
|
||||
const viewport = { width: 80, height: 24 };
|
||||
const { result, rerender } = renderHookWithProviders(
|
||||
const { result, rerender } = await renderHookWithProviders(
|
||||
({ vp }) =>
|
||||
useTextBuffer({
|
||||
initialText:
|
||||
|
|
@ -3284,10 +3284,10 @@ describe('Transformation Utilities', () => {
|
|||
expect(result.current.allVisualLines.length).toBeGreaterThan(1);
|
||||
});
|
||||
|
||||
it('should correctly handle cursor expansion/collapse in cached layout', () => {
|
||||
it('should correctly handle cursor expansion/collapse in cached layout', async () => {
|
||||
const viewport = { width: 80, height: 24 };
|
||||
const text = 'Check @image.png here';
|
||||
const { result } = renderHookWithProviders(() =>
|
||||
const { result } = await renderHookWithProviders(() =>
|
||||
useTextBuffer({
|
||||
initialText: text,
|
||||
viewport,
|
||||
|
|
@ -3317,10 +3317,10 @@ describe('Transformation Utilities', () => {
|
|||
expect(result.current.allVisualLines[0]).toContain('[Image image.png]');
|
||||
});
|
||||
|
||||
it('should reuse cache for unchanged lines during editing', () => {
|
||||
it('should reuse cache for unchanged lines during editing', async () => {
|
||||
const viewport = { width: 80, height: 24 };
|
||||
const initialText = 'line 1\nline 2\nline 3';
|
||||
const { result } = renderHookWithProviders(() =>
|
||||
const { result } = await renderHookWithProviders(() =>
|
||||
useTextBuffer({
|
||||
initialText,
|
||||
viewport,
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ describe('ExtensionDetails', () => {
|
|||
mockOnInstall = vi.fn();
|
||||
});
|
||||
|
||||
const renderDetails = (isInstalled = false) =>
|
||||
const renderDetails = async (isInstalled = false) =>
|
||||
renderWithProviders(
|
||||
<ExtensionDetails
|
||||
extension={mockExtension}
|
||||
|
|
@ -52,7 +52,7 @@ describe('ExtensionDetails', () => {
|
|||
);
|
||||
|
||||
it('should render extension details correctly', async () => {
|
||||
const { lastFrame } = renderDetails();
|
||||
const { lastFrame } = await renderDetails();
|
||||
await waitFor(() => {
|
||||
expect(lastFrame()).toContain('Test Extension');
|
||||
expect(lastFrame()).toContain('v1.2.3');
|
||||
|
|
@ -69,7 +69,7 @@ describe('ExtensionDetails', () => {
|
|||
});
|
||||
|
||||
it('should show install prompt when not installed', async () => {
|
||||
const { lastFrame } = renderDetails(false);
|
||||
const { lastFrame } = await renderDetails(false);
|
||||
await waitFor(() => {
|
||||
expect(lastFrame()).toContain('[Enter] Install');
|
||||
expect(lastFrame()).not.toContain('Already Installed');
|
||||
|
|
@ -77,7 +77,7 @@ describe('ExtensionDetails', () => {
|
|||
});
|
||||
|
||||
it('should show already installed message when installed', async () => {
|
||||
const { lastFrame } = renderDetails(true);
|
||||
const { lastFrame } = await renderDetails(true);
|
||||
await waitFor(() => {
|
||||
expect(lastFrame()).toContain('Already Installed');
|
||||
expect(lastFrame()).not.toContain('[Enter] Install');
|
||||
|
|
@ -85,7 +85,7 @@ describe('ExtensionDetails', () => {
|
|||
});
|
||||
|
||||
it('should call onBack when Escape is pressed', async () => {
|
||||
const { stdin } = renderDetails();
|
||||
const { stdin } = await renderDetails();
|
||||
await React.act(async () => {
|
||||
stdin.write('\x1b'); // Escape
|
||||
});
|
||||
|
|
@ -95,7 +95,7 @@ describe('ExtensionDetails', () => {
|
|||
});
|
||||
|
||||
it('should call onInstall when Enter is pressed and not installed', async () => {
|
||||
const { stdin } = renderDetails(false);
|
||||
const { stdin } = await renderDetails(false);
|
||||
await React.act(async () => {
|
||||
stdin.write('\r'); // Enter
|
||||
});
|
||||
|
|
@ -106,7 +106,7 @@ describe('ExtensionDetails', () => {
|
|||
|
||||
it('should NOT call onInstall when Enter is pressed and already installed', async () => {
|
||||
vi.useFakeTimers();
|
||||
const { stdin } = renderDetails(true);
|
||||
const { stdin } = await renderDetails(true);
|
||||
await React.act(async () => {
|
||||
stdin.write('\r'); // Enter
|
||||
});
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
import React from 'react';
|
||||
import { renderWithProviders } from '../../../test-utils/render.js';
|
||||
import { waitFor } from '../../../test-utils/async.js';
|
||||
import { makeFakeConfig } from '@google/gemini-cli-core';
|
||||
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
||||
import { ExtensionRegistryView } from './ExtensionRegistryView.js';
|
||||
import { type ExtensionManager } from '../../../config/extension-manager.js';
|
||||
|
|
@ -121,7 +122,7 @@ describe('ExtensionRegistryView', () => {
|
|||
);
|
||||
});
|
||||
|
||||
const renderView = () =>
|
||||
const renderView = async () =>
|
||||
renderWithProviders(
|
||||
<ExtensionRegistryView
|
||||
extensionManager={mockExtensionManager}
|
||||
|
|
@ -129,6 +130,7 @@ describe('ExtensionRegistryView', () => {
|
|||
onClose={mockOnClose}
|
||||
/>,
|
||||
{
|
||||
config: makeFakeConfig(),
|
||||
uiState: {
|
||||
staticExtraHeight: 5,
|
||||
terminalHeight: 40,
|
||||
|
|
@ -137,7 +139,7 @@ describe('ExtensionRegistryView', () => {
|
|||
);
|
||||
|
||||
it('should render extensions', async () => {
|
||||
const { lastFrame, waitUntilReady } = renderView();
|
||||
const { lastFrame, waitUntilReady } = await renderView();
|
||||
await waitUntilReady();
|
||||
|
||||
await waitFor(() => {
|
||||
|
|
@ -146,8 +148,8 @@ describe('ExtensionRegistryView', () => {
|
|||
});
|
||||
});
|
||||
|
||||
it('should use useRegistrySearch hook', () => {
|
||||
renderView();
|
||||
it('should use useRegistrySearch hook', async () => {
|
||||
await renderView();
|
||||
expect(useRegistrySearch).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
|
|
@ -185,7 +187,7 @@ describe('ExtensionRegistryView', () => {
|
|||
},
|
||||
);
|
||||
|
||||
renderView();
|
||||
await renderView();
|
||||
|
||||
await waitFor(() => {
|
||||
expect(useRegistrySearch).toHaveBeenCalledWith(
|
||||
|
|
@ -197,7 +199,7 @@ describe('ExtensionRegistryView', () => {
|
|||
});
|
||||
|
||||
it('should call onSelect when extension is selected and Enter is pressed in details', async () => {
|
||||
const { stdin, lastFrame } = renderView();
|
||||
const { stdin, lastFrame } = await renderView();
|
||||
|
||||
// Select the first extension in the list (Enter opens details)
|
||||
await React.act(async () => {
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ const mockTools: ToolDefinition[] = [
|
|||
|
||||
describe('<ToolsList />', () => {
|
||||
it('renders correctly with descriptions', async () => {
|
||||
const { lastFrame, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady } = await renderWithProviders(
|
||||
<ToolsList
|
||||
tools={mockTools}
|
||||
showDescriptions={true}
|
||||
|
|
@ -44,7 +44,7 @@ describe('<ToolsList />', () => {
|
|||
});
|
||||
|
||||
it('renders correctly without descriptions', async () => {
|
||||
const { lastFrame, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady } = await renderWithProviders(
|
||||
<ToolsList
|
||||
tools={mockTools}
|
||||
showDescriptions={false}
|
||||
|
|
@ -56,7 +56,7 @@ describe('<ToolsList />', () => {
|
|||
});
|
||||
|
||||
it('renders correctly with no tools', async () => {
|
||||
const { lastFrame, waitUntilReady } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady } = await renderWithProviders(
|
||||
<ToolsList tools={[]} showDescriptions={true} terminalWidth={40} />,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
|
|||
|
|
@ -49,10 +49,10 @@ class MockStdin extends EventEmitter {
|
|||
}
|
||||
|
||||
// Helper function to setup keypress test with standard configuration
|
||||
const setupKeypressTest = () => {
|
||||
const setupKeypressTest = async () => {
|
||||
const keyHandler = vi.fn();
|
||||
|
||||
const { result } = renderHookWithProviders(() => useKeypressContext());
|
||||
const { result } = await renderHookWithProviders(() => useKeypressContext());
|
||||
act(() => result.current.subscribe(keyHandler));
|
||||
|
||||
return { result, keyHandler };
|
||||
|
|
@ -85,7 +85,7 @@ describe('KeypressContext', () => {
|
|||
sequence: '\x1b[57414u',
|
||||
},
|
||||
])('should recognize $name in kitty protocol', async ({ sequence }) => {
|
||||
const { keyHandler } = setupKeypressTest();
|
||||
const { keyHandler } = await setupKeypressTest();
|
||||
|
||||
act(() => stdin.write(sequence));
|
||||
|
||||
|
|
@ -100,7 +100,7 @@ describe('KeypressContext', () => {
|
|||
});
|
||||
|
||||
it('should handle backslash return', async () => {
|
||||
const { keyHandler } = setupKeypressTest();
|
||||
const { keyHandler } = await setupKeypressTest();
|
||||
|
||||
act(() => stdin.write('\\\r'));
|
||||
|
||||
|
|
@ -133,7 +133,7 @@ describe('KeypressContext', () => {
|
|||
])(
|
||||
'should handle numpad enter with $modifier modifier',
|
||||
async ({ sequence, expected }) => {
|
||||
const { keyHandler } = setupKeypressTest();
|
||||
const { keyHandler } = await setupKeypressTest();
|
||||
|
||||
act(() => stdin.write(sequence));
|
||||
|
||||
|
|
@ -147,7 +147,7 @@ describe('KeypressContext', () => {
|
|||
);
|
||||
|
||||
it('should recognize \n (LF) as ctrl+j', async () => {
|
||||
const { keyHandler } = setupKeypressTest();
|
||||
const { keyHandler } = await setupKeypressTest();
|
||||
|
||||
act(() => stdin.write('\n'));
|
||||
|
||||
|
|
@ -162,7 +162,7 @@ describe('KeypressContext', () => {
|
|||
});
|
||||
|
||||
it('should recognize \\x1b\\n as Alt+Enter (return with meta)', async () => {
|
||||
const { keyHandler } = setupKeypressTest();
|
||||
const { keyHandler } = await setupKeypressTest();
|
||||
|
||||
act(() => stdin.write('\x1b\n'));
|
||||
|
||||
|
|
@ -190,7 +190,7 @@ describe('KeypressContext', () => {
|
|||
afterEach(() => kittySpy.mockRestore());
|
||||
|
||||
it('should buffer return key pressed quickly after another key', async () => {
|
||||
const { keyHandler } = setupKeypressTest();
|
||||
const { keyHandler } = await setupKeypressTest();
|
||||
|
||||
act(() => stdin.write('a'));
|
||||
expect(keyHandler).toHaveBeenLastCalledWith(
|
||||
|
|
@ -219,7 +219,7 @@ describe('KeypressContext', () => {
|
|||
});
|
||||
|
||||
it('should NOT buffer return key if delay is long enough', async () => {
|
||||
const { keyHandler } = setupKeypressTest();
|
||||
const { keyHandler } = await setupKeypressTest();
|
||||
|
||||
act(() => stdin.write('a'));
|
||||
|
||||
|
|
@ -241,7 +241,7 @@ describe('KeypressContext', () => {
|
|||
|
||||
describe('Escape key handling', () => {
|
||||
it('should recognize escape key (keycode 27) in kitty protocol', async () => {
|
||||
const { keyHandler } = setupKeypressTest();
|
||||
const { keyHandler } = await setupKeypressTest();
|
||||
|
||||
// Send kitty protocol sequence for escape: ESC[27u
|
||||
act(() => {
|
||||
|
|
@ -261,7 +261,9 @@ describe('KeypressContext', () => {
|
|||
|
||||
it('should handle double Escape', async () => {
|
||||
const keyHandler = vi.fn();
|
||||
const { result } = renderHookWithProviders(() => useKeypressContext());
|
||||
const { result } = await renderHookWithProviders(() =>
|
||||
useKeypressContext(),
|
||||
);
|
||||
act(() => result.current.subscribe(keyHandler));
|
||||
|
||||
act(() => {
|
||||
|
|
@ -295,7 +297,9 @@ describe('KeypressContext', () => {
|
|||
it('should handle lone Escape key (keycode 27) with timeout when kitty protocol is enabled', async () => {
|
||||
// Use real timers for this test to avoid issues with stream/buffer timing
|
||||
const keyHandler = vi.fn();
|
||||
const { result } = renderHookWithProviders(() => useKeypressContext());
|
||||
const { result } = await renderHookWithProviders(() =>
|
||||
useKeypressContext(),
|
||||
);
|
||||
act(() => result.current.subscribe(keyHandler));
|
||||
|
||||
// Send just ESC
|
||||
|
|
@ -369,7 +373,7 @@ describe('KeypressContext', () => {
|
|||
])(
|
||||
'should recognize $name in kitty protocol',
|
||||
async ({ inputSequence, expected }) => {
|
||||
const { keyHandler } = setupKeypressTest();
|
||||
const { keyHandler } = await setupKeypressTest();
|
||||
|
||||
act(() => {
|
||||
stdin.write(inputSequence);
|
||||
|
|
@ -418,7 +422,9 @@ describe('KeypressContext', () => {
|
|||
])('should $name', async ({ pastedText, writeSequence }) => {
|
||||
const keyHandler = vi.fn();
|
||||
|
||||
const { result } = renderHookWithProviders(() => useKeypressContext());
|
||||
const { result } = await renderHookWithProviders(() =>
|
||||
useKeypressContext(),
|
||||
);
|
||||
|
||||
act(() => result.current.subscribe(keyHandler));
|
||||
|
||||
|
|
@ -438,7 +444,9 @@ describe('KeypressContext', () => {
|
|||
|
||||
it('should parse valid OSC 52 response', async () => {
|
||||
const keyHandler = vi.fn();
|
||||
const { result } = renderHookWithProviders(() => useKeypressContext());
|
||||
const { result } = await renderHookWithProviders(() =>
|
||||
useKeypressContext(),
|
||||
);
|
||||
|
||||
act(() => result.current.subscribe(keyHandler));
|
||||
|
||||
|
|
@ -459,7 +467,9 @@ describe('KeypressContext', () => {
|
|||
|
||||
it('should handle split OSC 52 response', async () => {
|
||||
const keyHandler = vi.fn();
|
||||
const { result } = renderHookWithProviders(() => useKeypressContext());
|
||||
const { result } = await renderHookWithProviders(() =>
|
||||
useKeypressContext(),
|
||||
);
|
||||
|
||||
act(() => result.current.subscribe(keyHandler));
|
||||
|
||||
|
|
@ -485,7 +495,9 @@ describe('KeypressContext', () => {
|
|||
|
||||
it('should handle OSC 52 response terminated by ESC \\', async () => {
|
||||
const keyHandler = vi.fn();
|
||||
const { result } = renderHookWithProviders(() => useKeypressContext());
|
||||
const { result } = await renderHookWithProviders(() =>
|
||||
useKeypressContext(),
|
||||
);
|
||||
|
||||
act(() => result.current.subscribe(keyHandler));
|
||||
|
||||
|
|
@ -506,7 +518,9 @@ describe('KeypressContext', () => {
|
|||
|
||||
it('should ignore unknown OSC sequences', async () => {
|
||||
const keyHandler = vi.fn();
|
||||
const { result } = renderHookWithProviders(() => useKeypressContext());
|
||||
const { result } = await renderHookWithProviders(() =>
|
||||
useKeypressContext(),
|
||||
);
|
||||
|
||||
act(() => result.current.subscribe(keyHandler));
|
||||
|
||||
|
|
@ -523,7 +537,9 @@ describe('KeypressContext', () => {
|
|||
|
||||
it('should ignore invalid OSC 52 format', async () => {
|
||||
const keyHandler = vi.fn();
|
||||
const { result } = renderHookWithProviders(() => useKeypressContext());
|
||||
const { result } = await renderHookWithProviders(() =>
|
||||
useKeypressContext(),
|
||||
);
|
||||
|
||||
act(() => result.current.subscribe(keyHandler));
|
||||
|
||||
|
|
@ -555,11 +571,14 @@ describe('KeypressContext', () => {
|
|||
it('should not log keystrokes when debugKeystrokeLogging is false', async () => {
|
||||
const keyHandler = vi.fn();
|
||||
|
||||
const { result } = renderHookWithProviders(() => useKeypressContext(), {
|
||||
settings: createMockSettings({
|
||||
general: { debugKeystrokeLogging: false },
|
||||
}),
|
||||
});
|
||||
const { result } = await renderHookWithProviders(
|
||||
() => useKeypressContext(),
|
||||
{
|
||||
settings: createMockSettings({
|
||||
general: { debugKeystrokeLogging: false },
|
||||
}),
|
||||
},
|
||||
);
|
||||
|
||||
act(() => result.current.subscribe(keyHandler));
|
||||
|
||||
|
|
@ -577,11 +596,14 @@ describe('KeypressContext', () => {
|
|||
it('should log kitty buffer accumulation when debugKeystrokeLogging is true', async () => {
|
||||
const keyHandler = vi.fn();
|
||||
|
||||
const { result } = renderHookWithProviders(() => useKeypressContext(), {
|
||||
settings: createMockSettings({
|
||||
general: { debugKeystrokeLogging: true },
|
||||
}),
|
||||
});
|
||||
const { result } = await renderHookWithProviders(
|
||||
() => useKeypressContext(),
|
||||
{
|
||||
settings: createMockSettings({
|
||||
general: { debugKeystrokeLogging: true },
|
||||
}),
|
||||
},
|
||||
);
|
||||
|
||||
act(() => result.current.subscribe(keyHandler));
|
||||
|
||||
|
|
@ -596,11 +618,14 @@ describe('KeypressContext', () => {
|
|||
it('should show char codes when debugKeystrokeLogging is true even without debug mode', async () => {
|
||||
const keyHandler = vi.fn();
|
||||
|
||||
const { result } = renderHookWithProviders(() => useKeypressContext(), {
|
||||
settings: createMockSettings({
|
||||
general: { debugKeystrokeLogging: true },
|
||||
}),
|
||||
});
|
||||
const { result } = await renderHookWithProviders(
|
||||
() => useKeypressContext(),
|
||||
{
|
||||
settings: createMockSettings({
|
||||
general: { debugKeystrokeLogging: true },
|
||||
}),
|
||||
},
|
||||
);
|
||||
|
||||
act(() => result.current.subscribe(keyHandler));
|
||||
|
||||
|
|
@ -743,9 +768,11 @@ describe('KeypressContext', () => {
|
|||
},
|
||||
])(
|
||||
'should recognize sequence "$sequence" as $expected.name',
|
||||
({ sequence, expected }) => {
|
||||
async ({ sequence, expected }) => {
|
||||
const keyHandler = vi.fn();
|
||||
const { result } = renderHookWithProviders(() => useKeypressContext());
|
||||
const { result } = await renderHookWithProviders(() =>
|
||||
useKeypressContext(),
|
||||
);
|
||||
act(() => result.current.subscribe(keyHandler));
|
||||
|
||||
act(() => stdin.write(sequence));
|
||||
|
|
@ -835,8 +862,8 @@ describe('KeypressContext', () => {
|
|||
},
|
||||
])(
|
||||
'should recognize numpad sequence "$sequence" as $expected.name',
|
||||
({ sequence, expected }) => {
|
||||
const { keyHandler } = setupKeypressTest();
|
||||
async ({ sequence, expected }) => {
|
||||
const { keyHandler } = await setupKeypressTest();
|
||||
act(() => stdin.write(sequence));
|
||||
expect(keyHandler).toHaveBeenCalledWith(
|
||||
expect.objectContaining(expected),
|
||||
|
|
@ -847,7 +874,7 @@ describe('KeypressContext', () => {
|
|||
|
||||
describe('Double-tap and batching', () => {
|
||||
it('should emit two delete events for double-tap CSI[3~', async () => {
|
||||
const { keyHandler } = setupKeypressTest();
|
||||
const { keyHandler } = await setupKeypressTest();
|
||||
|
||||
act(() => stdin.write(`\x1b[3~`));
|
||||
act(() => stdin.write(`\x1b[3~`));
|
||||
|
|
@ -875,7 +902,7 @@ describe('KeypressContext', () => {
|
|||
});
|
||||
|
||||
it('should parse two concatenated tilde-coded sequences in one chunk', async () => {
|
||||
const { keyHandler } = setupKeypressTest();
|
||||
const { keyHandler } = await setupKeypressTest();
|
||||
|
||||
act(() => stdin.write(`\x1b[3~\x1b[5~`));
|
||||
|
||||
|
|
@ -978,9 +1005,17 @@ describe('KeypressContext', () => {
|
|||
),
|
||||
)(
|
||||
'should handle Alt+$key in $terminal',
|
||||
({ chunk, expected }: { chunk: string; expected: Partial<Key> }) => {
|
||||
async ({
|
||||
chunk,
|
||||
expected,
|
||||
}: {
|
||||
chunk: string;
|
||||
expected: Partial<Key>;
|
||||
}) => {
|
||||
const keyHandler = vi.fn();
|
||||
const { result } = renderHookWithProviders(() => useKeypressContext());
|
||||
const { result } = await renderHookWithProviders(() =>
|
||||
useKeypressContext(),
|
||||
);
|
||||
act(() => result.current.subscribe(keyHandler));
|
||||
|
||||
act(() => stdin.write(chunk));
|
||||
|
|
@ -993,8 +1028,8 @@ describe('KeypressContext', () => {
|
|||
});
|
||||
|
||||
describe('Backslash key handling', () => {
|
||||
it('should treat backslash as a regular keystroke', () => {
|
||||
const { keyHandler } = setupKeypressTest();
|
||||
it('should treat backslash as a regular keystroke', async () => {
|
||||
const { keyHandler } = await setupKeypressTest();
|
||||
|
||||
act(() => stdin.write('\\'));
|
||||
|
||||
|
|
@ -1017,7 +1052,9 @@ describe('KeypressContext', () => {
|
|||
|
||||
it('should timeout and flush incomplete kitty sequences after 50ms', async () => {
|
||||
const keyHandler = vi.fn();
|
||||
const { result } = renderHookWithProviders(() => useKeypressContext());
|
||||
const { result } = await renderHookWithProviders(() =>
|
||||
useKeypressContext(),
|
||||
);
|
||||
|
||||
act(() => result.current.subscribe(keyHandler));
|
||||
|
||||
|
|
@ -1052,7 +1089,9 @@ describe('KeypressContext', () => {
|
|||
|
||||
it('should immediately flush non-kitty CSI sequences', async () => {
|
||||
const keyHandler = vi.fn();
|
||||
const { result } = renderHookWithProviders(() => useKeypressContext());
|
||||
const { result } = await renderHookWithProviders(() =>
|
||||
useKeypressContext(),
|
||||
);
|
||||
|
||||
act(() => result.current.subscribe(keyHandler));
|
||||
|
||||
|
|
@ -1074,7 +1113,9 @@ describe('KeypressContext', () => {
|
|||
|
||||
it('should parse valid kitty sequences immediately when complete', async () => {
|
||||
const keyHandler = vi.fn();
|
||||
const { result } = renderHookWithProviders(() => useKeypressContext());
|
||||
const { result } = await renderHookWithProviders(() =>
|
||||
useKeypressContext(),
|
||||
);
|
||||
|
||||
act(() => result.current.subscribe(keyHandler));
|
||||
|
||||
|
|
@ -1092,7 +1133,9 @@ describe('KeypressContext', () => {
|
|||
|
||||
it('should handle batched kitty sequences correctly', async () => {
|
||||
const keyHandler = vi.fn();
|
||||
const { result } = renderHookWithProviders(() => useKeypressContext());
|
||||
const { result } = await renderHookWithProviders(() =>
|
||||
useKeypressContext(),
|
||||
);
|
||||
|
||||
act(() => result.current.subscribe(keyHandler));
|
||||
|
||||
|
|
@ -1119,7 +1162,9 @@ describe('KeypressContext', () => {
|
|||
|
||||
it('should handle mixed valid and invalid sequences', async () => {
|
||||
const keyHandler = vi.fn();
|
||||
const { result } = renderHookWithProviders(() => useKeypressContext());
|
||||
const { result } = await renderHookWithProviders(() =>
|
||||
useKeypressContext(),
|
||||
);
|
||||
|
||||
act(() => result.current.subscribe(keyHandler));
|
||||
|
||||
|
|
@ -1147,7 +1192,9 @@ describe('KeypressContext', () => {
|
|||
'should handle sequences arriving character by character with %s ms delay',
|
||||
async (delay) => {
|
||||
const keyHandler = vi.fn();
|
||||
const { result } = renderHookWithProviders(() => useKeypressContext());
|
||||
const { result } = await renderHookWithProviders(() =>
|
||||
useKeypressContext(),
|
||||
);
|
||||
|
||||
act(() => result.current.subscribe(keyHandler));
|
||||
|
||||
|
|
@ -1171,7 +1218,9 @@ describe('KeypressContext', () => {
|
|||
|
||||
it('should reset timeout when new input arrives', async () => {
|
||||
const keyHandler = vi.fn();
|
||||
const { result } = renderHookWithProviders(() => useKeypressContext());
|
||||
const { result } = await renderHookWithProviders(() =>
|
||||
useKeypressContext(),
|
||||
);
|
||||
|
||||
act(() => result.current.subscribe(keyHandler));
|
||||
|
||||
|
|
@ -1206,7 +1255,9 @@ describe('KeypressContext', () => {
|
|||
describe('SGR Mouse Handling', () => {
|
||||
it('should ignore SGR mouse sequences', async () => {
|
||||
const keyHandler = vi.fn();
|
||||
const { result } = renderHookWithProviders(() => useKeypressContext());
|
||||
const { result } = await renderHookWithProviders(() =>
|
||||
useKeypressContext(),
|
||||
);
|
||||
|
||||
act(() => result.current.subscribe(keyHandler));
|
||||
|
||||
|
|
@ -1224,7 +1275,9 @@ describe('KeypressContext', () => {
|
|||
|
||||
it('should handle mixed SGR mouse and key sequences', async () => {
|
||||
const keyHandler = vi.fn();
|
||||
const { result } = renderHookWithProviders(() => useKeypressContext());
|
||||
const { result } = await renderHookWithProviders(() =>
|
||||
useKeypressContext(),
|
||||
);
|
||||
|
||||
act(() => result.current.subscribe(keyHandler));
|
||||
|
||||
|
|
@ -1250,7 +1303,9 @@ describe('KeypressContext', () => {
|
|||
|
||||
it('should ignore X11 mouse sequences', async () => {
|
||||
const keyHandler = vi.fn();
|
||||
const { result } = renderHookWithProviders(() => useKeypressContext());
|
||||
const { result } = await renderHookWithProviders(() =>
|
||||
useKeypressContext(),
|
||||
);
|
||||
|
||||
act(() => result.current.subscribe(keyHandler));
|
||||
|
||||
|
|
@ -1266,7 +1321,9 @@ describe('KeypressContext', () => {
|
|||
|
||||
it('should not flush slow SGR mouse sequences as garbage', async () => {
|
||||
const keyHandler = vi.fn();
|
||||
const { result } = renderHookWithProviders(() => useKeypressContext());
|
||||
const { result } = await renderHookWithProviders(() =>
|
||||
useKeypressContext(),
|
||||
);
|
||||
|
||||
act(() => result.current.subscribe(keyHandler));
|
||||
|
||||
|
|
@ -1286,7 +1343,9 @@ describe('KeypressContext', () => {
|
|||
|
||||
it('should ignore specific SGR mouse sequence sandwiched between keystrokes', async () => {
|
||||
const keyHandler = vi.fn();
|
||||
const { result } = renderHookWithProviders(() => useKeypressContext());
|
||||
const { result } = await renderHookWithProviders(() =>
|
||||
useKeypressContext(),
|
||||
);
|
||||
|
||||
act(() => result.current.subscribe(keyHandler));
|
||||
|
||||
|
|
@ -1317,7 +1376,9 @@ describe('KeypressContext', () => {
|
|||
{ name: 'another mouse', sequence: '\u001b[<0;29;19m' },
|
||||
])('should ignore $name sequence', async ({ sequence }) => {
|
||||
const keyHandler = vi.fn();
|
||||
const { result } = renderHookWithProviders(() => useKeypressContext());
|
||||
const { result } = await renderHookWithProviders(() =>
|
||||
useKeypressContext(),
|
||||
);
|
||||
act(() => result.current.subscribe(keyHandler));
|
||||
|
||||
for (const char of sequence) {
|
||||
|
|
@ -1342,7 +1403,9 @@ describe('KeypressContext', () => {
|
|||
|
||||
it('should handle F12', async () => {
|
||||
const keyHandler = vi.fn();
|
||||
const { result } = renderHookWithProviders(() => useKeypressContext());
|
||||
const { result } = await renderHookWithProviders(() =>
|
||||
useKeypressContext(),
|
||||
);
|
||||
act(() => result.current.subscribe(keyHandler));
|
||||
|
||||
act(() => {
|
||||
|
|
@ -1371,7 +1434,9 @@ describe('KeypressContext', () => {
|
|||
'A你B好C', // Mixed characters
|
||||
])('should correctly handle string "%s"', async (inputString) => {
|
||||
const keyHandler = vi.fn();
|
||||
const { result } = renderHookWithProviders(() => useKeypressContext());
|
||||
const { result } = await renderHookWithProviders(() =>
|
||||
useKeypressContext(),
|
||||
);
|
||||
act(() => result.current.subscribe(keyHandler));
|
||||
|
||||
act(() => stdin.write(inputString));
|
||||
|
|
@ -1424,7 +1489,7 @@ describe('KeypressContext', () => {
|
|||
if (lang) vi.stubEnv('LANG', lang);
|
||||
if (lcAll) vi.stubEnv('LC_ALL', lcAll);
|
||||
|
||||
const { keyHandler } = setupKeypressTest();
|
||||
const { keyHandler } = await setupKeypressTest();
|
||||
|
||||
act(() => stdin.write(char));
|
||||
|
||||
|
|
|
|||
|
|
@ -62,9 +62,9 @@ describe('MouseContext', () => {
|
|||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
it('should subscribe and unsubscribe a handler', () => {
|
||||
it('should subscribe and unsubscribe a handler', async () => {
|
||||
const handler = vi.fn();
|
||||
const { result } = renderHookWithProviders(() => useMouseContext(), {
|
||||
const { result } = await renderHookWithProviders(() => useMouseContext(), {
|
||||
mouseEventsEnabled: true,
|
||||
});
|
||||
|
||||
|
|
@ -89,11 +89,14 @@ describe('MouseContext', () => {
|
|||
expect(handler).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('should not call handler if not active', () => {
|
||||
it('should not call handler if not active', async () => {
|
||||
const handler = vi.fn();
|
||||
renderHookWithProviders(() => useMouse(handler, { isActive: false }), {
|
||||
mouseEventsEnabled: true,
|
||||
});
|
||||
await renderHookWithProviders(
|
||||
() => useMouse(handler, { isActive: false }),
|
||||
{
|
||||
mouseEventsEnabled: true,
|
||||
},
|
||||
);
|
||||
|
||||
act(() => {
|
||||
stdin.write('\x1b[<0;10;20M');
|
||||
|
|
@ -102,8 +105,8 @@ describe('MouseContext', () => {
|
|||
expect(handler).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should emit SelectionWarning when move event is unhandled and has coordinates', () => {
|
||||
renderHookWithProviders(() => useMouseContext(), {
|
||||
it('should emit SelectionWarning when move event is unhandled and has coordinates', async () => {
|
||||
await renderHookWithProviders(() => useMouseContext(), {
|
||||
mouseEventsEnabled: true,
|
||||
});
|
||||
|
||||
|
|
@ -115,9 +118,9 @@ describe('MouseContext', () => {
|
|||
expect(appEvents.emit).toHaveBeenCalledWith(AppEvent.SelectionWarning);
|
||||
});
|
||||
|
||||
it('should not emit SelectionWarning when move event is handled', () => {
|
||||
it('should not emit SelectionWarning when move event is handled', async () => {
|
||||
const handler = vi.fn().mockReturnValue(true);
|
||||
const { result } = renderHookWithProviders(() => useMouseContext(), {
|
||||
const { result } = await renderHookWithProviders(() => useMouseContext(), {
|
||||
mouseEventsEnabled: true,
|
||||
});
|
||||
|
||||
|
|
@ -217,11 +220,14 @@ describe('MouseContext', () => {
|
|||
}, // Shift + scroll up
|
||||
])(
|
||||
'should recognize sequence "$sequence" as $expected.name',
|
||||
({ sequence, expected }) => {
|
||||
async ({ sequence, expected }) => {
|
||||
const mouseHandler = vi.fn();
|
||||
const { result } = renderHookWithProviders(() => useMouseContext(), {
|
||||
mouseEventsEnabled: true,
|
||||
});
|
||||
const { result } = await renderHookWithProviders(
|
||||
() => useMouseContext(),
|
||||
{
|
||||
mouseEventsEnabled: true,
|
||||
},
|
||||
);
|
||||
act(() => result.current.subscribe(mouseHandler));
|
||||
|
||||
act(() => stdin.write(sequence));
|
||||
|
|
@ -233,9 +239,9 @@ describe('MouseContext', () => {
|
|||
);
|
||||
});
|
||||
|
||||
it('should emit a double-click event when two left-presses occur quickly at the same position', () => {
|
||||
it('should emit a double-click event when two left-presses occur quickly at the same position', async () => {
|
||||
const handler = vi.fn();
|
||||
const { result } = renderHookWithProviders(() => useMouseContext(), {
|
||||
const { result } = await renderHookWithProviders(() => useMouseContext(), {
|
||||
mouseEventsEnabled: true,
|
||||
});
|
||||
|
||||
|
|
@ -265,9 +271,9 @@ describe('MouseContext', () => {
|
|||
);
|
||||
});
|
||||
|
||||
it('should NOT emit a double-click event if clicks are too far apart', () => {
|
||||
it('should NOT emit a double-click event if clicks are too far apart', async () => {
|
||||
const handler = vi.fn();
|
||||
const { result } = renderHookWithProviders(() => useMouseContext(), {
|
||||
const { result } = await renderHookWithProviders(() => useMouseContext(), {
|
||||
mouseEventsEnabled: true,
|
||||
});
|
||||
|
||||
|
|
@ -294,7 +300,7 @@ describe('MouseContext', () => {
|
|||
it('should NOT emit a double-click event if too much time passes', async () => {
|
||||
vi.useFakeTimers();
|
||||
const handler = vi.fn();
|
||||
const { result } = renderHookWithProviders(() => useMouseContext(), {
|
||||
const { result } = await renderHookWithProviders(() => useMouseContext(), {
|
||||
mouseEventsEnabled: true,
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -505,9 +505,7 @@ export const useSlashCommandProcessor = (
|
|||
const props = result.props as Record<string, unknown>;
|
||||
if (
|
||||
!props ||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
typeof props['name'] !== 'string' ||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
typeof props['displayName'] !== 'string' ||
|
||||
!props['definition']
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -38,6 +38,17 @@ vi.mock('./useAtCompletion', () => ({
|
|||
useAtCompletion: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock('./usePromptCompletion', () => ({
|
||||
usePromptCompletion: vi.fn(() => ({
|
||||
text: '',
|
||||
isLoading: false,
|
||||
isActive: false,
|
||||
accept: vi.fn(),
|
||||
clear: vi.fn(),
|
||||
markSelected: vi.fn(),
|
||||
})),
|
||||
}));
|
||||
|
||||
vi.mock('./useSlashCompletion', () => ({
|
||||
useSlashCompletion: vi.fn(() => ({
|
||||
completionStart: 0,
|
||||
|
|
@ -183,13 +194,13 @@ describe('useCommandCompletion', () => {
|
|||
return null;
|
||||
}
|
||||
|
||||
const renderCommandCompletionHook = (
|
||||
const renderCommandCompletionHook = async (
|
||||
initialText: string,
|
||||
cursorOffset?: number,
|
||||
shellModeActive = false,
|
||||
active = true,
|
||||
) => {
|
||||
const renderResult = renderWithProviders(
|
||||
const renderResult = await renderWithProviders(
|
||||
<TestComponent
|
||||
initialText={initialText}
|
||||
cursorOffset={cursorOffset}
|
||||
|
|
@ -219,8 +230,8 @@ describe('useCommandCompletion', () => {
|
|||
|
||||
describe('Core Hook Behavior', () => {
|
||||
describe('State Management', () => {
|
||||
it('should initialize with default state', () => {
|
||||
const { result } = renderCommandCompletionHook('');
|
||||
it('should initialize with default state', async () => {
|
||||
const { result } = await renderCommandCompletionHook('');
|
||||
|
||||
expect(result.current.suggestions).toEqual([]);
|
||||
expect(result.current.activeSuggestionIndex).toBe(-1);
|
||||
|
|
@ -235,7 +246,7 @@ describe('useCommandCompletion', () => {
|
|||
atSuggestions: [{ label: 'src/file.txt', value: 'src/file.txt' }],
|
||||
});
|
||||
|
||||
const { result } = renderCommandCompletionHook('@file');
|
||||
const { result } = await renderCommandCompletionHook('@file');
|
||||
|
||||
await waitFor(() => {
|
||||
expect(result.current.suggestions).toHaveLength(1);
|
||||
|
|
@ -256,8 +267,8 @@ describe('useCommandCompletion', () => {
|
|||
});
|
||||
});
|
||||
|
||||
it('should reset all state to default values', () => {
|
||||
const { result } = renderCommandCompletionHook('@files');
|
||||
it('should reset all state to default values', async () => {
|
||||
const { result } = await renderCommandCompletionHook('@files');
|
||||
|
||||
act(() => {
|
||||
result.current.setActiveSuggestionIndex(5);
|
||||
|
|
@ -274,7 +285,7 @@ describe('useCommandCompletion', () => {
|
|||
|
||||
it('should call useAtCompletion with the correct query for an escaped space', async () => {
|
||||
const text = '@src/a\\ file.txt';
|
||||
const { result } = renderCommandCompletionHook(text);
|
||||
const { result } = await renderCommandCompletionHook(text);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(useAtCompletion).toHaveBeenLastCalledWith(
|
||||
|
|
@ -291,7 +302,7 @@ describe('useCommandCompletion', () => {
|
|||
const text = '@file1 @file2';
|
||||
const cursorOffset = 3; // @fi|le1 @file2
|
||||
|
||||
renderCommandCompletionHook(text, cursorOffset);
|
||||
await renderCommandCompletionHook(text, cursorOffset);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(useAtCompletion).toHaveBeenLastCalledWith(
|
||||
|
|
@ -329,7 +340,7 @@ describe('useCommandCompletion', () => {
|
|||
slashSuggestions: [{ label: 'clear', value: 'clear' }],
|
||||
});
|
||||
|
||||
const { result } = renderCommandCompletionHook(
|
||||
const { result } = await renderCommandCompletionHook(
|
||||
'/',
|
||||
undefined,
|
||||
shellModeActive,
|
||||
|
|
@ -361,10 +372,10 @@ describe('useCommandCompletion', () => {
|
|||
setupMocks({ slashSuggestions: mockSuggestions });
|
||||
});
|
||||
|
||||
it('should handle navigateUp with no suggestions', () => {
|
||||
it('should handle navigateUp with no suggestions', async () => {
|
||||
setupMocks({ slashSuggestions: [] });
|
||||
|
||||
const { result } = renderCommandCompletionHook('/');
|
||||
const { result } = await renderCommandCompletionHook('/');
|
||||
|
||||
act(() => {
|
||||
result.current.navigateUp();
|
||||
|
|
@ -373,9 +384,9 @@ describe('useCommandCompletion', () => {
|
|||
expect(result.current.activeSuggestionIndex).toBe(-1);
|
||||
});
|
||||
|
||||
it('should handle navigateDown with no suggestions', () => {
|
||||
it('should handle navigateDown with no suggestions', async () => {
|
||||
setupMocks({ slashSuggestions: [] });
|
||||
const { result } = renderCommandCompletionHook('/');
|
||||
const { result } = await renderCommandCompletionHook('/');
|
||||
|
||||
act(() => {
|
||||
result.current.navigateDown();
|
||||
|
|
@ -385,7 +396,7 @@ describe('useCommandCompletion', () => {
|
|||
});
|
||||
|
||||
it('should navigate up through suggestions with wrap-around', async () => {
|
||||
const { result } = renderCommandCompletionHook('/');
|
||||
const { result } = await renderCommandCompletionHook('/');
|
||||
|
||||
await waitFor(() => {
|
||||
expect(result.current.suggestions.length).toBe(5);
|
||||
|
|
@ -401,7 +412,7 @@ describe('useCommandCompletion', () => {
|
|||
});
|
||||
|
||||
it('should navigate down through suggestions with wrap-around', async () => {
|
||||
const { result } = renderCommandCompletionHook('/');
|
||||
const { result } = await renderCommandCompletionHook('/');
|
||||
|
||||
await waitFor(() => {
|
||||
expect(result.current.suggestions.length).toBe(5);
|
||||
|
|
@ -420,7 +431,7 @@ describe('useCommandCompletion', () => {
|
|||
});
|
||||
|
||||
it('should handle navigation with multiple suggestions', async () => {
|
||||
const { result } = renderCommandCompletionHook('/');
|
||||
const { result } = await renderCommandCompletionHook('/');
|
||||
|
||||
await waitFor(() => {
|
||||
expect(result.current.suggestions.length).toBe(5);
|
||||
|
|
@ -447,7 +458,7 @@ describe('useCommandCompletion', () => {
|
|||
it('should automatically select the first item when suggestions are available', async () => {
|
||||
setupMocks({ slashSuggestions: mockSuggestions });
|
||||
|
||||
const { result } = renderCommandCompletionHook('/');
|
||||
const { result } = await renderCommandCompletionHook('/');
|
||||
|
||||
await waitFor(() => {
|
||||
expect(result.current.suggestions.length).toBe(
|
||||
|
|
@ -466,7 +477,7 @@ describe('useCommandCompletion', () => {
|
|||
slashCompletionRange: { completionStart: 1, completionEnd: 4 },
|
||||
});
|
||||
|
||||
const { result } = renderCommandCompletionHook('/mem');
|
||||
const { result } = await renderCommandCompletionHook('/mem');
|
||||
|
||||
await waitFor(() => {
|
||||
expect(result.current.suggestions.length).toBe(1);
|
||||
|
|
@ -484,7 +495,7 @@ describe('useCommandCompletion', () => {
|
|||
atSuggestions: [{ label: 'src/file1.txt', value: 'src/file1.txt' }],
|
||||
});
|
||||
|
||||
const { result } = renderCommandCompletionHook('@src/fi');
|
||||
const { result } = await renderCommandCompletionHook('@src/fi');
|
||||
|
||||
await waitFor(() => {
|
||||
expect(result.current.suggestions.length).toBe(1);
|
||||
|
|
@ -509,7 +520,7 @@ describe('useCommandCompletion', () => {
|
|||
slashCompletionRange: { completionStart: 1, completionEnd: 5 },
|
||||
});
|
||||
|
||||
const { result } = renderCommandCompletionHook('/resu');
|
||||
const { result } = await renderCommandCompletionHook('/resu');
|
||||
|
||||
await waitFor(() => {
|
||||
expect(result.current.suggestions.length).toBe(1);
|
||||
|
|
@ -530,7 +541,7 @@ describe('useCommandCompletion', () => {
|
|||
atSuggestions: [{ label: 'src/file1.txt', value: 'src/file1.txt' }],
|
||||
});
|
||||
|
||||
const { result } = renderCommandCompletionHook(text, cursorOffset);
|
||||
const { result } = await renderCommandCompletionHook(text, cursorOffset);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(result.current.suggestions.length).toBe(1);
|
||||
|
|
@ -550,7 +561,7 @@ describe('useCommandCompletion', () => {
|
|||
atSuggestions: [{ label: 'src/components/', value: 'src/components/' }],
|
||||
});
|
||||
|
||||
const { result } = renderCommandCompletionHook('@src/comp');
|
||||
const { result } = await renderCommandCompletionHook('@src/comp');
|
||||
|
||||
await waitFor(() => {
|
||||
expect(result.current.suggestions.length).toBe(1);
|
||||
|
|
@ -570,7 +581,7 @@ describe('useCommandCompletion', () => {
|
|||
],
|
||||
});
|
||||
|
||||
const { result } = renderCommandCompletionHook('@src\\comp');
|
||||
const { result } = await renderCommandCompletionHook('@src\\comp');
|
||||
|
||||
await waitFor(() => {
|
||||
expect(result.current.suggestions.length).toBe(1);
|
||||
|
|
@ -595,7 +606,7 @@ describe('useCommandCompletion', () => {
|
|||
},
|
||||
});
|
||||
|
||||
const { result } = renderCommandCompletionHook(
|
||||
const { result } = await renderCommandCompletionHook(
|
||||
text,
|
||||
text.length,
|
||||
true, // shellModeActive
|
||||
|
|
@ -624,7 +635,7 @@ describe('useCommandCompletion', () => {
|
|||
},
|
||||
});
|
||||
|
||||
const { result } = renderCommandCompletionHook(
|
||||
const { result } = await renderCommandCompletionHook(
|
||||
text,
|
||||
text.length,
|
||||
true, // shellModeActive
|
||||
|
|
@ -642,7 +653,7 @@ describe('useCommandCompletion', () => {
|
|||
const text = 'ls ';
|
||||
const cursorOffset = text.length;
|
||||
|
||||
const { result } = renderCommandCompletionHook(
|
||||
const { result } = await renderCommandCompletionHook(
|
||||
text,
|
||||
cursorOffset,
|
||||
true, // shellModeActive
|
||||
|
|
@ -668,7 +679,7 @@ describe('useCommandCompletion', () => {
|
|||
},
|
||||
});
|
||||
|
||||
const { result } = renderCommandCompletionHook(
|
||||
const { result } = await renderCommandCompletionHook(
|
||||
textWithoutSpace,
|
||||
textWithoutSpace.length,
|
||||
true, // shellModeActive
|
||||
|
|
@ -733,7 +744,7 @@ describe('useCommandCompletion', () => {
|
|||
hookResult = { ...completion, textBuffer };
|
||||
return null;
|
||||
}
|
||||
renderWithProviders(<TestComponent />);
|
||||
await renderWithProviders(<TestComponent />);
|
||||
|
||||
// Should not trigger prompt completion for comments
|
||||
await waitFor(() => {
|
||||
|
|
@ -768,7 +779,7 @@ describe('useCommandCompletion', () => {
|
|||
hookResult = { ...completion, textBuffer };
|
||||
return null;
|
||||
}
|
||||
renderWithProviders(<TestComponent />);
|
||||
await renderWithProviders(<TestComponent />);
|
||||
|
||||
// Should not trigger prompt completion for comments
|
||||
await waitFor(() => {
|
||||
|
|
@ -803,7 +814,7 @@ describe('useCommandCompletion', () => {
|
|||
hookResult = { ...completion, textBuffer };
|
||||
return null;
|
||||
}
|
||||
renderWithProviders(<TestComponent />);
|
||||
await renderWithProviders(<TestComponent />);
|
||||
|
||||
// This test verifies that comments are filtered out while regular text is not
|
||||
await waitFor(() => {
|
||||
|
|
@ -823,7 +834,7 @@ describe('useCommandCompletion', () => {
|
|||
const text = '/mycommand @src/fi';
|
||||
const cursorOffset = text.length;
|
||||
|
||||
renderCommandCompletionHook(text, cursorOffset);
|
||||
await renderCommandCompletionHook(text, cursorOffset);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(useAtCompletion).toHaveBeenLastCalledWith(
|
||||
|
|
@ -843,7 +854,7 @@ describe('useCommandCompletion', () => {
|
|||
const text = '/mycom';
|
||||
const cursorOffset = text.length;
|
||||
|
||||
const { result } = renderCommandCompletionHook(text, cursorOffset);
|
||||
const { result } = await renderCommandCompletionHook(text, cursorOffset);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(result.current.suggestions).toHaveLength(1);
|
||||
|
|
@ -859,7 +870,7 @@ describe('useCommandCompletion', () => {
|
|||
const text = '/command @';
|
||||
const cursorOffset = text.length;
|
||||
|
||||
renderCommandCompletionHook(text, cursorOffset);
|
||||
await renderCommandCompletionHook(text, cursorOffset);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(useAtCompletion).toHaveBeenLastCalledWith(
|
||||
|
|
@ -879,7 +890,7 @@ describe('useCommandCompletion', () => {
|
|||
const text = '/diff @src/foo.ts @src/ba';
|
||||
const cursorOffset = text.length;
|
||||
|
||||
renderCommandCompletionHook(text, cursorOffset);
|
||||
await renderCommandCompletionHook(text, cursorOffset);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(useAtCompletion).toHaveBeenLastCalledWith(
|
||||
|
|
@ -896,7 +907,7 @@ describe('useCommandCompletion', () => {
|
|||
atSuggestions: [{ label: 'src/file.txt', value: 'src/file.txt' }],
|
||||
});
|
||||
|
||||
const { result } = renderCommandCompletionHook('/cmd @src/fi');
|
||||
const { result } = await renderCommandCompletionHook('/cmd @src/fi');
|
||||
|
||||
await waitFor(() => {
|
||||
expect(result.current.suggestions.length).toBe(1);
|
||||
|
|
@ -915,7 +926,7 @@ describe('useCommandCompletion', () => {
|
|||
});
|
||||
|
||||
const text = '/help ';
|
||||
renderCommandCompletionHook(text);
|
||||
await renderCommandCompletionHook(text);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(useSlashCompletion).toHaveBeenLastCalledWith(
|
||||
|
|
|
|||
|
|
@ -47,13 +47,13 @@ describe('useFocus', () => {
|
|||
stdin.removeAllListeners();
|
||||
});
|
||||
|
||||
const renderFocusHook = () => {
|
||||
const renderFocusHook = async () => {
|
||||
let hookResult: ReturnType<typeof useFocus>;
|
||||
function TestComponent() {
|
||||
hookResult = useFocus();
|
||||
return null;
|
||||
}
|
||||
const { unmount } = renderWithProviders(<TestComponent />);
|
||||
const { unmount } = await renderWithProviders(<TestComponent />);
|
||||
return {
|
||||
result: {
|
||||
get current() {
|
||||
|
|
@ -64,15 +64,15 @@ describe('useFocus', () => {
|
|||
};
|
||||
};
|
||||
|
||||
it('should initialize with focus and enable focus reporting', () => {
|
||||
const { result } = renderFocusHook();
|
||||
it('should initialize with focus and enable focus reporting', async () => {
|
||||
const { result } = await renderFocusHook();
|
||||
|
||||
expect(result.current.isFocused).toBe(true);
|
||||
expect(stdout.write).toHaveBeenCalledWith('\x1b[?1004h');
|
||||
});
|
||||
|
||||
it('should set isFocused to false when a focus-out event is received', () => {
|
||||
const { result } = renderFocusHook();
|
||||
it('should set isFocused to false when a focus-out event is received', async () => {
|
||||
const { result } = await renderFocusHook();
|
||||
|
||||
// Initial state is focused
|
||||
expect(result.current.isFocused).toBe(true);
|
||||
|
|
@ -86,8 +86,8 @@ describe('useFocus', () => {
|
|||
expect(result.current.isFocused).toBe(false);
|
||||
});
|
||||
|
||||
it('should set isFocused to true when a focus-in event is received', () => {
|
||||
const { result } = renderFocusHook();
|
||||
it('should set isFocused to true when a focus-in event is received', async () => {
|
||||
const { result } = await renderFocusHook();
|
||||
|
||||
// Simulate focus-out to set initial state to false
|
||||
act(() => {
|
||||
|
|
@ -104,8 +104,8 @@ describe('useFocus', () => {
|
|||
expect(result.current.isFocused).toBe(true);
|
||||
});
|
||||
|
||||
it('should clean up and disable focus reporting on unmount', () => {
|
||||
const { unmount } = renderFocusHook();
|
||||
it('should clean up and disable focus reporting on unmount', async () => {
|
||||
const { unmount } = await renderFocusHook();
|
||||
|
||||
// At this point we should have listeners from both KeypressProvider and useFocus
|
||||
const listenerCountAfterMount = stdin.listenerCount('data');
|
||||
|
|
@ -119,8 +119,8 @@ describe('useFocus', () => {
|
|||
expect(stdin.listenerCount('data')).toBeLessThan(listenerCountAfterMount);
|
||||
});
|
||||
|
||||
it('should handle multiple focus events correctly', () => {
|
||||
const { result } = renderFocusHook();
|
||||
it('should handle multiple focus events correctly', async () => {
|
||||
const { result } = await renderFocusHook();
|
||||
|
||||
act(() => {
|
||||
stdin.emit('data', '\x1b[O');
|
||||
|
|
@ -143,8 +143,8 @@ describe('useFocus', () => {
|
|||
expect(result.current.isFocused).toBe(true);
|
||||
});
|
||||
|
||||
it('restores focus on keypress after focus is lost', () => {
|
||||
const { result } = renderFocusHook();
|
||||
it('restores focus on keypress after focus is lost', async () => {
|
||||
const { result } = await renderFocusHook();
|
||||
|
||||
// Simulate focus-out event
|
||||
act(() => {
|
||||
|
|
@ -159,8 +159,8 @@ describe('useFocus', () => {
|
|||
expect(result.current.isFocused).toBe(true);
|
||||
});
|
||||
|
||||
it('tracks whether any focus event has been received', () => {
|
||||
const { result } = renderFocusHook();
|
||||
it('tracks whether any focus event has been received', async () => {
|
||||
const { result } = await renderFocusHook();
|
||||
|
||||
expect(result.current.hasReceivedFocusEvent).toBe(false);
|
||||
|
||||
|
|
|
|||
|
|
@ -375,7 +375,7 @@ describe('useGeminiStream', () => {
|
|||
setValue: vi.fn(),
|
||||
} as unknown as LoadedSettings;
|
||||
|
||||
const renderTestHook = (
|
||||
const renderTestHook = async (
|
||||
initialToolCalls: TrackedToolCall[] = [],
|
||||
geminiClient?: any,
|
||||
loadedSettings: LoadedSettings = mockLoadedSettings,
|
||||
|
|
@ -436,7 +436,7 @@ describe('useGeminiStream', () => {
|
|||
];
|
||||
});
|
||||
|
||||
const { result, rerender } = renderHookWithProviders(
|
||||
const { result, rerender } = await renderHookWithProviders(
|
||||
(props: typeof initialProps) =>
|
||||
useGeminiStream(
|
||||
props.client,
|
||||
|
|
@ -518,7 +518,7 @@ describe('useGeminiStream', () => {
|
|||
});
|
||||
|
||||
// Helper to render hook with default parameters - reduces boilerplate
|
||||
const renderHookWithDefaults = (
|
||||
const renderHookWithDefaults = async (
|
||||
options: {
|
||||
shellModeActive?: boolean;
|
||||
onCancelSubmit?: () => void;
|
||||
|
|
@ -562,7 +562,7 @@ describe('useGeminiStream', () => {
|
|||
);
|
||||
};
|
||||
|
||||
it('should not submit tool responses if not all tool calls are completed', () => {
|
||||
it('should not submit tool responses if not all tool calls are completed', async () => {
|
||||
const toolCalls: TrackedToolCall[] = [
|
||||
{
|
||||
request: {
|
||||
|
|
@ -617,7 +617,7 @@ describe('useGeminiStream', () => {
|
|||
];
|
||||
|
||||
const { mockMarkToolsAsSubmitted, mockSendMessageStream } =
|
||||
renderTestHook(toolCalls);
|
||||
await renderTestHook(toolCalls);
|
||||
|
||||
// Effect for submitting tool responses depends on toolCalls and isResponding
|
||||
// isResponding is initially false, so the effect should run.
|
||||
|
|
@ -626,7 +626,7 @@ describe('useGeminiStream', () => {
|
|||
expect(mockSendMessageStream).not.toHaveBeenCalled(); // submitQuery uses this
|
||||
});
|
||||
|
||||
it('should expose activePtyId for non-shell executing tools that report an execution ID', () => {
|
||||
it('should expose activePtyId for non-shell executing tools that report an execution ID', async () => {
|
||||
const remoteExecutingTool: TrackedExecutingToolCall = {
|
||||
request: {
|
||||
callId: 'remote-call-1',
|
||||
|
|
@ -651,7 +651,7 @@ describe('useGeminiStream', () => {
|
|||
pid: 4242,
|
||||
};
|
||||
|
||||
const { result } = renderTestHook([remoteExecutingTool]);
|
||||
const { result } = await renderTestHook([remoteExecutingTool]);
|
||||
expect(result.current.activePtyId).toBe(4242);
|
||||
});
|
||||
|
||||
|
|
@ -716,7 +716,7 @@ describe('useGeminiStream', () => {
|
|||
];
|
||||
});
|
||||
|
||||
renderHookWithProviders(() =>
|
||||
await renderHookWithProviders(() =>
|
||||
useGeminiStream(
|
||||
new MockedGeminiClientClass(mockConfig),
|
||||
[],
|
||||
|
|
@ -817,7 +817,7 @@ describe('useGeminiStream', () => {
|
|||
];
|
||||
});
|
||||
|
||||
renderHookWithProviders(() =>
|
||||
await renderHookWithProviders(() =>
|
||||
useGeminiStream(
|
||||
new MockedGeminiClientClass(mockConfig),
|
||||
[],
|
||||
|
|
@ -927,7 +927,7 @@ describe('useGeminiStream', () => {
|
|||
];
|
||||
});
|
||||
|
||||
renderHookWithProviders(() =>
|
||||
await renderHookWithProviders(() =>
|
||||
useGeminiStream(
|
||||
client,
|
||||
[],
|
||||
|
|
@ -998,7 +998,7 @@ describe('useGeminiStream', () => {
|
|||
];
|
||||
const client = new MockedGeminiClientClass(mockConfig);
|
||||
|
||||
const { result } = renderTestHook([], client);
|
||||
const { result } = await renderTestHook([], client);
|
||||
|
||||
// Trigger the onComplete callback with STOP_EXECUTION tool
|
||||
await act(async () => {
|
||||
|
|
@ -1077,7 +1077,7 @@ describe('useGeminiStream', () => {
|
|||
} as LoadedSettings;
|
||||
const client = new MockedGeminiClientClass(mockConfig);
|
||||
|
||||
const { result } = renderTestHook([], client, lowVerbositySettings);
|
||||
const { result } = await renderTestHook([], client, lowVerbositySettings);
|
||||
|
||||
await act(async () => {
|
||||
if (capturedOnComplete) {
|
||||
|
|
@ -1190,7 +1190,7 @@ describe('useGeminiStream', () => {
|
|||
];
|
||||
});
|
||||
|
||||
renderHookWithProviders(() =>
|
||||
await renderHookWithProviders(() =>
|
||||
useGeminiStream(
|
||||
client,
|
||||
[],
|
||||
|
|
@ -1307,7 +1307,7 @@ describe('useGeminiStream', () => {
|
|||
];
|
||||
});
|
||||
|
||||
const { result, rerender } = renderHookWithProviders(() =>
|
||||
const { result, rerender } = await renderHookWithProviders(() =>
|
||||
useGeminiStream(
|
||||
new MockedGeminiClientClass(mockConfig),
|
||||
[],
|
||||
|
|
@ -1408,7 +1408,7 @@ describe('useGeminiStream', () => {
|
|||
})();
|
||||
mockSendMessageStream.mockReturnValue(mockStream);
|
||||
|
||||
const { result } = renderTestHook();
|
||||
const { result } = await renderTestHook();
|
||||
|
||||
// Start a query
|
||||
await act(async () => {
|
||||
|
|
@ -1445,7 +1445,7 @@ describe('useGeminiStream', () => {
|
|||
})();
|
||||
mockSendMessageStream.mockReturnValue(mockStream);
|
||||
|
||||
const { result } = renderHookWithProviders(() =>
|
||||
const { result } = await renderHookWithProviders(() =>
|
||||
useGeminiStream(
|
||||
mockConfig.getGeminiClient(),
|
||||
[],
|
||||
|
|
@ -1486,7 +1486,7 @@ describe('useGeminiStream', () => {
|
|||
})();
|
||||
mockSendMessageStream.mockReturnValue(mockStream);
|
||||
|
||||
const { result } = renderHookWithProviders(() =>
|
||||
const { result } = await renderHookWithProviders(() =>
|
||||
useGeminiStream(
|
||||
mockConfig.getGeminiClient(),
|
||||
[],
|
||||
|
|
@ -1519,8 +1519,8 @@ describe('useGeminiStream', () => {
|
|||
expect(setShellInputFocusedSpy).toHaveBeenCalledWith(false);
|
||||
});
|
||||
|
||||
it('should not do anything if escape is pressed when not responding', () => {
|
||||
const { result } = renderTestHook();
|
||||
it('should not do anything if escape is pressed when not responding', async () => {
|
||||
const { result } = await renderTestHook();
|
||||
|
||||
expect(result.current.streamingState).toBe(StreamingState.Idle);
|
||||
|
||||
|
|
@ -1548,7 +1548,7 @@ describe('useGeminiStream', () => {
|
|||
})();
|
||||
mockSendMessageStream.mockReturnValue(mockStream);
|
||||
|
||||
const { result } = renderTestHook();
|
||||
const { result } = await renderTestHook();
|
||||
|
||||
await act(async () => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
|
|
@ -1600,7 +1600,7 @@ describe('useGeminiStream', () => {
|
|||
} as TrackedExecutingToolCall,
|
||||
];
|
||||
|
||||
const { result } = renderTestHook(toolCalls);
|
||||
const { result } = await renderTestHook(toolCalls);
|
||||
|
||||
// State is `Responding` because a tool is running
|
||||
expect(result.current.streamingState).toBe(StreamingState.Responding);
|
||||
|
|
@ -1648,7 +1648,7 @@ describe('useGeminiStream', () => {
|
|||
} as TrackedWaitingToolCall,
|
||||
];
|
||||
|
||||
const { result } = renderTestHook(toolCalls);
|
||||
const { result } = await renderTestHook(toolCalls);
|
||||
|
||||
// State is `WaitingForConfirmation` because a tool is awaiting approval
|
||||
expect(result.current.streamingState).toBe(
|
||||
|
|
@ -1677,7 +1677,7 @@ describe('useGeminiStream', () => {
|
|||
|
||||
describe('Retry Handling', () => {
|
||||
it('should update retryStatus when CoreEvent.RetryAttempt is emitted', async () => {
|
||||
const { result } = renderHookWithDefaults();
|
||||
const { result } = await renderHookWithDefaults();
|
||||
|
||||
const retryPayload = {
|
||||
model: 'gemini-2.5-pro',
|
||||
|
|
@ -1694,7 +1694,7 @@ describe('useGeminiStream', () => {
|
|||
});
|
||||
|
||||
it('should reset retryStatus when isResponding becomes false', async () => {
|
||||
const { result } = renderTestHook();
|
||||
const { result } = await renderTestHook();
|
||||
|
||||
const retryPayload = {
|
||||
model: 'gemini-2.5-pro',
|
||||
|
|
@ -1744,7 +1744,7 @@ describe('useGeminiStream', () => {
|
|||
};
|
||||
mockHandleSlashCommand.mockResolvedValue(clientToolRequest);
|
||||
|
||||
const { result } = renderTestHook();
|
||||
const { result } = await renderTestHook();
|
||||
|
||||
await act(async () => {
|
||||
await result.current.submitQuery('/memory add "test fact"');
|
||||
|
|
@ -1771,7 +1771,7 @@ describe('useGeminiStream', () => {
|
|||
};
|
||||
mockHandleSlashCommand.mockResolvedValue(uiOnlyCommandResult);
|
||||
|
||||
const { result } = renderTestHook();
|
||||
const { result } = await renderTestHook();
|
||||
|
||||
await act(async () => {
|
||||
await result.current.submitQuery('/help');
|
||||
|
|
@ -1792,7 +1792,7 @@ describe('useGeminiStream', () => {
|
|||
mockHandleSlashCommand.mockResolvedValue(customCommandResult);
|
||||
|
||||
const { result, mockSendMessageStream: localMockSendMessageStream } =
|
||||
renderTestHook();
|
||||
await renderTestHook();
|
||||
|
||||
await act(async () => {
|
||||
await result.current.submitQuery('/my-custom-command');
|
||||
|
|
@ -1830,7 +1830,7 @@ describe('useGeminiStream', () => {
|
|||
mockHandleSlashCommand.mockResolvedValue(emptyPromptResult);
|
||||
|
||||
const { result, mockSendMessageStream: localMockSendMessageStream } =
|
||||
renderTestHook();
|
||||
await renderTestHook();
|
||||
|
||||
await act(async () => {
|
||||
await result.current.submitQuery('/emptycmd');
|
||||
|
|
@ -1851,7 +1851,7 @@ describe('useGeminiStream', () => {
|
|||
|
||||
it('should not call handleSlashCommand for line comments', async () => {
|
||||
const { result, mockSendMessageStream: localMockSendMessageStream } =
|
||||
renderTestHook();
|
||||
await renderTestHook();
|
||||
|
||||
await act(async () => {
|
||||
await result.current.submitQuery('// This is a line comment');
|
||||
|
|
@ -1872,7 +1872,7 @@ describe('useGeminiStream', () => {
|
|||
|
||||
it('should not call handleSlashCommand for block comments', async () => {
|
||||
const { result, mockSendMessageStream: localMockSendMessageStream } =
|
||||
renderTestHook();
|
||||
await renderTestHook();
|
||||
|
||||
await act(async () => {
|
||||
await result.current.submitQuery('/* This is a block comment */');
|
||||
|
|
@ -1892,7 +1892,7 @@ describe('useGeminiStream', () => {
|
|||
});
|
||||
|
||||
it('should not call handleSlashCommand is shell mode is active', async () => {
|
||||
const { result } = renderHookWithProviders(() =>
|
||||
const { result } = await renderHookWithProviders(() =>
|
||||
useGeminiStream(
|
||||
new MockedGeminiClientClass(mockConfig),
|
||||
[],
|
||||
|
|
@ -1972,7 +1972,7 @@ describe('useGeminiStream', () => {
|
|||
];
|
||||
});
|
||||
|
||||
renderHookWithProviders(() =>
|
||||
await renderHookWithProviders(() =>
|
||||
useGeminiStream(
|
||||
new MockedGeminiClientClass(mockConfig),
|
||||
[],
|
||||
|
|
@ -2031,7 +2031,7 @@ describe('useGeminiStream', () => {
|
|||
getModel: vi.fn(() => 'gemini-2.5-pro'),
|
||||
} as unknown as Config;
|
||||
|
||||
const { result } = renderHookWithProviders(() =>
|
||||
const { result } = await renderHookWithProviders(() =>
|
||||
useGeminiStream(
|
||||
new MockedGeminiClientClass(testConfig),
|
||||
[],
|
||||
|
|
@ -2078,7 +2078,7 @@ describe('useGeminiStream', () => {
|
|||
createMockToolCall('read_file', 'call2', 'info'),
|
||||
];
|
||||
|
||||
const { result } = renderTestHook(awaitingApprovalToolCalls);
|
||||
const { result } = await renderTestHook(awaitingApprovalToolCalls);
|
||||
|
||||
await act(async () => {
|
||||
await result.current.handleApprovalModeChange(ApprovalMode.YOLO);
|
||||
|
|
@ -2108,7 +2108,7 @@ describe('useGeminiStream', () => {
|
|||
createMockToolCall('read_file', 'call3', 'info'),
|
||||
];
|
||||
|
||||
const { result } = renderTestHook(awaitingApprovalToolCalls);
|
||||
const { result } = await renderTestHook(awaitingApprovalToolCalls);
|
||||
|
||||
await act(async () => {
|
||||
await result.current.handleApprovalModeChange(ApprovalMode.AUTO_EDIT);
|
||||
|
|
@ -2132,7 +2132,7 @@ describe('useGeminiStream', () => {
|
|||
createMockToolCall('replace', 'call1', 'edit'),
|
||||
];
|
||||
|
||||
const { result } = renderTestHook(awaitingApprovalToolCalls);
|
||||
const { result } = await renderTestHook(awaitingApprovalToolCalls);
|
||||
|
||||
await act(async () => {
|
||||
await result.current.handleApprovalModeChange(ApprovalMode.DEFAULT);
|
||||
|
|
@ -2154,7 +2154,7 @@ describe('useGeminiStream', () => {
|
|||
createMockToolCall('write_file', 'call2', 'edit'),
|
||||
];
|
||||
|
||||
const { result } = renderTestHook(awaitingApprovalToolCalls);
|
||||
const { result } = await renderTestHook(awaitingApprovalToolCalls);
|
||||
|
||||
await act(async () => {
|
||||
await result.current.handleApprovalModeChange(ApprovalMode.YOLO);
|
||||
|
|
@ -2196,7 +2196,7 @@ describe('useGeminiStream', () => {
|
|||
} as unknown as TrackedWaitingToolCall,
|
||||
];
|
||||
|
||||
const { result } = renderTestHook(awaitingApprovalToolCalls);
|
||||
const { result } = await renderTestHook(awaitingApprovalToolCalls);
|
||||
|
||||
// Should not throw an error
|
||||
await act(async () => {
|
||||
|
|
@ -2239,7 +2239,7 @@ describe('useGeminiStream', () => {
|
|||
} as TrackedExecutingToolCall,
|
||||
];
|
||||
|
||||
const { result } = renderTestHook(mixedStatusToolCalls);
|
||||
const { result } = await renderTestHook(mixedStatusToolCalls);
|
||||
|
||||
await act(async () => {
|
||||
await result.current.handleApprovalModeChange(ApprovalMode.YOLO);
|
||||
|
|
@ -2260,7 +2260,7 @@ describe('useGeminiStream', () => {
|
|||
(mockConfig.getApprovalMode as Mock).mockReturnValue(ApprovalMode.PLAN);
|
||||
|
||||
// Render the hook, which will initialize the previousApprovalModeRef with PLAN
|
||||
const { result, client } = renderTestHook([]);
|
||||
const { result, client } = await renderTestHook([]);
|
||||
|
||||
// Update mockConfig to return DEFAULT mode (new mode)
|
||||
(mockConfig.getApprovalMode as Mock).mockReturnValue(
|
||||
|
|
@ -2300,7 +2300,7 @@ describe('useGeminiStream', () => {
|
|||
})(),
|
||||
);
|
||||
|
||||
const { result } = renderHookWithProviders(() =>
|
||||
const { result } = await renderHookWithProviders(() =>
|
||||
useGeminiStream(
|
||||
new MockedGeminiClientClass(mockConfig),
|
||||
[],
|
||||
|
|
@ -2374,7 +2374,7 @@ describe('useGeminiStream', () => {
|
|||
})(),
|
||||
);
|
||||
|
||||
const { result } = renderHookWithDefaults();
|
||||
const { result } = await renderHookWithDefaults();
|
||||
|
||||
await act(async () => {
|
||||
await result.current.submitQuery('Test overflow');
|
||||
|
|
@ -2405,7 +2405,7 @@ describe('useGeminiStream', () => {
|
|||
})(),
|
||||
);
|
||||
|
||||
const { result } = renderHookWithProviders(() =>
|
||||
const { result } = await renderHookWithProviders(() =>
|
||||
useGeminiStream(
|
||||
new MockedGeminiClientClass(mockConfig),
|
||||
[],
|
||||
|
|
@ -2454,7 +2454,7 @@ describe('useGeminiStream', () => {
|
|||
})(),
|
||||
);
|
||||
|
||||
const { result } = renderHookWithDefaults();
|
||||
const { result } = await renderHookWithDefaults();
|
||||
|
||||
// Submit a query
|
||||
await act(async () => {
|
||||
|
|
@ -2541,7 +2541,7 @@ describe('useGeminiStream', () => {
|
|||
})(),
|
||||
);
|
||||
|
||||
const { result } = renderHookWithDefaults();
|
||||
const { result } = await renderHookWithDefaults();
|
||||
|
||||
await act(async () => {
|
||||
await result.current.submitQuery(`Test ${reason}`);
|
||||
|
|
@ -2613,7 +2613,7 @@ describe('useGeminiStream', () => {
|
|||
];
|
||||
});
|
||||
|
||||
const { result } = renderHookWithProviders(() =>
|
||||
const { result } = await renderHookWithProviders(() =>
|
||||
useGeminiStream(
|
||||
new MockedGeminiClientClass(mockConfig),
|
||||
[],
|
||||
|
|
@ -2684,7 +2684,7 @@ describe('useGeminiStream', () => {
|
|||
shouldProceed: true,
|
||||
});
|
||||
|
||||
const { result } = renderHookWithProviders(() =>
|
||||
const { result } = await renderHookWithProviders(() =>
|
||||
useGeminiStream(
|
||||
mockConfig.getGeminiClient(),
|
||||
[],
|
||||
|
|
@ -2777,7 +2777,7 @@ describe('useGeminiStream', () => {
|
|||
})(),
|
||||
);
|
||||
|
||||
const { result } = renderTestHook();
|
||||
const { result } = await renderTestHook();
|
||||
|
||||
await act(async () => {
|
||||
await result.current.submitQuery(userQuery);
|
||||
|
|
@ -2849,7 +2849,7 @@ describe('useGeminiStream', () => {
|
|||
})(),
|
||||
);
|
||||
|
||||
const { result } = renderHookWithProviders(() =>
|
||||
const { result } = await renderHookWithProviders(() =>
|
||||
useGeminiStream(
|
||||
new MockedGeminiClientClass(mockConfig),
|
||||
[],
|
||||
|
|
@ -2904,7 +2904,7 @@ describe('useGeminiStream', () => {
|
|||
})(),
|
||||
);
|
||||
|
||||
const { result } = renderTestHook();
|
||||
const { result } = await renderTestHook();
|
||||
|
||||
await act(async () => {
|
||||
await result.current.submitQuery('Test query');
|
||||
|
|
@ -2949,7 +2949,7 @@ describe('useGeminiStream', () => {
|
|||
})(),
|
||||
);
|
||||
|
||||
const { result } = renderHookWithProviders(() =>
|
||||
const { result } = await renderHookWithProviders(() =>
|
||||
useGeminiStream(
|
||||
new MockedGeminiClientClass(mockConfig),
|
||||
[],
|
||||
|
|
@ -3021,7 +3021,7 @@ describe('useGeminiStream', () => {
|
|||
});
|
||||
});
|
||||
|
||||
it('should memoize pendingHistoryItems', () => {
|
||||
it('should memoize pendingHistoryItems', async () => {
|
||||
mockUseToolScheduler.mockReturnValue([
|
||||
[],
|
||||
mockScheduleToolCalls,
|
||||
|
|
@ -3031,7 +3031,7 @@ describe('useGeminiStream', () => {
|
|||
0,
|
||||
]);
|
||||
|
||||
const { result, rerender } = renderHookWithProviders(() =>
|
||||
const { result, rerender } = await renderHookWithProviders(() =>
|
||||
useGeminiStream(
|
||||
mockConfig.getGeminiClient(),
|
||||
[],
|
||||
|
|
@ -3102,7 +3102,7 @@ describe('useGeminiStream', () => {
|
|||
})(),
|
||||
);
|
||||
|
||||
const { result } = renderHookWithProviders(() =>
|
||||
const { result } = await renderHookWithProviders(() =>
|
||||
useGeminiStream(
|
||||
new MockedGeminiClientClass(mockConfig),
|
||||
[],
|
||||
|
|
@ -3159,7 +3159,7 @@ describe('useGeminiStream', () => {
|
|||
})(),
|
||||
);
|
||||
|
||||
const { result } = renderHookWithProviders(() =>
|
||||
const { result } = await renderHookWithProviders(() =>
|
||||
useGeminiStream(
|
||||
new MockedGeminiClientClass(mockConfig),
|
||||
[],
|
||||
|
|
@ -3227,7 +3227,7 @@ describe('useGeminiStream', () => {
|
|||
})(),
|
||||
);
|
||||
|
||||
const { result } = renderHookWithProviders(() =>
|
||||
const { result } = await renderHookWithProviders(() =>
|
||||
useGeminiStream(
|
||||
new MockedGeminiClientClass(mockConfig),
|
||||
[],
|
||||
|
|
@ -3287,7 +3287,7 @@ describe('useGeminiStream', () => {
|
|||
})(),
|
||||
);
|
||||
|
||||
const { result } = renderTestHook();
|
||||
const { result } = await renderTestHook();
|
||||
|
||||
await act(async () => {
|
||||
await result.current.submitQuery('test query');
|
||||
|
|
@ -3334,7 +3334,7 @@ describe('useGeminiStream', () => {
|
|||
})(),
|
||||
);
|
||||
|
||||
const { result } = renderTestHook();
|
||||
const { result } = await renderTestHook();
|
||||
|
||||
await act(async () => {
|
||||
await result.current.submitQuery('test query');
|
||||
|
|
@ -3399,7 +3399,7 @@ describe('useGeminiStream', () => {
|
|||
})(),
|
||||
);
|
||||
|
||||
const { result } = renderTestHook();
|
||||
const { result } = await renderTestHook();
|
||||
|
||||
await act(async () => {
|
||||
await result.current.submitQuery('test query');
|
||||
|
|
@ -3434,7 +3434,7 @@ describe('useGeminiStream', () => {
|
|||
});
|
||||
|
||||
it('should handle multiple loop detection events properly', async () => {
|
||||
const { result } = renderTestHook();
|
||||
const { result } = await renderTestHook();
|
||||
|
||||
// First loop detection - set up fresh mock for first call
|
||||
mockSendMessageStream.mockReturnValueOnce(
|
||||
|
|
@ -3544,7 +3544,7 @@ describe('useGeminiStream', () => {
|
|||
})(),
|
||||
);
|
||||
|
||||
const { result } = renderTestHook();
|
||||
const { result } = await renderTestHook();
|
||||
|
||||
await act(async () => {
|
||||
await result.current.submitQuery('test query');
|
||||
|
|
@ -3581,7 +3581,7 @@ describe('useGeminiStream', () => {
|
|||
})(),
|
||||
);
|
||||
|
||||
const { result } = renderTestHook();
|
||||
const { result } = await renderTestHook();
|
||||
|
||||
// Start first query without awaiting (fire-and-forget, like existing tests)
|
||||
await act(async () => {
|
||||
|
|
@ -3637,7 +3637,7 @@ describe('useGeminiStream', () => {
|
|||
})(),
|
||||
);
|
||||
|
||||
const { result } = renderTestHook();
|
||||
const { result } = await renderTestHook();
|
||||
|
||||
await act(async () => {
|
||||
await result.current.submitQuery('test query');
|
||||
|
|
@ -3692,7 +3692,7 @@ describe('useGeminiStream', () => {
|
|||
})(),
|
||||
);
|
||||
|
||||
const { result } = renderTestHook();
|
||||
const { result } = await renderTestHook();
|
||||
|
||||
await act(async () => {
|
||||
await result.current.submitQuery('test stop');
|
||||
|
|
@ -3720,7 +3720,7 @@ describe('useGeminiStream', () => {
|
|||
})(),
|
||||
);
|
||||
|
||||
const { result } = renderTestHook();
|
||||
const { result } = await renderTestHook();
|
||||
|
||||
await act(async () => {
|
||||
await result.current.submitQuery('test stop');
|
||||
|
|
@ -3751,7 +3751,7 @@ describe('useGeminiStream', () => {
|
|||
})(),
|
||||
);
|
||||
|
||||
const { result } = renderTestHook();
|
||||
const { result } = await renderTestHook();
|
||||
|
||||
await act(async () => {
|
||||
await result.current.submitQuery('test block');
|
||||
|
|
@ -3778,7 +3778,7 @@ describe('useGeminiStream', () => {
|
|||
})(),
|
||||
);
|
||||
|
||||
const { result } = renderTestHook();
|
||||
const { result } = await renderTestHook();
|
||||
|
||||
await act(async () => {
|
||||
await result.current.submitQuery('test block');
|
||||
|
|
@ -3807,7 +3807,7 @@ describe('useGeminiStream', () => {
|
|||
})(),
|
||||
);
|
||||
|
||||
const { result } = renderTestHook();
|
||||
const { result } = await renderTestHook();
|
||||
|
||||
await act(async () => {
|
||||
await result.current.submitQuery('user query');
|
||||
|
|
@ -3855,7 +3855,7 @@ describe('useGeminiStream', () => {
|
|||
})(),
|
||||
);
|
||||
|
||||
const { result } = renderTestHook();
|
||||
const { result } = await renderTestHook();
|
||||
|
||||
await act(async () => {
|
||||
await result.current.submitQuery('user query');
|
||||
|
|
@ -3881,7 +3881,7 @@ describe('useGeminiStream', () => {
|
|||
});
|
||||
|
||||
it('should trace UserPrompt telemetry on submitQuery', async () => {
|
||||
const { result } = renderTestHook();
|
||||
const { result } = await renderTestHook();
|
||||
|
||||
mockSendMessageStream.mockReturnValue(
|
||||
(async function* () {
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ describe(`useKeypress`, () => {
|
|||
const onKeypress = vi.fn();
|
||||
let originalNodeVersion: string;
|
||||
|
||||
const renderKeypressHook = (isActive = true) =>
|
||||
const renderKeypressHook = async (isActive = true) =>
|
||||
renderHookWithProviders(() => useKeypress(onKeypress, { isActive }));
|
||||
|
||||
beforeEach(() => {
|
||||
|
|
@ -66,8 +66,8 @@ describe(`useKeypress`, () => {
|
|||
});
|
||||
});
|
||||
|
||||
it('should not listen if isActive is false', () => {
|
||||
renderKeypressHook(false);
|
||||
it('should not listen if isActive is false', async () => {
|
||||
await renderKeypressHook(false);
|
||||
act(() => stdin.write('a'));
|
||||
expect(onKeypress).not.toHaveBeenCalled();
|
||||
});
|
||||
|
|
@ -79,28 +79,31 @@ describe(`useKeypress`, () => {
|
|||
{ key: { name: 'up', sequence: '\x1b[A' } },
|
||||
{ key: { name: 'down', sequence: '\x1b[B' } },
|
||||
{ key: { name: 'tab', sequence: '\x1b[Z', shift: true } },
|
||||
])('should listen for keypress when active for key $key.name', ({ key }) => {
|
||||
renderKeypressHook(true);
|
||||
act(() => stdin.write(key.sequence));
|
||||
expect(onKeypress).toHaveBeenCalledWith(expect.objectContaining(key));
|
||||
});
|
||||
])(
|
||||
'should listen for keypress when active for key $key.name',
|
||||
async ({ key }) => {
|
||||
await renderKeypressHook(true);
|
||||
act(() => stdin.write(key.sequence));
|
||||
expect(onKeypress).toHaveBeenCalledWith(expect.objectContaining(key));
|
||||
},
|
||||
);
|
||||
|
||||
it('should set and release raw mode', () => {
|
||||
const { unmount } = renderKeypressHook(true);
|
||||
it('should set and release raw mode', async () => {
|
||||
const { unmount } = await renderKeypressHook(true);
|
||||
expect(mockSetRawMode).toHaveBeenCalledWith(true);
|
||||
unmount();
|
||||
expect(mockSetRawMode).toHaveBeenCalledWith(false);
|
||||
});
|
||||
|
||||
it('should stop listening after being unmounted', () => {
|
||||
const { unmount } = renderKeypressHook(true);
|
||||
it('should stop listening after being unmounted', async () => {
|
||||
const { unmount } = await renderKeypressHook(true);
|
||||
unmount();
|
||||
act(() => stdin.write('a'));
|
||||
expect(onKeypress).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should correctly identify alt+enter (meta key)', () => {
|
||||
renderKeypressHook(true);
|
||||
it('should correctly identify alt+enter (meta key)', async () => {
|
||||
await renderKeypressHook(true);
|
||||
const key = { name: 'enter', sequence: '\x1B\r' };
|
||||
act(() => stdin.write(key.sequence));
|
||||
expect(onKeypress).toHaveBeenCalledWith(
|
||||
|
|
@ -128,8 +131,8 @@ describe(`useKeypress`, () => {
|
|||
setup();
|
||||
});
|
||||
|
||||
it('should process a paste as a single event', () => {
|
||||
renderKeypressHook(true);
|
||||
it('should process a paste as a single event', async () => {
|
||||
await renderKeypressHook(true);
|
||||
const pasteText = 'hello world';
|
||||
act(() => stdin.write(PASTE_START + pasteText + PASTE_END));
|
||||
|
||||
|
|
@ -145,8 +148,8 @@ describe(`useKeypress`, () => {
|
|||
});
|
||||
});
|
||||
|
||||
it('should handle keypress interspersed with pastes', () => {
|
||||
renderKeypressHook(true);
|
||||
it('should handle keypress interspersed with pastes', async () => {
|
||||
await renderKeypressHook(true);
|
||||
|
||||
const keyA = { name: 'a', sequence: 'a' };
|
||||
act(() => stdin.write('a'));
|
||||
|
|
@ -169,8 +172,8 @@ describe(`useKeypress`, () => {
|
|||
expect(onKeypress).toHaveBeenCalledTimes(3);
|
||||
});
|
||||
|
||||
it('should handle lone pastes', () => {
|
||||
renderKeypressHook(true);
|
||||
it('should handle lone pastes', async () => {
|
||||
await renderKeypressHook(true);
|
||||
|
||||
const pasteText = 'pasted';
|
||||
act(() => {
|
||||
|
|
@ -184,7 +187,7 @@ describe(`useKeypress`, () => {
|
|||
});
|
||||
|
||||
it('should handle paste false alarm', async () => {
|
||||
renderKeypressHook(true);
|
||||
await renderKeypressHook(true);
|
||||
|
||||
act(() => {
|
||||
stdin.write(PASTE_START.slice(0, 5));
|
||||
|
|
@ -200,8 +203,8 @@ describe(`useKeypress`, () => {
|
|||
expect(onKeypress).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
|
||||
it('should handle back to back pastes', () => {
|
||||
renderKeypressHook(true);
|
||||
it('should handle back to back pastes', async () => {
|
||||
await renderKeypressHook(true);
|
||||
|
||||
const pasteText1 = 'herp';
|
||||
const pasteText2 = 'derp';
|
||||
|
|
@ -226,7 +229,7 @@ describe(`useKeypress`, () => {
|
|||
});
|
||||
|
||||
it('should handle pastes split across writes', async () => {
|
||||
renderKeypressHook(true);
|
||||
await renderKeypressHook(true);
|
||||
|
||||
const keyA = { name: 'a', sequence: 'a' };
|
||||
act(() => stdin.write('a'));
|
||||
|
|
|
|||
|
|
@ -30,10 +30,10 @@ describe('useReverseSearchCompletion', () => {
|
|||
|
||||
describe('Core Hook Behavior', () => {
|
||||
describe('State Management', () => {
|
||||
it('should initialize with default state', () => {
|
||||
it('should initialize with default state', async () => {
|
||||
const mockShellHistory = ['echo hello'];
|
||||
|
||||
const { result } = renderHookWithProviders(() =>
|
||||
const { result } = await renderHookWithProviders(() =>
|
||||
useReverseSearchCompletion(
|
||||
useTextBufferForTest(''),
|
||||
mockShellHistory,
|
||||
|
|
@ -48,9 +48,9 @@ describe('useReverseSearchCompletion', () => {
|
|||
expect(result.current.isLoadingSuggestions).toBe(false);
|
||||
});
|
||||
|
||||
it('should reset state when reverseSearchActive becomes false', () => {
|
||||
it('should reset state when reverseSearchActive becomes false', async () => {
|
||||
const mockShellHistory = ['echo hello'];
|
||||
const { result, rerender } = renderHookWithProviders(
|
||||
const { result, rerender } = await renderHookWithProviders(
|
||||
({ text, active }) => {
|
||||
const textBuffer = useTextBufferForTest(text);
|
||||
return useReverseSearchCompletion(
|
||||
|
|
@ -72,10 +72,10 @@ describe('useReverseSearchCompletion', () => {
|
|||
});
|
||||
|
||||
describe('Navigation', () => {
|
||||
it('should handle navigateUp with no suggestions', () => {
|
||||
it('should handle navigateUp with no suggestions', async () => {
|
||||
const mockShellHistory = ['echo hello'];
|
||||
|
||||
const { result } = renderHookWithProviders(() =>
|
||||
const { result } = await renderHookWithProviders(() =>
|
||||
useReverseSearchCompletion(
|
||||
useTextBufferForTest('grep'),
|
||||
mockShellHistory,
|
||||
|
|
@ -90,9 +90,9 @@ describe('useReverseSearchCompletion', () => {
|
|||
expect(result.current.activeSuggestionIndex).toBe(-1);
|
||||
});
|
||||
|
||||
it('should handle navigateDown with no suggestions', () => {
|
||||
it('should handle navigateDown with no suggestions', async () => {
|
||||
const mockShellHistory = ['echo hello'];
|
||||
const { result } = renderHookWithProviders(() =>
|
||||
const { result } = await renderHookWithProviders(() =>
|
||||
useReverseSearchCompletion(
|
||||
useTextBufferForTest('grep'),
|
||||
mockShellHistory,
|
||||
|
|
@ -107,7 +107,7 @@ describe('useReverseSearchCompletion', () => {
|
|||
expect(result.current.activeSuggestionIndex).toBe(-1);
|
||||
});
|
||||
|
||||
it('should navigate up through suggestions with wrap-around', () => {
|
||||
it('should navigate up through suggestions with wrap-around', async () => {
|
||||
const mockShellHistory = [
|
||||
'ls -l',
|
||||
'ls -la',
|
||||
|
|
@ -117,7 +117,7 @@ describe('useReverseSearchCompletion', () => {
|
|||
'echo Hi',
|
||||
];
|
||||
|
||||
const { result } = renderHookWithProviders(() =>
|
||||
const { result } = await renderHookWithProviders(() =>
|
||||
useReverseSearchCompletion(
|
||||
useTextBufferForTest('echo'),
|
||||
mockShellHistory,
|
||||
|
|
@ -135,7 +135,7 @@ describe('useReverseSearchCompletion', () => {
|
|||
expect(result.current.activeSuggestionIndex).toBe(1);
|
||||
});
|
||||
|
||||
it('should navigate down through suggestions with wrap-around', () => {
|
||||
it('should navigate down through suggestions with wrap-around', async () => {
|
||||
const mockShellHistory = [
|
||||
'ls -l',
|
||||
'ls -la',
|
||||
|
|
@ -144,7 +144,7 @@ describe('useReverseSearchCompletion', () => {
|
|||
'echo "Hello, World!"',
|
||||
'echo Hi',
|
||||
];
|
||||
const { result } = renderHookWithProviders(() =>
|
||||
const { result } = await renderHookWithProviders(() =>
|
||||
useReverseSearchCompletion(
|
||||
useTextBufferForTest('ls'),
|
||||
mockShellHistory,
|
||||
|
|
@ -162,7 +162,7 @@ describe('useReverseSearchCompletion', () => {
|
|||
expect(result.current.activeSuggestionIndex).toBe(1);
|
||||
});
|
||||
|
||||
it('should handle navigation with multiple suggestions', () => {
|
||||
it('should handle navigation with multiple suggestions', async () => {
|
||||
const mockShellHistory = [
|
||||
'ls -l',
|
||||
'ls -la',
|
||||
|
|
@ -172,7 +172,7 @@ describe('useReverseSearchCompletion', () => {
|
|||
'echo "Hi all"',
|
||||
];
|
||||
|
||||
const { result } = renderHookWithProviders(() =>
|
||||
const { result } = await renderHookWithProviders(() =>
|
||||
useReverseSearchCompletion(
|
||||
useTextBufferForTest('l'),
|
||||
mockShellHistory,
|
||||
|
|
@ -209,13 +209,13 @@ describe('useReverseSearchCompletion', () => {
|
|||
expect(result.current.activeSuggestionIndex).toBe(4);
|
||||
});
|
||||
|
||||
it('should handle navigation with large suggestion lists and scrolling', () => {
|
||||
it('should handle navigation with large suggestion lists and scrolling', async () => {
|
||||
const largeMockCommands = Array.from(
|
||||
{ length: 15 },
|
||||
(_, i) => `echo ${i}`,
|
||||
);
|
||||
|
||||
const { result } = renderHookWithProviders(() =>
|
||||
const { result } = await renderHookWithProviders(() =>
|
||||
useReverseSearchCompletion(
|
||||
useTextBufferForTest('echo'),
|
||||
largeMockCommands,
|
||||
|
|
@ -239,9 +239,9 @@ describe('useReverseSearchCompletion', () => {
|
|||
});
|
||||
|
||||
describe('Filtering', () => {
|
||||
it('filters history by buffer.text and sets showSuggestions', () => {
|
||||
it('filters history by buffer.text and sets showSuggestions', async () => {
|
||||
const history = ['foo', 'barfoo', 'baz'];
|
||||
const { result } = renderHookWithProviders(() =>
|
||||
const { result } = await renderHookWithProviders(() =>
|
||||
useReverseSearchCompletion(useTextBufferForTest('foo'), history, true),
|
||||
);
|
||||
|
||||
|
|
@ -253,9 +253,9 @@ describe('useReverseSearchCompletion', () => {
|
|||
expect(result.current.showSuggestions).toBe(true);
|
||||
});
|
||||
|
||||
it('hides suggestions when there are no matches', () => {
|
||||
it('hides suggestions when there are no matches', async () => {
|
||||
const history = ['alpha', 'beta'];
|
||||
const { result } = renderHookWithProviders(() =>
|
||||
const { result } = await renderHookWithProviders(() =>
|
||||
useReverseSearchCompletion(useTextBufferForTest('γ'), history, true),
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -48,10 +48,13 @@ describe('useSnowfall', () => {
|
|||
vi.useRealTimers();
|
||||
});
|
||||
|
||||
it('initially enables animation during holiday season with Holiday theme', () => {
|
||||
const { result } = renderHookWithProviders(() => useSnowfall(mockArt), {
|
||||
uiState: { history: [], historyRemountKey: 0 } as Partial<UIState>,
|
||||
});
|
||||
it('initially enables animation during holiday season with Holiday theme', async () => {
|
||||
const { result } = await renderHookWithProviders(
|
||||
() => useSnowfall(mockArt),
|
||||
{
|
||||
uiState: { history: [], historyRemountKey: 0 } as Partial<UIState>,
|
||||
},
|
||||
);
|
||||
|
||||
// Should contain holiday trees
|
||||
expect(result.current).toContain('|_|');
|
||||
|
|
@ -59,10 +62,13 @@ describe('useSnowfall', () => {
|
|||
expect(debugState.debugNumAnimatedComponents).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it('stops animation after 15 seconds', () => {
|
||||
const { result } = renderHookWithProviders(() => useSnowfall(mockArt), {
|
||||
uiState: { history: [], historyRemountKey: 0 } as Partial<UIState>,
|
||||
});
|
||||
it('stops animation after 15 seconds', async () => {
|
||||
const { result } = await renderHookWithProviders(
|
||||
() => useSnowfall(mockArt),
|
||||
{
|
||||
uiState: { history: [], historyRemountKey: 0 } as Partial<UIState>,
|
||||
},
|
||||
);
|
||||
|
||||
expect(debugState.debugNumAnimatedComponents).toBeGreaterThan(0);
|
||||
|
||||
|
|
@ -76,35 +82,44 @@ describe('useSnowfall', () => {
|
|||
expect(result.current).toBe(mockArt);
|
||||
});
|
||||
|
||||
it('does not enable animation if not holiday season', () => {
|
||||
it('does not enable animation if not holiday season', async () => {
|
||||
vi.setSystemTime(new Date('2025-06-15'));
|
||||
const { result } = renderHookWithProviders(() => useSnowfall(mockArt), {
|
||||
uiState: { history: [], historyRemountKey: 0 } as Partial<UIState>,
|
||||
});
|
||||
const { result } = await renderHookWithProviders(
|
||||
() => useSnowfall(mockArt),
|
||||
{
|
||||
uiState: { history: [], historyRemountKey: 0 } as Partial<UIState>,
|
||||
},
|
||||
);
|
||||
|
||||
expect(result.current).toBe(mockArt);
|
||||
expect(debugState.debugNumAnimatedComponents).toBe(0);
|
||||
});
|
||||
|
||||
it('does not enable animation if theme is not Holiday', () => {
|
||||
it('does not enable animation if theme is not Holiday', async () => {
|
||||
vi.mocked(themeManager.getActiveTheme).mockReturnValue({
|
||||
name: 'Default',
|
||||
} as Theme);
|
||||
const { result } = renderHookWithProviders(() => useSnowfall(mockArt), {
|
||||
uiState: { history: [], historyRemountKey: 0 } as Partial<UIState>,
|
||||
});
|
||||
const { result } = await renderHookWithProviders(
|
||||
() => useSnowfall(mockArt),
|
||||
{
|
||||
uiState: { history: [], historyRemountKey: 0 } as Partial<UIState>,
|
||||
},
|
||||
);
|
||||
|
||||
expect(result.current).toBe(mockArt);
|
||||
expect(debugState.debugNumAnimatedComponents).toBe(0);
|
||||
});
|
||||
|
||||
it('does not enable animation if chat has started', () => {
|
||||
const { result } = renderHookWithProviders(() => useSnowfall(mockArt), {
|
||||
uiState: {
|
||||
history: [{ type: 'user', text: 'hello' }],
|
||||
historyRemountKey: 0,
|
||||
} as Partial<UIState>,
|
||||
});
|
||||
it('does not enable animation if chat has started', async () => {
|
||||
const { result } = await renderHookWithProviders(
|
||||
() => useSnowfall(mockArt),
|
||||
{
|
||||
uiState: {
|
||||
history: [{ type: 'user', text: 'hello' }],
|
||||
historyRemountKey: 0,
|
||||
} as Partial<UIState>,
|
||||
},
|
||||
);
|
||||
|
||||
expect(result.current).toBe(mockArt);
|
||||
expect(debugState.debugNumAnimatedComponents).toBe(0);
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@ describe('useTips()', () => {
|
|||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it('should return false and call set(1) if state is undefined', () => {
|
||||
const { result } = renderHookWithProviders(() => useTips());
|
||||
it('should return false and call set(1) if state is undefined', async () => {
|
||||
const { result } = await renderHookWithProviders(() => useTips());
|
||||
|
||||
expect(result.current.showTips).toBe(true);
|
||||
|
||||
|
|
@ -25,20 +25,20 @@ describe('useTips()', () => {
|
|||
expect(persistentStateMock.get('tipsShown')).toBe(1);
|
||||
});
|
||||
|
||||
it('should return false and call set(6) if state is 5', () => {
|
||||
it('should return false and call set(6) if state is 5', async () => {
|
||||
persistentStateMock.setData({ tipsShown: 5 });
|
||||
|
||||
const { result } = renderHookWithProviders(() => useTips());
|
||||
const { result } = await renderHookWithProviders(() => useTips());
|
||||
|
||||
expect(result.current.showTips).toBe(true);
|
||||
|
||||
expect(persistentStateMock.get('tipsShown')).toBe(6);
|
||||
});
|
||||
|
||||
it('should return true if state is 10', () => {
|
||||
it('should return true if state is 10', async () => {
|
||||
persistentStateMock.setData({ tipsShown: 10 });
|
||||
|
||||
const { result } = renderHookWithProviders(() => useTips());
|
||||
const { result } = await renderHookWithProviders(() => useTips());
|
||||
|
||||
expect(result.current.showTips).toBe(false);
|
||||
expect(persistentStateMock.set).not.toHaveBeenCalled();
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ describe('colorizeCode', () => {
|
|||
hideLineNumbers: true,
|
||||
});
|
||||
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<>{result}</>,
|
||||
);
|
||||
await waitUntilReady();
|
||||
|
|
@ -76,7 +76,7 @@ describe('colorizeCode', () => {
|
|||
hideLineNumbers: true,
|
||||
});
|
||||
|
||||
const renderResult = renderWithProviders(<>{result}</>);
|
||||
const renderResult = await renderWithProviders(<>{result}</>);
|
||||
await renderResult.waitUntilReady();
|
||||
|
||||
await expect(renderResult).toMatchSvgSnapshot();
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue