diff --git a/server/src/message_session.rs b/server/src/message_session.rs index c2b311d5..85b2aa32 100644 --- a/server/src/message_session.rs +++ b/server/src/message_session.rs @@ -3,7 +3,7 @@ use std::sync::{mpsc, Arc, RwLock, Mutex}; use id::{Id, get_id}; -#[derive(Debug, Clone, Serialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] #[serde(tag = "type")] pub enum Message { InstanceChanged { diff --git a/server/src/rbx_session.rs b/server/src/rbx_session.rs index 4bfa1254..7db35bff 100644 --- a/server/src/rbx_session.rs +++ b/server/src/rbx_session.rs @@ -20,9 +20,6 @@ fn file_to_instances( ) -> (Id, Vec) { match file_item { FileItem::File { contents, route } => { - let mut properties = HashMap::new(); - properties.insert("Value".to_string(), contents.clone()); - let primary_id = match instances_by_route.get(&file_item.get_route()) { Some(&id) => id, None => { @@ -33,9 +30,33 @@ fn file_to_instances( }, }; + // This is placeholder logic; this whole function is! + let (class_name, property_key, name) = { + // TODO: Root instances have an empty route + let file_name = route.route.last().unwrap(); + + fn strip_suffix<'a>(source: &'a str, suffix: &'static str) -> &'a str { + &source[..source.len() - suffix.len()] + } + + if file_name.ends_with(".client.lua") { + ("LocalScript", "Source", strip_suffix(&file_name, ".client.lua")) + } else if file_name.ends_with(".server.lua") { + ("Script", "Source", strip_suffix(&file_name, ".server.lua")) + } else if file_name.ends_with(".lua") { + ("ModuleScript", "Source", strip_suffix(&file_name, ".lua")) + } else { + // TODO: Error/warn/skip instead of falling back + ("StringValue", "Value", file_name.as_str()) + } + }; + + let mut properties = HashMap::new(); + properties.insert(property_key.to_string(), contents.clone()); + tree.insert_instance(primary_id, RbxInstance { - name: route.name(partition).to_string(), - class_name: "StringValue".to_string(), + name: name.to_string(), + class_name: class_name.to_string(), properties, children: Vec::new(), parent: parent_id, @@ -92,7 +113,7 @@ pub struct RbxSession { /// The RbxInstance that represents each partition. // TODO: Can this be removed in favor of instances_by_route? - partition_instances: HashMap, + pub partition_instances: HashMap, /// Keeps track of all of the instances in the tree pub tree: RbxTree, diff --git a/server/src/web.rs b/server/src/web.rs index d2c1de0e..7c81641a 100644 --- a/server/src/web.rs +++ b/server/src/web.rs @@ -47,6 +47,7 @@ pub struct ReadAllResponse<'a> { pub server_id: &'a str, pub message_cursor: i32, pub instances: Cow<'a, HashMap>, + pub partition_instances: Cow<'a, HashMap>, } #[derive(Debug, Serialize, Deserialize)] @@ -57,7 +58,7 @@ pub struct ReadResponse<'a> { pub instances: HashMap>, } -#[derive(Debug, Serialize)] +#[derive(Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct SubscribeResponse<'a> { pub server_id: &'a str, @@ -164,6 +165,7 @@ impl Server { server_id: &self.server_id, message_cursor, instances: Cow::Borrowed(rbx_session.tree.get_all_instances()), + partition_instances: Cow::Borrowed(&rbx_session.partition_instances), }) }, diff --git a/server/test-projects/one-partition/lib/a.lua b/server/test-projects/one-partition/lib/a.lua new file mode 100644 index 00000000..f23fd06a --- /dev/null +++ b/server/test-projects/one-partition/lib/a.lua @@ -0,0 +1 @@ +-- a.lua \ No newline at end of file diff --git a/server/test-projects/one-partition/lib/a.server.lua b/server/test-projects/one-partition/lib/a.server.lua new file mode 100644 index 00000000..08491e94 --- /dev/null +++ b/server/test-projects/one-partition/lib/a.server.lua @@ -0,0 +1 @@ +-- a.server.lua \ No newline at end of file diff --git a/server/test-projects/one-partition/lib/b.client.lua b/server/test-projects/one-partition/lib/b.client.lua new file mode 100644 index 00000000..12d034fa --- /dev/null +++ b/server/test-projects/one-partition/lib/b.client.lua @@ -0,0 +1 @@ +-- b.client.lua \ No newline at end of file diff --git a/server/test-projects/one-partition/rojo.json b/server/test-projects/one-partition/rojo.json new file mode 100644 index 00000000..d774a8f8 --- /dev/null +++ b/server/test-projects/one-partition/rojo.json @@ -0,0 +1,10 @@ +{ + "name": "one-partition", + "servePort": 23456, + "partitions": { + "lib": { + "path": "lib", + "target": "ReplicatedStorage.OnePartition" + } + } +} \ No newline at end of file diff --git a/server/tests/web.rs b/server/tests/web.rs index c3585307..6615794b 100644 --- a/server/tests/web.rs +++ b/server/tests/web.rs @@ -57,4 +57,114 @@ fn empty() { assert_eq!(response.message_cursor, -1); assert_eq!(response.instances, HashMap::new()); } +} + +#[test] +fn one_partition() { + let project_path = { + let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + path.push("test-projects/one-partition"); + path + }; + + let project = Project::load(&project_path).unwrap(); + let mut session = Session::new(project.clone()); + session.start(); + + let web_config = WebConfig::from_session(0, project.serve_port, &session); + let server = Server::new(web_config); + + { + let body = server.get_string("/api/rojo"); + let response = serde_json::from_str::(&body).unwrap(); + + let mut partitions = HashMap::new(); + partitions.insert("lib".to_string(), vec!["ReplicatedStorage".to_string(), "OnePartition".to_string()]); + + assert_eq!(response.server_id, "0"); + assert_eq!(response.protocol_version, 2); + assert_eq!(response.partitions, partitions); + } + + { + let body = server.get_string("/api/read_all"); + let response = serde_json::from_str::(&body).unwrap(); + + let partition_id = *response.partition_instances.get("lib").unwrap(); + + assert_eq!(response.server_id, "0"); + assert_eq!(response.message_cursor, -1); + assert_eq!(response.instances.len(), 4); // root and three children + + let mut found_root = false; + let mut found_module = false; + let mut found_client = false; + let mut found_server = false; + + for (id, instance) in response.instances.iter() { + match instance.class_name.as_str() { + // TOOD: Should partition roots (and other directories) be some + // magical object instead of Folder? + "Folder" => { + assert!(!found_root); + found_root = true; + + assert_eq!(*id, partition_id); + + // TODO: Should this actually equal the last part of the + // partition's target? + assert_eq!(instance.name, "OnePartition"); + + assert_eq!(instance.properties.len(), 0); + assert_eq!(instance.parent, None); + assert_eq!(instance.children.len(), 3); + }, + "ModuleScript" => { + assert!(!found_module); + found_module = true; + + let mut properties = HashMap::new(); + properties.insert("Source".to_string(), "-- a.lua".to_string()); + + assert_eq!(instance.name, "a"); + assert_eq!(instance.properties, properties); + assert_eq!(instance.parent, Some(partition_id)); + assert_eq!(instance.children.len(), 0); + }, + "LocalScript" => { + assert!(!found_client); + found_client = true; + + let mut properties = HashMap::new(); + properties.insert("Source".to_string(), "-- b.client.lua".to_string()); + + assert_eq!(instance.name, "b"); + assert_eq!(instance.properties, properties); + assert_eq!(instance.parent, Some(partition_id)); + assert_eq!(instance.children.len(), 0); + }, + "Script" => { + assert!(!found_server); + found_server = true; + + let mut properties = HashMap::new(); + properties.insert("Source".to_string(), "-- a.server.lua".to_string()); + + assert_eq!(instance.name, "a"); + assert_eq!(instance.properties, properties); + assert_eq!(instance.parent, Some(partition_id)); + assert_eq!(instance.children.len(), 0); + }, + _ => panic!("Unexpected instance!"), + } + } + + assert!(found_root); + assert!(found_module); + assert!(found_client); + assert!(found_server); + } + + // TODO: Test /read + // TODO: Test /subscribe } \ No newline at end of file