From 78ef26d56c812c691995244e1a01e7386d58a3fc Mon Sep 17 00:00:00 2001 From: Lucien Greathouse Date: Wed, 13 Mar 2019 11:37:13 -0700 Subject: [PATCH] Track metadata in tree snapshot tests --- server/tests/snapshot_snapshots.rs | 68 ++++ server/tests/snapshots.rs | 194 ----------- server/tests/test_util/mod.rs | 2 + server/tests/test_util/snapshot.rs | 23 +- server/tests/test_util/tree.rs | 221 ++++++++++--- server/tests/tree_snapshots.rs | 68 ++++ .../multi_partition_game/initial.tree.json | 282 ++++++++++++---- .../multi_partition_game/with_dir.tree.json | 305 +++++++++++++----- .../with_moved_dir.tree.json | 305 +++++++++++++----- 9 files changed, 999 insertions(+), 469 deletions(-) create mode 100644 server/tests/snapshot_snapshots.rs delete mode 100644 server/tests/snapshots.rs create mode 100644 server/tests/tree_snapshots.rs diff --git a/server/tests/snapshot_snapshots.rs b/server/tests/snapshot_snapshots.rs new file mode 100644 index 00000000..d697f50f --- /dev/null +++ b/server/tests/snapshot_snapshots.rs @@ -0,0 +1,68 @@ +mod test_util; + +use std::path::Path; + +use pretty_assertions::assert_eq; + +use librojo::{ + imfs::Imfs, + project::Project, + rbx_snapshot::{SnapshotContext, snapshot_project_tree}, +}; + +use crate::test_util::{ + snapshot::*, +}; + +macro_rules! generate_snapshot_tests { + ($($name: ident),*) => { + $( + paste::item! { + #[test] + fn []() { + let _ = env_logger::try_init(); + + let tests_folder = Path::new(env!("CARGO_MANIFEST_DIR")).join("../test-projects"); + let project_folder = tests_folder.join(stringify!($name)); + run_snapshot_test(&project_folder); + } + } + )* + }; +} + +generate_snapshot_tests!( + empty, + multi_partition_game, + nested_partitions, + single_partition_game, + single_partition_model, + transmute_partition +); + +fn run_snapshot_test(path: &Path) { + println!("Running snapshot from project: {}", path.display()); + + let project = Project::load_fuzzy(path) + .expect("Couldn't load project file for snapshot test"); + + let mut imfs = Imfs::new(); + imfs.add_roots_from_project(&project) + .expect("Could not add IMFS roots to snapshot project"); + + let context = SnapshotContext { + plugin_context: None, + }; + + let mut snapshot = snapshot_project_tree(&context, &imfs, &project) + .expect("Could not generate snapshot for snapshot test"); + + if let Some(snapshot) = snapshot.as_mut() { + anonymize_snapshot(path, snapshot); + } + + match read_expected_snapshot(path) { + Some(expected_snapshot) => assert_eq!(snapshot, expected_snapshot), + None => write_expected_snapshot(path, &snapshot), + } +} \ No newline at end of file diff --git a/server/tests/snapshots.rs b/server/tests/snapshots.rs deleted file mode 100644 index 10ecadb9..00000000 --- a/server/tests/snapshots.rs +++ /dev/null @@ -1,194 +0,0 @@ -mod test_util; - -use std::{ - collections::HashMap, - fs, - path::{Path, PathBuf}, - sync::Arc, - thread, - time::Duration, -}; - -use log::error; -use tempfile::{tempdir, TempDir}; -use pretty_assertions::assert_eq; - -use librojo::{ - imfs::Imfs, - project::Project, - live_session::LiveSession, - rbx_snapshot::{SnapshotContext, snapshot_project_tree}, - visualize::{VisualizeRbxTree, graphviz_to_svg}, -}; - -use crate::test_util::{ - copy_recursive, - snapshot::*, - tree::{read_tree_by_name, write_tree_by_name, trees_equal}, -}; - -macro_rules! generate_snapshot_tests { - ($($name: ident),*) => { - $( - paste::item! { - #[test] - fn []() { - let _ = env_logger::try_init(); - - let tests_folder = Path::new(env!("CARGO_MANIFEST_DIR")).join("../test-projects"); - let project_folder = tests_folder.join(stringify!($name)); - run_snapshot_test(&project_folder); - } - } - )* - }; -} - -generate_snapshot_tests!( - empty, - multi_partition_game, - nested_partitions, - single_partition_game, - single_partition_model, - transmute_partition -); - -#[test] -fn multi_partition_game() { - let _ = env_logger::try_init(); - let source_path = project_path("multi_partition_game"); - - let (dir, live_session) = start_session(&source_path); - tree_step("initial", &live_session, &source_path); - - let added_path = dir.path().join("a/added"); - fs::create_dir_all(&added_path) - .expect("Couldn't create directory"); - thread::sleep(Duration::from_millis(250)); - - tree_step("with_dir", &live_session, &source_path); - - let moved_path = dir.path().join("b/added"); - fs::rename(&added_path, &moved_path) - .expect("Couldn't rename directory"); - thread::sleep(Duration::from_millis(250)); - - tree_step("with_moved_dir", &live_session, &source_path); -} - -/// Find the path to the given test project relative to the manifest. -fn project_path(name: &str) -> PathBuf { - let mut path = Path::new(env!("CARGO_MANIFEST_DIR")).join("../test-projects"); - path.push(name); - path -} - -/// Starts a new LiveSession for the project located at the given file path. -fn start_session(source_path: &Path) -> (TempDir, LiveSession) { - let dir = tempdir() - .expect("Couldn't create temporary directory"); - - copy_recursive(&source_path, dir.path()) - .expect("Couldn't copy project to temporary directory"); - - let project = Arc::new(Project::load_fuzzy(dir.path()) - .expect("Couldn't load project from temp directory")); - - let live_session = LiveSession::new(Arc::clone(&project)) - .expect("Couldn't start live session"); - - (dir, live_session) -} - -/// Marks a 'step' in the test, which will snapshot the session's current -/// RbxTree object and compare it against the saved snapshot if it exists. -fn tree_step(step: &str, live_session: &LiveSession, source_path: &Path) { - let rbx_session = live_session.rbx_session.lock().unwrap(); - let tree = rbx_session.get_tree(); - - match read_tree_by_name(source_path, step) { - Some(expected) => match trees_equal(&expected, tree) { - Ok(_) => {} - Err(e) => { - error!("Trees at step '{}' were not equal.\n{}", step, e); - - let expected_gv = format!("{}", VisualizeRbxTree { - tree: &expected, - metadata: &HashMap::new(), - }); - - let actual_gv = format!("{}", VisualizeRbxTree { - tree: rbx_session.get_tree(), - metadata: &HashMap::new(), - }); - - let output_dir = PathBuf::from("failed-snapshots"); - fs::create_dir_all(&output_dir) - .expect("Could not create failed-snapshots directory"); - - let expected_basename = format!("{}-{}-expected", live_session.root_project().name, step); - let actual_basename = format!("{}-{}-actual", live_session.root_project().name, step); - - let mut expected_out = output_dir.join(expected_basename); - let mut actual_out = output_dir.join(actual_basename); - - match (graphviz_to_svg(&expected_gv), graphviz_to_svg(&actual_gv)) { - (Some(expected_svg), Some(actual_svg)) => { - expected_out.set_extension("svg"); - actual_out.set_extension("svg"); - - fs::write(&expected_out, expected_svg) - .expect("Couldn't write expected SVG"); - - fs::write(&actual_out, actual_svg) - .expect("Couldn't write actual SVG"); - } - _ => { - expected_out.set_extension("gv"); - actual_out.set_extension("gv"); - - fs::write(&expected_out, expected_gv) - .expect("Couldn't write expected GV"); - - fs::write(&actual_out, actual_gv) - .expect("Couldn't write actual GV"); - } - } - - error!("Output at {} and {}", expected_out.display(), actual_out.display()); - - panic!("Tree mismatch at step '{}'", step); - } - } - None => { - write_tree_by_name(source_path, step, tree); - } - } -} - -fn run_snapshot_test(path: &Path) { - println!("Running snapshot from project: {}", path.display()); - - let project = Project::load_fuzzy(path) - .expect("Couldn't load project file for snapshot test"); - - let mut imfs = Imfs::new(); - imfs.add_roots_from_project(&project) - .expect("Could not add IMFS roots to snapshot project"); - - let context = SnapshotContext { - plugin_context: None, - }; - - let mut snapshot = snapshot_project_tree(&context, &imfs, &project) - .expect("Could not generate snapshot for snapshot test"); - - if let Some(snapshot) = snapshot.as_mut() { - anonymize_snapshot(path, snapshot); - } - - match read_expected_snapshot(path) { - Some(expected_snapshot) => assert_eq!(snapshot, expected_snapshot), - None => write_expected_snapshot(path, &snapshot), - } -} \ No newline at end of file diff --git a/server/tests/test_util/mod.rs b/server/tests/test_util/mod.rs index a604a62b..5988865d 100644 --- a/server/tests/test_util/mod.rs +++ b/server/tests/test_util/mod.rs @@ -1,3 +1,5 @@ +#![allow(dead_code)] + use std::fs::{create_dir, copy}; use std::path::Path; use std::io; diff --git a/server/tests/test_util/snapshot.rs b/server/tests/test_util/snapshot.rs index 3e61292f..43088684 100644 --- a/server/tests/test_util/snapshot.rs +++ b/server/tests/test_util/snapshot.rs @@ -6,6 +6,7 @@ use std::{ use librojo::{ project::ProjectNode, snapshot_reconciler::RbxSnapshotInstance, + rbx_session::MetadataPerInstance, }; const SNAPSHOT_EXPECTED_NAME: &str = "expected-snapshot.json"; @@ -19,15 +20,7 @@ const SNAPSHOT_EXPECTED_NAME: &str = "expected-snapshot.json"; /// We also need to sort children, since Rojo tends to enumerate the filesystem /// in an unpredictable order. pub fn anonymize_snapshot(project_folder_path: &Path, snapshot: &mut RbxSnapshotInstance) { - match snapshot.metadata.source_path.as_mut() { - Some(path) => *path = anonymize_path(project_folder_path, path), - None => {}, - } - - match snapshot.metadata.project_definition.as_mut() { - Some((_, project_node)) => anonymize_project_node(project_folder_path, project_node), - None => {}, - } + anonymize_metadata(project_folder_path, &mut snapshot.metadata); snapshot.children.sort_by(|a, b| a.partial_cmp(b).unwrap()); @@ -36,6 +29,18 @@ pub fn anonymize_snapshot(project_folder_path: &Path, snapshot: &mut RbxSnapshot } } +pub fn anonymize_metadata(project_folder_path: &Path, metadata: &mut MetadataPerInstance) { + match metadata.source_path.as_mut() { + Some(path) => *path = anonymize_path(project_folder_path, path), + None => {}, + } + + match metadata.project_definition.as_mut() { + Some((_, project_node)) => anonymize_project_node(project_folder_path, project_node), + None => {}, + } +} + pub fn anonymize_project_node(project_folder_path: &Path, project_node: &mut ProjectNode) { match project_node.path.as_mut() { Some(path) => *path = anonymize_path(project_folder_path, path), diff --git a/server/tests/test_util/tree.rs b/server/tests/test_util/tree.rs index e8f230fe..f24023e8 100644 --- a/server/tests/test_util/tree.rs +++ b/server/tests/test_util/tree.rs @@ -1,7 +1,7 @@ //! Defines a mechanism to compare two RbxTree objects and generate a useful //! diff if they aren't the same. These methods ignore IDs, which are randomly //! generated whenever a tree is constructed anyways. This makes matching up -//! pairs of instances that should be the same pretty difficult. +//! pairs of instances that should be the same potentially difficult. //! //! It relies on a couple different ideas: //! - Instances with the same name and class name are matched as the same @@ -12,26 +12,131 @@ use std::{ borrow::Cow, - collections::HashSet, - path::Path, - fs::{self, File}, + collections::{HashMap, HashSet}, fmt, + fs::{self, File}, + hash::Hash, + path::{Path, PathBuf}, }; +use log::error; +use serde_derive::{Serialize, Deserialize}; use rbx_dom_weak::{RbxId, RbxTree}; -pub fn read_tree_by_name(path: &Path, identifier: &str) -> Option { +use librojo::{ + rbx_session::MetadataPerInstance, + live_session::LiveSession, + visualize::{VisualizeRbxTree, graphviz_to_svg}, +}; + +use super::snapshot::anonymize_metadata; + +/// Marks a 'step' in the test, which will snapshot the session's current +/// RbxTree object and compare it against the saved snapshot if it exists. +pub fn tree_step(step: &str, live_session: &LiveSession, source_path: &Path) { + let rbx_session = live_session.rbx_session.lock().unwrap(); + let tree = rbx_session.get_tree(); + + let project_folder = live_session.root_project().folder_location(); + let metadata = rbx_session.get_all_instance_metadata() + .iter() + .map(|(key, meta)| { + let mut meta = meta.clone(); + anonymize_metadata(project_folder, &mut meta); + (*key, meta) + }) + .collect(); + + let tree_with_metadata = TreeWithMetadata { + tree: Cow::Borrowed(&tree), + metadata: Cow::Owned(metadata), + }; + + match read_tree_by_name(source_path, step) { + Some(expected) => match trees_equal(&expected, &tree_with_metadata) { + Ok(_) => {} + Err(e) => { + error!("Trees at step '{}' were not equal.\n{}", step, e); + + let expected_gv = format!("{}", VisualizeRbxTree { + tree: &expected.tree, + metadata: &expected.metadata, + }); + + let actual_gv = format!("{}", VisualizeRbxTree { + tree: &tree_with_metadata.tree, + metadata: &tree_with_metadata.metadata, + }); + + let output_dir = PathBuf::from("failed-snapshots"); + fs::create_dir_all(&output_dir) + .expect("Could not create failed-snapshots directory"); + + let expected_basename = format!("{}-{}-expected", live_session.root_project().name, step); + let actual_basename = format!("{}-{}-actual", live_session.root_project().name, step); + + let mut expected_out = output_dir.join(expected_basename); + let mut actual_out = output_dir.join(actual_basename); + + match (graphviz_to_svg(&expected_gv), graphviz_to_svg(&actual_gv)) { + (Some(expected_svg), Some(actual_svg)) => { + expected_out.set_extension("svg"); + actual_out.set_extension("svg"); + + fs::write(&expected_out, expected_svg) + .expect("Couldn't write expected SVG"); + + fs::write(&actual_out, actual_svg) + .expect("Couldn't write actual SVG"); + } + _ => { + expected_out.set_extension("gv"); + actual_out.set_extension("gv"); + + fs::write(&expected_out, expected_gv) + .expect("Couldn't write expected GV"); + + fs::write(&actual_out, actual_gv) + .expect("Couldn't write actual GV"); + } + } + + error!("Output at {} and {}", expected_out.display(), actual_out.display()); + + panic!("Tree mismatch at step '{}'", step); + } + } + None => { + write_tree_by_name(source_path, step, &tree_with_metadata); + } + } +} + +fn new_cow_map() -> Cow<'static, HashMap> { + Cow::Owned(HashMap::new()) +} + +#[derive(Debug, Serialize, Deserialize)] +struct TreeWithMetadata<'a> { + #[serde(flatten)] + pub tree: Cow<'a, RbxTree>, + + #[serde(default = "new_cow_map")] + pub metadata: Cow<'a, HashMap>, +} + +fn read_tree_by_name(path: &Path, identifier: &str) -> Option> { let mut file_path = path.join(identifier); file_path.set_extension("tree.json"); let contents = fs::read(&file_path).ok()?; - let tree: RbxTree = serde_json::from_slice(&contents) + let tree: TreeWithMetadata = serde_json::from_slice(&contents) .expect("Could not deserialize tree"); Some(tree) } -pub fn write_tree_by_name(path: &Path, identifier: &str, tree: &RbxTree) { +fn write_tree_by_name(path: &Path, identifier: &str, tree: &TreeWithMetadata) { let mut file_path = path.join(identifier); file_path.set_extension("tree.json"); @@ -43,7 +148,7 @@ pub fn write_tree_by_name(path: &Path, identifier: &str, tree: &RbxTree) { } #[derive(Debug)] -pub struct TreeMismatch { +struct TreeMismatch { pub path: Cow<'static, str>, pub detail: Cow<'static, str>, } @@ -74,27 +179,38 @@ impl fmt::Display for TreeMismatch { } } -pub fn trees_equal(left_tree: &RbxTree, right_tree: &RbxTree) -> Result<(), TreeMismatch> { - let left_id = left_tree.get_root_id(); - let right_id = right_tree.get_root_id(); +fn trees_equal( + left_tree: &TreeWithMetadata, + right_tree: &TreeWithMetadata, +) -> Result<(), TreeMismatch> { + let left_id = left_tree.tree.get_root_id(); + let right_id = right_tree.tree.get_root_id(); - basic_equal(left_tree, left_id, right_tree, right_id)?; - properties_equal(left_tree, left_id, right_tree, right_id)?; - - children_equal(left_tree, left_id, right_tree, right_id) - .map_err(|e| { - let left_instance = left_tree.get_instance(left_id) - .expect("ID did not exist in left tree"); - - e.add_parent(&left_instance.name) - }) + instances_equal(left_tree, left_id, right_tree, right_id) } -fn basic_equal(left_tree: &RbxTree, left_id: RbxId, right_tree: &RbxTree, right_id: RbxId) -> Result<(), TreeMismatch> { - let left_instance = left_tree.get_instance(left_id) +fn instances_equal( + left_tree: &TreeWithMetadata, + left_id: RbxId, + right_tree: &TreeWithMetadata, + right_id: RbxId, +) -> Result<(), TreeMismatch> { + basic_equal(left_tree, left_id, right_tree, right_id)?; + properties_equal(left_tree, left_id, right_tree, right_id)?; + children_equal(left_tree, left_id, right_tree, right_id)?; + metadata_equal(left_tree, left_id, right_tree, right_id) +} + +fn basic_equal( + left_tree: &TreeWithMetadata, + left_id: RbxId, + right_tree: &TreeWithMetadata, + right_id: RbxId, +) -> Result<(), TreeMismatch> { + let left_instance = left_tree.tree.get_instance(left_id) .expect("ID did not exist in left tree"); - let right_instance = right_tree.get_instance(right_id) + let right_instance = right_tree.tree.get_instance(right_id) .expect("ID did not exist in right tree"); if left_instance.name != right_instance.name { @@ -112,11 +228,16 @@ fn basic_equal(left_tree: &RbxTree, left_id: RbxId, right_tree: &RbxTree, right_ Ok(()) } -fn properties_equal(left_tree: &RbxTree, left_id: RbxId, right_tree: &RbxTree, right_id: RbxId) -> Result<(), TreeMismatch> { - let left_instance = left_tree.get_instance(left_id) +fn properties_equal( + left_tree: &TreeWithMetadata, + left_id: RbxId, + right_tree: &TreeWithMetadata, + right_id: RbxId, +) -> Result<(), TreeMismatch> { + let left_instance = left_tree.tree.get_instance(left_id) .expect("ID did not exist in left tree"); - let right_instance = right_tree.get_instance(right_id) + let right_instance = right_tree.tree.get_instance(right_id) .expect("ID did not exist in right tree"); let mut visited = HashSet::new(); @@ -147,7 +268,7 @@ fn properties_equal(left_tree: &RbxTree, left_id: RbxId, right_tree: &RbxTree, r if left_value != Some(right_value) { let message = format!( - "Property {} was {:?} on left and {:?} on right", + "Property {}:\n\tLeft: {:?}\n\tRight: {:?}", key, left_value, Some(right_value), @@ -160,11 +281,16 @@ fn properties_equal(left_tree: &RbxTree, left_id: RbxId, right_tree: &RbxTree, r Ok(()) } -fn children_equal(left_tree: &RbxTree, left_id: RbxId, right_tree: &RbxTree, right_id: RbxId) -> Result<(), TreeMismatch> { - let left_instance = left_tree.get_instance(left_id) +fn children_equal( + left_tree: &TreeWithMetadata, + left_id: RbxId, + right_tree: &TreeWithMetadata, + right_id: RbxId, +) -> Result<(), TreeMismatch> { + let left_instance = left_tree.tree.get_instance(left_id) .expect("ID did not exist in left tree"); - let right_instance = right_tree.get_instance(right_id) + let right_instance = right_tree.tree.get_instance(right_id) .expect("ID did not exist in right tree"); let left_children = left_instance.get_children_ids(); @@ -175,15 +301,34 @@ fn children_equal(left_tree: &RbxTree, left_id: RbxId, right_tree: &RbxTree, rig } for (left_child_id, right_child_id) in left_children.iter().zip(right_children) { - basic_equal(left_tree, *left_child_id, right_tree, *right_child_id) - .map_err(|e| e.add_parent(&left_instance.name))?; - - properties_equal(left_tree, *left_child_id, right_tree, *right_child_id) - .map_err(|e| e.add_parent(&left_instance.name))?; - - children_equal(left_tree, *left_child_id, right_tree, *right_child_id) + instances_equal(left_tree, *left_child_id, right_tree, *right_child_id) .map_err(|e| e.add_parent(&left_instance.name))?; } + Ok(()) +} + +fn metadata_equal( + left_tree: &TreeWithMetadata, + left_id: RbxId, + right_tree: &TreeWithMetadata, + right_id: RbxId, +) -> Result<(), TreeMismatch> { + let left_meta = left_tree.metadata.get(&left_id); + let right_meta = right_tree.metadata.get(&right_id); + + if left_meta != right_meta { + let left_instance = left_tree.tree.get_instance(left_id) + .expect("Left instance didn't exist in tree"); + + let message = format!( + "Metadata mismatch:\n\tLeft: {:?}\n\tRight: {:?}", + left_meta, + right_meta, + ); + + return Err(TreeMismatch::new(&left_instance.name, message)); + } + Ok(()) } \ No newline at end of file diff --git a/server/tests/tree_snapshots.rs b/server/tests/tree_snapshots.rs new file mode 100644 index 00000000..f5b991fa --- /dev/null +++ b/server/tests/tree_snapshots.rs @@ -0,0 +1,68 @@ +mod test_util; + +use std::{ + fs, + path::{Path, PathBuf}, + sync::Arc, + thread, + time::Duration, +}; + +use tempfile::{tempdir, TempDir}; + +use librojo::{ + live_session::LiveSession, + project::Project, +}; + +use crate::test_util::{ + copy_recursive, + tree::tree_step, +}; + +#[test] +fn multi_partition_game() { + let _ = env_logger::try_init(); + let source_path = project_path("multi_partition_game"); + + let (dir, live_session) = start_session(&source_path); + tree_step("initial", &live_session, &source_path); + + let added_path = dir.path().join("a/added"); + fs::create_dir_all(&added_path) + .expect("Couldn't create directory"); + thread::sleep(Duration::from_millis(250)); + + tree_step("with_dir", &live_session, &source_path); + + let moved_path = dir.path().join("b/added"); + fs::rename(&added_path, &moved_path) + .expect("Couldn't rename directory"); + thread::sleep(Duration::from_millis(250)); + + tree_step("with_moved_dir", &live_session, &source_path); +} + +/// Find the path to the given test project relative to the manifest. +fn project_path(name: &str) -> PathBuf { + let mut path = Path::new(env!("CARGO_MANIFEST_DIR")).join("../test-projects"); + path.push(name); + path +} + +/// Starts a new LiveSession for the project located at the given file path. +fn start_session(source_path: &Path) -> (TempDir, LiveSession) { + let dir = tempdir() + .expect("Couldn't create temporary directory"); + + copy_recursive(&source_path, dir.path()) + .expect("Couldn't copy project to temporary directory"); + + let project = Arc::new(Project::load_fuzzy(dir.path()) + .expect("Couldn't load project from temp directory")); + + let live_session = LiveSession::new(Arc::clone(&project)) + .expect("Couldn't start live session"); + + (dir, live_session) +} \ No newline at end of file diff --git a/test-projects/multi_partition_game/initial.tree.json b/test-projects/multi_partition_game/initial.tree.json index d1caf8fc..b6a2208c 100644 --- a/test-projects/multi_partition_game/initial.tree.json +++ b/test-projects/multi_partition_game/initial.tree.json @@ -1,19 +1,6 @@ { "instances": { - "6a7e0c50-e85d-4abc-863b-48db75038c65": { - "Name": "foo", - "ClassName": "StringValue", - "Properties": { - "Value": { - "Type": "String", - "Value": "Hello world, from a/foo.txt" - } - }, - "Id": "6a7e0c50-e85d-4abc-863b-48db75038c65", - "Children": [], - "Parent": "a27d1480-d3d6-424b-86e9-faf9cf387ae8" - }, - "7abdb15d-9899-414a-baf0-7874c56f8b2a": { + "8d44bb30-db3c-4366-a6c5-633bd1441885": { "Name": "main", "ClassName": "ModuleScript", "Properties": { @@ -22,67 +9,43 @@ "Value": "-- hello, from a/main.lua" } }, - "Id": "7abdb15d-9899-414a-baf0-7874c56f8b2a", + "Id": "8d44bb30-db3c-4366-a6c5-633bd1441885", "Children": [], - "Parent": "a27d1480-d3d6-424b-86e9-faf9cf387ae8" + "Parent": "1aafa29b-bdca-40a0-a677-7ead327b84ce" }, - "f147da62-b6dc-4833-985a-36941e47de82": { - "Name": "multi_partition_game", - "ClassName": "DataModel", - "Properties": {}, - "Id": "f147da62-b6dc-4833-985a-36941e47de82", - "Children": [ - "7be3f86d-f8ce-4c6b-88cb-03db03a3fd57", - "fe1dd5ab-3255-47e3-a2b4-8c7181ab715e" - ], - "Parent": null - }, - "fe1dd5ab-3255-47e3-a2b4-8c7181ab715e": { - "Name": "ReplicatedStorage", - "ClassName": "ReplicatedStorage", - "Properties": {}, - "Id": "fe1dd5ab-3255-47e3-a2b4-8c7181ab715e", - "Children": [ - "a27d1480-d3d6-424b-86e9-faf9cf387ae8", - "6ce9c44a-0e66-4aaf-97e7-086407aed226" - ], - "Parent": "f147da62-b6dc-4833-985a-36941e47de82" - }, - "7be3f86d-f8ce-4c6b-88cb-03db03a3fd57": { - "Name": "HttpService", - "ClassName": "HttpService", - "Properties": { - "HttpEnabled": { - "Type": "Bool", - "Value": true - } - }, - "Id": "7be3f86d-f8ce-4c6b-88cb-03db03a3fd57", - "Children": [], - "Parent": "f147da62-b6dc-4833-985a-36941e47de82" - }, - "a27d1480-d3d6-424b-86e9-faf9cf387ae8": { - "Name": "Ack", - "ClassName": "Folder", - "Properties": {}, - "Id": "a27d1480-d3d6-424b-86e9-faf9cf387ae8", - "Children": [ - "6a7e0c50-e85d-4abc-863b-48db75038c65", - "7abdb15d-9899-414a-baf0-7874c56f8b2a" - ], - "Parent": "fe1dd5ab-3255-47e3-a2b4-8c7181ab715e" - }, - "6ce9c44a-0e66-4aaf-97e7-086407aed226": { + "b1c9928c-bf11-427f-90eb-b672c811d859": { "Name": "Bar", "ClassName": "Folder", "Properties": {}, - "Id": "6ce9c44a-0e66-4aaf-97e7-086407aed226", + "Id": "b1c9928c-bf11-427f-90eb-b672c811d859", "Children": [ - "8e0006d3-9f03-4ed4-9cb6-81abe23a4754" + "8d690a2a-e987-4c86-b9ac-18e6d3a98503" ], - "Parent": "fe1dd5ab-3255-47e3-a2b4-8c7181ab715e" + "Parent": "9f141826-14c2-492b-b360-2558712f0c08" }, - "8e0006d3-9f03-4ed4-9cb6-81abe23a4754": { + "645ba594-4482-441f-9f41-5bb9c444405b": { + "Name": "multi_partition_game", + "ClassName": "DataModel", + "Properties": {}, + "Id": "645ba594-4482-441f-9f41-5bb9c444405b", + "Children": [ + "b1298bcc-e370-44a6-9ef4-fbefa290124c", + "9f141826-14c2-492b-b360-2558712f0c08" + ], + "Parent": null + }, + "9f141826-14c2-492b-b360-2558712f0c08": { + "Name": "ReplicatedStorage", + "ClassName": "ReplicatedStorage", + "Properties": {}, + "Id": "9f141826-14c2-492b-b360-2558712f0c08", + "Children": [ + "1aafa29b-bdca-40a0-a677-7ead327b84ce", + "b1c9928c-bf11-427f-90eb-b672c811d859" + ], + "Parent": "645ba594-4482-441f-9f41-5bb9c444405b" + }, + "8d690a2a-e987-4c86-b9ac-18e6d3a98503": { "Name": "something", "ClassName": "ModuleScript", "Properties": { @@ -91,10 +54,189 @@ "Value": "-- b/something.lua" } }, - "Id": "8e0006d3-9f03-4ed4-9cb6-81abe23a4754", + "Id": "8d690a2a-e987-4c86-b9ac-18e6d3a98503", "Children": [], - "Parent": "6ce9c44a-0e66-4aaf-97e7-086407aed226" + "Parent": "b1c9928c-bf11-427f-90eb-b672c811d859" + }, + "b1298bcc-e370-44a6-9ef4-fbefa290124c": { + "Name": "HttpService", + "ClassName": "HttpService", + "Properties": { + "HttpEnabled": { + "Type": "Bool", + "Value": true + } + }, + "Id": "b1298bcc-e370-44a6-9ef4-fbefa290124c", + "Children": [], + "Parent": "645ba594-4482-441f-9f41-5bb9c444405b" + }, + "54f2f276-964f-4c60-87d8-5fb2209c97c9": { + "Name": "foo", + "ClassName": "StringValue", + "Properties": { + "Value": { + "Type": "String", + "Value": "Hello world, from a/foo.txt" + } + }, + "Id": "54f2f276-964f-4c60-87d8-5fb2209c97c9", + "Children": [], + "Parent": "1aafa29b-bdca-40a0-a677-7ead327b84ce" + }, + "1aafa29b-bdca-40a0-a677-7ead327b84ce": { + "Name": "Ack", + "ClassName": "Folder", + "Properties": {}, + "Id": "1aafa29b-bdca-40a0-a677-7ead327b84ce", + "Children": [ + "54f2f276-964f-4c60-87d8-5fb2209c97c9", + "8d44bb30-db3c-4366-a6c5-633bd1441885" + ], + "Parent": "9f141826-14c2-492b-b360-2558712f0c08" } }, - "root_id": "f147da62-b6dc-4833-985a-36941e47de82" + "root_id": "645ba594-4482-441f-9f41-5bb9c444405b", + "metadata": { + "645ba594-4482-441f-9f41-5bb9c444405b": { + "ignore_unknown_instances": true, + "source_path": null, + "project_definition": [ + "multi_partition_game", + { + "class_name": "DataModel", + "children": { + "HttpService": { + "class_name": "HttpService", + "children": {}, + "properties": { + "HttpEnabled": { + "Type": "Bool", + "Value": true + } + }, + "ignore_unknown_instances": null, + "path": null + }, + "ReplicatedStorage": { + "class_name": "ReplicatedStorage", + "children": { + "Ack": { + "class_name": null, + "children": {}, + "properties": {}, + "ignore_unknown_instances": null, + "path": "a" + }, + "Bar": { + "class_name": null, + "children": {}, + "properties": {}, + "ignore_unknown_instances": null, + "path": "b" + } + }, + "properties": {}, + "ignore_unknown_instances": null, + "path": null + } + }, + "properties": {}, + "ignore_unknown_instances": null, + "path": null + } + ] + }, + "1aafa29b-bdca-40a0-a677-7ead327b84ce": { + "ignore_unknown_instances": false, + "source_path": "a", + "project_definition": [ + "Ack", + { + "class_name": null, + "children": {}, + "properties": {}, + "ignore_unknown_instances": null, + "path": "a" + } + ] + }, + "b1c9928c-bf11-427f-90eb-b672c811d859": { + "ignore_unknown_instances": false, + "source_path": "b", + "project_definition": [ + "Bar", + { + "class_name": null, + "children": {}, + "properties": {}, + "ignore_unknown_instances": null, + "path": "b" + } + ] + }, + "54f2f276-964f-4c60-87d8-5fb2209c97c9": { + "ignore_unknown_instances": false, + "source_path": "a/foo.txt", + "project_definition": null + }, + "9f141826-14c2-492b-b360-2558712f0c08": { + "ignore_unknown_instances": true, + "source_path": null, + "project_definition": [ + "ReplicatedStorage", + { + "class_name": "ReplicatedStorage", + "children": { + "Ack": { + "class_name": null, + "children": {}, + "properties": {}, + "ignore_unknown_instances": null, + "path": "a" + }, + "Bar": { + "class_name": null, + "children": {}, + "properties": {}, + "ignore_unknown_instances": null, + "path": "b" + } + }, + "properties": {}, + "ignore_unknown_instances": null, + "path": null + } + ] + }, + "8d44bb30-db3c-4366-a6c5-633bd1441885": { + "ignore_unknown_instances": false, + "source_path": "a/main.lua", + "project_definition": null + }, + "b1298bcc-e370-44a6-9ef4-fbefa290124c": { + "ignore_unknown_instances": true, + "source_path": null, + "project_definition": [ + "HttpService", + { + "class_name": "HttpService", + "children": {}, + "properties": { + "HttpEnabled": { + "Type": "Bool", + "Value": true + } + }, + "ignore_unknown_instances": null, + "path": null + } + ] + }, + "8d690a2a-e987-4c86-b9ac-18e6d3a98503": { + "ignore_unknown_instances": false, + "source_path": "b/something.lua", + "project_definition": null + } + } } \ No newline at end of file diff --git a/test-projects/multi_partition_game/with_dir.tree.json b/test-projects/multi_partition_game/with_dir.tree.json index dcecf790..5237c507 100644 --- a/test-projects/multi_partition_game/with_dir.tree.json +++ b/test-projects/multi_partition_game/with_dir.tree.json @@ -1,19 +1,6 @@ { "instances": { - "6a7e0c50-e85d-4abc-863b-48db75038c65": { - "Name": "foo", - "ClassName": "StringValue", - "Properties": { - "Value": { - "Type": "String", - "Value": "Hello world, from a/foo.txt" - } - }, - "Id": "6a7e0c50-e85d-4abc-863b-48db75038c65", - "Children": [], - "Parent": "a27d1480-d3d6-424b-86e9-faf9cf387ae8" - }, - "7abdb15d-9899-414a-baf0-7874c56f8b2a": { + "8d44bb30-db3c-4366-a6c5-633bd1441885": { "Name": "main", "ClassName": "ModuleScript", "Properties": { @@ -22,76 +9,43 @@ "Value": "-- hello, from a/main.lua" } }, - "Id": "7abdb15d-9899-414a-baf0-7874c56f8b2a", + "Id": "8d44bb30-db3c-4366-a6c5-633bd1441885", "Children": [], - "Parent": "a27d1480-d3d6-424b-86e9-faf9cf387ae8" + "Parent": "1aafa29b-bdca-40a0-a677-7ead327b84ce" }, - "f147da62-b6dc-4833-985a-36941e47de82": { - "Name": "multi_partition_game", - "ClassName": "DataModel", - "Properties": {}, - "Id": "f147da62-b6dc-4833-985a-36941e47de82", - "Children": [ - "7be3f86d-f8ce-4c6b-88cb-03db03a3fd57", - "fe1dd5ab-3255-47e3-a2b4-8c7181ab715e" - ], - "Parent": null - }, - "b3cc71c5-a558-4fce-a795-cd955ba73c38": { - "Name": "added", - "ClassName": "Folder", - "Properties": {}, - "Id": "b3cc71c5-a558-4fce-a795-cd955ba73c38", - "Children": [], - "Parent": "a27d1480-d3d6-424b-86e9-faf9cf387ae8" - }, - "fe1dd5ab-3255-47e3-a2b4-8c7181ab715e": { - "Name": "ReplicatedStorage", - "ClassName": "ReplicatedStorage", - "Properties": {}, - "Id": "fe1dd5ab-3255-47e3-a2b4-8c7181ab715e", - "Children": [ - "a27d1480-d3d6-424b-86e9-faf9cf387ae8", - "6ce9c44a-0e66-4aaf-97e7-086407aed226" - ], - "Parent": "f147da62-b6dc-4833-985a-36941e47de82" - }, - "7be3f86d-f8ce-4c6b-88cb-03db03a3fd57": { - "Name": "HttpService", - "ClassName": "HttpService", - "Properties": { - "HttpEnabled": { - "Type": "Bool", - "Value": true - } - }, - "Id": "7be3f86d-f8ce-4c6b-88cb-03db03a3fd57", - "Children": [], - "Parent": "f147da62-b6dc-4833-985a-36941e47de82" - }, - "a27d1480-d3d6-424b-86e9-faf9cf387ae8": { - "Name": "Ack", - "ClassName": "Folder", - "Properties": {}, - "Id": "a27d1480-d3d6-424b-86e9-faf9cf387ae8", - "Children": [ - "6a7e0c50-e85d-4abc-863b-48db75038c65", - "7abdb15d-9899-414a-baf0-7874c56f8b2a", - "b3cc71c5-a558-4fce-a795-cd955ba73c38" - ], - "Parent": "fe1dd5ab-3255-47e3-a2b4-8c7181ab715e" - }, - "6ce9c44a-0e66-4aaf-97e7-086407aed226": { + "b1c9928c-bf11-427f-90eb-b672c811d859": { "Name": "Bar", "ClassName": "Folder", "Properties": {}, - "Id": "6ce9c44a-0e66-4aaf-97e7-086407aed226", + "Id": "b1c9928c-bf11-427f-90eb-b672c811d859", "Children": [ - "8e0006d3-9f03-4ed4-9cb6-81abe23a4754" + "8d690a2a-e987-4c86-b9ac-18e6d3a98503" ], - "Parent": "fe1dd5ab-3255-47e3-a2b4-8c7181ab715e" + "Parent": "9f141826-14c2-492b-b360-2558712f0c08" }, - "8e0006d3-9f03-4ed4-9cb6-81abe23a4754": { + "645ba594-4482-441f-9f41-5bb9c444405b": { + "Name": "multi_partition_game", + "ClassName": "DataModel", + "Properties": {}, + "Id": "645ba594-4482-441f-9f41-5bb9c444405b", + "Children": [ + "b1298bcc-e370-44a6-9ef4-fbefa290124c", + "9f141826-14c2-492b-b360-2558712f0c08" + ], + "Parent": null + }, + "9f141826-14c2-492b-b360-2558712f0c08": { + "Name": "ReplicatedStorage", + "ClassName": "ReplicatedStorage", + "Properties": {}, + "Id": "9f141826-14c2-492b-b360-2558712f0c08", + "Children": [ + "1aafa29b-bdca-40a0-a677-7ead327b84ce", + "b1c9928c-bf11-427f-90eb-b672c811d859" + ], + "Parent": "645ba594-4482-441f-9f41-5bb9c444405b" + }, + "8d690a2a-e987-4c86-b9ac-18e6d3a98503": { "Name": "something", "ClassName": "ModuleScript", "Properties": { @@ -100,10 +54,203 @@ "Value": "-- b/something.lua" } }, - "Id": "8e0006d3-9f03-4ed4-9cb6-81abe23a4754", + "Id": "8d690a2a-e987-4c86-b9ac-18e6d3a98503", "Children": [], - "Parent": "6ce9c44a-0e66-4aaf-97e7-086407aed226" + "Parent": "b1c9928c-bf11-427f-90eb-b672c811d859" + }, + "b1298bcc-e370-44a6-9ef4-fbefa290124c": { + "Name": "HttpService", + "ClassName": "HttpService", + "Properties": { + "HttpEnabled": { + "Type": "Bool", + "Value": true + } + }, + "Id": "b1298bcc-e370-44a6-9ef4-fbefa290124c", + "Children": [], + "Parent": "645ba594-4482-441f-9f41-5bb9c444405b" + }, + "46353305-8818-48fe-94fd-80cf0c5d974c": { + "Name": "added", + "ClassName": "Folder", + "Properties": {}, + "Id": "46353305-8818-48fe-94fd-80cf0c5d974c", + "Children": [], + "Parent": "1aafa29b-bdca-40a0-a677-7ead327b84ce" + }, + "54f2f276-964f-4c60-87d8-5fb2209c97c9": { + "Name": "foo", + "ClassName": "StringValue", + "Properties": { + "Value": { + "Type": "String", + "Value": "Hello world, from a/foo.txt" + } + }, + "Id": "54f2f276-964f-4c60-87d8-5fb2209c97c9", + "Children": [], + "Parent": "1aafa29b-bdca-40a0-a677-7ead327b84ce" + }, + "1aafa29b-bdca-40a0-a677-7ead327b84ce": { + "Name": "Ack", + "ClassName": "Folder", + "Properties": {}, + "Id": "1aafa29b-bdca-40a0-a677-7ead327b84ce", + "Children": [ + "54f2f276-964f-4c60-87d8-5fb2209c97c9", + "8d44bb30-db3c-4366-a6c5-633bd1441885", + "46353305-8818-48fe-94fd-80cf0c5d974c" + ], + "Parent": "9f141826-14c2-492b-b360-2558712f0c08" } }, - "root_id": "f147da62-b6dc-4833-985a-36941e47de82" + "root_id": "645ba594-4482-441f-9f41-5bb9c444405b", + "metadata": { + "b1c9928c-bf11-427f-90eb-b672c811d859": { + "ignore_unknown_instances": false, + "source_path": "b", + "project_definition": [ + "Bar", + { + "class_name": null, + "children": {}, + "properties": {}, + "ignore_unknown_instances": null, + "path": "b" + } + ] + }, + "54f2f276-964f-4c60-87d8-5fb2209c97c9": { + "ignore_unknown_instances": false, + "source_path": "a/foo.txt", + "project_definition": null + }, + "8d44bb30-db3c-4366-a6c5-633bd1441885": { + "ignore_unknown_instances": false, + "source_path": "a/main.lua", + "project_definition": null + }, + "9f141826-14c2-492b-b360-2558712f0c08": { + "ignore_unknown_instances": true, + "source_path": null, + "project_definition": [ + "ReplicatedStorage", + { + "class_name": "ReplicatedStorage", + "children": { + "Ack": { + "class_name": null, + "children": {}, + "properties": {}, + "ignore_unknown_instances": null, + "path": "a" + }, + "Bar": { + "class_name": null, + "children": {}, + "properties": {}, + "ignore_unknown_instances": null, + "path": "b" + } + }, + "properties": {}, + "ignore_unknown_instances": null, + "path": null + } + ] + }, + "b1298bcc-e370-44a6-9ef4-fbefa290124c": { + "ignore_unknown_instances": true, + "source_path": null, + "project_definition": [ + "HttpService", + { + "class_name": "HttpService", + "children": {}, + "properties": { + "HttpEnabled": { + "Type": "Bool", + "Value": true + } + }, + "ignore_unknown_instances": null, + "path": null + } + ] + }, + "46353305-8818-48fe-94fd-80cf0c5d974c": { + "ignore_unknown_instances": false, + "source_path": "a/added", + "project_definition": null + }, + "1aafa29b-bdca-40a0-a677-7ead327b84ce": { + "ignore_unknown_instances": false, + "source_path": "a", + "project_definition": [ + "Ack", + { + "class_name": null, + "children": {}, + "properties": {}, + "ignore_unknown_instances": null, + "path": "a" + } + ] + }, + "8d690a2a-e987-4c86-b9ac-18e6d3a98503": { + "ignore_unknown_instances": false, + "source_path": "b/something.lua", + "project_definition": null + }, + "645ba594-4482-441f-9f41-5bb9c444405b": { + "ignore_unknown_instances": true, + "source_path": null, + "project_definition": [ + "multi_partition_game", + { + "class_name": "DataModel", + "children": { + "HttpService": { + "class_name": "HttpService", + "children": {}, + "properties": { + "HttpEnabled": { + "Type": "Bool", + "Value": true + } + }, + "ignore_unknown_instances": null, + "path": null + }, + "ReplicatedStorage": { + "class_name": "ReplicatedStorage", + "children": { + "Ack": { + "class_name": null, + "children": {}, + "properties": {}, + "ignore_unknown_instances": null, + "path": "a" + }, + "Bar": { + "class_name": null, + "children": {}, + "properties": {}, + "ignore_unknown_instances": null, + "path": "b" + } + }, + "properties": {}, + "ignore_unknown_instances": null, + "path": null + } + }, + "properties": {}, + "ignore_unknown_instances": null, + "path": null + } + ] + } + } } \ No newline at end of file diff --git a/test-projects/multi_partition_game/with_moved_dir.tree.json b/test-projects/multi_partition_game/with_moved_dir.tree.json index 9dd9a2a8..4da8884a 100644 --- a/test-projects/multi_partition_game/with_moved_dir.tree.json +++ b/test-projects/multi_partition_game/with_moved_dir.tree.json @@ -1,19 +1,6 @@ { "instances": { - "6a7e0c50-e85d-4abc-863b-48db75038c65": { - "Name": "foo", - "ClassName": "StringValue", - "Properties": { - "Value": { - "Type": "String", - "Value": "Hello world, from a/foo.txt" - } - }, - "Id": "6a7e0c50-e85d-4abc-863b-48db75038c65", - "Children": [], - "Parent": "a27d1480-d3d6-424b-86e9-faf9cf387ae8" - }, - "7abdb15d-9899-414a-baf0-7874c56f8b2a": { + "8d44bb30-db3c-4366-a6c5-633bd1441885": { "Name": "main", "ClassName": "ModuleScript", "Properties": { @@ -22,76 +9,44 @@ "Value": "-- hello, from a/main.lua" } }, - "Id": "7abdb15d-9899-414a-baf0-7874c56f8b2a", + "Id": "8d44bb30-db3c-4366-a6c5-633bd1441885", "Children": [], - "Parent": "a27d1480-d3d6-424b-86e9-faf9cf387ae8" + "Parent": "1aafa29b-bdca-40a0-a677-7ead327b84ce" }, - "f147da62-b6dc-4833-985a-36941e47de82": { - "Name": "multi_partition_game", - "ClassName": "DataModel", - "Properties": {}, - "Id": "f147da62-b6dc-4833-985a-36941e47de82", - "Children": [ - "7be3f86d-f8ce-4c6b-88cb-03db03a3fd57", - "fe1dd5ab-3255-47e3-a2b4-8c7181ab715e" - ], - "Parent": null - }, - "fe1dd5ab-3255-47e3-a2b4-8c7181ab715e": { - "Name": "ReplicatedStorage", - "ClassName": "ReplicatedStorage", - "Properties": {}, - "Id": "fe1dd5ab-3255-47e3-a2b4-8c7181ab715e", - "Children": [ - "a27d1480-d3d6-424b-86e9-faf9cf387ae8", - "6ce9c44a-0e66-4aaf-97e7-086407aed226" - ], - "Parent": "f147da62-b6dc-4833-985a-36941e47de82" - }, - "7be3f86d-f8ce-4c6b-88cb-03db03a3fd57": { - "Name": "HttpService", - "ClassName": "HttpService", - "Properties": { - "HttpEnabled": { - "Type": "Bool", - "Value": true - } - }, - "Id": "7be3f86d-f8ce-4c6b-88cb-03db03a3fd57", - "Children": [], - "Parent": "f147da62-b6dc-4833-985a-36941e47de82" - }, - "141f9e9a-8ffb-43df-9532-c438d321b7c7": { - "Name": "added", - "ClassName": "Folder", - "Properties": {}, - "Id": "141f9e9a-8ffb-43df-9532-c438d321b7c7", - "Children": [], - "Parent": "6ce9c44a-0e66-4aaf-97e7-086407aed226" - }, - "a27d1480-d3d6-424b-86e9-faf9cf387ae8": { - "Name": "Ack", - "ClassName": "Folder", - "Properties": {}, - "Id": "a27d1480-d3d6-424b-86e9-faf9cf387ae8", - "Children": [ - "6a7e0c50-e85d-4abc-863b-48db75038c65", - "7abdb15d-9899-414a-baf0-7874c56f8b2a" - ], - "Parent": "fe1dd5ab-3255-47e3-a2b4-8c7181ab715e" - }, - "6ce9c44a-0e66-4aaf-97e7-086407aed226": { + "b1c9928c-bf11-427f-90eb-b672c811d859": { "Name": "Bar", "ClassName": "Folder", "Properties": {}, - "Id": "6ce9c44a-0e66-4aaf-97e7-086407aed226", + "Id": "b1c9928c-bf11-427f-90eb-b672c811d859", "Children": [ - "8e0006d3-9f03-4ed4-9cb6-81abe23a4754", - "141f9e9a-8ffb-43df-9532-c438d321b7c7" + "8d690a2a-e987-4c86-b9ac-18e6d3a98503", + "a8566e76-0495-45a3-a713-1c59ab39453b" ], - "Parent": "fe1dd5ab-3255-47e3-a2b4-8c7181ab715e" + "Parent": "9f141826-14c2-492b-b360-2558712f0c08" }, - "8e0006d3-9f03-4ed4-9cb6-81abe23a4754": { + "645ba594-4482-441f-9f41-5bb9c444405b": { + "Name": "multi_partition_game", + "ClassName": "DataModel", + "Properties": {}, + "Id": "645ba594-4482-441f-9f41-5bb9c444405b", + "Children": [ + "b1298bcc-e370-44a6-9ef4-fbefa290124c", + "9f141826-14c2-492b-b360-2558712f0c08" + ], + "Parent": null + }, + "9f141826-14c2-492b-b360-2558712f0c08": { + "Name": "ReplicatedStorage", + "ClassName": "ReplicatedStorage", + "Properties": {}, + "Id": "9f141826-14c2-492b-b360-2558712f0c08", + "Children": [ + "1aafa29b-bdca-40a0-a677-7ead327b84ce", + "b1c9928c-bf11-427f-90eb-b672c811d859" + ], + "Parent": "645ba594-4482-441f-9f41-5bb9c444405b" + }, + "8d690a2a-e987-4c86-b9ac-18e6d3a98503": { "Name": "something", "ClassName": "ModuleScript", "Properties": { @@ -100,10 +55,202 @@ "Value": "-- b/something.lua" } }, - "Id": "8e0006d3-9f03-4ed4-9cb6-81abe23a4754", + "Id": "8d690a2a-e987-4c86-b9ac-18e6d3a98503", "Children": [], - "Parent": "6ce9c44a-0e66-4aaf-97e7-086407aed226" + "Parent": "b1c9928c-bf11-427f-90eb-b672c811d859" + }, + "b1298bcc-e370-44a6-9ef4-fbefa290124c": { + "Name": "HttpService", + "ClassName": "HttpService", + "Properties": { + "HttpEnabled": { + "Type": "Bool", + "Value": true + } + }, + "Id": "b1298bcc-e370-44a6-9ef4-fbefa290124c", + "Children": [], + "Parent": "645ba594-4482-441f-9f41-5bb9c444405b" + }, + "54f2f276-964f-4c60-87d8-5fb2209c97c9": { + "Name": "foo", + "ClassName": "StringValue", + "Properties": { + "Value": { + "Type": "String", + "Value": "Hello world, from a/foo.txt" + } + }, + "Id": "54f2f276-964f-4c60-87d8-5fb2209c97c9", + "Children": [], + "Parent": "1aafa29b-bdca-40a0-a677-7ead327b84ce" + }, + "a8566e76-0495-45a3-a713-1c59ab39453b": { + "Name": "added", + "ClassName": "Folder", + "Properties": {}, + "Id": "a8566e76-0495-45a3-a713-1c59ab39453b", + "Children": [], + "Parent": "b1c9928c-bf11-427f-90eb-b672c811d859" + }, + "1aafa29b-bdca-40a0-a677-7ead327b84ce": { + "Name": "Ack", + "ClassName": "Folder", + "Properties": {}, + "Id": "1aafa29b-bdca-40a0-a677-7ead327b84ce", + "Children": [ + "54f2f276-964f-4c60-87d8-5fb2209c97c9", + "8d44bb30-db3c-4366-a6c5-633bd1441885" + ], + "Parent": "9f141826-14c2-492b-b360-2558712f0c08" } }, - "root_id": "f147da62-b6dc-4833-985a-36941e47de82" + "root_id": "645ba594-4482-441f-9f41-5bb9c444405b", + "metadata": { + "645ba594-4482-441f-9f41-5bb9c444405b": { + "ignore_unknown_instances": true, + "source_path": null, + "project_definition": [ + "multi_partition_game", + { + "class_name": "DataModel", + "children": { + "HttpService": { + "class_name": "HttpService", + "children": {}, + "properties": { + "HttpEnabled": { + "Type": "Bool", + "Value": true + } + }, + "ignore_unknown_instances": null, + "path": null + }, + "ReplicatedStorage": { + "class_name": "ReplicatedStorage", + "children": { + "Ack": { + "class_name": null, + "children": {}, + "properties": {}, + "ignore_unknown_instances": null, + "path": "a" + }, + "Bar": { + "class_name": null, + "children": {}, + "properties": {}, + "ignore_unknown_instances": null, + "path": "b" + } + }, + "properties": {}, + "ignore_unknown_instances": null, + "path": null + } + }, + "properties": {}, + "ignore_unknown_instances": null, + "path": null + } + ] + }, + "1aafa29b-bdca-40a0-a677-7ead327b84ce": { + "ignore_unknown_instances": false, + "source_path": "a", + "project_definition": [ + "Ack", + { + "class_name": null, + "children": {}, + "properties": {}, + "ignore_unknown_instances": null, + "path": "a" + } + ] + }, + "a8566e76-0495-45a3-a713-1c59ab39453b": { + "ignore_unknown_instances": false, + "source_path": "b/added", + "project_definition": null + }, + "8d690a2a-e987-4c86-b9ac-18e6d3a98503": { + "ignore_unknown_instances": false, + "source_path": "b/something.lua", + "project_definition": null + }, + "8d44bb30-db3c-4366-a6c5-633bd1441885": { + "ignore_unknown_instances": false, + "source_path": "a/main.lua", + "project_definition": null + }, + "9f141826-14c2-492b-b360-2558712f0c08": { + "ignore_unknown_instances": true, + "source_path": null, + "project_definition": [ + "ReplicatedStorage", + { + "class_name": "ReplicatedStorage", + "children": { + "Ack": { + "class_name": null, + "children": {}, + "properties": {}, + "ignore_unknown_instances": null, + "path": "a" + }, + "Bar": { + "class_name": null, + "children": {}, + "properties": {}, + "ignore_unknown_instances": null, + "path": "b" + } + }, + "properties": {}, + "ignore_unknown_instances": null, + "path": null + } + ] + }, + "b1c9928c-bf11-427f-90eb-b672c811d859": { + "ignore_unknown_instances": false, + "source_path": "b", + "project_definition": [ + "Bar", + { + "class_name": null, + "children": {}, + "properties": {}, + "ignore_unknown_instances": null, + "path": "b" + } + ] + }, + "54f2f276-964f-4c60-87d8-5fb2209c97c9": { + "ignore_unknown_instances": false, + "source_path": "a/foo.txt", + "project_definition": null + }, + "b1298bcc-e370-44a6-9ef4-fbefa290124c": { + "ignore_unknown_instances": true, + "source_path": null, + "project_definition": [ + "HttpService", + { + "class_name": "HttpService", + "children": {}, + "properties": { + "HttpEnabled": { + "Type": "Bool", + "Value": true + } + }, + "ignore_unknown_instances": null, + "path": null + } + ] + } + } } \ No newline at end of file