fix display map tests
These tests failed due to an indefinite hang in buffer.condition in the following code: \`\`\`rust let buffer = cx .add_model(|cx| Buffer::new(0, cx.model_id() as u64, text).with_language(language, cx)); buffer.condition(cx, |buf, _| !buf.is_parsing()).await; `\`\` In both gpui1 and gpui2 \`.with_language\` spawns a task that notifies the context once it's done. The \`condition\` waits for notifications to be raised. The gist of the problem was that in gpui2, the spawned task was scheduled straight away, so we never really saw the notification with \`condition\`, causing us to wait indefinitely. This is probably a difference in test between schedulers in gpui1 and gpui2, but I kind of sidestepped the issue by spawning a condition before firing off a parsing task with \`set_language\`.
This commit is contained in:
parent
9ffe78d264
commit
0f7fc8c1a0
3 changed files with 42 additions and 31 deletions
|
@ -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<T: 'static>(&mut self, entity: &impl Entity<T>) -> impl Stream<Item = ()> {
|
||||
pub fn notifications<T: 'static>(&self, entity: &impl Entity<T>) -> impl Stream<Item = ()> {
|
||||
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<T: 'static>(
|
||||
&mut self,
|
||||
pub fn condition<T: 'static>(
|
||||
&self,
|
||||
model: &Model<T>,
|
||||
mut predicate: impl FnMut(&mut T, &mut ModelContext<T>) -> bool,
|
||||
) {
|
||||
mut predicate: impl FnMut(&mut T, &mut ModelContext<T>) -> 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()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue