magi-code 0.77.1

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

#[test]
fn alt_c_collapses_all_activity_tree_when_no_startup_prompt_is_queued() {
    let mut state = state_with_parent_and_child();
    state.expanded.insert(ActivityId::new("parent"));

    assert_eq!(
        handle_key(
            modified_key(KeyCode::Char('c'), KeyModifiers::ALT),
            &mut state,
        ),
        InputAction::None
    );
    assert!(state.expanded.is_empty());
}

#[test]
fn modifier_bindings_trigger_activity_actions() {
    let mut state = state_with_activity();
    state.focus_activity_tree();
    assert_eq!(state.selected, 0);

    assert!(matches!(
        handle_key(
            modified_key(KeyCode::Char('j'), KeyModifiers::ALT),
            &mut state
        ),
        InputAction::None
    ));
    assert_eq!(state.selected, 1);

    assert!(matches!(
        handle_key(
            modified_key(KeyCode::Char('k'), KeyModifiers::ALT),
            &mut state
        ),
        InputAction::None
    ));
    assert_eq!(state.selected, 0);

    assert!(matches!(
        handle_key(
            modified_key(KeyCode::Char('f'), KeyModifiers::ALT),
            &mut state
        ),
        InputAction::None
    ));
    assert_eq!(state.selected, 1);

    assert!(matches!(
        handle_key(
            modified_key(KeyCode::Char('r'), KeyModifiers::ALT),
            &mut state
        ),
        InputAction::None
    ));
    assert_eq!(state.selected, 0);
}

#[test]
fn left_and_right_collapse_and_expand_selected_activity() {
    let mut state = state_with_parent_and_child();
    assert_eq!(state.visible_nodes().len(), 2);
    assert_eq!(state.selected, 0);

    assert!(matches!(
        handle_key(key(KeyCode::Left), &mut state),
        InputAction::None
    ));
    assert_eq!(state.visible_nodes().len(), 1);
    assert_eq!(state.selected, 0);
    assert_eq!(state.selected_activity_id().unwrap().as_str(), "parent");

    assert!(matches!(
        handle_key(key(KeyCode::Right), &mut state),
        InputAction::None
    ));
    assert_eq!(state.visible_nodes().len(), 2);
    assert_eq!(state.selected, 0);
    assert_eq!(state.selected_activity_id().unwrap().as_str(), "parent");
}

#[test]
fn left_right_on_leaf_are_no_ops() {
    let mut state = state_with_parent_and_child();
    state.selected = 1;
    let child = state.selected_activity_id().unwrap();
    let was_expanded = state.expanded.clone();

    assert!(matches!(
        handle_key(key(KeyCode::Left), &mut state),
        InputAction::None
    ));
    assert_eq!(state.selected, 1);
    assert_eq!(state.selected_activity_id().unwrap(), child);
    assert_eq!(state.expanded, was_expanded);

    assert!(matches!(
        handle_key(key(KeyCode::Right), &mut state),
        InputAction::None
    ));
    assert_eq!(state.selected, 1);
    assert_eq!(state.selected_activity_id().unwrap(), child);
    assert_eq!(state.expanded, was_expanded);
}

#[test]
fn changing_activity_selection_resets_detail() {
    let mut state = state_with_activity();
    for id in ["running", "failed"] {
        state.apply_activity_event(ActivityEvent::Delta {
            id: ActivityId::new(id),
            preview: "detail row 1\ndetail row 2\ndetail row 3".to_string(),
        });
    }
    state.focus_activity_tree();
    state.scroll_detail_down();
    assert_eq!(state.detail_offset(), 1);

    assert!(matches!(
        handle_key(key(KeyCode::Down), &mut state),
        InputAction::None
    ));
    assert_eq!(state.selected, 1);
    assert_eq!(state.detail_offset(), 0);

    state.scroll_detail_down();
    assert!(matches!(
        handle_key(
            modified_key(KeyCode::Char('r'), KeyModifiers::ALT),
            &mut state
        ),
        InputAction::None
    ));
    assert_eq!(state.selected, 0);
    assert_eq!(state.detail_offset(), 0);
}

#[test]
fn collapse_all_clamps_child_selection_and_preserves_valid_detail() {
    let mut state = MissionControlState {
        focus_pane: crate::tui::state::TuiFocusPane::ActivityTree,
        prompt_editor: crate::tui::state::PromptEditor::new("draft stays", "draft stays".len()),
        transcript: vec!["you: existing".to_string()].into(),
        ..Default::default()
    };
    let parent = ActivityId::new("parent");
    let child = ActivityId::new("child");
    state.apply_activity_event(ActivityEvent::Started {
        id: parent.clone(),
        parent_id: None,
        kind: ActivityKind::SubagentBatch,
        status: ActivityStatus::Running,
        metadata: ActivityMetadata::new("parent activity"),
    });
    state.apply_activity_event(ActivityEvent::Started {
        id: child,
        parent_id: Some(parent),
        kind: ActivityKind::Tool,
        status: ActivityStatus::Success,
        metadata: ActivityMetadata::new("child activity"),
    });
    state.apply_activity_event(ActivityEvent::Delta {
        id: ActivityId::new("child"),
        preview: "detail row 1\ndetail row 2".to_string(),
    });
    assert_eq!(state.visible_nodes().len(), 2);
    state.selected = 1;
    state.scroll_detail_down();

    assert!(matches!(
        handle_key(
            modified_key(KeyCode::Char('c'), KeyModifiers::ALT),
            &mut state
        ),
        InputAction::None
    ));

    assert_eq!(state.visible_nodes().len(), 1);
    assert_eq!(state.prompt_plain_text(), "draft stays");
    assert_eq!(state.prompt_cursor(), "draft stays".len());
    assert_eq!(state.transcript, vec!["you: existing".to_string()]);
    assert_eq!(state.selected, 0);
    assert_eq!(state.detail_offset(), 0);
    let detail = state.selected_activity_text();
    assert!(detail.contains("id: parent"));
    assert!(detail.contains("label: parent activity"));
    assert!(!detail.contains("No activity selected"));
}

#[test]
fn activity_arrows_still_control_activity_when_activity_focused() {
    let mut state = state_with_activity();
    state.focus_activity_tree();

    assert!(matches!(
        handle_key_with_viewport(key(KeyCode::Down), &mut state, None, &[]),
        InputAction::None
    ));
    assert_eq!(state.selected, 1);
    assert_eq!(state.prompt_cursor(), 0);
}