diff --git a/rojo-test/serve-test-snapshots/end_to_end__tests__serve__empty_json_model_all-2.snap b/rojo-test/serve-test-snapshots/end_to_end__tests__serve__empty_json_model_all-2.snap new file mode 100644 index 00000000..6f02d667 --- /dev/null +++ b/rojo-test/serve-test-snapshots/end_to_end__tests__serve__empty_json_model_all-2.snap @@ -0,0 +1,28 @@ +--- +source: tests/tests/serve.rs +expression: "read_response.intern_and_redact(&mut redactions, root_id)" + +--- +instances: + id-2: + Children: + - id-3 + ClassName: Folder + Id: id-2 + Metadata: + ignoreUnknownInstances: false + Name: empty_folder + Parent: "00000000000000000000000000000000" + Properties: {} + id-3: + Children: [] + ClassName: Model + Id: id-3 + Metadata: + ignoreUnknownInstances: false + Name: test + Parent: id-2 + Properties: {} +messageCursor: 1 +sessionId: id-1 + diff --git a/rojo-test/serve-test-snapshots/end_to_end__tests__serve__empty_json_model_all.snap b/rojo-test/serve-test-snapshots/end_to_end__tests__serve__empty_json_model_all.snap new file mode 100644 index 00000000..f7440a4a --- /dev/null +++ b/rojo-test/serve-test-snapshots/end_to_end__tests__serve__empty_json_model_all.snap @@ -0,0 +1,18 @@ +--- +source: tests/tests/serve.rs +expression: "read_response.intern_and_redact(&mut redactions, root_id)" + +--- +instances: + id-2: + Children: [] + ClassName: Folder + Id: id-2 + Metadata: + ignoreUnknownInstances: false + Name: empty_folder + Parent: "00000000000000000000000000000000" + Properties: {} +messageCursor: 0 +sessionId: id-1 + diff --git a/rojo-test/serve-test-snapshots/end_to_end__tests__serve__empty_json_model_info.snap b/rojo-test/serve-test-snapshots/end_to_end__tests__serve__empty_json_model_info.snap new file mode 100644 index 00000000..70168b53 --- /dev/null +++ b/rojo-test/serve-test-snapshots/end_to_end__tests__serve__empty_json_model_info.snap @@ -0,0 +1,14 @@ +--- +source: tests/tests/serve.rs +expression: redactions.redacted_yaml(info) + +--- +expectedPlaceIds: ~ +gameId: ~ +placeId: ~ +projectName: empty_folder +protocolVersion: 4 +rootInstanceId: id-2 +serverVersion: "[server-version]" +sessionId: id-1 + diff --git a/rojo-test/serve-test-snapshots/end_to_end__tests__serve__empty_json_model_subscribe.snap b/rojo-test/serve-test-snapshots/end_to_end__tests__serve__empty_json_model_subscribe.snap new file mode 100644 index 00000000..bb747b86 --- /dev/null +++ b/rojo-test/serve-test-snapshots/end_to_end__tests__serve__empty_json_model_subscribe.snap @@ -0,0 +1,21 @@ +--- +source: tests/tests/serve.rs +expression: "subscribe_response.intern_and_redact(&mut redactions, ())" + +--- +messageCursor: 1 +messages: + - added: + id-3: + Children: [] + ClassName: Model + Id: id-3 + Metadata: + ignoreUnknownInstances: false + Name: test + Parent: id-2 + Properties: {} + removed: [] + updated: [] +sessionId: id-1 + diff --git a/rojo-test/serve-tests/empty_json_model/default.project.json b/rojo-test/serve-tests/empty_json_model/default.project.json new file mode 100644 index 00000000..5d67b95b --- /dev/null +++ b/rojo-test/serve-tests/empty_json_model/default.project.json @@ -0,0 +1,6 @@ +{ + "name": "empty_folder", + "tree": { + "$path": "src" + } +} \ No newline at end of file diff --git a/rojo-test/serve-tests/empty_json_model/src/test.model.json b/rojo-test/serve-tests/empty_json_model/src/test.model.json new file mode 100644 index 00000000..e69de29b diff --git a/src/snapshot_middleware/json_model.rs b/src/snapshot_middleware/json_model.rs index b14b66b4..653cc86d 100644 --- a/src/snapshot_middleware/json_model.rs +++ b/src/snapshot_middleware/json_model.rs @@ -1,4 +1,4 @@ -use std::{borrow::Cow, collections::HashMap, path::Path}; +use std::{borrow::Cow, collections::HashMap, path::Path, str}; use anyhow::Context; use memofs::Vfs; @@ -18,7 +18,14 @@ pub fn snapshot_json_model( instance_name: &str, ) -> SnapshotInstanceResult { let contents = vfs.read(path)?; - let instance: JsonModel = serde_json::from_slice(&contents) + let contents_str = str::from_utf8(&contents) + .with_context(|| format!("File was not valid UTF-8: {}", path.display()))?; + + if contents_str.trim().is_empty() { + return Ok(None); + } + + let instance: JsonModel = serde_json::from_str(contents_str) .with_context(|| format!("File is not a valid JSON model: {}", path.display()))?; let mut snapshot = instance diff --git a/tests/tests/serve.rs b/tests/tests/serve.rs index 61912275..4eb1ebe5 100644 --- a/tests/tests/serve.rs +++ b/tests/tests/serve.rs @@ -186,3 +186,37 @@ fn move_folder_of_stuff() { ); }); } + +#[test] +fn empty_json_model() { + run_serve_test("empty_json_model", |session, mut redactions| { + let info = session.get_api_rojo().unwrap(); + let root_id = info.root_instance_id; + + assert_yaml_snapshot!("empty_json_model_info", redactions.redacted_yaml(info)); + + let read_response = session.get_api_read(root_id).unwrap(); + assert_yaml_snapshot!( + "empty_json_model_all", + read_response.intern_and_redact(&mut redactions, root_id) + ); + + fs::write( + session.path().join("src/test.model.json"), + r#"{"ClassName": "Model"}"#, + ) + .unwrap(); + + let subscribe_response = session.get_api_subscribe(0).unwrap(); + assert_yaml_snapshot!( + "empty_json_model_subscribe", + subscribe_response.intern_and_redact(&mut redactions, ()) + ); + + let read_response = session.get_api_read(root_id).unwrap(); + assert_yaml_snapshot!( + "empty_json_model_all-2", + read_response.intern_and_redact(&mut redactions, root_id) + ); + }); +}