diff --git a/src/change_processor.rs b/src/change_processor.rs index f6b7fff6..0157cc58 100644 --- a/src/change_processor.rs +++ b/src/change_processor.rs @@ -12,7 +12,7 @@ use rbx_dom_weak::RbxId; use crate::{ message_queue::MessageQueue, snapshot::{apply_patch_set, compute_patch_set, AppliedPatchSet, InstigatingSource, RojoTree}, - snapshot_middleware::{snapshot_from_vfs, InstanceSnapshotContext}, + snapshot_middleware::{snapshot_from_vfs, snapshot_project_node, InstanceSnapshotContext}, vfs::{Vfs, VfsEvent, VfsFetcher}, }; @@ -139,22 +139,24 @@ fn update_affected_instances( } }; + // TODO: Use persisted snapshot context struct instead of recreating it + // every time. + let mut snapshot_context = InstanceSnapshotContext::default(); + let snapshot = match instigating_source { InstigatingSource::Path(path) => { let entry = vfs .get(path) .expect("could not get instigating path from filesystem"); - // TODO: Use persisted snapshot - // context struct instead of - // recreating it every time. - snapshot_from_vfs(&mut InstanceSnapshotContext::default(), &vfs, &entry) + snapshot_from_vfs(&mut snapshot_context, &vfs, &entry) .expect("snapshot failed") .expect("snapshot did not return an instance") } - InstigatingSource::ProjectNode(_, _) => { - log::warn!("Instance {} had an instigating source that was a project node, which is not yet supported.", id); - continue; + InstigatingSource::ProjectNode(instance_name, project_node) => { + snapshot_project_node(&mut snapshot_context, instance_name, project_node, &vfs) + .expect("snapshot failed") + .expect("snapshot did not return an instance") } }; diff --git a/src/serve_session.rs b/src/serve_session.rs index 0652a728..7a90d6b0 100644 --- a/src/serve_session.rs +++ b/src/serve_session.rs @@ -311,4 +311,57 @@ mod serve_session { view_tree(&session.tree(), &mut redactions) ); } + + #[test] + fn change_file_in_project() { + let (state, fetcher) = TestFetcher::new(); + + state.load_snapshot( + "/foo", + VfsSnapshot::dir(hashmap! { + "default.project.json" => VfsSnapshot::file(r#" + { + "name": "change_file_in_project", + "tree": { + "$className": "Folder", + + "Child": { + "$path": "file.txt" + } + } + } + "#), + "file.txt" => VfsSnapshot::file("initial content"), + }), + ); + + let vfs = Vfs::new(fetcher); + let session = ServeSession::new(vfs, "/foo"); + + let mut redactions = RedactionMap::new(); + assert_yaml_snapshot!( + "change_file_in_project_before", + view_tree(&session.tree(), &mut redactions) + ); + + state.load_snapshot("/foo/file.txt", VfsSnapshot::file("Changed!")); + + let receiver = session.message_queue().subscribe_any(); + + state.raise_event(VfsEvent::Modified(PathBuf::from("/foo/file.txt"))); + + let receiver = Timeout::new(receiver, Duration::from_millis(200)); + + let mut rt = Runtime::new().unwrap(); + let result = rt.block_on(receiver).unwrap(); + + assert_yaml_snapshot!( + "change_file_in_project_patch", + redactions.redacted_yaml(result) + ); + assert_yaml_snapshot!( + "change_file_in_project_after", + view_tree(&session.tree(), &mut redactions) + ); + } } diff --git a/src/snapshot_middleware/mod.rs b/src/snapshot_middleware/mod.rs index 25f0bedb..6c3174e9 100644 --- a/src/snapshot_middleware/mod.rs +++ b/src/snapshot_middleware/mod.rs @@ -39,6 +39,8 @@ use self::{ }; use crate::vfs::{Vfs, VfsEntry, VfsFetcher}; +pub use self::project::snapshot_project_node; + macro_rules! middlewares { ( $($middleware: ident,)* ) => { /// Generates a snapshot of instances from the given VfsEntry. diff --git a/src/snapshot_middleware/project.rs b/src/snapshot_middleware/project.rs index bb4a8ffe..91ed6ccb 100644 --- a/src/snapshot_middleware/project.rs +++ b/src/snapshot_middleware/project.rs @@ -76,7 +76,7 @@ impl SnapshotMiddleware for SnapshotProject { } } -fn snapshot_project_node( +pub fn snapshot_project_node( context: &mut InstanceSnapshotContext, instance_name: &str, node: &ProjectNode, diff --git a/src/snapshots/serve_session__change_file_in_project_after.snap b/src/snapshots/serve_session__change_file_in_project_after.snap new file mode 100644 index 00000000..0efeb6c5 --- /dev/null +++ b/src/snapshots/serve_session__change_file_in_project_after.snap @@ -0,0 +1,36 @@ +--- +source: src/serve_session.rs +expression: "view_tree(&session.tree(), &mut redactions)" +--- +id: id-1 +name: change_file_in_project +class_name: Folder +properties: {} +metadata: + ignore_unknown_instances: true + instigating_source: + Path: /foo/default.project.json + relevant_paths: + - /foo/default.project.json +children: + - id: id-2 + name: Child + class_name: StringValue + properties: + Value: + Type: String + Value: Changed! + metadata: + ignore_unknown_instances: false + instigating_source: + ProjectNode: + - Child + - class_name: ~ + children: {} + properties: {} + ignore_unknown_instances: ~ + path: "/foo\\file.txt" + relevant_paths: + - /foo/file.txt + - /foo/file.meta.json + children: [] diff --git a/src/snapshots/serve_session__change_file_in_project_before.snap b/src/snapshots/serve_session__change_file_in_project_before.snap new file mode 100644 index 00000000..c824b355 --- /dev/null +++ b/src/snapshots/serve_session__change_file_in_project_before.snap @@ -0,0 +1,36 @@ +--- +source: src/serve_session.rs +expression: "view_tree(&session.tree(), &mut redactions)" +--- +id: id-1 +name: change_file_in_project +class_name: Folder +properties: {} +metadata: + ignore_unknown_instances: true + instigating_source: + Path: /foo/default.project.json + relevant_paths: + - /foo/default.project.json +children: + - id: id-2 + name: Child + class_name: StringValue + properties: + Value: + Type: String + Value: initial content + metadata: + ignore_unknown_instances: false + instigating_source: + ProjectNode: + - Child + - class_name: ~ + children: {} + properties: {} + ignore_unknown_instances: ~ + path: "/foo\\file.txt" + relevant_paths: + - /foo/file.txt + - /foo/file.meta.json + children: [] diff --git a/src/snapshots/serve_session__change_file_in_project_patch.snap b/src/snapshots/serve_session__change_file_in_project_patch.snap new file mode 100644 index 00000000..062181c5 --- /dev/null +++ b/src/snapshots/serve_session__change_file_in_project_patch.snap @@ -0,0 +1,16 @@ +--- +source: src/serve_session.rs +expression: redactions.redacted_yaml(result) +--- +- 1 +- - removed: [] + added: [] + updated: + - id: id-2 + changed_name: ~ + changed_class_name: ~ + changed_properties: + Value: + Type: String + Value: Changed! + changed_metadata: ~