git-iris 2.0.8

AI-powered Git workflow assistant for smart commits, code reviews, changelogs, and release notes
Documentation
use crate::config::Config;
use crate::studio::events::SideEffect;
use crate::studio::handlers::handle_explore_key;
use crate::studio::state::{FileLogEntry, Mode, NotificationLevel, PanelId, StudioState};
use crossterm::event::{KeyCode, KeyEvent};
use std::path::PathBuf;

fn test_state() -> StudioState {
    let mut state = StudioState::new(Config::default(), None);
    state.active_mode = Mode::Explore;
    state.focused_panel = PanelId::Center;
    state
}

#[test]
fn open_in_editor_copies_editor_command_for_selected_file() {
    let mut state = test_state();
    state.modes.explore.current_file = Some(PathBuf::from("src/main.rs"));
    state.modes.explore.current_line = 42;

    let effects = handle_explore_key(&mut state, KeyEvent::from(KeyCode::Char('o')));

    let copied = effects
        .iter()
        .find_map(|effect| match effect {
            SideEffect::CopyToClipboard(command) => Some(command),
            _ => None,
        })
        .expect("editor command should be copied");

    assert!(copied.contains("+42"));
    assert!(copied.contains("src/main.rs"));

    let notification = state
        .notifications
        .back()
        .expect("success notification should be emitted");
    assert_eq!(notification.level, NotificationLevel::Success);
    assert_eq!(notification.message, "Editor command copied");
}

#[test]
fn open_in_editor_without_selection_warns() {
    let mut state = test_state();

    let effects = handle_explore_key(&mut state, KeyEvent::from(KeyCode::Char('o')));

    assert!(effects.is_empty());

    let notification = state
        .notifications
        .back()
        .expect("warning notification should be emitted");
    assert_eq!(notification.level, NotificationLevel::Warning);
    assert_eq!(notification.message, "No file selected");
}

#[test]
fn enter_on_file_history_copies_git_show_command() {
    let mut state = test_state();
    state.focused_panel = PanelId::Right;
    state.modes.explore.current_file = Some(PathBuf::from("src/main.rs"));
    state.modes.explore.file_log = vec![FileLogEntry {
        hash: "abcdef1234567890".to_string(),
        short_hash: "abcdef1".to_string(),
        message: "Add feature".to_string(),
        author: "Bliss".to_string(),
        relative_time: "today".to_string(),
        additions: Some(5),
        deletions: Some(1),
    }];

    let effects = handle_explore_key(&mut state, KeyEvent::from(KeyCode::Enter));

    let copied = effects
        .iter()
        .find_map(|effect| match effect {
            SideEffect::CopyToClipboard(command) => Some(command),
            _ => None,
        })
        .expect("git show command should be copied");

    assert_eq!(copied, "git show abcdef1234567890 -- 'src/main.rs'");

    let notification = state
        .notifications
        .back()
        .expect("success notification should be emitted");
    assert_eq!(notification.level, NotificationLevel::Success);
    assert_eq!(notification.message, "git show command copied");
}

#[test]
fn enter_on_global_history_uses_global_log_entry() {
    let mut state = test_state();
    state.focused_panel = PanelId::Right;
    state.modes.explore.show_global_log = true;
    state.modes.explore.file_log = vec![FileLogEntry {
        hash: "wrong111111111111".to_string(),
        short_hash: "wrong11".to_string(),
        message: "Wrong entry".to_string(),
        author: "Bliss".to_string(),
        relative_time: "today".to_string(),
        additions: None,
        deletions: None,
    }];
    state.modes.explore.global_log = vec![FileLogEntry {
        hash: "fedcba0987654321".to_string(),
        short_hash: "fedcba0".to_string(),
        message: "Global entry".to_string(),
        author: "Bliss".to_string(),
        relative_time: "today".to_string(),
        additions: None,
        deletions: None,
    }];

    let effects = handle_explore_key(&mut state, KeyEvent::from(KeyCode::Enter));

    let copied = effects
        .iter()
        .find_map(|effect| match effect {
            SideEffect::CopyToClipboard(command) => Some(command),
            _ => None,
        })
        .expect("git show command should be copied");

    assert_eq!(copied, "git show fedcba0987654321");
}