Correctly check existence of target directory in copy_recursive function (#6875)

Fixes https://github.com/zed-industries/zed/issues/6778

Release Notes:

- Fixed issue where copy-paste for folders was not working in the
project panel
([#6778](https://github.com/zed-industries/zed/issues/6778)).
This commit is contained in:
George Munyoro 2024-01-29 12:06:02 +02:00 committed by GitHub
parent 9ef830e9bb
commit 49542757fd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 96 additions and 1 deletions

View file

@ -1183,7 +1183,7 @@ pub fn copy_recursive<'a>(
.await?
.ok_or_else(|| anyhow!("path does not exist: {}", source.display()))?;
if metadata.is_dir {
if !options.overwrite && fs.metadata(target).await.is_ok() {
if !options.overwrite && fs.metadata(target).await.is_ok_and(|m| m.is_some()) {
if options.ignore_if_exists {
return Ok(());
} else {

View file

@ -2455,6 +2455,101 @@ mod tests {
);
}
#[gpui::test]
async fn test_copy_paste_directory(cx: &mut gpui::TestAppContext) {
init_test(cx);
let fs = FakeFs::new(cx.executor().clone());
fs.insert_tree(
"/root",
json!({
"a": {
"one.txt": "",
"two.txt": "",
"inner_dir": {
"three.txt": "",
"four.txt": "",
}
},
"b": {}
}),
)
.await;
let project = Project::test(fs.clone(), ["/root".as_ref()], cx).await;
let workspace = cx.add_window(|cx| Workspace::test_new(project.clone(), cx));
let cx = &mut VisualTestContext::from_window(*workspace, cx);
let panel = workspace
.update(cx, |workspace, cx| ProjectPanel::new(workspace, cx))
.unwrap();
select_path(&panel, "root/a", cx);
panel.update(cx, |panel, cx| {
panel.copy(&Default::default(), cx);
panel.select_next(&Default::default(), cx);
panel.paste(&Default::default(), cx);
});
cx.executor().run_until_parked();
let pasted_dir = find_project_entry(&panel, "root/b/a", cx);
assert_ne!(pasted_dir, None, "Pasted directory should have an entry");
let pasted_dir_file = find_project_entry(&panel, "root/b/a/one.txt", cx);
assert_ne!(
pasted_dir_file, None,
"Pasted directory file should have an entry"
);
let pasted_dir_inner_dir = find_project_entry(&panel, "root/b/a/inner_dir", cx);
assert_ne!(
pasted_dir_inner_dir, None,
"Directories inside pasted directory should have an entry"
);
toggle_expand_dir(&panel, "root/b", cx);
toggle_expand_dir(&panel, "root/b/a", cx);
toggle_expand_dir(&panel, "root/b/a/inner_dir", cx);
assert_eq!(
visible_entries_as_strings(&panel, 0..50, cx),
&[
//
"v root",
" > a",
" v b",
" v a",
" v inner_dir <== selected",
" four.txt",
" three.txt",
" one.txt",
" two.txt",
]
);
select_path(&panel, "root", cx);
panel.update(cx, |panel, cx| panel.paste(&Default::default(), cx));
cx.executor().run_until_parked();
panel.update(cx, |panel, cx| panel.paste(&Default::default(), cx));
cx.executor().run_until_parked();
assert_eq!(
visible_entries_as_strings(&panel, 0..50, cx),
&[
//
"v root <== selected",
" > a",
" > a copy",
" > a copy 1",
" v b",
" v a",
" v inner_dir",
" four.txt",
" three.txt",
" one.txt",
" two.txt"
]
);
}
#[gpui::test]
async fn test_remove_opened_file(cx: &mut gpui::TestAppContext) {
init_test_with_editor(cx);