Restore project diff test (#21606)
Restores a basic project diff test Release Notes: - N/A --------- Co-authored-by: Cole Miller <cole@zed.dev>
This commit is contained in:
parent
787c75cbda
commit
1efd165ead
2 changed files with 141 additions and 112 deletions
|
@ -55,6 +55,7 @@ struct ProjectDiffEditor {
|
||||||
_subscriptions: Vec<Subscription>,
|
_subscriptions: Vec<Subscription>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
struct Changes {
|
struct Changes {
|
||||||
_status: GitFileStatus,
|
_status: GitFileStatus,
|
||||||
buffer: Model<Buffer>,
|
buffer: Model<Buffer>,
|
||||||
|
@ -235,15 +236,16 @@ impl ProjectDiffEditor {
|
||||||
let mut change_sets = Vec::new();
|
let mut change_sets = Vec::new();
|
||||||
for (status, entry_id, entry_path, open_task) in open_tasks {
|
for (status, entry_id, entry_path, open_task) in open_tasks {
|
||||||
let (_, opened_model) = open_task.await.with_context(|| {
|
let (_, opened_model) = open_task.await.with_context(|| {
|
||||||
format!("loading buffer {} for git diff", entry_path.path.display())
|
format!("loading buffer {:?} for git diff", entry_path.path)
|
||||||
})?;
|
})?;
|
||||||
let buffer = match opened_model.downcast::<Buffer>() {
|
let buffer = match opened_model.downcast::<Buffer>() {
|
||||||
Ok(buffer) => buffer,
|
Ok(buffer) => buffer,
|
||||||
Err(_model) => anyhow::bail!(
|
Err(_model) => anyhow::bail!(
|
||||||
"Could not load {} as a buffer for git diff",
|
"Could not load {:?} as a buffer for git diff",
|
||||||
entry_path.path.display()
|
entry_path.path
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
let change_set = project
|
let change_set = project
|
||||||
.update(&mut cx, |project, cx| {
|
.update(&mut cx, |project, cx| {
|
||||||
project.open_unstaged_changes(buffer.clone(), cx)
|
project.open_unstaged_changes(buffer.clone(), cx)
|
||||||
|
@ -1089,13 +1091,16 @@ impl Render for ProjectDiffEditor {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
// use std::{ops::Deref as _, path::Path, sync::Arc};
|
use gpui::{SemanticVersion, TestAppContext, VisualTestContext};
|
||||||
|
use project::buffer_store::BufferChangeSet;
|
||||||
|
use serde_json::json;
|
||||||
|
use settings::SettingsStore;
|
||||||
|
use std::{
|
||||||
|
ops::Deref as _,
|
||||||
|
path::{Path, PathBuf},
|
||||||
|
};
|
||||||
|
|
||||||
// use fs::RealFs;
|
use super::*;
|
||||||
// use gpui::{SemanticVersion, TestAppContext, VisualTestContext};
|
|
||||||
// use settings::SettingsStore;
|
|
||||||
|
|
||||||
// use super::*;
|
|
||||||
|
|
||||||
// TODO finish
|
// TODO finish
|
||||||
// #[gpui::test]
|
// #[gpui::test]
|
||||||
|
@ -1111,114 +1116,131 @@ mod tests {
|
||||||
// // Apply randomized changes to the project: select a random file, random change and apply to buffers
|
// // Apply randomized changes to the project: select a random file, random change and apply to buffers
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// #[gpui::test]
|
#[gpui::test(iterations = 30)]
|
||||||
// async fn simple_edit_test(cx: &mut TestAppContext) {
|
async fn simple_edit_test(cx: &mut TestAppContext) {
|
||||||
// cx.executor().allow_parking();
|
cx.executor().allow_parking();
|
||||||
// init_test(cx);
|
init_test(cx);
|
||||||
|
|
||||||
// let dir = tempfile::tempdir().unwrap();
|
let fs = fs::FakeFs::new(cx.executor().clone());
|
||||||
// let dst = dir.path();
|
fs.insert_tree(
|
||||||
|
"/root",
|
||||||
|
json!({
|
||||||
|
".git": {},
|
||||||
|
"file_a": "This is file_a",
|
||||||
|
"file_b": "This is file_b",
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
// std::fs::write(dst.join("file_a"), "This is file_a").unwrap();
|
let project = Project::test(fs.clone(), [Path::new("/root")], cx).await;
|
||||||
// std::fs::write(dst.join("file_b"), "This is file_b").unwrap();
|
let workspace = cx.add_window(|cx| Workspace::test_new(project.clone(), cx));
|
||||||
|
let cx = &mut VisualTestContext::from_window(*workspace.deref(), cx);
|
||||||
|
|
||||||
// run_git(dst, &["init"]);
|
let file_a_editor = workspace
|
||||||
// run_git(dst, &["add", "*"]);
|
.update(cx, |workspace, cx| {
|
||||||
// run_git(dst, &["commit", "-m", "Initial commit"]);
|
let file_a_editor =
|
||||||
|
workspace.open_abs_path(PathBuf::from("/root/file_a"), true, cx);
|
||||||
|
ProjectDiffEditor::deploy(workspace, &Deploy, cx);
|
||||||
|
file_a_editor
|
||||||
|
})
|
||||||
|
.unwrap()
|
||||||
|
.await
|
||||||
|
.expect("did not open an item at all")
|
||||||
|
.downcast::<Editor>()
|
||||||
|
.expect("did not open an editor for file_a");
|
||||||
|
let project_diff_editor = workspace
|
||||||
|
.update(cx, |workspace, cx| {
|
||||||
|
workspace
|
||||||
|
.active_pane()
|
||||||
|
.read(cx)
|
||||||
|
.items()
|
||||||
|
.find_map(|item| item.downcast::<ProjectDiffEditor>())
|
||||||
|
})
|
||||||
|
.unwrap()
|
||||||
|
.expect("did not find a ProjectDiffEditor");
|
||||||
|
project_diff_editor.update(cx, |project_diff_editor, cx| {
|
||||||
|
assert!(
|
||||||
|
project_diff_editor.editor.read(cx).text(cx).is_empty(),
|
||||||
|
"Should have no changes after opening the diff on no git changes"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
// let project = Project::test(Arc::new(RealFs::default()), [dst], cx).await;
|
let old_text = file_a_editor.update(cx, |editor, cx| editor.text(cx));
|
||||||
// let workspace = cx.add_window(|cx| Workspace::test_new(project.clone(), cx));
|
let change = "an edit after git add";
|
||||||
// let cx = &mut VisualTestContext::from_window(*workspace.deref(), cx);
|
file_a_editor
|
||||||
|
.update(cx, |file_a_editor, cx| {
|
||||||
|
file_a_editor.insert(change, cx);
|
||||||
|
file_a_editor.save(false, project.clone(), cx)
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.expect("failed to save a file");
|
||||||
|
file_a_editor.update(cx, |file_a_editor, cx| {
|
||||||
|
let change_set = cx.new_model(|cx| {
|
||||||
|
BufferChangeSet::new_with_base_text(
|
||||||
|
old_text.clone(),
|
||||||
|
file_a_editor
|
||||||
|
.buffer()
|
||||||
|
.read(cx)
|
||||||
|
.as_singleton()
|
||||||
|
.unwrap()
|
||||||
|
.read(cx)
|
||||||
|
.text_snapshot(),
|
||||||
|
cx,
|
||||||
|
)
|
||||||
|
});
|
||||||
|
file_a_editor
|
||||||
|
.diff_map
|
||||||
|
.add_change_set(change_set.clone(), cx);
|
||||||
|
project.update(cx, |project, cx| {
|
||||||
|
project.buffer_store().update(cx, |buffer_store, cx| {
|
||||||
|
buffer_store.set_change_set(
|
||||||
|
file_a_editor
|
||||||
|
.buffer()
|
||||||
|
.read(cx)
|
||||||
|
.as_singleton()
|
||||||
|
.unwrap()
|
||||||
|
.read(cx)
|
||||||
|
.remote_id(),
|
||||||
|
change_set,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
fs.set_status_for_repo_via_git_operation(
|
||||||
|
Path::new("/root/.git"),
|
||||||
|
&[(Path::new("file_a"), GitFileStatus::Modified)],
|
||||||
|
);
|
||||||
|
cx.executor()
|
||||||
|
.advance_clock(UPDATE_DEBOUNCE + Duration::from_millis(100));
|
||||||
|
cx.run_until_parked();
|
||||||
|
|
||||||
// let file_a_editor = workspace
|
project_diff_editor.update(cx, |project_diff_editor, cx| {
|
||||||
// .update(cx, |workspace, cx| {
|
assert_eq!(
|
||||||
// let file_a_editor = workspace.open_abs_path(dst.join("file_a"), true, cx);
|
// TODO assert it better: extract added text (based on the background changes) and deleted text (based on the deleted blocks added)
|
||||||
// ProjectDiffEditor::deploy(workspace, &Deploy, cx);
|
project_diff_editor.editor.read(cx).text(cx),
|
||||||
// file_a_editor
|
format!("{change}{old_text}"),
|
||||||
// })
|
"Should have a new change shown in the beginning, and the old text shown as deleted text afterwards"
|
||||||
// .unwrap()
|
);
|
||||||
// .await
|
});
|
||||||
// .expect("did not open an item at all")
|
}
|
||||||
// .downcast::<Editor>()
|
|
||||||
// .expect("did not open an editor for file_a");
|
|
||||||
|
|
||||||
// let project_diff_editor = workspace
|
fn init_test(cx: &mut gpui::TestAppContext) {
|
||||||
// .update(cx, |workspace, cx| {
|
if std::env::var("RUST_LOG").is_ok() {
|
||||||
// workspace
|
env_logger::try_init().ok();
|
||||||
// .active_pane()
|
}
|
||||||
// .read(cx)
|
|
||||||
// .items()
|
|
||||||
// .find_map(|item| item.downcast::<ProjectDiffEditor>())
|
|
||||||
// })
|
|
||||||
// .unwrap()
|
|
||||||
// .expect("did not find a ProjectDiffEditor");
|
|
||||||
// project_diff_editor.update(cx, |project_diff_editor, cx| {
|
|
||||||
// assert!(
|
|
||||||
// project_diff_editor.editor.read(cx).text(cx).is_empty(),
|
|
||||||
// "Should have no changes after opening the diff on no git changes"
|
|
||||||
// );
|
|
||||||
// });
|
|
||||||
|
|
||||||
// let old_text = file_a_editor.update(cx, |editor, cx| editor.text(cx));
|
cx.update(|cx| {
|
||||||
// let change = "an edit after git add";
|
assets::Assets.load_test_fonts(cx);
|
||||||
// file_a_editor
|
let settings_store = SettingsStore::test(cx);
|
||||||
// .update(cx, |file_a_editor, cx| {
|
cx.set_global(settings_store);
|
||||||
// file_a_editor.insert(change, cx);
|
theme::init(theme::LoadThemes::JustBase, cx);
|
||||||
// file_a_editor.save(false, project.clone(), cx)
|
release_channel::init(SemanticVersion::default(), cx);
|
||||||
// })
|
client::init_settings(cx);
|
||||||
// .await
|
language::init(cx);
|
||||||
// .expect("failed to save a file");
|
Project::init_settings(cx);
|
||||||
// cx.executor().advance_clock(Duration::from_secs(1));
|
workspace::init_settings(cx);
|
||||||
// cx.run_until_parked();
|
crate::init(cx);
|
||||||
|
cx.set_staff(true);
|
||||||
// // TODO does not work on Linux for some reason, returning a blank line
|
});
|
||||||
// // hence disable the last check for now, and do some fiddling to avoid the warnings.
|
}
|
||||||
// #[cfg(target_os = "linux")]
|
|
||||||
// {
|
|
||||||
// if true {
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// project_diff_editor.update(cx, |project_diff_editor, cx| {
|
|
||||||
// // TODO assert it better: extract added text (based on the background changes) and deleted text (based on the deleted blocks added)
|
|
||||||
// assert_eq!(
|
|
||||||
// project_diff_editor.editor.read(cx).text(cx),
|
|
||||||
// format!("{change}{old_text}"),
|
|
||||||
// "Should have a new change shown in the beginning, and the old text shown as deleted text afterwards"
|
|
||||||
// );
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
// fn run_git(path: &Path, args: &[&str]) -> String {
|
|
||||||
// let output = std::process::Command::new("git")
|
|
||||||
// .args(args)
|
|
||||||
// .current_dir(path)
|
|
||||||
// .output()
|
|
||||||
// .expect("git commit failed");
|
|
||||||
|
|
||||||
// format!(
|
|
||||||
// "Stdout: {}; stderr: {}",
|
|
||||||
// String::from_utf8(output.stdout).unwrap(),
|
|
||||||
// String::from_utf8(output.stderr).unwrap()
|
|
||||||
// )
|
|
||||||
// }
|
|
||||||
|
|
||||||
// fn init_test(cx: &mut gpui::TestAppContext) {
|
|
||||||
// if std::env::var("RUST_LOG").is_ok() {
|
|
||||||
// env_logger::try_init().ok();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// cx.update(|cx| {
|
|
||||||
// assets::Assets.load_test_fonts(cx);
|
|
||||||
// let settings_store = SettingsStore::test(cx);
|
|
||||||
// cx.set_global(settings_store);
|
|
||||||
// theme::init(theme::LoadThemes::JustBase, cx);
|
|
||||||
// release_channel::init(SemanticVersion::default(), cx);
|
|
||||||
// client::init_settings(cx);
|
|
||||||
// language::init(cx);
|
|
||||||
// Project::init_settings(cx);
|
|
||||||
// workspace::init_settings(cx);
|
|
||||||
// crate::init(cx);
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,7 @@ struct SharedBuffer {
|
||||||
unstaged_changes: Option<Model<BufferChangeSet>>,
|
unstaged_changes: Option<Model<BufferChangeSet>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct BufferChangeSet {
|
pub struct BufferChangeSet {
|
||||||
pub buffer_id: BufferId,
|
pub buffer_id: BufferId,
|
||||||
pub base_text: Option<Model<Buffer>>,
|
pub base_text: Option<Model<Buffer>>,
|
||||||
|
@ -1045,6 +1046,12 @@ impl BufferStore {
|
||||||
.spawn(async move { task.await.map_err(|e| anyhow!("{e}")) })
|
.spawn(async move { task.await.map_err(|e| anyhow!("{e}")) })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(any(test, feature = "test-support"))]
|
||||||
|
pub fn set_change_set(&mut self, buffer_id: BufferId, change_set: Model<BufferChangeSet>) {
|
||||||
|
self.loading_change_sets
|
||||||
|
.insert(buffer_id, Task::ready(Ok(change_set)).shared());
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn open_unstaged_changes_internal(
|
pub async fn open_unstaged_changes_internal(
|
||||||
this: WeakModel<Self>,
|
this: WeakModel<Self>,
|
||||||
text: Result<Option<String>>,
|
text: Result<Option<String>>,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue