Files
gpui-native-kit/crates/core/tests/tooltip.rs
T
2026-10-29 20:16:30 +07:00

121 lines
3.5 KiB
Rust

use std::cell::RefCell;
use std::rc::Rc;
use gpui::{
Context, InteractiveElement as _, IntoElement, Modifiers, MouseMoveEvent, ParentElement as _,
Render, StatefulInteractiveElement as _, Styled as _, TestAppContext, VisualTestContext,
Window, div, point, px,
};
use gpui_native_core::button::Button;
use gpui_native_core::tooltip::Tooltip;
use gpui_native_theme::Theme;
/// Hover target at the top-left with a tooltip whose builder records every
/// invocation.
struct Harness {
calls: Rc<RefCell<Vec<&'static str>>>,
}
impl Render for Harness {
fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
let calls = self.calls.clone();
let target = div()
.id("hover-target")
.w(px(100.))
.h(px(40.))
.bg(gpui::black())
.tooltip(move |_, cx| {
calls.borrow_mut().push("target");
Tooltip::new("Target tooltip", cx).into()
});
let button_calls = self.calls.clone();
let button = Button::new("hover-button")
.label("Hover me")
.tooltip(move |_, cx| {
button_calls.borrow_mut().push("button");
Tooltip::new("Button tooltip", cx).into()
});
div()
.size_full()
.child(target)
.child(div().mt_12().child(button))
}
}
fn tooltip_window() -> (
TestAppContext,
VisualTestContext,
Rc<RefCell<Vec<&'static str>>>,
) {
let mut cx = TestAppContext::single();
cx.update(Theme::init);
let calls = Rc::new(RefCell::new(Vec::new()));
let harness_calls = calls.clone();
let window = cx.add_window(move |_, _| Harness {
calls: harness_calls,
});
let mut visual = VisualTestContext::from_window(window.into(), &cx);
visual.update(|window, cx| {
window.draw(cx).clear(cx);
});
(cx, visual, calls)
}
fn hover(visual: &mut VisualTestContext, position: gpui::Point<gpui::Pixels>) {
visual.simulate_event(MouseMoveEvent {
position,
pressed_button: None,
modifiers: Modifiers::default(),
});
}
/// gpui's hover delay before deploying a tooltip.
const SHOW_DELAY: std::time::Duration = std::time::Duration::from_millis(500);
fn draw(visual: &mut VisualTestContext) {
visual.update(|window, cx| {
window.draw(cx).clear(cx);
});
}
#[test]
fn hovering_the_target_deploys_the_tooltip_after_the_delay() {
let (cx, mut visual, calls) = tooltip_window();
hover(&mut visual, point(px(50.), px(20.)));
assert!(
calls.borrow().is_empty(),
"builder runs only after the delay"
);
assert!(
calls.borrow().is_empty(),
"builder runs only after the delay"
);
cx.executor().advance_clock(SHOW_DELAY);
visual.run_until_parked();
draw(&mut visual);
assert_eq!(*calls.borrow(), vec!["target"]);
}
#[test]
fn hovering_elsewhere_deploys_nothing() {
let (cx, mut visual, calls) = tooltip_window();
hover(&mut visual, point(px(800.), px(600.)));
cx.executor().advance_clock(SHOW_DELAY);
visual.run_until_parked();
draw(&mut visual);
assert!(calls.borrow().is_empty());
}
#[test]
fn the_button_passthrough_deploys_the_tooltip() {
let (cx, mut visual, calls) = tooltip_window();
hover(&mut visual, point(px(50.), px(100.)));
cx.executor().advance_clock(SHOW_DELAY);
visual.run_until_parked();
draw(&mut visual);
assert_eq!(*calls.borrow(), vec!["button"]);
}