Add failing test for buffer detecting on-disk changes

This commit is contained in:
Max Brunsfeld 2021-05-11 11:38:10 -07:00
parent de6376ca80
commit d5218fbac5

View file

@ -509,6 +509,10 @@ impl Buffer {
self.version > self.saved_version || self.file.as_ref().map_or(false, |f| f.is_deleted())
}
pub fn has_conflict(&self) -> bool {
false
}
pub fn version(&self) -> time::Global {
self.version.clone()
}
@ -2381,7 +2385,10 @@ impl ToPoint for usize {
#[cfg(test)]
mod tests {
use super::*;
use crate::{test::temp_tree, worktree::Worktree};
use crate::{
test::temp_tree,
worktree::{Worktree, WorktreeHandle},
};
use cmp::Ordering;
use gpui::App;
use serde_json::json;
@ -2989,8 +2996,6 @@ mod tests {
#[test]
fn test_is_dirty() {
use crate::worktree::WorktreeHandle;
App::test_async((), |mut app| async move {
let dir = temp_tree(json!({
"file1": "",
@ -3105,6 +3110,92 @@ mod tests {
});
}
#[test]
fn test_file_changes_on_disk() {
App::test_async((), |mut app| async move {
let initial_contents = "aaa\nbbb\nccc\n";
let dir = temp_tree(json!({ "the-file": initial_contents }));
let tree = app.add_model(|ctx| Worktree::new(dir.path(), ctx));
app.read(|ctx| tree.read(ctx).scan_complete()).await;
let abs_path = dir.path().join("the-file");
let file = app.read(|ctx| tree.file("the-file", ctx));
let buffer = app.add_model(|ctx| {
Buffer::from_history(0, History::new(initial_contents.into()), Some(file), ctx)
});
// Add a cursor at the start of each row.
let (selection_set_id, _) = buffer.update(&mut app, |buffer, ctx| {
assert!(!buffer.is_dirty());
buffer.add_selection_set(
(0..3)
.map(|row| {
let anchor = buffer
.anchor_at(Point::new(row, 0), AnchorBias::Left)
.unwrap();
Selection {
id: row as usize,
start: anchor.clone(),
end: anchor,
reversed: false,
goal: SelectionGoal::None,
}
})
.collect::<Vec<_>>(),
Some(ctx),
)
});
// Change the file on disk, adding a new line of text before each existing line.
buffer.update(&mut app, |buffer, _| {
assert!(!buffer.is_dirty());
assert!(!buffer.has_conflict());
});
tree.flush_fs_events(&app).await;
let new_contents = "AAA\naaa\nBBB\nbbb\nCCC\nccc\n";
fs::write(&abs_path, new_contents).unwrap();
// Because the buffer was not modified, it is reloaded from disk. Its
// contents are edited according to the diff between the old and new
// file contents.
buffer
.condition(&app, |buffer, _| buffer.text() == new_contents)
.await;
buffer.update(&mut app, |buffer, _| {
let selections = buffer.selections(selection_set_id).unwrap();
let cursor_positions = selections
.iter()
.map(|selection| {
assert_eq!(selection.start, selection.end);
selection.start.to_point(&buffer).unwrap()
})
.collect::<Vec<_>>();
assert_eq!(
cursor_positions,
&[Point::new(1, 0), Point::new(3, 0), Point::new(5, 0),]
);
});
// Modify the buffer
buffer.update(&mut app, |buffer, ctx| {
assert!(!buffer.is_dirty());
assert!(!buffer.has_conflict());
buffer.edit(vec![0..0], " ", Some(ctx)).unwrap();
assert!(buffer.is_dirty());
});
// Change the file on disk again, adding blank lines to the beginning.
fs::write(&abs_path, "\n\n\nAAA\naaa\nBBB\nbbb\nCCC\nccc\n").unwrap();
// Becaues the buffer is modified, it doesn't reload from disk, but is
// marked as having a conflict.
buffer
.condition(&app, |buffer, _| buffer.has_conflict())
.await;
});
}
#[test]
fn test_undo_redo() {
App::test((), |app| {