use super::*;
#[test]
fn render_uses_matrix_green_palette() {
let mut state = MissionControlState {
status: "ready".to_string(),
prompt_editor: crate::tui::state::PromptEditor::new_with_visibility("scan", 0, true),
..Default::default()
};
state.apply_output_event(&OutputEvent::AssistantDelta {
text: "hello".to_string(),
});
let backend = TestBackend::new(100, 24);
let mut terminal = ratatui::Terminal::new(backend).unwrap();
terminal.draw(|frame| draw(frame, &state)).unwrap();
let buffer = terminal.backend().buffer();
let footer_version =
find_text(buffer, &format!("MAGI-CODE v{}", env!("CARGO_PKG_VERSION"))).unwrap();
assert_eq!(
buffer[footer_version].fg,
MissionControlTheme::default().text_accent()
);
assert_eq!(
buffer[footer_version].bg,
MissionControlTheme::default().surface_background()
);
let transcript_text = find_text(buffer, "hello").unwrap();
assert_eq!(
buffer[transcript_text].fg,
MissionControlTheme::default().text_primary()
);
assert_eq!(
buffer[transcript_text].bg,
MissionControlTheme::default().surface_panel()
);
let prompt_area = layout_for(Rect::new(0, 0, 100, 24), &state).prompt;
let prompt_text_area = content_text_area_for_pane(TuiPane::Prompt, prompt_area);
assert_eq!(
state.prompt_editor.rendered_cursor_position(),
Some(ratatui::layout::Position::new(
prompt_text_area.x,
prompt_text_area.y,
))
);
assert!(find_text(buffer, "█").is_none());
let status = find_text(buffer, "ready").unwrap();
assert_eq!(
buffer[status].fg,
MissionControlTheme::default().text_accent()
);
assert_eq!(
buffer[status].bg,
MissionControlTheme::default().surface_background()
);
}
#[test]
fn render_fills_full_frame_with_opaque_background() {
let state = MissionControlState::default();
let backend = TestBackend::new(100, 24);
let mut terminal = ratatui::Terminal::new(backend).unwrap();
terminal.draw(|frame| draw(frame, &state)).unwrap();
let buffer = terminal.backend().buffer();
assert_eq!(
buffer[(0, 0)].bg,
MissionControlTheme::default().surface_background()
);
assert_eq!(
buffer[(0, 23)].bg,
MissionControlTheme::default().surface_background()
);
}
#[test]
fn render_focus_group_controls_pane_borders() {
let mut state = MissionControlState {
prompt_editor: crate::tui::state::PromptEditor::new_with_visibility("ready", 0, true),
..Default::default()
};
state.apply_output_event(&OutputEvent::AssistantDelta {
text: "transcript-active".to_string(),
});
state.apply_activity_event(ActivityEvent::Started {
id: ActivityId::new("a1"),
parent_id: None,
kind: ActivityKind::Tool,
status: ActivityStatus::Running,
metadata: ActivityMetadata::new("activity-inactive"),
});
let backend = TestBackend::new(100, 24);
let mut terminal = ratatui::Terminal::new(backend).unwrap();
terminal.draw(|frame| draw(frame, &state)).unwrap();
let buffer = terminal.backend().buffer();
let transcript_text = find_text(buffer, "transcript-active").unwrap();
let prompt_text = find_text(buffer, "ready").unwrap();
let activity_text = find_text(buffer, "activity-inactive").unwrap();
let detail_text = find_text(buffer, "id: a1").unwrap();
assert_eq!(
buffer[transcript_text].bg,
MissionControlTheme::default().surface_panel()
);
assert_eq!(
buffer[prompt_text].bg,
MissionControlTheme::default().surface_background()
);
assert_eq!(
buffer[activity_text].bg,
MissionControlTheme::default().surface_background()
);
assert_eq!(
buffer[detail_text].bg,
MissionControlTheme::default().surface_background()
);
let layout = layout_for(Rect::new(0, 0, 100, 24), &state);
let activity_tree = layout.activity_tree.expect("activity tree");
let detail = layout.detail.expect("detail");
let transcript_title = find_text(buffer, "Session:").unwrap();
assert_eq!(
buffer[transcript_title].fg,
MissionControlTheme::default().text_muted()
);
assert_eq!(
buffer[(layout.prompt.x, layout.prompt.y)].fg,
MissionControlTheme::default().text_accent()
);
assert_eq!(
buffer[(activity_tree.x, activity_tree.y)].fg,
MissionControlTheme::default().border(false).fg.unwrap()
);
assert_eq!(
buffer[(detail.x, detail.y)].fg,
MissionControlTheme::default().border(false).fg.unwrap()
);
state.focus_activity_tree();
terminal.draw(|frame| draw(frame, &state)).unwrap();
let buffer = terminal.backend().buffer();
let transcript_text = find_text(buffer, "transcript-active").unwrap();
let prompt_text = find_text(buffer, "ready").unwrap();
let activity_text = find_text(buffer, "activity-inactive").unwrap();
let detail_text = find_text(buffer, "id: a1").unwrap();
assert_eq!(
buffer[transcript_text].bg,
MissionControlTheme::default().surface_panel()
);
assert_eq!(
buffer[prompt_text].bg,
MissionControlTheme::default().surface_background()
);
assert_eq!(
buffer[activity_text].bg,
MissionControlTheme::default().surface_panel_alt()
);
assert_eq!(
buffer[detail_text].bg,
MissionControlTheme::default().surface_background()
);
let layout = layout_for(Rect::new(0, 0, 100, 24), &state);
let activity_tree = layout.activity_tree.expect("activity tree");
let detail = layout.detail.expect("detail");
let transcript_title = find_text(buffer, "Session:").unwrap();
assert_eq!(
buffer[transcript_title].fg,
MissionControlTheme::default().text_muted()
);
assert_eq!(
buffer[(layout.prompt.x, layout.prompt.y)].fg,
MissionControlTheme::default().border(false).fg.unwrap()
);
assert_eq!(
buffer[(activity_tree.x, activity_tree.y)].fg,
MissionControlTheme::default().text_accent()
);
assert_eq!(
buffer[(detail.x, detail.y)].fg,
MissionControlTheme::default().border(false).fg.unwrap()
);
}
#[test]
fn active_style_tracks_exact_focused_pane() {
let mut state = MissionControlState::default();
let backend = TestBackend::new(100, 24);
let mut terminal = ratatui::Terminal::new(backend).unwrap();
for (focus, expected) in [
(
crate::tui::state::TuiFocusPane::Transcript,
TuiPane::Transcript,
),
(
crate::tui::state::TuiFocusPane::ActivityTree,
TuiPane::ActivityTree,
),
(
crate::tui::state::TuiFocusPane::ActivityDetail,
TuiPane::Detail,
),
(crate::tui::state::TuiFocusPane::Prompt, TuiPane::Prompt),
] {
state.focus_pane = focus;
terminal.draw(|frame| draw(frame, &state)).unwrap();
let buffer = terminal.backend().buffer();
let layout = layout_for(Rect::new(0, 0, 100, 24), &state);
let activity_tree = layout.activity_tree.expect("activity tree");
let detail = layout.detail.expect("detail");
for (pane, area) in [
(TuiPane::Transcript, layout.transcript),
(TuiPane::ActivityTree, activity_tree),
(TuiPane::Detail, detail),
(TuiPane::Prompt, layout.prompt),
] {
let expected_fg = if pane == TuiPane::Transcript {
if pane == expected {
MissionControlTheme::default().text_accent()
} else {
MissionControlTheme::default().text_muted()
}
} else if pane == expected {
MissionControlTheme::default().text_accent()
} else {
MissionControlTheme::default().border(false).fg.unwrap()
};
let style_position = if pane == TuiPane::Transcript {
find_text(buffer, "Session:").unwrap()
} else {
(area.x, area.y)
};
assert_eq!(buffer[style_position].fg, expected_fg, "{focus:?} {pane:?}");
}
}
}
#[test]
fn render_pane_borders_use_square_corners_and_padded_titles() {
let state = MissionControlState {
status: "Recent action/status".to_string(),
focus_pane: crate::tui::state::TuiFocusPane::Prompt,
provider_ready: true,
provider: "provider".to_string(),
model: "model".to_string(),
..Default::default()
};
let backend = TestBackend::new(200, 24);
let mut terminal = ratatui::Terminal::new(backend).unwrap();
terminal.draw(|frame| draw(frame, &state)).unwrap();
let buffer = terminal.backend().buffer();
let layout = layout_for(Rect::new(0, 0, 200, 24), &state);
let activity_tree = layout.activity_tree.expect("activity tree");
let detail = layout.detail.expect("detail");
for area in [activity_tree, detail, layout.prompt] {
assert_square_corners(buffer, area);
}
let transcript = rendered_text_in_area(buffer, layout.transcript);
assert!(transcript.contains("Session:"));
assert!(transcript.contains("[Alt-A] Show/Hide Panel"));
assert!(!transcript.contains(" Recent action/status "));
assert!(rendered_text_in_area(buffer, activity_tree).contains(" Activity Tree "));
assert!(!rendered_text_in_area(buffer, activity_tree).contains("[Alt-A]"));
assert!(!rendered_text_in_area(buffer, activity_tree).contains(" 0 Activities "));
assert!(rendered_text_in_area(buffer, detail).contains(" Selected Activity Detail "));
let prompt = rendered_text_in_area(buffer, layout.prompt);
assert!(prompt.contains(" Session: "));
assert!(prompt.contains(" [Shift-Tab] Agent: None "));
assert!(!prompt.contains("Prompt [Alt-P]"));
assert!(!prompt.contains(" [Enter] Submit • [Shift-Enter] Newline "));
let agent_help = find_text_in_area(buffer, layout.prompt, "[Shift-Tab]")
.expect("prompt agent title rendered");
assert_eq!(
buffer[agent_help].fg,
MissionControlTheme::default().text_dim()
);
assert!(!buffer[agent_help].modifier.contains(Modifier::BOLD));
assert_eq!(agent_help.1, layout.prompt.y);
assert!(agent_help.0 > layout.prompt.x + layout.prompt.width / 2);
let prompt_title = find_text_in_area(buffer, layout.prompt, "Session:")
.expect("session usage footer rendered");
assert_eq!(prompt_title.1, layout.prompt.y + layout.prompt.height - 1);
assert!(prompt.contains(" Recent action/status "));
assert!(
prompt.contains(" [Alt-M] provider/model [Alt-T] (default) • [Shift-Tab] Agent: None "),
"{prompt}"
);
}
#[test]
fn render_pane_background_stays_base_inside_borders() {
let state = MissionControlState {
prompt_editor: crate::tui::state::PromptEditor::new_with_visibility("ready", 0, true),
..Default::default()
};
let backend = TestBackend::new(100, 24);
let mut terminal = ratatui::Terminal::new(backend).unwrap();
terminal.draw(|frame| draw(frame, &state)).unwrap();
let buffer = terminal.backend().buffer();
let layout = layout_for(Rect::new(0, 0, 100, 24), &state);
let prompt_border = (layout.prompt.x, layout.prompt.y);
let prompt_inner = find_text(buffer, "ready").unwrap();
assert_eq!(
buffer[prompt_border].bg,
MissionControlTheme::default().surface_background()
);
assert_eq!(
buffer[prompt_inner].bg,
MissionControlTheme::default().surface_background()
);
}
#[test]
fn render_pane_background_uses_base_across_inner_area() {
let mut state = MissionControlState {
focus_pane: crate::tui::state::TuiFocusPane::Prompt,
..Default::default()
};
state.transcript = vec!["padded transcript".to_string()].into();
let backend = TestBackend::new(100, 30);
let mut terminal = ratatui::Terminal::new(backend).unwrap();
terminal.draw(|frame| draw(frame, &state)).unwrap();
let buffer = terminal.backend().buffer();
let layout = layout_for(Rect::new(0, 0, 100, 30), &state);
let transcript_inner =
crate::tui::render::content_text_area_for_pane(TuiPane::Transcript, layout.transcript);
let card_row = transcript_inner.y;
assert_eq!(
buffer[(layout.transcript.x, card_row)].bg,
MissionControlTheme::default().surface_background()
);
assert_eq!(
buffer[(layout.transcript.x + layout.transcript.width - 1, card_row)].bg,
MissionControlTheme::default().surface_background()
);
assert_eq!(
buffer[(transcript_inner.x, layout.transcript.y)].bg,
MissionControlTheme::default().surface_background()
);
assert_eq!(
buffer[(
transcript_inner.x,
layout.transcript.y + layout.transcript.height - 1
)]
.bg,
MissionControlTheme::default().surface_background()
);
assert_eq!(
buffer[(transcript_inner.x, transcript_inner.y)].bg,
MissionControlTheme::default().surface_panel_alt()
);
assert_eq!(
buffer[(transcript_inner.x + 1, transcript_inner.y)].bg,
MissionControlTheme::default().surface_panel_alt()
);
assert_eq!(
buffer[(
transcript_inner.x + transcript_inner.width - 1,
transcript_inner.y
)]
.bg,
MissionControlTheme::default().surface_background()
);
assert_eq!(
buffer[(
transcript_inner.x + 1,
transcript_inner.y + transcript_inner.height - 1
)]
.bg,
MissionControlTheme::default().surface_background()
);
}
#[test]
fn render_pane_text_uses_horizontal_padding_and_border_only_vertical() {
let mut state = MissionControlState {
focus_pane: crate::tui::state::TuiFocusPane::Prompt,
..Default::default()
};
state.transcript = vec!["padded transcript".to_string()].into();
let backend = TestBackend::new(100, 30);
let mut terminal = ratatui::Terminal::new(backend).unwrap();
terminal.draw(|frame| draw(frame, &state)).unwrap();
let buffer = terminal.backend().buffer();
let layout = layout_for(Rect::new(0, 0, 100, 30), &state);
let text_area = content_text_area_for_pane(TuiPane::Transcript, layout.transcript);
let transcript_text = find_text(buffer, "padded transcript").unwrap();
assert_eq!(transcript_text.0, text_area.x + 3);
assert_eq!(transcript_text.1, text_area.y + 4);
assert_eq!(
buffer[transcript_text].bg,
MissionControlTheme::default().surface_panel()
);
}