From d43e8b270a21856d9931dd4d9bc3b27ff8fb95fb Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Tue, 5 Jul 2022 15:47:45 +0200 Subject: [PATCH] Add unit test for `ViewContext::observe_window_activation` --- crates/gpui/src/app.rs | 113 ++++++++++++++++++++++++++++++- crates/gpui/src/platform/test.rs | 6 +- 2 files changed, 116 insertions(+), 3 deletions(-) diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index 9171120628..505f609f57 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -401,9 +401,12 @@ impl TestAppContext { T: View, F: FnOnce(&mut ViewContext) -> T, { - self.cx + let (window_id, view) = self + .cx .borrow_mut() - .add_window(Default::default(), build_root_view) + .add_window(Default::default(), build_root_view); + self.simulate_window_activation(Some(window_id)); + (window_id, view) } pub fn window_ids(&self) -> Vec { @@ -551,6 +554,35 @@ impl TestAppContext { } } + pub fn simulate_window_activation(&self, to_activate: Option) { + let mut handlers = BTreeMap::new(); + { + let mut cx = self.cx.borrow_mut(); + for (window_id, (_, window)) in &mut cx.presenters_and_platform_windows { + let window = window + .as_any_mut() + .downcast_mut::() + .unwrap(); + handlers.insert( + *window_id, + mem::take(&mut window.active_status_change_handlers), + ); + } + }; + let mut handlers = handlers.into_iter().collect::>(); + handlers.sort_unstable_by_key(|(window_id, _)| Some(*window_id) == to_activate); + + for (window_id, mut window_handlers) in handlers { + for window_handler in &mut window_handlers { + window_handler(Some(window_id) == to_activate); + } + + self.window_mut(window_id) + .active_status_change_handlers + .extend(window_handlers); + } + } + pub fn is_window_edited(&self, window_id: usize) -> bool { self.window_mut(window_id).edited } @@ -6992,4 +7024,81 @@ mod tests { ); assert_eq!(presenter.borrow().rendered_views.len(), 1); } + + #[crate::test(self)] + async fn test_window_activation(cx: &mut TestAppContext) { + struct View(&'static str); + + impl super::Entity for View { + type Event = (); + } + + impl super::View for View { + fn ui_name() -> &'static str { + "test view" + } + + fn render(&mut self, _: &mut RenderContext) -> ElementBox { + Empty::new().boxed() + } + } + + let events = Rc::new(RefCell::new(Vec::new())); + let (window_1, _) = cx.add_window(|cx: &mut ViewContext| { + cx.observe_window_activation({ + let events = events.clone(); + move |this, active, _| events.borrow_mut().push((this.0, active)) + }) + .detach(); + View("window 1") + }); + assert_eq!(mem::take(&mut *events.borrow_mut()), [("window 1", true)]); + + let (window_2, _) = cx.add_window(|cx: &mut ViewContext| { + cx.observe_window_activation({ + let events = events.clone(); + move |this, active, _| events.borrow_mut().push((this.0, active)) + }) + .detach(); + View("window 2") + }); + assert_eq!( + mem::take(&mut *events.borrow_mut()), + [("window 1", false), ("window 2", true)] + ); + + let (window_3, _) = cx.add_window(|cx: &mut ViewContext| { + cx.observe_window_activation({ + let events = events.clone(); + move |this, active, _| events.borrow_mut().push((this.0, active)) + }) + .detach(); + View("window 3") + }); + assert_eq!( + mem::take(&mut *events.borrow_mut()), + [("window 2", false), ("window 3", true)] + ); + + cx.simulate_window_activation(Some(window_2)); + assert_eq!( + mem::take(&mut *events.borrow_mut()), + [("window 3", false), ("window 2", true)] + ); + + cx.simulate_window_activation(Some(window_1)); + assert_eq!( + mem::take(&mut *events.borrow_mut()), + [("window 2", false), ("window 1", true)] + ); + + cx.simulate_window_activation(Some(window_3)); + assert_eq!( + mem::take(&mut *events.borrow_mut()), + [("window 1", false), ("window 3", true)] + ); + + cx.simulate_window_activation(Some(window_3)); + assert_eq!(mem::take(&mut *events.borrow_mut()), []); + } } diff --git a/crates/gpui/src/platform/test.rs b/crates/gpui/src/platform/test.rs index eb241797c3..a58bd603f2 100644 --- a/crates/gpui/src/platform/test.rs +++ b/crates/gpui/src/platform/test.rs @@ -37,6 +37,7 @@ pub struct Window { event_handlers: Vec bool>>, resize_handlers: Vec>, close_handlers: Vec>, + pub(crate) active_status_change_handlers: Vec>, pub(crate) should_close_handler: Option bool>>, pub(crate) title: Option, pub(crate) edited: bool, @@ -191,6 +192,7 @@ impl Window { resize_handlers: Default::default(), close_handlers: Default::default(), should_close_handler: Default::default(), + active_status_change_handlers: Default::default(), scale_factor: 1.0, current_scene: None, title: None, @@ -241,7 +243,9 @@ impl super::Window for Window { self.event_handlers.push(callback); } - fn on_active_status_change(&mut self, _: Box) {} + fn on_active_status_change(&mut self, callback: Box) { + self.active_status_change_handlers.push(callback); + } fn on_resize(&mut self, callback: Box) { self.resize_handlers.push(callback);