From 720eb57701bcb94e5e18c222fe4ba0ff5a5a3ed4 Mon Sep 17 00:00:00 2001 From: repo-worker-code Date: Sat, 31 Oct 2026 01:32:28 -0500 Subject: [PATCH 1/3] =?UTF-8?q?id(roc):=20finish=20example=20migration=20?= =?UTF-8?q?=E2=80=94=20tic-tac-toe=20to=20RocJson,=20roc-counter=20to=20Sc?= =?UTF-8?q?reen=20+=20RocText=20(#565)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkgs/id/examples/roc-counter/counter.wasm | Bin 29894 -> 59951 bytes pkgs/id/examples/roc-counter/main.roc | 27 +++++-- pkgs/id/examples/tic-tac-toe/main.roc | 15 +++- pkgs/id/examples/tic-tac-toe/tic-tac-toe.wasm | Bin 33130 -> 69319 bytes pkgs/id/src/sandbox.rs | 72 ++++++++++++++---- pkgs/id/src/world_compile.rs | 10 ++- pkgs/id/src/world_session/tests.rs | 48 +++++++++--- 7 files changed, 136 insertions(+), 36 deletions(-) mode change 100755 => 100644 pkgs/id/examples/roc-counter/counter.wasm mode change 100755 => 100644 pkgs/id/examples/tic-tac-toe/tic-tac-toe.wasm diff --git a/pkgs/id/examples/roc-counter/counter.wasm b/pkgs/id/examples/roc-counter/counter.wasm old mode 100755 new mode 100644 index 2ede55cd67929f7507c0803179806d0496ac84e8..4ca1d8f23835b45abb096f155af2a32c2d715e66 GIT binary patch literal 59951 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 delta 3542 zcmbVPYitzP6~5=r?Cg5S>zQ2};ummdaU+|R!344{>4Uus4p;B! zLR;`U3QcGm2wTWom@64_V zP}Co_v~%v<$9a9{J9qqp_pEm=Q&z0q`Zx(8=qajQV-<@}Bw0~QSon*J2rRgg$RW#>F%l%Ac2tUp z6UR!VIuf-LBpsp}ig=Q$s-n_y96u>ic7(o6$z;SP@f0~#a7|zQ(V*={&r*$J()6oo zlSycD{X~uDCsU10&9i5xJKAT>tfqMU)!))$6HIM39r96m)h`{8=ZQv31-nt&uX}+o z$>cn9+8L9td*LG}d8!r;?@RB`d%zcrE2O91( zqt!o~m_3)M%zoAk)qHzm_C@c8*_avdpD(ZcmBn}O7)VB!^lwQ-mDGMgrBp2}zL45F zar(j9n@)eau5!A^Oqq1u2WRpt<^8KoI!Lr z7o(c)?tCw$gsv~NN|BX9pTRlZQfQL`NA(E5HBY<^hdS$cVK8Z)Yih3_hCW|eN@is} z1Z8ENvh;Au{JQC|98Q(CHqVTZUHV=yCLxL~dn_r1p{ezypmnd5Cz57p#=|UXGD_}F znvTp87P~StAWE-gUXt>-Z?5DTOJA7zF3As)Ce!gKMCrMXxa8M^cTHt+;;y-@^1%rm>^9F>Rs(#*NzBro};S=nB8V)rK>i$Q7WO76Uk*LS*f?q|Ll#Q)r=Cwd`&@_bxjUT=P{#$0kyC)mO4j9wX!h3StH5FfA)HrCrN^ zPb5m~?w?MX>lWw+3lbLmIZF6*VeA+c0*SFUKYU;kTVPccP+$RImMu`l!jx4RlUkww zhwqzKu-LA#ep37MS1l zeqt(I5FgvWU4+GFZHg38UuUT=ZKJ?!g&L}cpiaw&keyb&vbD;>cf8sttgJkWp~k)= z_%@dv(9o{mzi{qv4r4X6Ltp&}XOvKpq85G^+bgp#60%P@Atm9x zzd%J1WEz(Bc~Pk)6;)Q7?BQCqkVrHSB>qOA?KU|amNLWOTgv9_F|-)iS$T$mgu$Of z*0hEK@I#IJZ}Zcox#D#cZ>3TNMf4z`7^$F0KrsXn@l-%`${;fT0HULuGKj=(pu3QcDIdEDMJl5R$UChvh{S2;T$VvZQB8mdlRW`Sx(p&j z8AS7!eRXDeZ&UGh@E}E8DL@B`7#&nHql2U|I_wqD;T{5X=mvBmO!N>P+?KaN=T;i} zmbr6fTk(P|alZ~AtEXDU%?3^D#9fxN^ z-r_8%h&u&Tg=}RuTYd~P@L$6J;zXxnm2L7k=+D>AS@4t*W|Y#nBmg1TJ5+={wgNqf z!_YH51Xv~(g9o^fw(D`xkHRCS46-iVK+2rtHEU4<#D@^`u%W- z5<-9APQ=AjaS>1;`Dx+jF#w+qqW57ge|c=L#aq$+z`;nKcBUh%5`-uYBcp=rRPV>l z8iQ=&CMUS99V7rPbkRo^U%;5NxSu6&Jp^D=yjehUa4@KrgwgFMF55u`d*}zP*cwze zDO!a5SMju>f*wmP#m2EzL5ZbX7#SBUWalu&8^U50?rM(k|BBVszK)?4p__DC92?37 zHN#{;$hLX&;W3HtikCkBN3zYg9x33Z^p8ifmK#RoMg$x&`__FbhHnG-<0s5B>lP#` zFEvUcd!{h|aatv~!1VaEr3ulfEVKIbLzpj}p57bRR(}wcIThD-cLE3n z5&a81Ws z>+W<}iSqAFpgwDr)fZGLS9yiNhe#BHxRp~<#m$f3>Zx@Lf$OSh7s@tVlgc&CZ*N+k zHD7O!>gw8wg?CFur%^o8t_W1P3>{uLMlE_Qkd^B=D<;;Df z4eKft;R_l4nezu9V;EN!I!4jYO(cX6HTZe>`9hET(C{Daw)dg{ diff --git a/pkgs/id/examples/roc-counter/main.roc b/pkgs/id/examples/roc-counter/main.roc index ac9edcd6f..e4120f3f8 100644 --- a/pkgs/id/examples/roc-counter/main.roc +++ b/pkgs/id/examples/roc-counter/main.roc @@ -1,5 +1,8 @@ app [program] { pf: platform "../roc-world/platform.roc" } +import pf.Screen +import pf.RocText + Model := { count : I64 } program = { init, update, view, layout, records, wants, snapshot, restore } @@ -7,17 +10,31 @@ program = { init, update, view, layout, records, wants, snapshot, restore } init : U64 -> Model init = |_seed| { count: 0 } +## Events are matched after a RocText trim, so a journaled or typed +## " inc " counts the same as "inc". update : Model, U64, Str -> Model -update = |model, _pid, ev| if ev == "inc" { count: model.count + 1 } else model +update = |model, _pid, ev| if RocText.trim(ev) == "inc" { count: model.count + 1 } else model +## The counter renders through Screen, like roc-screen: a boxed 20x3 +## screen whose JSON the host draws, instead of a bare text view. view : Model -> Str -view = |model| Str.concat("count=", model.count.to_str()) +view = |model| render(model, 20, 3) -## Structured data the host stores and replicates: a JSON object of records. -## This program renders the same layout at any viewport. +# Reflow: a wide viewport gets a wider box, a short one keeps three rows. layout : Model, U64, U64 -> Str -layout = |model, _width, _height| view(model) +layout = |model, width, height| { + w = if width >= 30 30 else 20 + h = if height >= 4 3 else 3 + render(model, w, h) +} +render : Model, U64, U64 -> Str +render = |model, w, h| { + base = Screen.boxed(Screen.new(w, h), 0, 0, w, h, "counter") + Screen.render_json(Screen.put_text(base, 2, 1, "count=${model.count.to_str()}", { fg: 0, bg: 0, bold: Bool.False })) +} + +## Structured data the host stores and replicates: a JSON object of records. records : Model -> Str records = |model| "{\"count\":${model.count.to_str()}}" diff --git a/pkgs/id/examples/tic-tac-toe/main.roc b/pkgs/id/examples/tic-tac-toe/main.roc index 49aef58d3..e331f55f0 100644 --- a/pkgs/id/examples/tic-tac-toe/main.roc +++ b/pkgs/id/examples/tic-tac-toe/main.roc @@ -1,5 +1,7 @@ app [program] { pf: platform "../roc-world/platform.roc" } +import pf.RocJson + # A two-player tic-tac-toe world. # # State is a 9-character board string, the ply count, and the winner. The @@ -59,7 +61,13 @@ layout : Model, U64, U64 -> Str layout = |model, _width, _height| view(model) records : Model -> Str -records = |model| "{\"board\":\"${model.board}\",\"plays\":${model.plays.to_str()},\"winner\":\"${model.winner}\"}" +records = |model| encode_or_crash( + RocJson.Object([ + { key: "board", value: RocJson.String(model.board) }, + { key: "plays", value: RocJson.Number(model.plays.to_str()) }, + { key: "winner", value: RocJson.String(model.winner) }, + ]), +) ## The board is the whole state: the ply count is the number of marks on it ## and the winner follows from its lines, so nothing else is stored. @@ -79,6 +87,11 @@ restore = |board| { # --- helpers --------------------------------------------------------------- +encode_or_crash = |value| match RocJson.encode(value) { + Ok(text) => text + Err(_) => crash "tic-tac-toe attempted to encode an invalid or oversized JSON value" +} + empty_cell : U8 empty_cell = 45 # '-' diff --git a/pkgs/id/examples/tic-tac-toe/tic-tac-toe.wasm b/pkgs/id/examples/tic-tac-toe/tic-tac-toe.wasm old mode 100755 new mode 100644 index f7c320b5ffd5bd288568829544d79554435d4f0d..90a00d97d90b0985c4a16a111ab66984ac4fc514 GIT binary patch literal 69319 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 E0T7;#;{X5v diff --git a/pkgs/id/src/sandbox.rs b/pkgs/id/src/sandbox.rs index be3857859..6530403a9 100644 --- a/pkgs/id/src/sandbox.rs +++ b/pkgs/id/src/sandbox.rs @@ -951,11 +951,23 @@ mod tests { let wasm = include_bytes!("../examples/roc-counter/counter.wasm"); let runner = Sandbox::compile(wasm, SandboxLimits::default()).unwrap(); let mut world = runner.instantiate(7).unwrap(); - assert_eq!(world.view().unwrap(), b"count=0"); + assert!( + String::from_utf8(world.view().unwrap()) + .unwrap() + .contains("count=0") + ); world.update(1, b"inc").unwrap(); - assert_eq!(world.view().unwrap(), b"count=1"); + assert!( + String::from_utf8(world.view().unwrap()) + .unwrap() + .contains("count=1") + ); world.update(1, b"inc").unwrap(); - assert_eq!(world.view().unwrap(), b"count=2"); + assert!( + String::from_utf8(world.view().unwrap()) + .unwrap() + .contains("count=2") + ); } #[tokio::test] @@ -971,25 +983,37 @@ mod tests { ); let (_, capability) = actor.issue("Ada", WorldScopes::GUEST).await.unwrap(); - assert_eq!( - actor.view(capability.clone()).await.unwrap().as_deref(), - Some("count=0") + assert!( + actor + .view(capability.clone()) + .await + .unwrap() + .as_deref() + .is_some_and(|view| view.contains("count=0")) ); actor .input(capability.clone(), b"inc".to_vec()) .await .unwrap(); - assert_eq!( - actor.view(capability.clone()).await.unwrap().as_deref(), - Some("count=1") + assert!( + actor + .view(capability.clone()) + .await + .unwrap() + .as_deref() + .is_some_and(|view| view.contains("count=1")) ); actor .chat(capability.clone(), "chat does not mutate the game") .await .unwrap(); - assert_eq!( - actor.view(capability).await.unwrap().as_deref(), - Some("count=1") + assert!( + actor + .view(capability) + .await + .unwrap() + .as_deref() + .is_some_and(|view| view.contains("count=1")) ); } @@ -1003,7 +1027,11 @@ mod tests { world.update(1, b"inc").unwrap(); assert_eq!(world.records().unwrap().unwrap(), br#"{"count":2}"#); // A view between records calls must not disturb either output. - assert_eq!(world.view().unwrap(), b"count=2"); + assert!( + String::from_utf8(world.view().unwrap()) + .unwrap() + .contains("count=2") + ); assert_eq!(world.records().unwrap().unwrap(), br#"{"count":2}"#); } @@ -1065,15 +1093,27 @@ mod tests { assert_eq!(live.snapshot().unwrap().unwrap(), b"3"); let mut restored = runner.instantiate(7).unwrap(); restored.restore(b"3").unwrap(); - assert_eq!(restored.view().unwrap(), b"count=3"); + assert!( + String::from_utf8(restored.view().unwrap()) + .unwrap() + .contains("count=3") + ); restored.update(1, b"inc").unwrap(); - assert_eq!(restored.view().unwrap(), b"count=4"); + assert!( + String::from_utf8(restored.view().unwrap()) + .unwrap() + .contains("count=4") + ); // The trait-level snapshot is the verified one the actor journals. assert_eq!(live.snapshot_via_trait(), Some("3".to_owned())); // Garbage restores to a defined state instead of trapping. let mut garbage = runner.instantiate(7).unwrap(); garbage.restore(b"not a number").unwrap(); - assert_eq!(garbage.view().unwrap(), b"count=0"); + assert!( + String::from_utf8(garbage.view().unwrap()) + .unwrap() + .contains("count=0") + ); // Tic-tac-toe: the board alone carries the ply count and the winner. let wasm = include_bytes!("../examples/tic-tac-toe/tic-tac-toe.wasm"); diff --git a/pkgs/id/src/world_compile.rs b/pkgs/id/src/world_compile.rs index 64758d081..ce2ba7989 100644 --- a/pkgs/id/src/world_compile.rs +++ b/pkgs/id/src/world_compile.rs @@ -1087,7 +1087,7 @@ restore = |text| match U64.from_str(text) { native: false, }, &compiler, - &[], + &["Screen".to_owned(), "RocText".to_owned()], COMPILE_TIMEOUT, ) .await @@ -1115,7 +1115,11 @@ restore = |text| match U64.from_str(text) { }, ) .unwrap(); - assert_eq!(world.view().unwrap(), b"count=1"); + assert!( + String::from_utf8(world.view().unwrap()) + .unwrap() + .contains("count=1") + ); } #[tokio::test] @@ -1251,7 +1255,7 @@ restore = |text| match U64.from_str(text) { }, ) .unwrap(); - assert_eq!(view.as_deref(), Some("count=1")); + assert!(view.as_deref().is_some_and(|view| view.contains("count=1"))); } #[test] diff --git a/pkgs/id/src/world_session/tests.rs b/pkgs/id/src/world_session/tests.rs index 5e1128a7f..7a8968ffb 100644 --- a/pkgs/id/src/world_session/tests.rs +++ b/pkgs/id/src/world_session/tests.rs @@ -1553,12 +1553,23 @@ mod tests { blobs.blobs().has(hash).await.unwrap(), "uploaded module is pinned in the blob store" ); - assert_eq!( - world.view(guest.clone()).await.unwrap().as_deref(), - Some("count=0") + assert!( + world + .view(guest.clone()) + .await + .unwrap() + .as_deref() + .is_some_and(|view| view.contains("count=0")) ); world.input(guest.clone(), b"inc".to_vec()).await.unwrap(); - assert_eq!(world.view(guest).await.unwrap().as_deref(), Some("count=1")); + assert!( + world + .view(guest) + .await + .unwrap() + .as_deref() + .is_some_and(|view| view.contains("count=1")) + ); } #[cfg(feature = "sandbox")] @@ -1685,9 +1696,13 @@ mod tests { let service = WorldService::new(world.clone(), Some("admin".to_owned())).with_blob_store(blobs); let (_, guest) = world.issue("guest", WorldScopes::GUEST).await.unwrap(); - assert_eq!( - world.view(guest.clone()).await.unwrap().as_deref(), - Some("count=0") + assert!( + world + .view(guest.clone()) + .await + .unwrap() + .as_deref() + .is_some_and(|view| view.contains("count=0")) ); let bad = b"not wasm".to_vec(); @@ -1699,12 +1714,23 @@ mod tests { .unwrap_err(), InstallError::InvalidModule ); - assert_eq!( - world.view(guest.clone()).await.unwrap().as_deref(), - Some("count=0") + assert!( + world + .view(guest.clone()) + .await + .unwrap() + .as_deref() + .is_some_and(|view| view.contains("count=0")) ); world.input(guest.clone(), b"inc".to_vec()).await.unwrap(); - assert_eq!(world.view(guest).await.unwrap().as_deref(), Some("count=1")); + assert!( + world + .view(guest) + .await + .unwrap() + .as_deref() + .is_some_and(|view| view.contains("count=1")) + ); } #[tokio::test] From e29ddd520ea60ea6bd496e78d154c77aeb64360b Mon Sep 17 00:00:00 2001 From: Drewry Pope Date: Sat, 31 Oct 2026 03:09:25 -0500 Subject: [PATCH 2/3] id(roc): migrate remaining counter-fixture assertions to Screen views + grant Screen/RocText in native compile test (#565, Codex P2 x2 on PR #2970) --- pkgs/id/src/sandbox.rs | 6 +----- pkgs/id/src/world_compile.rs | 2 +- pkgs/id/src/world_net.rs | 4 ++-- pkgs/id/src/world_store.rs | 18 +++++++----------- 4 files changed, 11 insertions(+), 19 deletions(-) diff --git a/pkgs/id/src/sandbox.rs b/pkgs/id/src/sandbox.rs index 6530403a9..c310e08ea 100644 --- a/pkgs/id/src/sandbox.rs +++ b/pkgs/id/src/sandbox.rs @@ -1505,11 +1505,7 @@ mod tests { ) .unwrap(); let _ = crate::world::WorldProgram::records(&mut program).unwrap(); - assert_eq!( - view(&mut program), - "count=1", - "wasm handles the actor order" - ); + assert!(view(&mut program).contains("count=1"), "wasm handles the actor order"); } #[test] diff --git a/pkgs/id/src/world_compile.rs b/pkgs/id/src/world_compile.rs index ce2ba7989..0860c0642 100644 --- a/pkgs/id/src/world_compile.rs +++ b/pkgs/id/src/world_compile.rs @@ -1216,7 +1216,7 @@ restore = |text| match U64.from_str(text) { native: true, }, &compiler, - &[], + &["Screen".to_owned(), "RocText".to_owned()], COMPILE_TIMEOUT, ) .await diff --git a/pkgs/id/src/world_net.rs b/pkgs/id/src/world_net.rs index 2015a4dfc..e75e36de0 100644 --- a/pkgs/id/src/world_net.rs +++ b/pkgs/id/src/world_net.rs @@ -1484,7 +1484,7 @@ mod tests { assert_eq!(next(&mut client).await.unwrap()["type"], "snapshot"); let initial = next(&mut client).await.unwrap(); assert_eq!(initial["type"], "view"); - assert_eq!(initial["data"], "count=0"); + assert!(initial["data"].as_str().is_some_and(|data| data.contains("count=0"))); client .send_json(&serde_json::json!({ "type": "input", "data_hex": "696e63" })) @@ -1493,7 +1493,7 @@ mod tests { let event = next(&mut client).await.unwrap(); assert_eq!(event["type"], "event"); let view = next(&mut client).await.unwrap(); - assert_eq!(view["data"], "count=1"); + assert!(view["data"].as_str().is_some_and(|data| data.contains("count=1"))); client_ep.close().await; router.shutdown().await.unwrap(); diff --git a/pkgs/id/src/world_store.rs b/pkgs/id/src/world_store.rs index 4918ab7dc..58e863b67 100644 --- a/pkgs/id/src/world_store.rs +++ b/pkgs/id/src/world_store.rs @@ -1174,7 +1174,7 @@ mod tests { .unwrap(); } svc.world().chat(ann.clone(), "hi").await.unwrap(); - assert_eq!(view(&svc, &ann).await, "count=3"); + assert!(view(&svc, &ann).await.contains("count=3")); svc.world().shutdown().await.unwrap(); let fresh_blobs: iroh_blobs::api::Store = iroh_blobs::store::mem::MemStore::new().into(); @@ -1190,7 +1190,7 @@ mod tests { assert_eq!(report.program_error, None); assert_eq!(report.replayed_inputs, 3); assert_eq!(report.module_hash.as_deref(), Some(hash.as_str())); - assert_eq!(view(&svc, &ann).await, "count=3", "state rebuilt by replay"); + assert!(view(&svc, &ann).await.contains("count=3"), "state rebuilt by replay"); assert_eq!( svc.active_module_hash().await.as_deref(), Some(hash.as_str()), @@ -1200,7 +1200,7 @@ mod tests { .input(ann.clone(), b"inc".to_vec()) .await .unwrap(); - assert_eq!(view(&svc, &ann).await, "count=4"); + assert!(view(&svc, &ann).await.contains("count=4")); } #[cfg(feature = "sandbox")] @@ -1242,7 +1242,7 @@ mod tests { .input(ann.clone(), b"inc".to_vec()) .await .unwrap(); - assert_eq!(view(&svc, &ann).await, "count=1"); + assert!(view(&svc, &ann).await.contains("count=1")); svc.world().shutdown().await.unwrap(); } @@ -1290,7 +1290,7 @@ mod tests { } svc.world().chat(ann.clone(), "hi").await.unwrap(); assert!(svc.world().revoke(bob_participant.id).await.unwrap()); - assert_eq!(view(&svc, &ann).await, "count=13"); + assert!(view(&svc, &ann).await.contains("count=13")); let sequence = svc .world() .snapshot(ann.clone()) @@ -1336,11 +1336,7 @@ mod tests { report.replayed_inputs < 5, "replay starts at the checkpoint" ); - assert_eq!( - view(&svc, &ann).await, - "count=13", - "state from checkpoint + tail" - ); + assert!(view(&svc, &ann).await.contains("count=13"), "state from checkpoint + tail"); assert_eq!( svc.active_module_hash().await.as_deref(), Some(hash.as_str()) @@ -1353,7 +1349,7 @@ mod tests { .input(ann.clone(), b"inc".to_vec()) .await .unwrap(); - assert_eq!(view(&svc, &ann).await, "count=14"); + assert!(view(&svc, &ann).await.contains("count=14")); let page = svc .world() .events_after(ann.clone(), sequence) From bfd580419b3f0223af69174a13ff8680009d21fc Mon Sep 17 00:00:00 2001 From: Drewry Pope Date: Sat, 31 Oct 2026 03:13:21 -0500 Subject: [PATCH 3/3] style(id): rustfmt the counter-fixture assertion updates (#565) --- pkgs/id/src/sandbox.rs | 5 ++++- pkgs/id/src/world_net.rs | 12 ++++++++++-- pkgs/id/src/world_store.rs | 10 ++++++++-- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/pkgs/id/src/sandbox.rs b/pkgs/id/src/sandbox.rs index c310e08ea..aac6fee22 100644 --- a/pkgs/id/src/sandbox.rs +++ b/pkgs/id/src/sandbox.rs @@ -1505,7 +1505,10 @@ mod tests { ) .unwrap(); let _ = crate::world::WorldProgram::records(&mut program).unwrap(); - assert!(view(&mut program).contains("count=1"), "wasm handles the actor order"); + assert!( + view(&mut program).contains("count=1"), + "wasm handles the actor order" + ); } #[test] diff --git a/pkgs/id/src/world_net.rs b/pkgs/id/src/world_net.rs index e75e36de0..4e55ede29 100644 --- a/pkgs/id/src/world_net.rs +++ b/pkgs/id/src/world_net.rs @@ -1484,7 +1484,11 @@ mod tests { assert_eq!(next(&mut client).await.unwrap()["type"], "snapshot"); let initial = next(&mut client).await.unwrap(); assert_eq!(initial["type"], "view"); - assert!(initial["data"].as_str().is_some_and(|data| data.contains("count=0"))); + assert!( + initial["data"] + .as_str() + .is_some_and(|data| data.contains("count=0")) + ); client .send_json(&serde_json::json!({ "type": "input", "data_hex": "696e63" })) @@ -1493,7 +1497,11 @@ mod tests { let event = next(&mut client).await.unwrap(); assert_eq!(event["type"], "event"); let view = next(&mut client).await.unwrap(); - assert!(view["data"].as_str().is_some_and(|data| data.contains("count=1"))); + assert!( + view["data"] + .as_str() + .is_some_and(|data| data.contains("count=1")) + ); client_ep.close().await; router.shutdown().await.unwrap(); diff --git a/pkgs/id/src/world_store.rs b/pkgs/id/src/world_store.rs index 58e863b67..53c66ef6f 100644 --- a/pkgs/id/src/world_store.rs +++ b/pkgs/id/src/world_store.rs @@ -1190,7 +1190,10 @@ mod tests { assert_eq!(report.program_error, None); assert_eq!(report.replayed_inputs, 3); assert_eq!(report.module_hash.as_deref(), Some(hash.as_str())); - assert!(view(&svc, &ann).await.contains("count=3"), "state rebuilt by replay"); + assert!( + view(&svc, &ann).await.contains("count=3"), + "state rebuilt by replay" + ); assert_eq!( svc.active_module_hash().await.as_deref(), Some(hash.as_str()), @@ -1336,7 +1339,10 @@ mod tests { report.replayed_inputs < 5, "replay starts at the checkpoint" ); - assert!(view(&svc, &ann).await.contains("count=13"), "state from checkpoint + tail"); + assert!( + view(&svc, &ann).await.contains("count=13"), + "state from checkpoint + tail" + ); assert_eq!( svc.active_module_hash().await.as_deref(), Some(hash.as_str())