diff --git a/crates/editor2/src/display_map.rs b/crates/editor2/src/display_map.rs index 1aee04dd0a..74890d9edb 100644 --- a/crates/editor2/src/display_map.rs +++ b/crates/editor2/src/display_map.rs @@ -1467,10 +1467,12 @@ pub mod tests { cx.update(|cx| init_test(cx, |s| s.defaults.tab_size = Some(2.try_into().unwrap()))); - let buffer = cx.build_model(|cx| { - Buffer::new(0, cx.entity_id().as_u64(), text).with_language(language, cx) + let buffer = cx.build_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), text)); + let condition = cx.condition(&buffer, |buf, _| !buf.is_parsing()); + cx.update_model(&buffer, |this, cx| { + this.set_language(Some(language), cx); }); - cx.condition(&buffer, |buf, _| !buf.is_parsing()).await; + condition.await; let buffer = cx.build_model(|cx| MultiBuffer::singleton(buffer, cx)); let font_size = px(14.0); @@ -1554,10 +1556,12 @@ pub mod tests { cx.update(|cx| init_test(cx, |_| {})); - let buffer = cx.build_model(|cx| { - Buffer::new(0, cx.entity_id().as_u64(), text).with_language(language, cx) + let buffer = cx.build_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), text)); + let condition = cx.condition(&buffer, |buf, _| !buf.is_parsing()); + buffer.update(cx, |this, cx| { + this.set_language(Some(language), cx); }); - cx.condition(&buffer, |buf, _| !buf.is_parsing()).await; + condition.await; let buffer = cx.build_model(|cx| MultiBuffer::singleton(buffer, cx)); let font_size = px(16.0); @@ -1621,10 +1625,10 @@ pub mod tests { let (text, highlighted_ranges) = marked_text_ranges(r#"constˇ «a»: B = "c «d»""#, false); - let buffer = cx.build_model(|cx| { - Buffer::new(0, cx.entity_id().as_u64(), text).with_language(language, cx) - }); - cx.condition(&buffer, |buf, _| !buf.is_parsing()).await; + let buffer = cx.build_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), text)); + let condition = cx.condition(&buffer, |buf, _| !buf.is_parsing()); + buffer.update(cx, |this, cx| this.set_language(Some(language), cx)); + condition.await; let buffer = cx.build_model(|cx| MultiBuffer::singleton(buffer, cx)); let buffer_snapshot = buffer.read_with(cx, |buffer, cx| buffer.snapshot(cx)); diff --git a/crates/gpui2/src/app/test_context.rs b/crates/gpui2/src/app/test_context.rs index c915753749..5c2bf65c02 100644 --- a/crates/gpui2/src/app/test_context.rs +++ b/crates/gpui2/src/app/test_context.rs @@ -8,6 +8,7 @@ use crate::{ use anyhow::{anyhow, bail}; use futures::{Stream, StreamExt}; use std::{future::Future, ops::Deref, rc::Rc, sync::Arc, time::Duration}; +use util::ResultExt; #[derive(Clone)] pub struct TestAppContext { @@ -297,7 +298,7 @@ impl TestAppContext { .unwrap() } - pub fn notifications(&mut self, entity: &impl Entity) -> impl Stream { + pub fn notifications(&self, entity: &impl Entity) -> impl Stream { let (tx, rx) = futures::channel::mpsc::unbounded(); self.update(|cx| { cx.observe(entity, { @@ -307,7 +308,7 @@ impl TestAppContext { } }) .detach(); - cx.observe_release(entity, move |_, _| tx.close_channel()) + cx.observe_release(entity, move |_, _| dbg!(tx.close_channel())) .detach() }); rx @@ -331,28 +332,30 @@ impl TestAppContext { rx } - pub async fn condition( - &mut self, + pub fn condition( + &self, model: &Model, - mut predicate: impl FnMut(&mut T, &mut ModelContext) -> bool, - ) { + mut predicate: impl FnMut(&mut T, &mut ModelContext) -> bool + Send + 'static, + ) -> Task<()> { let timer = self.executor().timer(Duration::from_secs(3)); let mut notifications = self.notifications(model); use futures::FutureExt as _; use smol::future::FutureExt as _; - - async { - while notifications.next().await.is_some() { - if model.update(self, &mut predicate) { - return Ok(()); + let model = model.clone(); + self.spawn(move |mut cx| async move { + async move { + while notifications.next().await.is_some() { + if model.update(&mut cx, &mut predicate).log_err().unwrap() { + return Ok(()); + } } + bail!("model dropped") } - bail!("model dropped") - } - .race(timer.map(|_| Err(anyhow!("condition timed out")))) - .await - .unwrap(); + .race(timer.map(|_| Err(anyhow!("condition timed out")))) + .await + .unwrap() + }) } } diff --git a/crates/project2/src/worktree.rs b/crates/project2/src/worktree.rs index e424375220..86cfc67374 100644 --- a/crates/project2/src/worktree.rs +++ b/crates/project2/src/worktree.rs @@ -4187,7 +4187,7 @@ impl WorktreeModelHandle for Model { &self, cx: &'a mut gpui::TestAppContext, ) -> futures::future::LocalBoxFuture<'a, ()> { - let file_name = "fs-event-sentinel"; + let file_name: &'static str = "fs-event-sentinel"; let tree = self.clone(); let (fs, root_path) = self.update(cx, |tree, _| { @@ -4200,14 +4200,18 @@ impl WorktreeModelHandle for Model { .await .unwrap(); - cx.condition(&tree, |tree, _| tree.entry_for_path(file_name).is_some()) - .await; + cx.condition(&tree, move |tree, _| { + tree.entry_for_path(file_name).is_some() + }) + .await; fs.remove_file(&root_path.join(file_name), Default::default()) .await .unwrap(); - cx.condition(&tree, |tree, _| tree.entry_for_path(file_name).is_none()) - .await; + cx.condition(&tree, move |tree, _| { + tree.entry_for_path(file_name).is_none() + }) + .await; cx.update(|cx| tree.read(cx).as_local().unwrap().scan_complete()) .await;