split toast into alert and toast
This commit is contained in:
+97
-24
@@ -3,7 +3,7 @@ use std::rc::Rc;
|
||||
use std::time::Duration;
|
||||
|
||||
use gpui::{AppContext as _, TestAppContext};
|
||||
use gpui_native_core::toast::{Toast, ToastSeverity, Toasts};
|
||||
use gpui_native_core::toast::{Toast, ToastAction, Toasts};
|
||||
use gpui_native_theme::Theme;
|
||||
|
||||
fn toasts_store() -> (TestAppContext, gpui::Entity<Toasts>) {
|
||||
@@ -14,23 +14,49 @@ fn toasts_store() -> (TestAppContext, gpui::Entity<Toasts>) {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn push_raises_a_toast_and_the_timer_dismisses_it() {
|
||||
fn push_raises_a_toast_and_the_timer_fades_it_out() {
|
||||
let (cx, toasts) = toasts_store();
|
||||
|
||||
let id = cx.update(|cx| {
|
||||
toasts.update(cx, |toasts, cx| {
|
||||
toasts.push(Toast::new("Saved").severity(ToastSeverity::Success), cx)
|
||||
})
|
||||
});
|
||||
let id = cx.update(|cx| toasts.update(cx, |toasts, cx| toasts.push(Toast::new("Saved"), cx)));
|
||||
assert_eq!(cx.update(|cx| toasts.read(cx).count()), 1);
|
||||
|
||||
// The default lifetime is five seconds.
|
||||
// The default lifetime is five seconds; the fade-out follows it.
|
||||
cx.executor().advance_clock(Toast::DURATION);
|
||||
cx.run_until_parked();
|
||||
assert_eq!(cx.update(|cx| toasts.read(cx).count()), 1, "fading out");
|
||||
cx.executor()
|
||||
.advance_clock(std::time::Duration::from_secs(1));
|
||||
cx.run_until_parked();
|
||||
assert_eq!(cx.update(|cx| toasts.read(cx).count()), 0);
|
||||
let _ = id;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pushing_replaces_the_toast_on_screen() {
|
||||
let (cx, toasts) = toasts_store();
|
||||
|
||||
cx.update(|cx| {
|
||||
toasts.update(cx, |toasts, cx| toasts.push(Toast::new("first"), cx));
|
||||
});
|
||||
cx.update(|cx| {
|
||||
toasts.update(cx, |toasts, cx| toasts.push(Toast::new("second"), cx));
|
||||
});
|
||||
|
||||
// One showing, one fading out: never two current toasts.
|
||||
let (current, total) = cx.update(|cx| {
|
||||
toasts.read_with(cx, |toasts, _| {
|
||||
(toasts.current().map(|entry| entry.id), toasts.count())
|
||||
})
|
||||
});
|
||||
assert_eq!(current, Some(1));
|
||||
assert_eq!(total, 2);
|
||||
|
||||
cx.executor()
|
||||
.advance_clock(std::time::Duration::from_secs(6));
|
||||
cx.run_until_parked();
|
||||
assert_eq!(cx.update(|cx| toasts.read(cx).count()), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sticky_toasts_ignore_the_timer_until_dismissed() {
|
||||
let (cx, toasts) = toasts_store();
|
||||
@@ -48,42 +74,89 @@ fn sticky_toasts_ignore_the_timer_until_dismissed() {
|
||||
cx.update(|cx| {
|
||||
toasts.update(cx, |toasts, cx| toasts.dismiss(id, cx));
|
||||
});
|
||||
assert_eq!(cx.update(|cx| toasts.read(cx).count()), 1, "fading out");
|
||||
cx.executor()
|
||||
.advance_clock(std::time::Duration::from_secs(1));
|
||||
cx.run_until_parked();
|
||||
assert_eq!(cx.update(|cx| toasts.read(cx).count()), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dismiss_runs_the_handler_and_clear_removes_everything() {
|
||||
fn dismiss_runs_the_handler_only_after_the_fade_completes() {
|
||||
let (cx, toasts) = toasts_store();
|
||||
let dismissed = Rc::new(std::cell::RefCell::new(Vec::<&'static str>::new()));
|
||||
|
||||
let ids = cx.update(|cx| {
|
||||
cx.update(|cx| {
|
||||
let first = dismissed.clone();
|
||||
toasts.update(cx, |toasts, cx| {
|
||||
let first = dismissed.clone();
|
||||
let second = dismissed.clone();
|
||||
vec![
|
||||
toasts.push(
|
||||
Toast::new("first").on_dismiss(move |_| record(&first, "first")),
|
||||
cx,
|
||||
),
|
||||
toasts.push(
|
||||
Toast::new("second").on_dismiss(move |_| record(&second, "second")),
|
||||
cx,
|
||||
),
|
||||
]
|
||||
})
|
||||
toasts.push(
|
||||
Toast::new("first").on_dismiss(move |_| record(&first, "first")),
|
||||
cx,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
cx.update(|cx| {
|
||||
toasts.update(cx, |toasts, cx| toasts.dismiss(ids[0], cx));
|
||||
toasts.update(cx, |toasts, cx| toasts.dismiss(0, cx));
|
||||
});
|
||||
assert!(
|
||||
dismissed.borrow().is_empty(),
|
||||
"the handler waits out the fade"
|
||||
);
|
||||
cx.executor()
|
||||
.advance_clock(std::time::Duration::from_secs(1));
|
||||
cx.run_until_parked();
|
||||
assert_eq!(*dismissed.borrow(), vec!["first"]);
|
||||
|
||||
cx.update(|cx| {
|
||||
toasts.update(cx, |toasts, cx| toasts.clear(cx));
|
||||
});
|
||||
cx.executor()
|
||||
.advance_clock(std::time::Duration::from_secs(1));
|
||||
cx.run_until_parked();
|
||||
assert_eq!(cx.update(|cx| toasts.read(cx).count()), 0);
|
||||
|
||||
fn record(sink: &Rc<RefCell<Vec<&'static str>>>, what: &'static str) {
|
||||
sink.borrow_mut().push(what);
|
||||
}
|
||||
}
|
||||
|
||||
/// Dismissing by any other path never runs the action: only a click on the
|
||||
/// action itself does (the view wires the two together).
|
||||
#[test]
|
||||
fn dismissal_does_not_run_the_action() {
|
||||
let (cx, toasts) = toasts_store();
|
||||
let ran = Rc::new(std::cell::RefCell::new(false));
|
||||
let dismissed = Rc::new(std::cell::RefCell::new(false));
|
||||
|
||||
cx.update(|cx| {
|
||||
let action_ran = ran.clone();
|
||||
let toast_dismissed = dismissed.clone();
|
||||
toasts.update(cx, |toasts, cx| {
|
||||
toasts.push(
|
||||
Toast::new("Draft deleted")
|
||||
.action(ToastAction::new("Undo", move |_| {
|
||||
*action_ran.borrow_mut() = true;
|
||||
}))
|
||||
.on_dismiss(move |_| *toast_dismissed.borrow_mut() = true),
|
||||
cx,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
cx.update(|cx| {
|
||||
toasts.update(cx, |toasts, cx| toasts.dismiss(0, cx));
|
||||
});
|
||||
assert!(!*ran.borrow(), "dismiss is not the action");
|
||||
cx.executor()
|
||||
.advance_clock(std::time::Duration::from_secs(1));
|
||||
cx.run_until_parked();
|
||||
assert!(
|
||||
*dismissed.borrow(),
|
||||
"on_dismiss still reports the dismissal"
|
||||
);
|
||||
assert!(
|
||||
*dismissed.borrow(),
|
||||
"on_dismiss still reports the dismissal"
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user