diff --git a/Cargo.lock b/Cargo.lock index 2ed22933..afba911c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1489,10 +1489,12 @@ dependencies = [ "insta 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "paste 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "rbx_dom_weak 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "reqwest 0.9.20 (registry+https://github.com/rust-lang/crates.io-index)", "rojo 0.5.0", "serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_yaml 0.8.9 (registry+https://github.com/rust-lang/crates.io-index)", "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/rojo-test/Cargo.toml b/rojo-test/Cargo.toml index 3c55212c..2a9e5c56 100644 --- a/rojo-test/Cargo.toml +++ b/rojo-test/Cargo.toml @@ -9,9 +9,11 @@ publish = false env_logger = "0.6.2" log = "0.4.8" paste = "0.1.5" +rbx_dom_weak = "1.9.0" reqwest = "0.9.20" serde = "1.0.99" serde_json = "1.0.40" +serde_yaml = "0.8.9" tempfile = "3.1.0" walkdir = "2.2.9" diff --git a/rojo-test/serve-test-snapshots/serve_test__empty-2.snap b/rojo-test/serve-test-snapshots/serve_test__empty-2.snap new file mode 100644 index 00000000..5ef25f8a --- /dev/null +++ b/rojo-test/serve-test-snapshots/serve_test__empty-2.snap @@ -0,0 +1,14 @@ +--- +source: rojo-test/src/serve_test.rs +expression: read_result +--- +sessionId: id-1 +messageCursor: 0 +instances: + id-2: + Name: empty + ClassName: Folder + Properties: {} + Children: [] + Metadata: + ignoreUnknownInstances: true diff --git a/rojo-test/serve-test-snapshots/serve_test__empty.snap b/rojo-test/serve-test-snapshots/serve_test__empty.snap index e65f8192..4ecdb7ea 100644 --- a/rojo-test/serve-test-snapshots/serve_test__empty.snap +++ b/rojo-test/serve-test-snapshots/serve_test__empty.snap @@ -2,8 +2,8 @@ source: rojo-test/src/serve_test.rs expression: info --- -sessionId: "[session id]" +sessionId: id-1 serverVersion: 0.5.0 protocolVersion: 3 expectedPlaceIds: ~ -rootInstanceId: "[root id]" +rootInstanceId: id-2 diff --git a/rojo-test/src/serve_test.rs b/rojo-test/src/serve_test.rs index e8f4cdeb..a5887655 100644 --- a/rojo-test/src/serve_test.rs +++ b/rojo-test/src/serve_test.rs @@ -1,4 +1,5 @@ use std::{ + collections::HashMap, fs, path::{Path, PathBuf}, process::Command, @@ -6,9 +7,10 @@ use std::{ }; use insta::assert_yaml_snapshot; +use rbx_dom_weak::RbxId; use tempfile::{tempdir, TempDir}; -use librojo::web_interface::ServerInfoResponse; +use librojo::web_interface::{ReadResponse, ServerInfoResponse}; use crate::util::{ copy_recursive, get_rojo_path, get_serve_tests_path, get_working_dir_path, KillOnDrop, @@ -16,6 +18,28 @@ use crate::util::{ #[test] fn empty() { + run_serve_test(|session, mut dm| { + let info = session.get_api_rojo().unwrap(); + + let root_id = info.root_instance_id; + + let mut info = serde_yaml::to_value(info).unwrap(); + dm.redact(&mut info); + + assert_yaml_snapshot!(info); + + let read_result = session.get_api_read(root_id).unwrap(); + + dm.intern_iter(read_result.instances.keys().copied()); + + let mut read_result = serde_yaml::to_value(read_result).unwrap(); + dm.redact(&mut read_result); + + assert_yaml_snapshot!(read_result); + }); +} + +fn run_serve_test(callback: impl FnOnce(TestServeSession, DeterMap)) { let _ = env_logger::try_init(); let mut settings = insta::Settings::new(); @@ -23,15 +47,77 @@ fn empty() { let snapshot_path = Path::new(env!("CARGO_MANIFEST_DIR")).join("serve-test-snapshots"); settings.set_snapshot_path(snapshot_path); - settings.bind(|| { - let mut session = TestServeSession::new("empty"); - let info = session.wait_to_come_online(); + let mut dm = DeterMap::new(); - assert_yaml_snapshot!(info, { - ".sessionId" => "[session id]", - ".rootInstanceId" => "[root id]" + let mut session = TestServeSession::new("empty"); + let info = session.wait_to_come_online(); + + dm.intern(info.session_id); + dm.intern(info.root_instance_id); + + settings.bind(move || callback(session, dm)); +} + +struct DeterMap { + ids: HashMap, + last_id: usize, +} + +impl DeterMap { + fn new() -> DeterMap { + DeterMap { + ids: HashMap::new(), + last_id: 0, + } + } + + fn intern(&mut self, id: impl ToString) { + let last_id = &mut self.last_id; + + self.ids.entry(id.to_string()).or_insert_with(|| { + *last_id += 1; + *last_id }); - }); + } + + fn intern_iter(&mut self, ids: impl Iterator) { + for id in ids { + self.intern(id.to_string()); + } + } + + fn redact(&self, yaml_value: &mut serde_yaml::Value) { + use serde_yaml::{Mapping, Value}; + + match yaml_value { + Value::String(value) => { + if let Some(redacted) = self.ids.get(value) { + *yaml_value = Value::String(format!("id-{}", *redacted)); + } + } + Value::Sequence(sequence) => { + for value in sequence { + self.redact(value); + } + } + Value::Mapping(mapping) => { + // We can't mutate the keys of a map in-place, so we take + // ownership of the map and rebuild it. + + let owned_map = std::mem::replace(mapping, Mapping::new()); + let mut new_map = Mapping::with_capacity(owned_map.len()); + + for (mut key, mut value) in owned_map { + self.redact(&mut key); + self.redact(&mut value); + new_map.insert(key, value); + } + + *mapping = new_map; + } + _ => {} + } + } } fn get_port_number() -> usize { @@ -111,8 +197,15 @@ impl TestServeSession { } pub fn get_api_rojo(&self) -> Result { - let info_url = format!("http://localhost:{}/api/rojo", self.port); - let body = reqwest::get(&info_url)?.text()?; + let url = format!("http://localhost:{}/api/rojo", self.port); + let body = reqwest::get(&url)?.text()?; + + Ok(serde_json::from_str(&body).expect("Server returned malformed response")) + } + + pub fn get_api_read(&self, id: RbxId) -> Result { + let url = format!("http://localhost:{}/api/read/{}", self.port, id); + let body = reqwest::get(&url)?.text()?; Ok(serde_json::from_str(&body).expect("Server returned malformed response")) } diff --git a/src/session_id.rs b/src/session_id.rs index 51596ba0..d178a5b4 100644 --- a/src/session_id.rs +++ b/src/session_id.rs @@ -1,3 +1,5 @@ +use std::fmt; + use serde::{Deserialize, Serialize}; use uuid::Uuid; @@ -13,3 +15,9 @@ impl SessionId { SessionId(Uuid::new_v4()) } } + +impl fmt::Display for SessionId { + fn fmt(&self, writer: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(writer, "{}", self.0) + } +}