mirror of
https://github.com/zed-industries/zed.git
synced 2025-02-03 08:54:04 +00:00
Get all worktree tests passing
* Store non-canocalized path on worktree, but canonicalize it for the purpose of processing events * Simplify rescan unit test
This commit is contained in:
parent
f06164ade9
commit
f27b01fcd5
1 changed files with 36 additions and 51 deletions
|
@ -260,18 +260,19 @@ impl Snapshot {
|
||||||
let mut edits = Vec::new();
|
let mut edits = Vec::new();
|
||||||
edits.push(Edit::Insert(entry.clone()));
|
edits.push(Edit::Insert(entry.clone()));
|
||||||
if let Some(parent) = entry.parent() {
|
if let Some(parent) = entry.parent() {
|
||||||
let mut parent_entry = self.entries.get(&parent).unwrap().clone();
|
if let Some(mut parent_entry) = self.entries.get(&parent).cloned() {
|
||||||
if let Entry::Dir { children, .. } = &mut parent_entry {
|
if let Entry::Dir { children, .. } = &mut parent_entry {
|
||||||
let name = Arc::from(path.file_name().unwrap());
|
let name = Arc::from(path.file_name().unwrap());
|
||||||
*children = children
|
*children = children
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.cloned()
|
.cloned()
|
||||||
.chain(Some((entry.inode(), name)))
|
.chain(Some((entry.inode(), name)))
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.into();
|
.into();
|
||||||
edits.push(Edit::Insert(parent_entry));
|
edits.push(Edit::Insert(parent_entry));
|
||||||
} else {
|
} else {
|
||||||
unreachable!();
|
unreachable!();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.entries.edit(edits);
|
self.entries.edit(edits);
|
||||||
|
@ -500,16 +501,7 @@ impl BackgroundScanner {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run(&self) {
|
fn run(&self) {
|
||||||
let path = {
|
let path = self.snapshot.lock().path.clone();
|
||||||
let mut snapshot = self.snapshot.lock();
|
|
||||||
let canonical_path = snapshot
|
|
||||||
.path
|
|
||||||
.canonicalize()
|
|
||||||
.map(Arc::from)
|
|
||||||
.unwrap_or_else(|_| snapshot.path.clone());
|
|
||||||
snapshot.path = canonical_path.clone();
|
|
||||||
canonical_path
|
|
||||||
};
|
|
||||||
|
|
||||||
// Create the event stream before we start scanning to ensure we receive events for changes
|
// Create the event stream before we start scanning to ensure we receive events for changes
|
||||||
// that occur in the middle of the scan.
|
// that occur in the middle of the scan.
|
||||||
|
@ -699,15 +691,19 @@ impl BackgroundScanner {
|
||||||
|
|
||||||
fn process_events(&self, mut events: Vec<fsevent::Event>) {
|
fn process_events(&self, mut events: Vec<fsevent::Event>) {
|
||||||
let mut snapshot = self.snapshot();
|
let mut snapshot = self.snapshot();
|
||||||
|
let root_path = snapshot
|
||||||
|
.path
|
||||||
|
.canonicalize()
|
||||||
|
.unwrap_or_else(|_| snapshot.path.to_path_buf());
|
||||||
|
|
||||||
events.sort_unstable_by(|a, b| a.path.cmp(&b.path));
|
events.sort_unstable_by(|a, b| a.path.cmp(&b.path));
|
||||||
let mut paths = events.into_iter().map(|e| e.path).peekable();
|
let mut paths = events.into_iter().map(|e| e.path).peekable();
|
||||||
let (scan_queue_tx, scan_queue_rx) = crossbeam_channel::unbounded();
|
let (scan_queue_tx, scan_queue_rx) = crossbeam_channel::unbounded();
|
||||||
while let Some(path) = paths.next() {
|
while let Some(path) = paths.next() {
|
||||||
let relative_path = match path.strip_prefix(&snapshot.path) {
|
let relative_path = match path.strip_prefix(&root_path) {
|
||||||
Ok(relative_path) => relative_path.to_path_buf(),
|
Ok(relative_path) => relative_path.to_path_buf(),
|
||||||
Err(e) => {
|
Err(_) => {
|
||||||
log::error!("unexpected event {:?}", e);
|
log::error!("unexpected event {:?} for root path {:?}", path, root_path);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -718,7 +714,7 @@ impl BackgroundScanner {
|
||||||
|
|
||||||
snapshot.remove_entry(&relative_path);
|
snapshot.remove_entry(&relative_path);
|
||||||
|
|
||||||
match self.fs_entry_for_path(&snapshot.path, &path) {
|
match self.fs_entry_for_path(&root_path, &path) {
|
||||||
Ok(Some((fs_entry, ignore))) => {
|
Ok(Some((fs_entry, ignore))) => {
|
||||||
snapshot.insert_entry(&path, fs_entry.clone());
|
snapshot.insert_entry(&path, fs_entry.clone());
|
||||||
|
|
||||||
|
@ -977,61 +973,49 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_rescan() {
|
fn test_rescan() {
|
||||||
App::test_async((), |mut app| async move {
|
App::test_async((), |mut app| async move {
|
||||||
let dir2 = temp_tree(json!({
|
|
||||||
"dir1": {
|
|
||||||
"dir3": {
|
|
||||||
"file": "contents",
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"dir2": {
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
let dir = temp_tree(json!({
|
let dir = temp_tree(json!({
|
||||||
"dir1": {
|
"dir1": {
|
||||||
"dir3": {
|
"file1": "contents 1",
|
||||||
"file": "contents",
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"dir2": {
|
"dir2": {
|
||||||
|
"dir3": {
|
||||||
|
"file2": "contents 2",
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
let tree = app.add_model(|ctx| Worktree::new(dir.path(), ctx));
|
let tree = app.add_model(|ctx| Worktree::new(dir.path(), ctx));
|
||||||
assert_condition(1, 300, || app.read(|ctx| tree.read(ctx).file_count() == 1)).await;
|
assert_condition(1, 300, || app.read(|ctx| tree.read(ctx).file_count() == 2)).await;
|
||||||
|
|
||||||
let dir_inode = app.read(|ctx| {
|
let file2_inode = app.read(|ctx| {
|
||||||
tree.read(ctx)
|
tree.read(ctx)
|
||||||
.snapshot()
|
.snapshot()
|
||||||
.inode_for_path("dir1/dir3")
|
.inode_for_path("dir2/dir3/file2")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
});
|
});
|
||||||
app.read(|ctx| {
|
app.read(|ctx| {
|
||||||
let tree = tree.read(ctx);
|
let tree = tree.read(ctx);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
tree.path_for_inode(dir_inode, false)
|
tree.path_for_inode(file2_inode, false)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.to_str()
|
.to_str()
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
"dir1/dir3"
|
"dir2/dir3/file2"
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
std::fs::rename(dir2.path(), dir.path().join("foo")).unwrap();
|
std::fs::rename(dir.path().join("dir2/dir3"), dir.path().join("dir4")).unwrap();
|
||||||
assert_condition(1, 300, || {
|
assert_condition(1, 300, || {
|
||||||
app.read(|ctx| {
|
app.read(|ctx| {
|
||||||
let tree = tree.read(ctx);
|
let tree = tree.read(ctx);
|
||||||
tree.path_for_inode(dir_inode, false)
|
tree.path_for_inode(file2_inode, false)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.to_str()
|
.to_str()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
== "dir2/dir3"
|
== "dir4/file2"
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
app.read(|ctx| {
|
|
||||||
let tree = tree.read(ctx);
|
|
||||||
assert_eq!(tree.snapshot().inode_for_path("dir2/dir3"), Some(dir_inode));
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1112,7 +1096,8 @@ mod tests {
|
||||||
insertion_probability: f64,
|
insertion_probability: f64,
|
||||||
rng: &mut impl Rng,
|
rng: &mut impl Rng,
|
||||||
) -> Result<Vec<fsevent::Event>> {
|
) -> Result<Vec<fsevent::Event>> {
|
||||||
let (dirs, files) = read_dir_recursive(root_path.to_path_buf());
|
let root_path = root_path.canonicalize().unwrap();
|
||||||
|
let (dirs, files) = read_dir_recursive(root_path.clone());
|
||||||
|
|
||||||
let mut events = Vec::new();
|
let mut events = Vec::new();
|
||||||
let mut record_event = |path: PathBuf| {
|
let mut record_event = |path: PathBuf| {
|
||||||
|
|
Loading…
Reference in a new issue