2026-02-04 22:29:26 -08:00
/ * *
* @license
* Copyright 2026 Google LLC
* SPDX - License - Identifier : Apache - 2.0
* /
2026-02-10 12:00:13 -08:00
import { renderWithProviders } from '../../../test-utils/render.js' ;
2026-02-04 22:29:26 -08:00
import { Card } from './Card.js' ;
import { Text } from 'ink' ;
2026-02-10 10:55:51 -08:00
import { describe , it , expect , afterEach , vi } from 'vitest' ;
2026-02-10 12:00:13 -08:00
import { ToolCallStatus , StreamingState } from '../../types.js' ;
2026-02-04 22:29:26 -08:00
describe ( 'Card' , ( ) = > {
2026-02-10 10:55:51 -08:00
afterEach ( ( ) = > {
vi . restoreAllMocks ( ) ;
} ) ;
2026-02-04 22:29:26 -08:00
it . each ( [
{
2026-02-05 15:37:24 -08:00
status : ToolCallStatus.Pending ,
2026-02-04 22:29:26 -08:00
title : 'Gemini CLI update available' ,
suffix : '0.26.0 → 0.27.0' ,
2026-02-10 11:36:01 -08:00
showStatusIndicator : true ,
2026-02-04 22:29:26 -08:00
body : 'Installed via Homebrew. Please update with "brew upgrade gemini-cli".' ,
} ,
{
2026-02-05 15:37:24 -08:00
status : ToolCallStatus.Canceled ,
2026-02-04 22:29:26 -08:00
title : 'Delegate to agent' ,
suffix : "Delegating to agent 'cli_help'" ,
2026-02-10 11:36:01 -08:00
showStatusIndicator : true ,
2026-02-04 22:29:26 -08:00
body : '🤖💭 Execution limit reached (ERROR_NO_COMPLETE_TASK_CALL). Attempting one final recovery turn with a grace period.' ,
} ,
{
2026-02-05 15:37:24 -08:00
status : ToolCallStatus.Error ,
2026-02-04 22:29:26 -08:00
title : 'Error' ,
suffix : '429 You exceeded your current quota' ,
2026-02-10 11:36:01 -08:00
showStatusIndicator : true ,
2026-02-04 22:29:26 -08:00
body : 'Go to https://aistudio.google.com/apikey to upgrade your quota tier, or submit a quota increase request in https://ai.google.dev/gemini-api/docs/rate-limits' ,
} ,
{
2026-02-05 15:37:24 -08:00
status : ToolCallStatus.Confirming ,
2026-02-04 22:29:26 -08:00
title : 'Shell' ,
suffix : 'node -v && which gemini' ,
2026-02-10 11:36:01 -08:00
showStatusIndicator : true ,
2026-02-04 22:29:26 -08:00
body : "ls /usr/local/bin | grep 'xattr'" ,
} ,
{
2026-02-05 15:37:24 -08:00
status : ToolCallStatus.Success ,
2026-02-04 22:29:26 -08:00
title : 'ReadFolder' ,
suffix : '/usr/local/bin' ,
2026-02-10 11:36:01 -08:00
showStatusIndicator : true ,
2026-02-04 22:29:26 -08:00
body : 'Listed 39 item(s).' ,
} ,
2026-02-10 12:00:13 -08:00
{
status : ToolCallStatus.Executing ,
title : 'Searching' ,
suffix : 'ripgrep' ,
showStatusIndicator : true ,
body : 'Searching for pattern in directory...' ,
} ,
{
status : ToolCallStatus.Pending ,
title : 'No Status Indicator' ,
suffix : 'Hidden' ,
showStatusIndicator : false ,
body : 'The status indicator should be hidden.' ,
} ,
2026-02-10 10:55:51 -08:00
{
status : ToolCallStatus.Pending ,
title : 'Fixed Width Card' ,
suffix : undefined ,
2026-02-10 11:36:01 -08:00
showStatusIndicator : true ,
2026-02-10 10:55:51 -08:00
width : 40 ,
body : 'This card has a fixed width of 40 characters.' ,
} ,
2026-02-05 11:07:19 -08:00
] as const ) (
2026-02-10 11:36:01 -08:00
"renders '$title' card with status=$status and showStatusIndicator=$showStatusIndicator" ,
( { status , title , suffix , showStatusIndicator , body , width } ) = > {
2026-02-10 12:00:13 -08:00
const { lastFrame } = renderWithProviders (
2026-02-10 10:55:51 -08:00
< Card
status = { status }
title = { title }
suffix = { suffix }
2026-02-10 11:36:01 -08:00
showStatusIndicator = { showStatusIndicator }
2026-02-10 10:55:51 -08:00
width = { width }
>
2026-02-04 22:29:26 -08:00
< Text > { body } < / Text >
< / Card > ,
2026-02-10 12:00:13 -08:00
{
uiState : {
streamingState : StreamingState.Responding ,
} ,
} ,
2026-02-04 22:29:26 -08:00
) ;
const output = lastFrame ( ) ;
expect ( output ) . toMatchSnapshot ( ) ;
} ,
) ;
} ) ;