use super::*;
#[test]
fn render_uses_matrix_green_palette() {
let mut state = MissionControlState {
status: "ready".to_string(),
input: "scan".to_string(),
focus_pane: crate::tui::state::TuiFocusPane::Prompt,
prompt_cursor_visible: 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, MATRIX_GREEN.green_bright);
assert_eq!(buffer[footer_version].bg, MATRIX_GREEN.background);
let transcript_text = find_text(buffer, "hello").unwrap();
assert_eq!(buffer[transcript_text].fg, MATRIX_GREEN.text);
assert_eq!(buffer[transcript_text].bg, MATRIX_GREEN.background);
let cursor = find_text(buffer, "â–ˆ").unwrap();
assert_eq!(buffer[cursor].fg, MATRIX_GREEN.green_neon);
assert_eq!(buffer[cursor].bg, MATRIX_GREEN.background);
let status = find_text(buffer, "ready").unwrap();
assert_eq!(buffer[status].fg, MATRIX_GREEN.green_bright);
assert_eq!(buffer[status].bg, MATRIX_GREEN.background);
}
#[test]
fn render_focus_group_controls_pane_borders() {
let mut state = MissionControlState {
input: "ready".to_string(),
focus_pane: crate::tui::state::TuiFocusPane::Prompt,
prompt_cursor_visible: 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, MATRIX_GREEN.background);
assert_eq!(buffer[prompt_text].bg, MATRIX_GREEN.background);
assert_eq!(buffer[activity_text].bg, MATRIX_GREEN.background);
assert_eq!(buffer[detail_text].bg, MATRIX_GREEN.background);
let layout = layout_for(Rect::new(0, 0, 100, 24), &state);
assert_eq!(
buffer[(layout.transcript.x, layout.transcript.y)].fg,
MATRIX_GREEN.green_muted
);
assert_eq!(
buffer[(layout.prompt.x, layout.prompt.y)].fg,
MATRIX_GREEN.green_bright
);
assert_eq!(
buffer[(layout.activity_tree.x, layout.activity_tree.y)].fg,
MATRIX_GREEN.border_dark
);
assert_eq!(
buffer[(layout.detail.x, layout.detail.y)].fg,
MATRIX_GREEN.border_dark
);
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, MATRIX_GREEN.background);
assert_eq!(buffer[prompt_text].bg, MATRIX_GREEN.background);
assert_eq!(buffer[activity_text].bg, MATRIX_GREEN.selection);
assert_eq!(buffer[detail_text].bg, MATRIX_GREEN.background);
let layout = layout_for(Rect::new(0, 0, 100, 24), &state);
assert_eq!(
buffer[(layout.transcript.x, layout.transcript.y)].fg,
MATRIX_GREEN.green_muted
);
assert_eq!(
buffer[(layout.prompt.x, layout.prompt.y)].fg,
MATRIX_GREEN.border_dark
);
assert_eq!(
buffer[(layout.activity_tree.x, layout.activity_tree.y)].fg,
MATRIX_GREEN.green_bright
);
assert_eq!(
buffer[(layout.detail.x, layout.detail.y)].fg,
MATRIX_GREEN.border_dark
);
}
#[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);
for (pane, area) in [
(TuiPane::Transcript, layout.transcript),
(TuiPane::ActivityTree, layout.activity_tree),
(TuiPane::Detail, layout.detail),
(TuiPane::Prompt, layout.prompt),
] {
let expected_fg = if pane == TuiPane::Transcript {
if pane == expected {
MATRIX_GREEN.green_bright
} else {
MATRIX_GREEN.green_muted
}
} else if pane == expected {
MATRIX_GREEN.green_bright
} else {
MATRIX_GREEN.border_dark
};
assert_eq!(
buffer[(area.x, area.y)].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);
for area in [layout.activity_tree, layout.detail, layout.prompt] {
assert_square_corners(buffer, area);
}
let transcript = rendered_text_in_area(buffer, layout.transcript);
assert!(transcript.contains("Session:"));
assert!(!transcript.contains("Transcript [Alt-1]"));
assert!(!transcript.contains(" Recent action/status "));
assert!(
rendered_text_in_area(buffer, layout.activity_tree).contains(" Activity Tree [Alt-1] ")
);
assert!(!rendered_text_in_area(buffer, layout.activity_tree).contains(" 0 Activities "));
assert!(
rendered_text_in_area(buffer, layout.detail).contains(" Selected Activity Detail [Alt-2] ")
);
let prompt = rendered_text_in_area(buffer, layout.prompt);
assert!(prompt.contains(" Prompt [Alt-P] • [Shift-Tab] Agent: None "));
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, MATRIX_GREEN.green_dim);
assert!(!buffer[agent_help].modifier.contains(Modifier::BOLD));
assert!(prompt.contains(" Recent action/status "));
assert!(
prompt.contains(" [Alt-M] • provider • model "),
"{prompt}"
);
}
#[test]
fn render_pane_background_stays_base_inside_borders() {
let state = MissionControlState {
input: "ready".to_string(),
focus_pane: crate::tui::state::TuiFocusPane::Prompt,
prompt_cursor_visible: 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, MATRIX_GREEN.background);
assert_eq!(buffer[prompt_inner].bg, MATRIX_GREEN.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);
assert_eq!(
buffer[(transcript_inner.x, transcript_inner.y)].bg,
MATRIX_GREEN.background
);
assert_eq!(
buffer[(transcript_inner.x + 1, transcript_inner.y)].bg,
MATRIX_GREEN.background
);
assert_eq!(
buffer[(
transcript_inner.x + transcript_inner.width - 1,
transcript_inner.y
)]
.bg,
MATRIX_GREEN.background
);
assert_eq!(
buffer[(
transcript_inner.x + 1,
transcript_inner.y + transcript_inner.height - 1
)]
.bg,
MATRIX_GREEN.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 + 4);
assert_eq!(transcript_text.1, text_area.y + 1);
assert_eq!(buffer[transcript_text].bg, MATRIX_GREEN.background);
}