magi-code 0.64.0

Repository-aware CLI coding agent for terminal work
Documentation
use super::*;

#[test]
fn render_activity_tree_scrolls_to_selected_overflow_item() {
    let mut state = MissionControlState::default();
    for index in 0..10 {
        state.apply_activity_event(ActivityEvent::Started {
            id: ActivityId::new(format!("a{index}")),
            parent_id: None,
            kind: ActivityKind::Tool,
            status: ActivityStatus::Running,
            metadata: ActivityMetadata::new(format!("item-{index}")),
        });
    }
    state.selected = 9;

    let backend = TestBackend::new(80, 16);
    let mut terminal = ratatui::Terminal::new(backend).unwrap();
    terminal.draw(|frame| draw(frame, &state)).unwrap();
    let rendered = terminal
        .backend()
        .buffer()
        .content()
        .iter()
        .map(|cell| cell.symbol())
        .collect::<String>();

    assert!(rendered.contains("item-9"));
    assert!(!rendered.contains("item-0"));
}

#[test]
fn render_selected_activity_detail_when_activity_selected_after_scrolling() {
    let mut state = MissionControlState::default();
    state.apply_activity_event(ActivityEvent::Started {
        id: ActivityId::new("a1"),
        parent_id: None,
        kind: ActivityKind::Tool,
        status: ActivityStatus::Running,
        metadata: ActivityMetadata::new("bash echo"),
    });
    state.apply_activity_event(ActivityEvent::Started {
        id: ActivityId::new("a2"),
        parent_id: None,
        kind: ActivityKind::Tool,
        status: ActivityStatus::Success,
        metadata: ActivityMetadata::new("read file"),
    });
    state.selected = 1;

    let backend = TestBackend::new(100, 30);
    let mut terminal = ratatui::Terminal::new(backend).unwrap();
    terminal.draw(|frame| draw(frame, &state)).unwrap();
    let rendered = terminal
        .backend()
        .buffer()
        .content()
        .iter()
        .map(|cell| cell.symbol())
        .collect::<String>();

    assert!(rendered.contains("✓ SUCCESS"));
    assert!(rendered.contains("id: a2"));
    assert!(rendered.contains("label: read file"));
}

#[test]
fn render_activity_tree_includes_compact_metadata_without_raw_detail_noise() {
    let mut state = MissionControlState::default();
    let mut metadata = ActivityMetadata::new("bash cargo test");
    metadata.detail = Some("bash preview: final output only".to_string());
    metadata.fields = vec![
        ("exit_code".to_string(), "101".to_string()),
        ("output_lines".to_string(), "12".to_string()),
        ("timed_out".to_string(), "false".to_string()),
    ];
    state.apply_activity_event(ActivityEvent::Started {
        id: ActivityId::new("tool-1"),
        parent_id: None,
        kind: ActivityKind::Tool,
        status: ActivityStatus::Failed,
        metadata,
    });

    let backend = TestBackend::new(200, 20);
    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, 20), &state);
    let rendered = rendered_text_in_area(buffer, layout.activity_tree);

    assert!(rendered.contains("bash cargo test • exit 101 • lines 12"));
    assert!(!rendered.contains("timed out false"));
    assert!(!rendered.contains("final output only"));
}

#[test]
fn render_subagent_activity_tree_includes_identity_metadata() {
    let mut state = MissionControlState::default();
    let mut metadata = ActivityMetadata::new("g1 • inspect UI");
    metadata.fields = vec![("identity".to_string(), "frontend-dev".to_string())];
    state.apply_activity_event(ActivityEvent::Started {
        id: ActivityId::new("subagents/g1"),
        parent_id: None,
        kind: ActivityKind::SubagentTask,
        status: ActivityStatus::Running,
        metadata,
    });

    let backend = TestBackend::new(200, 20);
    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, 20), &state);
    let rendered = rendered_text_in_area(buffer, layout.activity_tree);

    assert!(rendered.contains("g1 • inspect UI • identity: frontend-dev"));
}

#[test]
fn render_activity_status_kind_and_selection_styles() {
    let mut state = MissionControlState {
        focus_pane: crate::tui::state::TuiFocusPane::ActivityTree,
        ..Default::default()
    };
    let cases = [
        ("queued-tool", ActivityStatus::Queued, ActivityKind::Tool),
        (
            "running-batch",
            ActivityStatus::Running,
            ActivityKind::SubagentBatch,
        ),
        (
            "success-task",
            ActivityStatus::Success,
            ActivityKind::SubagentTask,
        ),
        (
            "failed-assistant",
            ActivityStatus::Failed,
            ActivityKind::Assistant,
        ),
        (
            "canceled-diagnostic",
            ActivityStatus::Canceled,
            ActivityKind::Diagnostic,
        ),
    ];
    for (label, status, kind) in cases {
        state.apply_activity_event(ActivityEvent::Started {
            id: ActivityId::new(label),
            parent_id: None,
            kind,
            status,
            metadata: ActivityMetadata::new(label),
        });
    }
    state.selected = 2;

    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 queued = find_text(buffer, "queued-tool").unwrap();
    assert_eq!(buffer[(queued.0 - 4, queued.1)].fg, MATRIX_GREEN.green_dim);
    assert_eq!(buffer[(queued.0 - 4, queued.1)].bg, MATRIX_GREEN.background);
    assert_eq!(
        buffer[(queued.0 - 2, queued.1)].fg,
        MATRIX_GREEN.green_bright
    );

    let running = find_text(buffer, "running-batch").unwrap();
    assert_eq!(
        buffer[(running.0 - 4, running.1)].fg,
        MATRIX_GREEN.green_bright
    );
    assert_eq!(
        buffer[(running.0 - 2, running.1)].fg,
        MATRIX_GREEN.cyan_mint
    );

    let selected = find_text(buffer, "success-task").unwrap();
    assert_eq!(buffer[selected].bg, MATRIX_GREEN.selection);
    assert_eq!(
        buffer[(selected.0 - 4, selected.1)].fg,
        MATRIX_GREEN.green_neon
    );
    assert_eq!(
        buffer[(selected.0 - 4, selected.1)].bg,
        MATRIX_GREEN.selection
    );
    assert_eq!(buffer[(selected.0 - 2, selected.1)].fg, MATRIX_GREEN.mint);

    let failed = find_text(buffer, "failed-assistant").unwrap();
    assert_eq!(
        buffer[(failed.0 - 4, failed.1)].fg,
        MATRIX_GREEN.lavender_cool
    );
    assert_eq!(buffer[(failed.0 - 4, failed.1)].bg, MATRIX_GREEN.error_bg);
    assert_eq!(buffer[(failed.0 - 2, failed.1)].fg, MATRIX_GREEN.green_neon);

    let canceled = find_text(buffer, "canceled-diagnostic").unwrap();
    assert_eq!(
        buffer[(canceled.0 - 4, canceled.1)].fg,
        MATRIX_GREEN.green_dim
    );
    assert_eq!(
        buffer[(canceled.0 - 2, canceled.1)].fg,
        MATRIX_GREEN.lavender_cool
    );
}