facett-toast/tests/render.rs
//! **CPU render-proof for facett-toast.** The inline unit tests only cover
//! `tick`/`dismiss`/`state_json`; the `ui()` overlay path (the anchored `Area`, the
//! per-toast frame, the icon/label, and the ✕ dismiss button) is never executed. This
//! drives a real `egui_kittest` frame so the painter + interaction code runs, and
//! asserts the toast text + dismiss control ride into the AccessKit tree.
use egui_kittest::kittest::Queryable;
use egui_kittest::Harness;
use facett_toast::{Level, Toasts};
#[test]
fn overlay_paints_toasts_and_dismiss_buttons() {
let mut toasts = Toasts::new();
toasts.push("assigned to you", Level::Info, 5.0);
toasts.push("SLA breach on SUPP-1", Level::Error, 5.0);
assert_eq!(toasts.len(), 2);
let mut harness = Harness::new_ui(move |ui| {
// `Toasts::ui` draws into an `Area` on the Context, not the current Ui.
toasts.ui(ui.ctx());
});
// The overlay requests a repaint each frame (it animates while toasts live), so
// run a fixed number of steps rather than to-quiescence.
harness.run_steps(2);
// Both toast texts + a dismiss control reached the tree.
assert!(harness.query_by_label("assigned to you").is_some(), "the info toast painted");
assert!(harness.query_by_label("SLA breach on SUPP-1").is_some(), "the error toast painted");
assert!(harness.get_all_by_label("✕").count() >= 2, "each toast has a ✕ dismiss button");
}
#[test]
fn empty_overlay_paints_nothing_and_does_not_panic() {
let mut toasts = Toasts::new();
let mut harness = Harness::new_ui(move |ui| {
toasts.ui(ui.ctx());
});
harness.run();
// No toast labels present.
assert!(harness.query_by_label("assigned to you").is_none());
}
#[test]
fn clicking_a_case_toast_is_addressable_after_render() {
// A case-linked toast records its case key when clicked; drive the state through
// the public API + assert state_json reflects the overlay after a render frame.
let mut toasts = Toasts::new();
toasts.push_case("case moved", Level::Success, 4.0, Some("SUPP-9".into()));
let mut harness = Harness::new_ui(move |ui| {
toasts.ui(ui.ctx());
// The overlay's observable state is still the single case toast.
assert_eq!(toasts.state_json()["count"], 1);
assert_eq!(toasts.state_json()["toasts"][0]["case"], "SUPP-9");
});
harness.run_steps(2);
assert!(harness.query_by_label("case moved").is_some());
}