/** * @license * Copyright 2026 Google LLC * SPDX-License-Identifier: Apache-2.0 */ import { describe, it, expect } from 'vitest'; import { calculateToolContentMaxLines, calculateShellMaxLines, SHELL_CONTENT_OVERHEAD, TOOL_RESULT_STATIC_HEIGHT, TOOL_RESULT_STANDARD_RESERVED_LINE_COUNT, TOOL_RESULT_ASB_RESERVED_LINE_COUNT, TOOL_RESULT_MIN_LINES_SHOWN, } from './toolLayoutUtils.js'; import { CoreToolCallStatus } from '@google/gemini-cli-core'; import { ACTIVE_SHELL_MAX_LINES, COMPLETED_SHELL_MAX_LINES, } from '../constants.js'; describe('toolLayoutUtils', () => { describe('calculateToolContentMaxLines', () => { interface CalculateToolContentMaxLinesTestCase { desc: string; options: Parameters[0]; expected: number | undefined; } const testCases: CalculateToolContentMaxLinesTestCase[] = [ { desc: 'returns undefined if availableTerminalHeight is undefined', options: { availableTerminalHeight: undefined, isAlternateBuffer: false, }, expected: undefined, }, { desc: 'returns maxLinesLimit if maxLinesLimit applies but availableTerminalHeight is undefined', options: { availableTerminalHeight: undefined, isAlternateBuffer: false, maxLinesLimit: 10, }, expected: 10, }, { desc: 'returns available space directly in constrained terminal (Standard mode)', options: { availableTerminalHeight: 2, isAlternateBuffer: false, }, expected: TOOL_RESULT_MIN_LINES_SHOWN + 1, }, { desc: 'returns available space directly in constrained terminal (ASB mode)', options: { availableTerminalHeight: 4, isAlternateBuffer: true, }, expected: TOOL_RESULT_MIN_LINES_SHOWN + 1, }, { desc: 'returns remaining space if sufficient space exists (Standard mode)', options: { availableTerminalHeight: 20, isAlternateBuffer: false, }, expected: 20 - TOOL_RESULT_STATIC_HEIGHT - TOOL_RESULT_STANDARD_RESERVED_LINE_COUNT, }, { desc: 'returns remaining space if sufficient space exists (ASB mode)', options: { availableTerminalHeight: 20, isAlternateBuffer: true, }, expected: 20 - TOOL_RESULT_STATIC_HEIGHT - TOOL_RESULT_ASB_RESERVED_LINE_COUNT, }, ]; it.each(testCases)('$desc', ({ options, expected }) => { const result = calculateToolContentMaxLines(options); expect(result).toBe(expected); }); }); describe('calculateShellMaxLines', () => { interface CalculateShellMaxLinesTestCase { desc: string; options: Parameters[0]; expected: number | undefined; } const testCases: CalculateShellMaxLinesTestCase[] = [ { desc: 'returns undefined when not constrained and is expandable', options: { status: CoreToolCallStatus.Executing, isAlternateBuffer: false, isThisShellFocused: false, availableTerminalHeight: 20, constrainHeight: false, isExpandable: true, }, expected: undefined, }, { desc: 'returns ACTIVE_SHELL_MAX_LINES - SHELL_CONTENT_OVERHEAD for ASB mode when availableTerminalHeight is undefined', options: { status: CoreToolCallStatus.Executing, isAlternateBuffer: true, isThisShellFocused: false, availableTerminalHeight: undefined, constrainHeight: true, isExpandable: false, }, expected: ACTIVE_SHELL_MAX_LINES - SHELL_CONTENT_OVERHEAD, }, { desc: 'returns undefined for Standard mode when availableTerminalHeight is undefined', options: { status: CoreToolCallStatus.Executing, isAlternateBuffer: false, isThisShellFocused: false, availableTerminalHeight: undefined, constrainHeight: true, isExpandable: false, }, expected: undefined, }, { desc: 'handles small availableTerminalHeight gracefully without overflow in Standard mode', options: { status: CoreToolCallStatus.Executing, isAlternateBuffer: false, isThisShellFocused: false, availableTerminalHeight: 2, constrainHeight: true, isExpandable: false, }, expected: 1, }, { desc: 'handles small availableTerminalHeight gracefully without overflow in ASB mode', options: { status: CoreToolCallStatus.Executing, isAlternateBuffer: true, isThisShellFocused: false, availableTerminalHeight: 6, constrainHeight: true, isExpandable: false, }, expected: 6 - TOOL_RESULT_STANDARD_RESERVED_LINE_COUNT, }, { desc: 'handles negative availableTerminalHeight gracefully', options: { status: CoreToolCallStatus.Executing, isAlternateBuffer: false, isThisShellFocused: false, availableTerminalHeight: -5, constrainHeight: true, isExpandable: false, }, expected: 1, }, { desc: 'returns maxLinesBasedOnHeight for focused ASB shells', options: { status: CoreToolCallStatus.Executing, isAlternateBuffer: true, isThisShellFocused: true, availableTerminalHeight: 30, constrainHeight: false, isExpandable: false, }, expected: 30 - TOOL_RESULT_STANDARD_RESERVED_LINE_COUNT, }, { desc: 'falls back to COMPLETED_SHELL_MAX_LINES - SHELL_CONTENT_OVERHEAD for completed shells if space allows', options: { status: CoreToolCallStatus.Success, isAlternateBuffer: false, isThisShellFocused: false, availableTerminalHeight: 100, constrainHeight: true, isExpandable: false, }, expected: COMPLETED_SHELL_MAX_LINES - SHELL_CONTENT_OVERHEAD, }, { desc: 'falls back to ACTIVE_SHELL_MAX_LINES - SHELL_CONTENT_OVERHEAD for executing shells if space allows', options: { status: CoreToolCallStatus.Executing, isAlternateBuffer: false, isThisShellFocused: false, availableTerminalHeight: 100, constrainHeight: true, isExpandable: false, }, expected: ACTIVE_SHELL_MAX_LINES - SHELL_CONTENT_OVERHEAD, }, ]; it.each(testCases)('$desc', ({ options, expected }) => { const result = calculateShellMaxLines(options); expect(result).toBe(expected); }); }); });