magi-code 0.82.1

Repository-aware CLI coding agent for terminal work
Documentation
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, "No recorded file activity.").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, "No recorded file activity.").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::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(" Session files "));
    let prompt = rendered_text_in_area(buffer, layout.prompt);
    assert!(prompt.contains(" Session: "));
    assert!(prompt.contains(" [Alt-P] 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, "[Alt-P]").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) • [Alt-P] 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 + 2);
    assert_eq!(
        buffer[transcript_text].bg,
        MissionControlTheme::default().surface_panel()
    );
}