aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_vfs/tests/vfs.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_vfs/tests/vfs.rs')
-rw-r--r--crates/ra_vfs/tests/vfs.rs156
1 files changed, 117 insertions, 39 deletions
diff --git a/crates/ra_vfs/tests/vfs.rs b/crates/ra_vfs/tests/vfs.rs
index f56fc4603..357e1c775 100644
--- a/crates/ra_vfs/tests/vfs.rs
+++ b/crates/ra_vfs/tests/vfs.rs
@@ -1,24 +1,47 @@
1use std::{ 1use std::{collections::HashSet, fs, time::Duration};
2 fs,
3 collections::HashSet,
4};
5 2
3// use flexi_logger::Logger;
4use crossbeam_channel::RecvTimeoutError;
5use ra_vfs::{Vfs, VfsChange};
6use tempfile::tempdir; 6use tempfile::tempdir;
7 7
8use ra_vfs::{Vfs, VfsChange}; 8fn process_tasks(vfs: &mut Vfs, num_tasks: u32) {
9 for _ in 0..num_tasks {
10 let task = vfs
11 .task_receiver()
12 .recv_timeout(Duration::from_secs(3))
13 .unwrap();
14 log::debug!("{:?}", task);
15 vfs.handle_task(task);
16 }
17}
18
19macro_rules! assert_match {
20 ($x:expr, $pat:pat) => {
21 assert_match!($x, $pat, ())
22 };
23 ($x:expr, $pat:pat, $assert:expr) => {
24 match $x {
25 $pat => $assert,
26 x => assert!(false, "Expected {}, got {:?}", stringify!($pat), x),
27 };
28 };
29}
9 30
10#[test] 31#[test]
11fn test_vfs_works() -> std::io::Result<()> { 32fn test_vfs_works() -> std::io::Result<()> {
33 // Logger::with_str("vfs=debug,ra_vfs=debug").start().unwrap();
34
12 let files = [ 35 let files = [
13 ("a/foo.rs", "hello"), 36 ("a/foo.rs", "hello"),
14 ("a/bar.rs", "world"), 37 ("a/bar.rs", "world"),
15 ("a/b/baz.rs", "nested hello"), 38 ("a/b/baz.rs", "nested hello"),
16 ]; 39 ];
17 40
18 let dir = tempdir()?; 41 let dir = tempdir().unwrap();
19 for (path, text) in files.iter() { 42 for (path, text) in files.iter() {
20 let file_path = dir.path().join(path); 43 let file_path = dir.path().join(path);
21 fs::create_dir_all(file_path.parent().unwrap())?; 44 fs::create_dir_all(file_path.parent().unwrap()).unwrap();
22 fs::write(file_path, text)? 45 fs::write(file_path, text)?
23 } 46 }
24 47
@@ -26,10 +49,7 @@ fn test_vfs_works() -> std::io::Result<()> {
26 let b_root = dir.path().join("a/b"); 49 let b_root = dir.path().join("a/b");
27 50
28 let (mut vfs, _) = Vfs::new(vec![a_root, b_root]); 51 let (mut vfs, _) = Vfs::new(vec![a_root, b_root]);
29 for _ in 0..2 { 52 process_tasks(&mut vfs, 2);
30 let task = vfs.task_receiver().recv().unwrap();
31 vfs.handle_task(task);
32 }
33 { 53 {
34 let files = vfs 54 let files = vfs
35 .commit_changes() 55 .commit_changes()
@@ -58,43 +78,101 @@ fn test_vfs_works() -> std::io::Result<()> {
58 assert_eq!(files, expected_files); 78 assert_eq!(files, expected_files);
59 } 79 }
60 80
61 vfs.add_file_overlay(&dir.path().join("a/b/baz.rs"), "quux".to_string()); 81 fs::write(&dir.path().join("a/b/baz.rs"), "quux").unwrap();
62 let change = vfs.commit_changes().pop().unwrap(); 82 process_tasks(&mut vfs, 1);
63 match change { 83 assert_match!(
64 VfsChange::ChangeFile { text, .. } => assert_eq!(&*text, "quux"), 84 vfs.commit_changes().as_slice(),
65 _ => panic!("unexpected change"), 85 [VfsChange::ChangeFile { text, .. }],
66 } 86 assert_eq!(text.as_str(), "quux")
87 );
67 88
68 vfs.change_file_overlay(&dir.path().join("a/b/baz.rs"), "m".to_string()); 89 vfs.add_file_overlay(&dir.path().join("a/b/baz.rs"), "m".to_string());
69 let change = vfs.commit_changes().pop().unwrap(); 90 assert_match!(
70 match change { 91 vfs.commit_changes().as_slice(),
71 VfsChange::ChangeFile { text, .. } => assert_eq!(&*text, "m"), 92 [VfsChange::ChangeFile { text, .. }],
72 _ => panic!("unexpected change"), 93 assert_eq!(text.as_str(), "m")
73 } 94 );
74 95
96 // changing file on disk while overlayed doesn't generate a VfsChange
97 fs::write(&dir.path().join("a/b/baz.rs"), "corge").unwrap();
98 process_tasks(&mut vfs, 1);
99 assert_match!(vfs.commit_changes().as_slice(), []);
100
101 // removing overlay restores data on disk
75 vfs.remove_file_overlay(&dir.path().join("a/b/baz.rs")); 102 vfs.remove_file_overlay(&dir.path().join("a/b/baz.rs"));
76 let change = vfs.commit_changes().pop().unwrap(); 103 assert_match!(
77 match change { 104 vfs.commit_changes().as_slice(),
78 VfsChange::ChangeFile { text, .. } => assert_eq!(&*text, "nested hello"), 105 [VfsChange::ChangeFile { text, .. }],
79 _ => panic!("unexpected change"), 106 assert_eq!(text.as_str(), "corge")
80 } 107 );
81 108
82 vfs.add_file_overlay(&dir.path().join("a/b/spam.rs"), "spam".to_string()); 109 vfs.add_file_overlay(&dir.path().join("a/b/spam.rs"), "spam".to_string());
83 let change = vfs.commit_changes().pop().unwrap(); 110 assert_match!(
84 match change { 111 vfs.commit_changes().as_slice(),
85 VfsChange::AddFile { text, path, .. } => { 112 [VfsChange::AddFile { text, path, .. }],
86 assert_eq!(&*text, "spam"); 113 {
114 assert_eq!(text.as_str(), "spam");
87 assert_eq!(path, "spam.rs"); 115 assert_eq!(path, "spam.rs");
88 } 116 }
89 _ => panic!("unexpected change"), 117 );
90 }
91 118
92 vfs.remove_file_overlay(&dir.path().join("a/b/spam.rs")); 119 vfs.remove_file_overlay(&dir.path().join("a/b/spam.rs"));
93 let change = vfs.commit_changes().pop().unwrap(); 120 assert_match!(
94 match change { 121 vfs.commit_changes().as_slice(),
95 VfsChange::RemoveFile { .. } => (), 122 [VfsChange::RemoveFile { path, .. }],
96 _ => panic!("unexpected change"), 123 assert_eq!(path, "spam.rs")
97 } 124 );
125
126 fs::create_dir_all(dir.path().join("a/sub1/sub2")).unwrap();
127 fs::write(dir.path().join("a/sub1/sub2/new.rs"), "new hello").unwrap();
128 process_tasks(&mut vfs, 1);
129 assert_match!(
130 vfs.commit_changes().as_slice(),
131 [VfsChange::AddFile { text, path, .. }],
132 {
133 assert_eq!(text.as_str(), "new hello");
134 assert_eq!(path, "sub1/sub2/new.rs");
135 }
136 );
137
138 fs::rename(
139 &dir.path().join("a/sub1/sub2/new.rs"),
140 &dir.path().join("a/sub1/sub2/new1.rs"),
141 )
142 .unwrap();
143 process_tasks(&mut vfs, 2);
144 assert_match!(
145 vfs.commit_changes().as_slice(),
146 [VfsChange::RemoveFile {
147 path: removed_path, ..
148 }, VfsChange::AddFile {
149 text,
150 path: added_path,
151 ..
152 }],
153 {
154 assert_eq!(removed_path, "sub1/sub2/new.rs");
155 assert_eq!(added_path, "sub1/sub2/new1.rs");
156 assert_eq!(text.as_str(), "new hello");
157 }
158 );
159
160 fs::remove_file(&dir.path().join("a/sub1/sub2/new1.rs")).unwrap();
161 process_tasks(&mut vfs, 1);
162 assert_match!(
163 vfs.commit_changes().as_slice(),
164 [VfsChange::RemoveFile { path, .. }],
165 assert_eq!(path, "sub1/sub2/new1.rs")
166 );
167
168 // should be ignored
169 fs::create_dir_all(dir.path().join("a/target")).unwrap();
170 fs::write(&dir.path().join("a/target/new.rs"), "ignore me").unwrap();
171
172 assert_match!(
173 vfs.task_receiver().recv_timeout(Duration::from_millis(300)), // slightly more than watcher debounce delay
174 Err(RecvTimeoutError::Timeout)
175 );
98 176
99 vfs.shutdown().unwrap(); 177 vfs.shutdown().unwrap();
100 Ok(()) 178 Ok(())