mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-04-23 03:24:42 -07:00
test(cli): refactor tests for async render utilities (#23252)
This commit is contained in:
committed by
GitHub
parent
86a3a913b5
commit
6c78eb7a39
@@ -138,33 +138,25 @@ describe('<Footer />', () => {
|
||||
});
|
||||
|
||||
it('renders the component', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: {
|
||||
branchName: defaultProps.branchName,
|
||||
sessionStats: mockSessionStats,
|
||||
},
|
||||
const { lastFrame, unmount } = await renderWithProviders(<Footer />, {
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: {
|
||||
branchName: defaultProps.branchName,
|
||||
sessionStats: mockSessionStats,
|
||||
},
|
||||
);
|
||||
await waitUntilReady();
|
||||
});
|
||||
expect(lastFrame()).toBeDefined();
|
||||
unmount();
|
||||
});
|
||||
|
||||
describe('path display', () => {
|
||||
it('should display a shortened path on a narrow terminal', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 79,
|
||||
uiState: { sessionStats: mockSessionStats },
|
||||
},
|
||||
);
|
||||
await waitUntilReady();
|
||||
const { lastFrame, unmount } = await renderWithProviders(<Footer />, {
|
||||
config: mockConfig,
|
||||
width: 79,
|
||||
uiState: { sessionStats: mockSessionStats },
|
||||
});
|
||||
const output = lastFrame();
|
||||
expect(output).toBeDefined();
|
||||
// Should contain some part of the path, likely shortened
|
||||
@@ -173,15 +165,11 @@ describe('<Footer />', () => {
|
||||
});
|
||||
|
||||
it('should use wide layout at 80 columns', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 80,
|
||||
uiState: { sessionStats: mockSessionStats },
|
||||
},
|
||||
);
|
||||
await waitUntilReady();
|
||||
const { lastFrame, unmount } = await renderWithProviders(<Footer />, {
|
||||
config: mockConfig,
|
||||
width: 80,
|
||||
uiState: { sessionStats: mockSessionStats },
|
||||
});
|
||||
const output = lastFrame();
|
||||
expect(output).toBeDefined();
|
||||
expect(output).toContain(path.join('make', 'it'));
|
||||
@@ -189,28 +177,24 @@ describe('<Footer />', () => {
|
||||
});
|
||||
|
||||
it('should not truncate high-priority items on narrow terminals (regression)', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 60,
|
||||
uiState: {
|
||||
sessionStats: mockSessionStats,
|
||||
},
|
||||
settings: createMockSettings({
|
||||
general: {
|
||||
vimMode: true,
|
||||
},
|
||||
ui: {
|
||||
footer: {
|
||||
showLabels: true,
|
||||
items: ['workspace', 'model-name'],
|
||||
},
|
||||
},
|
||||
}),
|
||||
const { lastFrame, unmount } = await renderWithProviders(<Footer />, {
|
||||
config: mockConfig,
|
||||
width: 60,
|
||||
uiState: {
|
||||
sessionStats: mockSessionStats,
|
||||
},
|
||||
);
|
||||
await waitUntilReady();
|
||||
settings: createMockSettings({
|
||||
general: {
|
||||
vimMode: true,
|
||||
},
|
||||
ui: {
|
||||
footer: {
|
||||
showLabels: true,
|
||||
items: ['workspace', 'model-name'],
|
||||
},
|
||||
},
|
||||
}),
|
||||
});
|
||||
const output = lastFrame();
|
||||
// [INSERT] is high priority and should be fully visible
|
||||
// (Note: VimModeProvider defaults to 'INSERT' mode when enabled)
|
||||
@@ -222,168 +206,140 @@ describe('<Footer />', () => {
|
||||
});
|
||||
|
||||
it('displays the branch name when provided', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: {
|
||||
branchName: defaultProps.branchName,
|
||||
sessionStats: mockSessionStats,
|
||||
},
|
||||
const { lastFrame, unmount } = await renderWithProviders(<Footer />, {
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: {
|
||||
branchName: defaultProps.branchName,
|
||||
sessionStats: mockSessionStats,
|
||||
},
|
||||
);
|
||||
await waitUntilReady();
|
||||
});
|
||||
expect(lastFrame()).toContain(defaultProps.branchName);
|
||||
unmount();
|
||||
});
|
||||
|
||||
it('does not display the branch name when not provided', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: { branchName: undefined, sessionStats: mockSessionStats },
|
||||
},
|
||||
);
|
||||
await waitUntilReady();
|
||||
const { lastFrame, unmount } = await renderWithProviders(<Footer />, {
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: { branchName: undefined, sessionStats: mockSessionStats },
|
||||
});
|
||||
expect(lastFrame()).not.toContain('Branch');
|
||||
unmount();
|
||||
});
|
||||
|
||||
it('displays the model name and context percentage', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: {
|
||||
currentModel: defaultProps.model,
|
||||
sessionStats: {
|
||||
...mockSessionStats,
|
||||
lastPromptTokenCount: 1000,
|
||||
const { lastFrame, unmount } = await renderWithProviders(<Footer />, {
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: {
|
||||
currentModel: defaultProps.model,
|
||||
sessionStats: {
|
||||
...mockSessionStats,
|
||||
lastPromptTokenCount: 1000,
|
||||
},
|
||||
},
|
||||
settings: createMockSettings({
|
||||
ui: {
|
||||
footer: {
|
||||
hideContextPercentage: false,
|
||||
},
|
||||
},
|
||||
settings: createMockSettings({
|
||||
ui: {
|
||||
footer: {
|
||||
hideContextPercentage: false,
|
||||
},
|
||||
},
|
||||
}),
|
||||
},
|
||||
);
|
||||
await waitUntilReady();
|
||||
}),
|
||||
});
|
||||
expect(lastFrame()).toContain(defaultProps.model);
|
||||
expect(lastFrame()).toMatch(/\d+% used/);
|
||||
unmount();
|
||||
});
|
||||
|
||||
it('displays the usage indicator when usage is low', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: {
|
||||
sessionStats: mockSessionStats,
|
||||
quota: {
|
||||
userTier: undefined,
|
||||
stats: {
|
||||
remaining: 15,
|
||||
limit: 100,
|
||||
resetTime: undefined,
|
||||
},
|
||||
proQuotaRequest: null,
|
||||
validationRequest: null,
|
||||
overageMenuRequest: null,
|
||||
emptyWalletRequest: null,
|
||||
const { lastFrame, unmount } = await renderWithProviders(<Footer />, {
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: {
|
||||
sessionStats: mockSessionStats,
|
||||
quota: {
|
||||
userTier: undefined,
|
||||
stats: {
|
||||
remaining: 15,
|
||||
limit: 100,
|
||||
resetTime: undefined,
|
||||
},
|
||||
proQuotaRequest: null,
|
||||
validationRequest: null,
|
||||
overageMenuRequest: null,
|
||||
emptyWalletRequest: null,
|
||||
},
|
||||
},
|
||||
);
|
||||
await waitUntilReady();
|
||||
});
|
||||
expect(lastFrame()).toContain('85%');
|
||||
expect(normalizeFrame(lastFrame())).toMatchSnapshot();
|
||||
unmount();
|
||||
});
|
||||
|
||||
it('hides the usage indicator when usage is not near limit', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: {
|
||||
sessionStats: mockSessionStats,
|
||||
quota: {
|
||||
userTier: undefined,
|
||||
stats: {
|
||||
remaining: 85,
|
||||
limit: 100,
|
||||
resetTime: undefined,
|
||||
},
|
||||
proQuotaRequest: null,
|
||||
validationRequest: null,
|
||||
overageMenuRequest: null,
|
||||
emptyWalletRequest: null,
|
||||
const { lastFrame, unmount } = await renderWithProviders(<Footer />, {
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: {
|
||||
sessionStats: mockSessionStats,
|
||||
quota: {
|
||||
userTier: undefined,
|
||||
stats: {
|
||||
remaining: 85,
|
||||
limit: 100,
|
||||
resetTime: undefined,
|
||||
},
|
||||
proQuotaRequest: null,
|
||||
validationRequest: null,
|
||||
overageMenuRequest: null,
|
||||
emptyWalletRequest: null,
|
||||
},
|
||||
},
|
||||
);
|
||||
await waitUntilReady();
|
||||
});
|
||||
expect(normalizeFrame(lastFrame())).not.toContain('used');
|
||||
expect(normalizeFrame(lastFrame())).toMatchSnapshot();
|
||||
unmount();
|
||||
});
|
||||
|
||||
it('displays "Limit reached" message when remaining is 0', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: {
|
||||
sessionStats: mockSessionStats,
|
||||
quota: {
|
||||
userTier: undefined,
|
||||
stats: {
|
||||
remaining: 0,
|
||||
limit: 100,
|
||||
resetTime: undefined,
|
||||
},
|
||||
proQuotaRequest: null,
|
||||
validationRequest: null,
|
||||
overageMenuRequest: null,
|
||||
emptyWalletRequest: null,
|
||||
const { lastFrame, unmount } = await renderWithProviders(<Footer />, {
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: {
|
||||
sessionStats: mockSessionStats,
|
||||
quota: {
|
||||
userTier: undefined,
|
||||
stats: {
|
||||
remaining: 0,
|
||||
limit: 100,
|
||||
resetTime: undefined,
|
||||
},
|
||||
proQuotaRequest: null,
|
||||
validationRequest: null,
|
||||
overageMenuRequest: null,
|
||||
emptyWalletRequest: null,
|
||||
},
|
||||
},
|
||||
);
|
||||
await waitUntilReady();
|
||||
});
|
||||
expect(lastFrame()?.toLowerCase()).toContain('limit reached');
|
||||
expect(normalizeFrame(lastFrame())).toMatchSnapshot();
|
||||
unmount();
|
||||
});
|
||||
|
||||
it('displays the model name and abbreviated context used label on narrow terminals', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 99,
|
||||
uiState: { sessionStats: mockSessionStats },
|
||||
settings: createMockSettings({
|
||||
ui: {
|
||||
footer: {
|
||||
hideContextPercentage: false,
|
||||
},
|
||||
const { lastFrame, unmount } = await renderWithProviders(<Footer />, {
|
||||
config: mockConfig,
|
||||
width: 99,
|
||||
uiState: { sessionStats: mockSessionStats },
|
||||
settings: createMockSettings({
|
||||
ui: {
|
||||
footer: {
|
||||
hideContextPercentage: false,
|
||||
},
|
||||
}),
|
||||
},
|
||||
);
|
||||
await waitUntilReady();
|
||||
},
|
||||
}),
|
||||
});
|
||||
expect(lastFrame()).toContain(defaultProps.model);
|
||||
expect(lastFrame()).toMatch(/\d+%/);
|
||||
expect(lastFrame()).not.toContain('context used');
|
||||
@@ -392,33 +348,25 @@ describe('<Footer />', () => {
|
||||
|
||||
describe('sandbox and trust info', () => {
|
||||
it('should display untrusted when isTrustedFolder is false', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: { isTrustedFolder: false, sessionStats: mockSessionStats },
|
||||
},
|
||||
);
|
||||
await waitUntilReady();
|
||||
const { lastFrame, unmount } = await renderWithProviders(<Footer />, {
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: { isTrustedFolder: false, sessionStats: mockSessionStats },
|
||||
});
|
||||
expect(lastFrame()).toContain('untrusted');
|
||||
unmount();
|
||||
});
|
||||
|
||||
it('should display custom sandbox info when SANDBOX env is set', async () => {
|
||||
vi.stubEnv('SANDBOX', 'gemini-cli-test-sandbox');
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: {
|
||||
isTrustedFolder: undefined,
|
||||
sessionStats: mockSessionStats,
|
||||
},
|
||||
const { lastFrame, unmount } = await renderWithProviders(<Footer />, {
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: {
|
||||
isTrustedFolder: undefined,
|
||||
sessionStats: mockSessionStats,
|
||||
},
|
||||
);
|
||||
await waitUntilReady();
|
||||
});
|
||||
expect(lastFrame()).toContain('test');
|
||||
vi.unstubAllEnvs();
|
||||
unmount();
|
||||
@@ -427,15 +375,11 @@ 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 } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: { isTrustedFolder: true, sessionStats: mockSessionStats },
|
||||
},
|
||||
);
|
||||
await waitUntilReady();
|
||||
const { lastFrame, unmount } = await renderWithProviders(<Footer />, {
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: { isTrustedFolder: true, sessionStats: mockSessionStats },
|
||||
});
|
||||
expect(lastFrame()).toMatch(/macOS Seatbelt.*\(test-profile\)/s);
|
||||
vi.unstubAllEnvs();
|
||||
unmount();
|
||||
@@ -444,15 +388,11 @@ 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 } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: { isTrustedFolder: true, sessionStats: mockSessionStats },
|
||||
},
|
||||
);
|
||||
await waitUntilReady();
|
||||
const { lastFrame, unmount } = await renderWithProviders(<Footer />, {
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: { isTrustedFolder: true, sessionStats: mockSessionStats },
|
||||
});
|
||||
expect(lastFrame()).toContain('no sandbox');
|
||||
vi.unstubAllEnvs();
|
||||
unmount();
|
||||
@@ -460,15 +400,11 @@ describe('<Footer />', () => {
|
||||
|
||||
it('should prioritize untrusted message over sandbox info', async () => {
|
||||
vi.stubEnv('SANDBOX', 'gemini-cli-test-sandbox');
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: { isTrustedFolder: false, sessionStats: mockSessionStats },
|
||||
},
|
||||
);
|
||||
await waitUntilReady();
|
||||
const { lastFrame, unmount } = await renderWithProviders(<Footer />, {
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: { isTrustedFolder: false, sessionStats: mockSessionStats },
|
||||
});
|
||||
expect(lastFrame()).toContain('untrusted');
|
||||
expect(lastFrame()).not.toMatch(/test-sandbox/s);
|
||||
vi.unstubAllEnvs();
|
||||
@@ -478,22 +414,18 @@ describe('<Footer />', () => {
|
||||
|
||||
describe('footer configuration filtering (golden snapshots)', () => {
|
||||
it('renders complete footer with all sections visible (baseline)', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: { sessionStats: mockSessionStats },
|
||||
settings: createMockSettings({
|
||||
ui: {
|
||||
footer: {
|
||||
hideContextPercentage: false,
|
||||
},
|
||||
const { lastFrame, unmount } = await renderWithProviders(<Footer />, {
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: { sessionStats: mockSessionStats },
|
||||
settings: createMockSettings({
|
||||
ui: {
|
||||
footer: {
|
||||
hideContextPercentage: false,
|
||||
},
|
||||
}),
|
||||
},
|
||||
);
|
||||
await waitUntilReady();
|
||||
},
|
||||
}),
|
||||
});
|
||||
expect(normalizeFrame(lastFrame())).toMatchSnapshot(
|
||||
'complete-footer-wide',
|
||||
);
|
||||
@@ -523,47 +455,39 @@ describe('<Footer />', () => {
|
||||
});
|
||||
|
||||
it('renders footer with only model info hidden (partial filtering)', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: { sessionStats: mockSessionStats },
|
||||
settings: createMockSettings({
|
||||
ui: {
|
||||
footer: {
|
||||
hideCWD: false,
|
||||
hideSandboxStatus: false,
|
||||
hideModelInfo: true,
|
||||
},
|
||||
const { lastFrame, unmount } = await renderWithProviders(<Footer />, {
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: { sessionStats: mockSessionStats },
|
||||
settings: createMockSettings({
|
||||
ui: {
|
||||
footer: {
|
||||
hideCWD: false,
|
||||
hideSandboxStatus: false,
|
||||
hideModelInfo: true,
|
||||
},
|
||||
}),
|
||||
},
|
||||
);
|
||||
await waitUntilReady();
|
||||
},
|
||||
}),
|
||||
});
|
||||
expect(normalizeFrame(lastFrame())).toMatchSnapshot('footer-no-model');
|
||||
unmount();
|
||||
});
|
||||
|
||||
it('renders footer with CWD and model info hidden to test alignment (only sandbox visible)', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: { sessionStats: mockSessionStats },
|
||||
settings: createMockSettings({
|
||||
ui: {
|
||||
footer: {
|
||||
hideCWD: true,
|
||||
hideSandboxStatus: false,
|
||||
hideModelInfo: true,
|
||||
},
|
||||
const { lastFrame, unmount } = await renderWithProviders(<Footer />, {
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: { sessionStats: mockSessionStats },
|
||||
settings: createMockSettings({
|
||||
ui: {
|
||||
footer: {
|
||||
hideCWD: true,
|
||||
hideSandboxStatus: false,
|
||||
hideModelInfo: true,
|
||||
},
|
||||
}),
|
||||
},
|
||||
);
|
||||
await waitUntilReady();
|
||||
},
|
||||
}),
|
||||
});
|
||||
expect(normalizeFrame(lastFrame())).toMatchSnapshot(
|
||||
'footer-only-sandbox',
|
||||
);
|
||||
@@ -571,64 +495,52 @@ describe('<Footer />', () => {
|
||||
});
|
||||
|
||||
it('hides the context percentage when hideContextPercentage is true', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: { sessionStats: mockSessionStats },
|
||||
settings: createMockSettings({
|
||||
ui: {
|
||||
footer: {
|
||||
hideContextPercentage: true,
|
||||
},
|
||||
const { lastFrame, unmount } = await renderWithProviders(<Footer />, {
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: { sessionStats: mockSessionStats },
|
||||
settings: createMockSettings({
|
||||
ui: {
|
||||
footer: {
|
||||
hideContextPercentage: true,
|
||||
},
|
||||
}),
|
||||
},
|
||||
);
|
||||
await waitUntilReady();
|
||||
},
|
||||
}),
|
||||
});
|
||||
expect(lastFrame()).toContain(defaultProps.model);
|
||||
expect(lastFrame()).not.toMatch(/\d+% used/);
|
||||
unmount();
|
||||
});
|
||||
it('shows the context percentage when hideContextPercentage is false', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: { sessionStats: mockSessionStats },
|
||||
settings: createMockSettings({
|
||||
ui: {
|
||||
footer: {
|
||||
hideContextPercentage: false,
|
||||
},
|
||||
const { lastFrame, unmount } = await renderWithProviders(<Footer />, {
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: { sessionStats: mockSessionStats },
|
||||
settings: createMockSettings({
|
||||
ui: {
|
||||
footer: {
|
||||
hideContextPercentage: false,
|
||||
},
|
||||
}),
|
||||
},
|
||||
);
|
||||
await waitUntilReady();
|
||||
},
|
||||
}),
|
||||
});
|
||||
expect(lastFrame()).toContain(defaultProps.model);
|
||||
expect(lastFrame()).toMatch(/\d+% used/);
|
||||
unmount();
|
||||
});
|
||||
it('renders complete footer in narrow terminal (baseline narrow)', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 79,
|
||||
uiState: { sessionStats: mockSessionStats },
|
||||
settings: createMockSettings({
|
||||
ui: {
|
||||
footer: {
|
||||
hideContextPercentage: false,
|
||||
},
|
||||
const { lastFrame, unmount } = await renderWithProviders(<Footer />, {
|
||||
config: mockConfig,
|
||||
width: 79,
|
||||
uiState: { sessionStats: mockSessionStats },
|
||||
settings: createMockSettings({
|
||||
ui: {
|
||||
footer: {
|
||||
hideContextPercentage: false,
|
||||
},
|
||||
}),
|
||||
},
|
||||
);
|
||||
await waitUntilReady();
|
||||
},
|
||||
}),
|
||||
});
|
||||
expect(normalizeFrame(lastFrame())).toMatchSnapshot(
|
||||
'complete-footer-narrow',
|
||||
);
|
||||
@@ -714,60 +626,48 @@ describe('<Footer />', () => {
|
||||
});
|
||||
|
||||
it('hides error summary in low verbosity mode out of dev mode', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: {
|
||||
sessionStats: mockSessionStats,
|
||||
errorCount: 2,
|
||||
showErrorDetails: false,
|
||||
},
|
||||
settings: createMockSettings({ ui: { errorVerbosity: 'low' } }),
|
||||
const { lastFrame, unmount } = await renderWithProviders(<Footer />, {
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: {
|
||||
sessionStats: mockSessionStats,
|
||||
errorCount: 2,
|
||||
showErrorDetails: false,
|
||||
},
|
||||
);
|
||||
await waitUntilReady();
|
||||
settings: createMockSettings({ ui: { errorVerbosity: 'low' } }),
|
||||
});
|
||||
expect(lastFrame()).not.toContain('F12 for details');
|
||||
unmount();
|
||||
});
|
||||
|
||||
it('shows error summary in low verbosity mode in dev mode', async () => {
|
||||
mocks.isDevelopment = true;
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: {
|
||||
sessionStats: mockSessionStats,
|
||||
errorCount: 2,
|
||||
showErrorDetails: false,
|
||||
},
|
||||
settings: createMockSettings({ ui: { errorVerbosity: 'low' } }),
|
||||
const { lastFrame, unmount } = await renderWithProviders(<Footer />, {
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: {
|
||||
sessionStats: mockSessionStats,
|
||||
errorCount: 2,
|
||||
showErrorDetails: false,
|
||||
},
|
||||
);
|
||||
await waitUntilReady();
|
||||
settings: createMockSettings({ ui: { errorVerbosity: 'low' } }),
|
||||
});
|
||||
expect(lastFrame()).toContain('F12 for details');
|
||||
expect(lastFrame()).toContain('2 errors');
|
||||
unmount();
|
||||
});
|
||||
|
||||
it('shows error summary in full verbosity mode', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: {
|
||||
sessionStats: mockSessionStats,
|
||||
errorCount: 2,
|
||||
showErrorDetails: false,
|
||||
},
|
||||
settings: createMockSettings({ ui: { errorVerbosity: 'full' } }),
|
||||
const { lastFrame, unmount } = await renderWithProviders(<Footer />, {
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: {
|
||||
sessionStats: mockSessionStats,
|
||||
errorCount: 2,
|
||||
showErrorDetails: false,
|
||||
},
|
||||
);
|
||||
await waitUntilReady();
|
||||
settings: createMockSettings({ ui: { errorVerbosity: 'full' } }),
|
||||
});
|
||||
expect(lastFrame()).toContain('F12 for details');
|
||||
expect(lastFrame()).toContain('2 errors');
|
||||
unmount();
|
||||
@@ -776,25 +676,21 @@ describe('<Footer />', () => {
|
||||
|
||||
describe('Footer Custom Items', () => {
|
||||
it('renders items in the specified order', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: {
|
||||
currentModel: 'gemini-pro',
|
||||
sessionStats: mockSessionStats,
|
||||
},
|
||||
settings: createMockSettings({
|
||||
ui: {
|
||||
footer: {
|
||||
items: ['model-name', 'workspace'],
|
||||
},
|
||||
},
|
||||
}),
|
||||
const { lastFrame, unmount } = await renderWithProviders(<Footer />, {
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: {
|
||||
currentModel: 'gemini-pro',
|
||||
sessionStats: mockSessionStats,
|
||||
},
|
||||
);
|
||||
await waitUntilReady();
|
||||
settings: createMockSettings({
|
||||
ui: {
|
||||
footer: {
|
||||
items: ['model-name', 'workspace'],
|
||||
},
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
const output = lastFrame();
|
||||
const modelIdx = output.indexOf('/model');
|
||||
@@ -804,28 +700,24 @@ describe('<Footer />', () => {
|
||||
});
|
||||
|
||||
it('renders multiple items with proper alignment', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: {
|
||||
sessionStats: mockSessionStats,
|
||||
branchName: 'main',
|
||||
},
|
||||
settings: createMockSettings({
|
||||
vimMode: {
|
||||
vimMode: true,
|
||||
},
|
||||
ui: {
|
||||
footer: {
|
||||
items: ['workspace', 'git-branch', 'sandbox', 'model-name'],
|
||||
},
|
||||
},
|
||||
}),
|
||||
const { lastFrame, unmount } = await renderWithProviders(<Footer />, {
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: {
|
||||
sessionStats: mockSessionStats,
|
||||
branchName: 'main',
|
||||
},
|
||||
);
|
||||
await waitUntilReady();
|
||||
settings: createMockSettings({
|
||||
vimMode: {
|
||||
vimMode: true,
|
||||
},
|
||||
ui: {
|
||||
footer: {
|
||||
items: ['workspace', 'git-branch', 'sandbox', 'model-name'],
|
||||
},
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
const output = lastFrame();
|
||||
expect(output).toBeDefined();
|
||||
@@ -862,25 +754,21 @@ describe('<Footer />', () => {
|
||||
});
|
||||
|
||||
it('does not render items that are conditionally hidden', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: {
|
||||
sessionStats: mockSessionStats,
|
||||
branchName: undefined, // No branch
|
||||
},
|
||||
settings: createMockSettings({
|
||||
ui: {
|
||||
footer: {
|
||||
items: ['workspace', 'git-branch', 'model-name'],
|
||||
},
|
||||
},
|
||||
}),
|
||||
const { lastFrame, unmount } = await renderWithProviders(<Footer />, {
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: {
|
||||
sessionStats: mockSessionStats,
|
||||
branchName: undefined, // No branch
|
||||
},
|
||||
);
|
||||
await waitUntilReady();
|
||||
settings: createMockSettings({
|
||||
ui: {
|
||||
footer: {
|
||||
items: ['workspace', 'git-branch', 'model-name'],
|
||||
},
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
const output = lastFrame();
|
||||
expect(output).toBeDefined();
|
||||
@@ -893,18 +781,14 @@ 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 } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: {
|
||||
sessionStats: mockSessionStats,
|
||||
currentModel: 'gemini-2.5-flash', // Fallback active, showing Flash
|
||||
},
|
||||
const { lastFrame, unmount } = await renderWithProviders(<Footer />, {
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: {
|
||||
sessionStats: mockSessionStats,
|
||||
currentModel: 'gemini-2.5-flash', // Fallback active, showing Flash
|
||||
},
|
||||
);
|
||||
await waitUntilReady();
|
||||
});
|
||||
|
||||
// Footer should show the effective model (Flash), not the config model (Pro)
|
||||
expect(lastFrame()).toContain('gemini-2.5-flash');
|
||||
@@ -913,18 +797,14 @@ describe('<Footer />', () => {
|
||||
});
|
||||
|
||||
it('should display Pro model when NOT in fallback mode', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = await renderWithProviders(
|
||||
<Footer />,
|
||||
{
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: {
|
||||
sessionStats: mockSessionStats,
|
||||
currentModel: 'gemini-2.5-pro', // Normal mode, showing Pro
|
||||
},
|
||||
const { lastFrame, unmount } = await renderWithProviders(<Footer />, {
|
||||
config: mockConfig,
|
||||
width: 120,
|
||||
uiState: {
|
||||
sessionStats: mockSessionStats,
|
||||
currentModel: 'gemini-2.5-pro', // Normal mode, showing Pro
|
||||
},
|
||||
);
|
||||
await waitUntilReady();
|
||||
});
|
||||
|
||||
expect(lastFrame()).toContain('gemini-2.5-pro');
|
||||
unmount();
|
||||
|
||||
Reference in New Issue
Block a user