mirror of
https://github.com/rojo-rbx/rojo.git
synced 2026-04-24 14:45:56 +00:00
Permute order of FS change events semi-exhaustively
This commit is contained in:
@@ -25,7 +25,7 @@ fn add_sync_points(imfs: &mut Imfs, project_node: &ProjectNode) -> io::Result<()
|
|||||||
/// The in-memory filesystem keeps a mirror of all files being watcher by Rojo
|
/// The in-memory filesystem keeps a mirror of all files being watcher by Rojo
|
||||||
/// in order to deduplicate file changes in the case of bidirectional syncing
|
/// in order to deduplicate file changes in the case of bidirectional syncing
|
||||||
/// from Roblox Studio.
|
/// from Roblox Studio.
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Imfs {
|
pub struct Imfs {
|
||||||
items: HashMap<PathBuf, ImfsItem>,
|
items: HashMap<PathBuf, ImfsItem>,
|
||||||
roots: HashSet<PathBuf>,
|
roots: HashSet<PathBuf>,
|
||||||
@@ -219,19 +219,19 @@ enum PathKind {
|
|||||||
NotInRoot,
|
NotInRoot,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
pub struct ImfsFile {
|
pub struct ImfsFile {
|
||||||
pub path: PathBuf,
|
pub path: PathBuf,
|
||||||
pub contents: Vec<u8>,
|
pub contents: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
pub struct ImfsDirectory {
|
pub struct ImfsDirectory {
|
||||||
pub path: PathBuf,
|
pub path: PathBuf,
|
||||||
pub children: HashSet<PathBuf>,
|
pub children: HashSet<PathBuf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
pub enum ImfsItem {
|
pub enum ImfsItem {
|
||||||
File(ImfsFile),
|
File(ImfsFile),
|
||||||
Directory(ImfsDirectory),
|
Directory(ImfsDirectory),
|
||||||
|
|||||||
@@ -11,6 +11,27 @@ use librojo::{
|
|||||||
imfs::{Imfs, ImfsItem, ImfsFile, ImfsDirectory},
|
imfs::{Imfs, ImfsItem, ImfsFile, ImfsDirectory},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum FsEvent {
|
||||||
|
Created(PathBuf),
|
||||||
|
Updated(PathBuf),
|
||||||
|
Removed(PathBuf),
|
||||||
|
Moved(PathBuf, PathBuf),
|
||||||
|
}
|
||||||
|
|
||||||
|
fn send_events(imfs: &mut Imfs, events: &[FsEvent]) -> io::Result<()> {
|
||||||
|
for event in events {
|
||||||
|
match event {
|
||||||
|
FsEvent::Created(path) => imfs.path_created(path)?,
|
||||||
|
FsEvent::Updated(path) => imfs.path_updated(path)?,
|
||||||
|
FsEvent::Removed(path) => imfs.path_removed(path)?,
|
||||||
|
FsEvent::Moved(from, to) => imfs.path_moved(from, to)?,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
struct ExpectedImfs {
|
struct ExpectedImfs {
|
||||||
roots: HashSet<PathBuf>,
|
roots: HashSet<PathBuf>,
|
||||||
items: HashMap<PathBuf, ImfsItem>,
|
items: HashMap<PathBuf, ImfsItem>,
|
||||||
@@ -123,9 +144,6 @@ fn adding_files() -> io::Result<()> {
|
|||||||
fs::write(&add_one_path, b"add_one")?;
|
fs::write(&add_one_path, b"add_one")?;
|
||||||
fs::write(&add_two_path, b"add_two")?;
|
fs::write(&add_two_path, b"add_two")?;
|
||||||
|
|
||||||
imfs.path_created(&add_one_path)?;
|
|
||||||
imfs.path_created(&add_two_path)?;
|
|
||||||
|
|
||||||
match expected_imfs.items.get_mut(root.path()) {
|
match expected_imfs.items.get_mut(root.path()) {
|
||||||
Some(ImfsItem::Directory(directory)) => {
|
Some(ImfsItem::Directory(directory)) => {
|
||||||
directory.children.insert(add_one_path.clone());
|
directory.children.insert(add_one_path.clone());
|
||||||
@@ -150,6 +168,9 @@ fn adding_files() -> io::Result<()> {
|
|||||||
contents: b"add_two".to_vec(),
|
contents: b"add_two".to_vec(),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
imfs.path_created(&add_one_path)?;
|
||||||
|
imfs.path_created(&add_two_path)?;
|
||||||
|
|
||||||
check_expected(&imfs, &expected_imfs);
|
check_expected(&imfs, &expected_imfs);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -169,10 +190,6 @@ fn adding_folder() -> io::Result<()> {
|
|||||||
fs::write(&file1_path, b"file1")?;
|
fs::write(&file1_path, b"file1")?;
|
||||||
fs::write(&file2_path, b"file2")?;
|
fs::write(&file2_path, b"file2")?;
|
||||||
|
|
||||||
// TODO: Enumerate all possible combinations of file changed events this
|
|
||||||
// could trigger.
|
|
||||||
imfs.path_created(&folder_path)?;
|
|
||||||
|
|
||||||
match expected_imfs.items.get_mut(root.path()) {
|
match expected_imfs.items.get_mut(root.path()) {
|
||||||
Some(ImfsItem::Directory(directory)) => {
|
Some(ImfsItem::Directory(directory)) => {
|
||||||
directory.children.insert(folder_path.clone());
|
directory.children.insert(folder_path.clone());
|
||||||
@@ -205,7 +222,23 @@ fn adding_folder() -> io::Result<()> {
|
|||||||
});
|
});
|
||||||
expected_imfs.items.insert(file2_path.clone(), file2_item);
|
expected_imfs.items.insert(file2_path.clone(), file2_item);
|
||||||
|
|
||||||
check_expected(&imfs, &expected_imfs);
|
let possible_event_sequences = vec![
|
||||||
|
vec![
|
||||||
|
FsEvent::Created(folder_path.clone())
|
||||||
|
],
|
||||||
|
vec![
|
||||||
|
FsEvent::Created(folder_path.clone()),
|
||||||
|
FsEvent::Created(file1_path.clone()),
|
||||||
|
FsEvent::Created(file2_path.clone()),
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
for events in &possible_event_sequences {
|
||||||
|
let mut imfs = imfs.clone();
|
||||||
|
|
||||||
|
send_events(&mut imfs, events);
|
||||||
|
check_expected(&imfs, &expected_imfs);
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -242,10 +275,6 @@ fn removing_folder() -> io::Result<()> {
|
|||||||
|
|
||||||
fs::remove_dir_all(&resources.foo_path)?;
|
fs::remove_dir_all(&resources.foo_path)?;
|
||||||
|
|
||||||
// TODO: Enumerate all possible combinations of file changed events this
|
|
||||||
// could trigger.
|
|
||||||
imfs.path_removed(&resources.foo_path)?;
|
|
||||||
|
|
||||||
match expected_imfs.items.get_mut(root.path()) {
|
match expected_imfs.items.get_mut(root.path()) {
|
||||||
Some(ImfsItem::Directory(directory)) => {
|
Some(ImfsItem::Directory(directory)) => {
|
||||||
directory.children.remove(&resources.foo_path);
|
directory.children.remove(&resources.foo_path);
|
||||||
@@ -256,7 +285,22 @@ fn removing_folder() -> io::Result<()> {
|
|||||||
expected_imfs.items.remove(&resources.foo_path);
|
expected_imfs.items.remove(&resources.foo_path);
|
||||||
expected_imfs.items.remove(&resources.baz_path);
|
expected_imfs.items.remove(&resources.baz_path);
|
||||||
|
|
||||||
check_expected(&imfs, &expected_imfs);
|
let possible_event_sequences = vec![
|
||||||
|
vec![
|
||||||
|
FsEvent::Removed(resources.foo_path.clone()),
|
||||||
|
],
|
||||||
|
vec![
|
||||||
|
FsEvent::Removed(resources.baz_path.clone()),
|
||||||
|
FsEvent::Removed(resources.foo_path.clone()),
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
for events in &possible_event_sequences {
|
||||||
|
let mut imfs = imfs.clone();
|
||||||
|
|
||||||
|
send_events(&mut imfs, events);
|
||||||
|
check_expected(&imfs, &expected_imfs);
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user