use pretty_assertions::assert_eq;
use ratatui::{layout::Rect, text::Line};
use super::{PanelPointer, PanelPointerEffect, PanelPointerEvent};
use crate::tui::{
copy_interaction::CopyHit,
overlay_panel::{render_overlay_panel, OverlayPanelFrame},
};
const DOWN: PanelPointerEvent = PanelPointerEvent::Press;
const DRAG: PanelPointerEvent = PanelPointerEvent::Drag;
const UP: PanelPointerEvent = PanelPointerEvent::Release;
fn frame(scroll: usize) -> OverlayPanelFrame {
let body = (0..40)
.map(|index| Line::raw(format!("row-{index:02} tail")))
.collect();
render_overlay_panel("Title", "Esc close", body, scroll, Rect::new(0, 0, 40, 14))
}
#[test]
fn scrollbar_drag_maps_pointer_rows_to_top_lines() {
let frame = frame( 0);
let track = frame
.scrollbar()
.expect("overflowing body shows a scrollbar")
.rect;
let body = frame.body();
assert_eq!(track, Rect::new(body.right(), body.y, 1, body.height));
let mut pointer = PanelPointer::default();
assert_eq!(
pointer.handle(DOWN, track.x, track.y, &frame),
PanelPointerEffect::ScrollTo(0)
);
let cases = [
("middle", track.y + 3, 16),
("bottom", track.bottom() - 1, 32),
("past the track", track.bottom() + 5, 32),
("top", track.y, 0),
];
for (name, row, top_line) in cases {
assert_eq!(
pointer.handle(DRAG, track.x, row, &frame),
PanelPointerEffect::ScrollTo(top_line),
"{name}"
);
}
assert_eq!(
pointer.handle(UP, track.x, track.y, &frame),
PanelPointerEffect::None
);
assert_eq!(
pointer.handle(DRAG, track.x, track.bottom() - 1, &frame),
PanelPointerEffect::None
);
}
type PointerStep = (PanelPointerEvent, u16);
#[test]
fn body_press_routes_to_copy_target_or_scrolled_selection() {
let mut scrolled = frame( 10);
let body = scrolled.body();
scrolled.copy_hits.push(CopyHit {
row: 11,
columns: 8..12,
text: "payload".into(),
});
let row = body.y + 1;
let cases: [(&str, &[PointerStep], PanelPointerEffect); 2] = [
(
"drag copies the scrolled line",
&[(DOWN, 0), (DRAG, 3), (UP, 5)],
PanelPointerEffect::Copy("row-11".into()),
),
(
"copy target copies on press",
&[(DOWN, 9)],
PanelPointerEffect::Copy("payload".into()),
),
];
for (name, events, expected) in cases {
let mut pointer = PanelPointer::default();
let mut last = PanelPointerEffect::None;
for &(kind, column) in events {
last = pointer.handle(kind, body.x + column, row, &scrolled);
}
assert_eq!(last, expected, "{name}");
}
}