WIP - flush_fs_events

This commit is contained in:
Max Brunsfeld 2023-11-01 17:45:38 -07:00
parent 6ee93125d0
commit 401ddc6f49
3 changed files with 51 additions and 12 deletions

View file

@ -40,15 +40,15 @@ impl<'a, T: 'static> ModelContext<'a, T> {
self.model_state.clone() self.model_state.clone()
} }
pub fn observe<T2, E>( pub fn observe<W, E>(
&mut self, &mut self,
entity: &E, entity: &E,
mut on_notify: impl FnMut(&mut T, E, &mut ModelContext<'_, T>) + 'static, mut on_notify: impl FnMut(&mut T, E, &mut ModelContext<'_, T>) + 'static,
) -> Subscription ) -> Subscription
where where
T: 'static, T: 'static,
T2: 'static, W: 'static,
E: Entity<T2>, E: Entity<W>,
{ {
let this = self.weak_model(); let this = self.weak_model();
let entity_id = entity.entity_id(); let entity_id = entity.entity_id();

View file

@ -3,8 +3,9 @@ use crate::{
ForegroundExecutor, Model, ModelContext, Result, Task, TestDispatcher, TestPlatform, ForegroundExecutor, Model, ModelContext, Result, Task, TestDispatcher, TestPlatform,
WindowContext, WindowContext,
}; };
use futures::SinkExt; use anyhow::anyhow;
use std::{cell::RefCell, future::Future, rc::Rc, sync::Arc}; use futures::{SinkExt, StreamExt};
use std::{cell::RefCell, future::Future, rc::Rc, sync::Arc, time::Duration};
#[derive(Clone)] #[derive(Clone)]
pub struct TestAppContext { pub struct TestAppContext {
@ -158,4 +159,40 @@ impl TestAppContext {
.detach(); .detach();
rx rx
} }
pub async fn condition<T: EventEmitter + 'static>(
&mut self,
model: &Model<T>,
mut predicate: impl FnMut(&mut T, &mut ModelContext<T>) -> bool,
) {
let (mut tx, mut rx) = futures::channel::mpsc::unbounded::<()>();
let timer = self.executor().timer(Duration::from_secs(3));
let subscriptions = model.update(self, move |_, cx| {
(
cx.observe(model, move |_, _, _| {
// let _ = tx.send(());
}),
cx.subscribe(model, move |_, _, _, _| {
let _ = tx.send(());
}),
)
});
use futures::FutureExt as _;
use smol::future::FutureExt as _;
async {
while rx.next().await.is_some() {
if model.update(self, &mut predicate) {
return Ok(());
}
}
drop(subscriptions);
unreachable!()
}
.race(timer.map(|_| Err(anyhow!("condition timed out"))))
.await
.unwrap();
}
} }

View file

@ -17,7 +17,7 @@ use futures::{
}, },
select_biased, select_biased,
task::Poll, task::Poll,
FutureExt, Stream, StreamExt, FutureExt as _, Stream, StreamExt,
}; };
use fuzzy2::CharBag; use fuzzy2::CharBag;
use git::{DOT_GIT, GITIGNORE}; use git::{DOT_GIT, GITIGNORE};
@ -4053,7 +4053,8 @@ impl WorktreeModelHandle for Model<Worktree> {
&self, &self,
cx: &'a mut gpui2::TestAppContext, cx: &'a mut gpui2::TestAppContext,
) -> futures::future::LocalBoxFuture<'a, ()> { ) -> futures::future::LocalBoxFuture<'a, ()> {
let filename = "fs-event-sentinel"; let file_name = "fs-event-sentinel";
let tree = self.clone(); let tree = self.clone();
let (fs, root_path) = self.update(cx, |tree, _| { let (fs, root_path) = self.update(cx, |tree, _| {
let tree = tree.as_local().unwrap(); let tree = tree.as_local().unwrap();
@ -4061,16 +4062,17 @@ impl WorktreeModelHandle for Model<Worktree> {
}); });
async move { async move {
fs.create_file(&root_path.join(filename), Default::default()) fs.create_file(&root_path.join(file_name), Default::default())
.await .await
.unwrap(); .unwrap();
cx.condition(&tree, |tree, _| tree.entry_for_path(file_name).is_some())
.await;
assert!(tree.update(cx, |tree, _| tree.entry_for_path(filename).is_some())); fs.remove_file(&root_path.join(file_name), Default::default())
fs.remove_file(&root_path.join(filename), Default::default())
.await .await
.unwrap(); .unwrap();
assert!(tree.update(cx, |tree, _| tree.entry_for_path(filename).is_none())); cx.condition(&tree, |tree, _| tree.entry_for_path(file_name).is_none())
.await;
cx.update(|cx| tree.read(cx).as_local().unwrap().scan_complete()) cx.update(|cx| tree.read(cx).as_local().unwrap().scan_complete())
.await; .await;