use super::super::{link, link_marked, row, tab};
use crate::paint_probe::{fills_of, frame::Window, seen_of};
use crate::ui::theme::{INK, INK_FAINT, RAISED, hover};
fn under(at: egui::Pos2, body: impl FnMut(&egui::Context)) -> egui::FullOutput {
let window = Window::sized(300.0, 100.0);
let mut body = body;
window.frame(Vec::new(), &mut body);
window.frame(vec![egui::Event::PointerMoved(at)], &mut body)
}
fn lifted(output: &egui::FullOutput) -> bool {
fills_of(output).iter().any(|(_, fill)| *fill == hover())
}
fn pickables(ctx: &egui::Context, chosen: bool) {
egui::CentralPanel::default().show(ctx, |ui| {
row(ui, "a row", INK, None, chosen, 0.0, "a row");
link(ui, "a link", INK, "a link");
tab(ui, "a tab", INK, "a tab");
});
}
#[test]
fn a_row_a_link_and_a_tab_lift_under_the_pointer() {
let away = under(egui::pos2(290.0, 95.0), |ctx| pickables(ctx, false));
assert!(!lifted(&away), "bare at rest");
for words in ["a row", "a link", "a tab"] {
let laid = under(egui::pos2(290.0, 95.0), |ctx| pickables(ctx, false));
let at = seen_of(&laid)
.into_iter()
.find(|run| run.text == words)
.unwrap_or_else(|| panic!("{words:?} on the glass"))
.shown
.center();
assert!(lifted(&under(at, |ctx| pickables(ctx, false))), "{words}");
}
}
#[test]
fn a_chosen_row_keeps_its_raise_under_the_pointer() {
let at = egui::pos2(20.0, 15.0);
let output = under(at, |ctx| pickables(ctx, true));
let fills = fills_of(&output);
assert!(fills.iter().any(|(_, fill)| *fill == RAISED), "raised");
let row = fills
.iter()
.find(|(rect, _)| rect.contains(at))
.map(|(_, fill)| *fill);
assert_ne!(row, Some(hover()), "not washed over");
}
#[test]
fn the_mark_is_inside_the_link() {
let body = |ctx: &egui::Context| {
egui::CentralPanel::default().show(ctx, |ui| {
link_marked(ui, "model", INK, ("⏶", INK_FAINT), "opens");
});
};
let laid = under(egui::pos2(290.0, 95.0), body);
let run = seen_of(&laid)
.into_iter()
.find(|run| run.text == "model ⏶")
.expect("one run");
let on_mark = egui::pos2(run.shown.max.x - 2.0, run.shown.center().y);
let output = under(on_mark, body);
assert!(lifted(&output), "the mark lifts the seat");
assert_eq!(
output.platform_output.cursor_icon,
egui::CursorIcon::PointingHand
);
}
#[test]
fn a_block_row_is_one_seat_over_every_line() {
let body = |ctx: &egui::Context| {
egui::CentralPanel::default().show(ctx, |ui| {
super::super::Row {
mark: ("?".to_owned(), INK),
words: "head".to_owned(),
ink: INK,
state: None,
chosen: false,
indent: 0.0,
aside: Some("2m".to_owned()),
beneath: vec![("beneath".to_owned(), INK_FAINT, egui::TextStyle::Small)],
door: None,
help: "a block".to_owned(),
}
.paint(ui);
});
};
let laid = under(egui::pos2(290.0, 95.0), body);
let at = |text: &str| {
seen_of(&laid)
.into_iter()
.find(|run| run.text == text)
.unwrap_or_else(|| panic!("{text:?}"))
.shown
};
let (aside, beneath) = (at("2m"), at("beneath"));
assert!(
aside.left() > at("? head").right(),
"the aside at the right end"
);
let output = under(beneath.center(), body);
let block = fills_of(&output)
.into_iter()
.find(|(_, fill)| *fill == hover())
.expect("the pointer on a line beneath lifts the block")
.0;
assert!(block.contains(aside.center()) && block.contains(beneath.center()));
}
#[test]
fn a_doored_row_tells_the_door_under_the_pointer_and_itself_elsewhere() {
let body = |ctx: &egui::Context| {
egui::CentralPanel::default().show(ctx, |ui| {
super::super::Row {
mark: (String::new(), INK),
words: "head".to_owned(),
ink: INK,
state: None,
chosen: false,
indent: 0.0,
aside: None,
beneath: Vec::new(),
door: Some(("×", "the door's sentence")),
help: "the row's sentence".to_owned(),
}
.paint_doored(ui);
});
};
let window = Window::sized(300.0, 100.0);
window.ctx().style_mut(|style| {
style.interaction.tooltip_delay = 0.0;
style.interaction.tooltip_grace_time = 0.0;
});
let mut body = body;
let said = |output: &egui::FullOutput, words: &str| {
seen_of(output).into_iter().any(|run| run.text == words)
};
window.frame(Vec::new(), &mut body);
let on_row = egui::pos2(20.0, 15.0);
let mut output = window.frame(vec![egui::Event::PointerMoved(on_row)], &mut body);
for _ in 0..12 {
output = window.frame(Vec::new(), &mut body);
}
assert!(said(&output, "the row's sentence"), "the row tells");
let door = seen_of(&output)
.into_iter()
.find(|run| run.text == "×")
.expect("the door stands while the pointer is on the row")
.shown
.center();
output = window.frame(vec![egui::Event::PointerMoved(door)], &mut body);
for _ in 0..12 {
output = window.frame(Vec::new(), &mut body);
}
assert!(said(&output, "the door's sentence"), "the door tells");
assert!(!said(&output, "the row's sentence"), "the row stands down");
}