diff --git a/crates/project/src/worktree.rs b/crates/project/src/worktree.rs index 248a7d3dd7ab6d64780a4078189fb8bb03f3912a..79e3a7e528b0b310978d46cb26f64f5bf2be546d 100644 --- a/crates/project/src/worktree.rs +++ b/crates/project/src/worktree.rs @@ -2124,7 +2124,7 @@ struct UpdateIgnoreStatusJob { } pub trait WorktreeHandle { - #[cfg(test)] + #[cfg(any(test, feature = "test-support"))] fn flush_fs_events<'a>( &self, cx: &'a gpui::TestAppContext, @@ -2138,7 +2138,7 @@ impl WorktreeHandle for ModelHandle { // // This function mutates the worktree's directory and waits for those mutations to be picked up, // to ensure that all redundant FS events have already been processed. - #[cfg(test)] + #[cfg(any(test, feature = "test-support"))] fn flush_fs_events<'a>( &self, cx: &'a gpui::TestAppContext, @@ -2146,14 +2146,22 @@ impl WorktreeHandle for ModelHandle { use smol::future::FutureExt; let filename = "fs-event-sentinel"; - let root_path = cx.read(|cx| self.read(cx).as_local().unwrap().abs_path().clone()); let tree = self.clone(); + let (fs, root_path) = self.read_with(cx, |tree, _| { + let tree = tree.as_local().unwrap(); + (tree.fs.clone(), tree.abs_path().clone()) + }); + async move { - std::fs::write(root_path.join(filename), "").unwrap(); + fs.create_file(&root_path.join(filename), Default::default()) + .await + .unwrap(); tree.condition(&cx, |tree, _| tree.entry_for_path(filename).is_some()) .await; - std::fs::remove_file(root_path.join(filename)).unwrap(); + fs.remove_file(&root_path.join(filename), Default::default()) + .await + .unwrap(); tree.condition(&cx, |tree, _| tree.entry_for_path(filename).is_none()) .await; diff --git a/crates/server/src/rpc.rs b/crates/server/src/rpc.rs index 45d11141339b30495caff3d447d182068128099a..5704a787b9397ef5bb0f4385ee586bedcb692f9d 100644 --- a/crates/server/src/rpc.rs +++ b/crates/server/src/rpc.rs @@ -1238,7 +1238,7 @@ mod tests { LanguageConfig, LanguageRegistry, LanguageServerConfig, Point, }, lsp, - project::{DiagnosticSummary, Project, ProjectPath}, + project::{worktree::WorktreeHandle, DiagnosticSummary, Project, ProjectPath}, }; #[cfg(test)] @@ -1608,6 +1608,11 @@ mod tests { buffer_b.read_with(&cx_b, |buf, _| assert!(!buf.is_dirty())); buffer_c.condition(&cx_c, |buf, _| !buf.is_dirty()).await; + // Ensure worktree observes a/file1's change event *before* the rename occurs, otherwise + // when interpreting the change event it will mistakenly think that the file has been + // deleted (because its path has changed) and will subsequently fail to detect the rename. + worktree_a.flush_fs_events(&cx_a).await; + // Make changes on host's file system, see those changes on guest worktrees. fs.rename( "/a/file1".as_ref(),