use ratatui::crossterm::event::{MouseButton, MouseEvent, MouseEventKind};
use ratatui::layout::Rect;
use super::*;
use crate::ai::suggestion::{Suggestion, SuggestionType};
use crate::test_utils::test_helpers::test_app;
fn create_test_app() -> App {
test_app(r#"{"test": "data"}"#)
}
fn create_mouse_event(column: u16, row: u16) -> MouseEvent {
MouseEvent {
kind: MouseEventKind::Moved,
column,
row,
modifiers: ratatui::crossterm::event::KeyModifiers::NONE,
}
}
fn create_drag_event(column: u16, row: u16) -> MouseEvent {
MouseEvent {
kind: MouseEventKind::Drag(MouseButton::Left),
column,
row,
modifiers: ratatui::crossterm::event::KeyModifiers::NONE,
}
}
#[test]
fn test_hover_outside_ai_window_clears_hover() {
let mut app = create_test_app();
app.ai.visible = true;
app.ai.suggestions = vec![Suggestion {
query: ".test".to_string(),
suggestion_type: SuggestionType::Fix,
description: String::new(),
}];
app.ai.selection.set_hovered(Some(0));
let mouse = create_mouse_event(0, 0);
handle_hover(&mut app, None, mouse);
assert!(app.ai.selection.get_hovered().is_none());
}
#[test]
fn test_hover_ai_window_no_suggestions() {
let mut app = create_test_app();
app.ai.visible = true;
app.ai.suggestions = vec![];
app.layout_regions.ai_window = Some(Rect::new(10, 5, 30, 10));
let mouse = create_mouse_event(15, 7);
handle_hover(&mut app, Some(Region::AiWindow), mouse);
assert!(app.ai.selection.get_hovered().is_none());
}
#[test]
fn test_hover_ai_window_not_visible() {
let mut app = create_test_app();
app.ai.visible = false;
app.ai.suggestions = vec![Suggestion {
query: ".test".to_string(),
suggestion_type: SuggestionType::Fix,
description: String::new(),
}];
app.layout_regions.ai_window = Some(Rect::new(10, 5, 30, 10));
let mouse = create_mouse_event(15, 7);
handle_hover(&mut app, Some(Region::AiWindow), mouse);
assert!(app.ai.selection.get_hovered().is_none());
}
#[test]
fn test_hover_ai_window_no_region() {
let mut app = create_test_app();
app.ai.visible = true;
app.ai.suggestions = vec![Suggestion {
query: ".test".to_string(),
suggestion_type: SuggestionType::Fix,
description: String::new(),
}];
app.layout_regions.ai_window = None;
let mouse = create_mouse_event(15, 7);
handle_hover(&mut app, Some(Region::AiWindow), mouse);
assert!(app.ai.selection.get_hovered().is_none());
}
#[test]
fn test_hover_on_border_clears_hover() {
let mut app = create_test_app();
app.ai.visible = true;
app.ai.suggestions = vec![Suggestion {
query: ".test".to_string(),
suggestion_type: SuggestionType::Fix,
description: String::new(),
}];
app.layout_regions.ai_window = Some(Rect::new(10, 5, 30, 10));
app.ai.selection.update_layout(vec![3], 8);
app.ai.selection.set_hovered(Some(0));
let mouse = create_mouse_event(10, 5);
handle_hover(&mut app, Some(Region::AiWindow), mouse);
assert!(app.ai.selection.get_hovered().is_none());
}
#[test]
fn test_hover_results_pane_clears_ai_hover() {
let mut app = create_test_app();
app.ai.selection.set_hovered(Some(0));
let mouse = create_mouse_event(5, 5);
handle_hover(&mut app, Some(Region::ResultsPane), mouse);
assert!(app.ai.selection.get_hovered().is_none());
}
#[test]
fn test_hover_snippet_list_updates_hovered_index() {
let mut app = create_test_app();
app.snippets.open();
app.snippets.set_snippets(vec![
crate::snippets::Snippet {
name: "test1".to_string(),
query: ".test1".to_string(),
description: None,
},
crate::snippets::Snippet {
name: "test2".to_string(),
query: ".test2".to_string(),
description: None,
},
]);
app.layout_regions.snippet_list = Some(Rect::new(0, 0, 50, 10));
let mouse = create_mouse_event(5, 2);
handle_hover(&mut app, Some(Region::SnippetList), mouse);
assert_eq!(app.snippets.get_hovered(), Some(1));
}
#[test]
fn test_hover_snippet_list_on_border_clears_hover() {
let mut app = create_test_app();
app.snippets.open();
app.snippets.set_snippets(vec![crate::snippets::Snippet {
name: "test1".to_string(),
query: ".test1".to_string(),
description: None,
}]);
app.snippets.set_hovered(Some(0));
app.layout_regions.snippet_list = Some(Rect::new(10, 5, 30, 10));
let mouse = create_mouse_event(10, 5);
handle_hover(&mut app, Some(Region::SnippetList), mouse);
assert!(app.snippets.get_hovered().is_none());
}
#[test]
fn test_leaving_snippet_list_clears_hover() {
let mut app = create_test_app();
app.snippets.open();
app.snippets.set_snippets(vec![crate::snippets::Snippet {
name: "test1".to_string(),
query: ".test1".to_string(),
description: None,
}]);
app.snippets.set_hovered(Some(0));
let mouse = create_mouse_event(5, 5);
handle_hover(&mut app, Some(Region::ResultsPane), mouse);
assert!(app.snippets.get_hovered().is_none());
}
#[test]
fn test_hover_snippet_list_when_not_visible() {
let mut app = create_test_app();
app.snippets.set_snippets(vec![crate::snippets::Snippet {
name: "test1".to_string(),
query: ".test1".to_string(),
description: None,
}]);
app.layout_regions.snippet_list = Some(Rect::new(0, 0, 50, 10));
let mouse = create_mouse_event(5, 2);
handle_hover(&mut app, Some(Region::SnippetList), mouse);
assert!(app.snippets.get_hovered().is_none());
}
#[test]
fn test_hover_snippet_list_no_region() {
let mut app = create_test_app();
app.snippets.open();
app.snippets.set_snippets(vec![crate::snippets::Snippet {
name: "test1".to_string(),
query: ".test1".to_string(),
description: None,
}]);
app.layout_regions.snippet_list = None;
let mouse = create_mouse_event(5, 2);
handle_hover(&mut app, Some(Region::SnippetList), mouse);
assert!(app.snippets.get_hovered().is_none());
}
#[test]
fn test_hover_help_popup_tab_bar() {
use crate::help::HelpTab;
let mut app = create_test_app();
app.help.visible = true;
app.layout_regions.help_popup = Some(Rect::new(10, 5, 70, 20));
let mouse = create_mouse_event(15, 6);
handle_hover(&mut app, Some(Region::HelpPopup), mouse);
assert_eq!(app.help.get_hovered_tab(), Some(HelpTab::Global));
}
#[test]
fn test_hover_help_popup_second_tab() {
use crate::help::HelpTab;
let mut app = create_test_app();
app.help.visible = true;
app.layout_regions.help_popup = Some(Rect::new(10, 5, 70, 20));
let mouse = create_mouse_event(24, 6);
handle_hover(&mut app, Some(Region::HelpPopup), mouse);
assert_eq!(app.help.get_hovered_tab(), Some(HelpTab::Input));
}
#[test]
fn test_hover_help_popup_on_divider_clears_hover() {
let mut app = create_test_app();
app.help.visible = true;
app.layout_regions.help_popup = Some(Rect::new(10, 5, 70, 20));
app.help.set_hovered_tab(Some(crate::help::HelpTab::Input));
let mouse = create_mouse_event(21, 6);
handle_hover(&mut app, Some(Region::HelpPopup), mouse);
assert_eq!(app.help.get_hovered_tab(), None);
}
#[test]
fn test_hover_help_popup_below_tab_bar_clears_hover() {
use crate::help::HelpTab;
let mut app = create_test_app();
app.help.visible = true;
app.layout_regions.help_popup = Some(Rect::new(10, 5, 70, 20));
app.help.set_hovered_tab(Some(HelpTab::Input));
let mouse = create_mouse_event(15, 8);
handle_hover(&mut app, Some(Region::HelpPopup), mouse);
assert_eq!(app.help.get_hovered_tab(), None);
}
#[test]
fn test_hover_help_popup_not_visible() {
let mut app = create_test_app();
app.help.visible = false;
app.layout_regions.help_popup = Some(Rect::new(10, 5, 70, 20));
let mouse = create_mouse_event(15, 6);
handle_hover(&mut app, Some(Region::HelpPopup), mouse);
assert_eq!(app.help.get_hovered_tab(), None);
}
#[test]
fn test_hover_help_popup_no_region() {
let mut app = create_test_app();
app.help.visible = true;
app.layout_regions.help_popup = None;
let mouse = create_mouse_event(15, 6);
handle_hover(&mut app, Some(Region::HelpPopup), mouse);
assert_eq!(app.help.get_hovered_tab(), None);
}
#[test]
fn test_leaving_help_popup_clears_hover() {
use crate::help::HelpTab;
let mut app = create_test_app();
app.help.visible = true;
app.help.set_hovered_tab(Some(HelpTab::Input));
let mouse = create_mouse_event(5, 5);
handle_hover(&mut app, Some(Region::ResultsPane), mouse);
assert_eq!(app.help.get_hovered_tab(), None);
}
#[test]
fn test_drag_in_visual_mode_extends_selection() {
let mut app = test_app(
r#"["line1","line2","line3","line4","line5","line6","line7","line8","line9","line10"]"#,
);
app.results_cursor.update_total_lines(10);
app.layout_regions.results_pane = Some(Rect::new(0, 0, 50, 12));
app.results_cursor.click_select(2);
assert!(app.results_cursor.is_visual_mode());
assert_eq!(app.results_cursor.selection_range(), (2, 2));
let mouse = create_drag_event(5, 6);
handle_hover(&mut app, Some(Region::ResultsPane), mouse);
assert_eq!(app.results_cursor.selection_range(), (2, 5));
}
#[test]
fn test_drag_extends_selection_upward() {
let mut app = test_app(
r#"["line1","line2","line3","line4","line5","line6","line7","line8","line9","line10"]"#,
);
app.results_cursor.update_total_lines(10);
app.layout_regions.results_pane = Some(Rect::new(0, 0, 50, 12));
app.results_cursor.click_select(5);
assert_eq!(app.results_cursor.selection_range(), (5, 5));
let mouse = create_drag_event(5, 3);
handle_hover(&mut app, Some(Region::ResultsPane), mouse);
assert_eq!(app.results_cursor.selection_range(), (2, 5));
}
#[test]
fn test_drag_without_visual_mode_does_not_extend() {
let mut app = test_app(
r#"["line1","line2","line3","line4","line5","line6","line7","line8","line9","line10"]"#,
);
app.results_cursor.update_total_lines(10);
app.layout_regions.results_pane = Some(Rect::new(0, 0, 50, 12));
app.results_cursor.move_to_line(2);
assert!(!app.results_cursor.is_visual_mode());
let initial_line = app.results_cursor.cursor_line();
let mouse = create_drag_event(5, 6);
handle_hover(&mut app, Some(Region::ResultsPane), mouse);
assert_eq!(app.results_cursor.cursor_line(), initial_line);
}
#[test]
fn test_drag_outside_results_pane_clears_hover() {
let mut app = test_app(
r#"["line1","line2","line3","line4","line5","line6","line7","line8","line9","line10"]"#,
);
app.results_cursor.update_total_lines(10);
app.layout_regions.results_pane = Some(Rect::new(0, 0, 50, 12));
app.results_cursor.click_select(2);
app.results_cursor.set_hovered(Some(2));
let mouse = create_drag_event(5, 15);
handle_hover(&mut app, Some(Region::ResultsPane), mouse);
assert_eq!(app.results_cursor.hovered_line(), None);
}
#[test]
fn test_drag_with_scroll_offset() {
let mut app = test_app(
r#"["line1","line2","line3","line4","line5","line6","line7","line8","line9","line10"]"#,
);
app.results_cursor.update_total_lines(10);
app.results_scroll.offset = 3;
app.layout_regions.results_pane = Some(Rect::new(0, 0, 50, 12));
app.results_cursor.click_select(3);
let mouse = create_drag_event(5, 4);
handle_hover(&mut app, Some(Region::ResultsPane), mouse);
assert_eq!(app.results_cursor.selection_range(), (3, 6));
}