use docs_native_host::Host; use serde_json::json; #[test] fn interpreter_executes_native_crdt_without_host_imports() { let mut host = Host::new().unwrap(); host.call(br#"{"op":"open","guid":"fixture","client":123}"#).unwrap(); host.call(br#"{"op":"insert_element","at":0,"type":"paragraph"}"#).unwrap(); let p: serde_json::Value = serde_json::from_slice(host.call(br#"{"op":"project"}"#).unwrap()).unwrap(); assert_eq!(p["children"][0]["type"], "paragraph"); let node = p["children"][0]["id"].as_str().unwrap(); host.call(&serde_json::to_vec(&json!({"op":"insert_text","node":node,"at":0,"text":"Sandbox 😀"})).unwrap()).unwrap(); let p: serde_json::Value = serde_json::from_slice(host.call(br#"{"op":"project"}"#).unwrap()).unwrap(); assert_eq!(p["children"][0]["children"][0]["runs"][0]["insert"], "Sandbox 😀"); } #[test] fn failed_replica_cannot_be_reused() { let mut host = Host::new().unwrap(); host.call(br#"{"op":"open","guid":"fixture","client":456}"#).unwrap(); assert!(host.call(br#"{"op":"apply","bytes":[255,255,255]}"#).is_err()); assert!(host.call(br#"{"op":"project"}"#).is_err()); let mut clean = Host::new().unwrap(); assert!(clean.call(br#"{"op":"open","guid":"fixture","client":789}"#).is_ok()); } #[test] fn selection_anchor_call_does_not_poison_source_interpreter() { let mut host = Host::new().unwrap(); host.call(br#"{"op":"open","guid":"anchor","client":4000000000}"#).unwrap(); host.call(br#"{"op":"insert_element","at":0,"type":"paragraph"}"#).unwrap(); host.call(br#"{"op":"display_edit","at":0,"length":0,"text":"N"}"#).unwrap(); let anchored = host.call(br#"{"op":"anchor","at":1}"#); assert!(anchored.is_ok(), "anchor must succeed: {:?}", anchored.err()); assert!(host.call(br#"{"op":"snapshot"}"#).is_ok()); assert!(host.call(br#"{"op":"display_edit","at":1,"length":0,"text":"a"}"#).is_ok()); host.call("{\"op\":\"display_edit\",\"at\":2,\"length\":0,\"text\":\"😀\"}".as_bytes()).unwrap(); let anchor: serde_json::Value = serde_json::from_slice(host.call(br#"{"op":"anchor","at":4}"#).unwrap()).unwrap(); let resolved = host.call(&serde_json::to_vec(&json!({"op":"resolve","anchor":anchor})).unwrap()).unwrap(); assert_eq!(resolved,b"4"); assert!(host.call(br#"{"op":"anchor","at":999}"#).is_ok()); assert!(host.call(br#"{"op":"snapshot"}"#).is_ok()); } #[test] fn generated_source_delta_applies_to_authority_with_protocol_client_ids() { let mut authority = Host::new().unwrap(); authority.call(br#"{"op":"open","guid":"generation","client":3088656600}"#).unwrap(); authority.call(br#"{"op":"insert_element","at":0,"type":"paragraph"}"#).unwrap(); let snapshot = authority.call(br#"{"op":"snapshot"}"#).unwrap().to_vec(); let mut source = Host::new().unwrap(); source.call(br#"{"op":"open","guid":"generation","client":4088656600}"#).unwrap(); let mut imported = vec![255]; imported.extend(snapshot); source.call(&imported).unwrap(); let update = source.call(br#"{"op":"display_edit","at":0,"length":0,"text":"N"}"#).unwrap().to_vec(); let mut applied = vec![254]; applied.extend(update); authority.call(&applied).unwrap(); let p: serde_json::Value = serde_json::from_slice(authority.call(br#"{"op":"project"}"#).unwrap()).unwrap(); assert_eq!(p["children"][0]["children"][0]["runs"][0]["insert"], "N"); } #[test] fn native_boundary_rejects_client_ids_that_v1_decoder_would_truncate() { let mut host = Host::new().unwrap(); assert!(host.call(br#"{"op":"open","guid":"generation","client":6088656600138213}"#).is_err()); }