Files
codex/codex-rs/tui/src/oss_selection_tests.rs
T
Eric Traut c9d13e8c75 Unify TUI prompts with shared picker styling and layouts (#46695)
## Why

Prompt layouts use inconsistent selection styles, and long content can crowd out choices and keyboard hints in small terminals.

## What changed

- Apply shared picker surfaces, selection highlights, accent colors, and shortcut styling across approval, question, startup, and session prompts.
- Reuse numbered picker rows with wrapping and selected-item visibility. Bound folder paths to preserve trust disclosures and choices, prioritizing the repository root when space is limited.
- Give multiline prompts a shared layout for rendering and cursor placement, with Escape hints that reflect Vim mode.
- Present local providers as vertical choices with inline status, adding arrow-key and `j`/`k` navigation plus `1`/`2` selection shortcuts.

## Testing

Add snapshots and regression tests for narrow and short viewports, long trust paths, multiline cursor placement after resizing, selection styling, provider shortcuts, and confirmation behavior.

GitOrigin-RevId: 89bb133dfa0d085d568a3a84473afd9e2fb20838
2026-09-19 19:14:11 +00:00

85 lines
2.6 KiB
Rust

//! Presentation and new keyboard navigation checks for the local-provider startup picker.
use super::*;
use crate::test_backend::VT100Backend;
use pretty_assertions::assert_eq;
use ratatui::widgets::FrameExt;
#[test]
fn provider_picker_snapshots() {
for (name, lmstudio, ollama, width, height, selected) in [
(
"oss_providers_stopped",
ProviderStatus::NotRunning,
ProviderStatus::NotRunning,
80,
24,
0,
),
(
"oss_providers_running",
ProviderStatus::Running,
ProviderStatus::Running,
80,
24,
1,
),
(
"oss_providers_unknown_narrow",
ProviderStatus::Unknown,
ProviderStatus::Unknown,
40,
16,
0,
),
(
"oss_providers_mixed_short",
ProviderStatus::NotRunning,
ProviderStatus::Running,
28,
12,
1,
),
] {
let mut widget = OssSelectionWidget::new(lmstudio, ollama);
widget.selected_option = selected;
let mut terminal = Terminal::new(VT100Backend::new(width, height)).expect("terminal");
terminal
.draw(|frame| frame.render_widget_ref(&widget, frame.area()))
.expect("draw");
insta::assert_snapshot!(name, terminal.backend());
}
}
#[test]
fn navigation_wraps_without_confirming() {
for event in [
KeyEvent::new(KeyCode::Up, KeyModifiers::NONE),
KeyEvent::new(KeyCode::Down, KeyModifiers::NONE),
KeyEvent::new(KeyCode::Char('j'), KeyModifiers::NONE),
KeyEvent::new(KeyCode::Char('k'), KeyModifiers::NONE),
] {
let mut widget = OssSelectionWidget::new(ProviderStatus::Running, ProviderStatus::Running);
assert_eq!(widget.handle_key_event(event), None);
assert_eq!((widget.selected_option, widget.is_complete()), (1, false));
assert_eq!(widget.handle_key_event(event), None);
assert_eq!((widget.selected_option, widget.is_complete()), (0, false));
}
}
#[test]
fn shortcuts_select_the_provider_even_when_unavailable() {
for (key, provider) in [
('1', LMSTUDIO_OSS_PROVIDER_ID),
('2', OLLAMA_OSS_PROVIDER_ID),
] {
let mut widget =
OssSelectionWidget::new(ProviderStatus::NotRunning, ProviderStatus::NotRunning);
assert_eq!(
widget.handle_key_event(KeyEvent::new(KeyCode::Char(key), KeyModifiers::NONE)),
Some(provider.to_string())
);
assert!(widget.is_complete());
}
}