From e4f801db5d150fb1bf5540d9ba00f491a6129a5c Mon Sep 17 00:00:00 2001 From: tv Date: Sat, 31 Oct 2026 19:03:15 +0100 Subject: tests write through document::testing helpers --- src/remake/catchup.rs | 12 ++-- src/remake/delta.rs | 117 +++++++++++++++++----------------- src/remake/kind.rs | 34 +++++----- src/remake/records.rs | 91 ++++++++++++++------------- src/remake/snapshot.rs | 166 +++++++++++++++++++++++++------------------------ 5 files changed, 210 insertions(+), 210 deletions(-) (limited to 'src/remake') diff --git a/src/remake/catchup.rs b/src/remake/catchup.rs index 0be7dfd..e265d0b 100644 --- a/src/remake/catchup.rs +++ b/src/remake/catchup.rs @@ -555,6 +555,7 @@ async fn abandon(host: &H, rejoin: Rejoin, reason: String) { #[cfg(test)] mod tests { use super::*; + use crate::document::testing::change; use crate::remake::snapshot::{SnapshotParams, build}; use automerge::{ActorId, ROOT, transaction::Transactable}; use serde_json::{Value as JsonValue, json}; @@ -563,8 +564,7 @@ mod tests { /// document of the next epoch (snapshot plus one foreign change). fn scenario(policy: &JsonValue) -> (AutoCommit, AutoCommit, Epoch) { let mut old = AutoCommit::new().with_actor(ActorId::from(&b"late-node"[..])); - old.put(ROOT, "base", 1_i64).unwrap(); - old.commit(); + change(&mut old, |old| old.put(ROOT, "base", 1_i64).unwrap()); let base = old.get_heads(); let snapshot = build( @@ -584,11 +584,11 @@ mod tests { let target = snapshot.epoch; let mut swarm = snapshot.doc.with_actor(ActorId::from(&b"swarm-node"[..])); - swarm.put(ROOT, "theirs", 1_i64).unwrap(); - swarm.commit(); + change(&mut swarm, |swarm| { + swarm.put(ROOT, "theirs", 1_i64).unwrap() + }); - old.put(ROOT, "mine", 1_i64).unwrap(); - old.commit(); + change(&mut old, |old| old.put(ROOT, "mine", 1_i64).unwrap()); (old, swarm, target) } diff --git a/src/remake/delta.rs b/src/remake/delta.rs index aebd048..21c07b7 100644 --- a/src/remake/delta.rs +++ b/src/remake/delta.rs @@ -251,6 +251,7 @@ pub(crate) fn changed_paths( #[cfg(test)] mod tests { use super::*; + use crate::document::testing::{change, try_change}; use automerge::{ObjType, ROOT, ReadDoc, ScalarValue, transaction::Transactable}; use serde_json::json; @@ -265,8 +266,8 @@ mod tests { const KEYS: [&str; 3] = ["a", "b", "c"]; let depth = rng.between(1, 3); let path: Vec = (0..depth).map(|_| rng.pick(&KEYS).to_string()).collect(); - let result = if rng.chance(0.2) { - store::delete_path(doc, &path, false) + let _ = if rng.chance(0.2) { + try_change(doc, |doc| store::delete_path(doc, &path, false)) } else { let value = match rng.below(4) { 0 => json!(rng.below(100)), @@ -278,16 +279,8 @@ mod tests { serde_json::Value::Object(map) } }; - store::write_path(doc, &path, &value) + try_change(doc, |doc| store::write_path(doc, &path, &value)) }; - match result { - Ok(()) => { - doc.commit_with(automerge::transaction::CommitOptions::default().with_time(0)); - } - Err(_) => { - doc.rollback(); - } - } } /// Compaction's promise: a snapshot of the base plus everything replayed since gives @@ -302,8 +295,9 @@ mod tests { } let base = old.get_heads(); let mut new = AutoCommit::new().with_actor(actor(100)); - store::materialize_into(&old, &mut new, &|_| false).unwrap(); - new.commit(); + change(&mut new, |new| { + store::materialize_into(&old, new, &|_| false).unwrap() + }); let mut nodes: Vec = (1..=rng.between(1, 3)) .map(|i| old.fork().with_actor(actor(i as u8))) @@ -395,19 +389,21 @@ mod tests { #[test] fn minimal_paths() { let mut doc = AutoCommit::new(); - doc.put(ROOT, "untouched", 1_i64).unwrap(); + change(&mut doc, |doc| doc.put(ROOT, "untouched", 1_i64).unwrap()); let before = doc.get_heads(); - let m = doc.put_object(ROOT, "m", ObjType::Map).unwrap(); - doc.put(&m, "a", 1_i64).unwrap(); - doc.put(ROOT, "x", 1_i64).unwrap(); - doc.put(ROOT, "c", ScalarValue::counter(0)).unwrap(); - doc.commit(); + change(&mut doc, |doc| { + let m = doc.put_object(ROOT, "m", ObjType::Map).unwrap(); + doc.put(&m, "a", 1_i64).unwrap(); + doc.put(ROOT, "x", 1_i64).unwrap(); + doc.put(ROOT, "c", ScalarValue::counter(0)).unwrap(); + }); let middle = doc.get_heads(); - doc.increment(ROOT, "c", 2).unwrap(); - let list = doc.put_object(ROOT, "l", ObjType::List).unwrap(); - doc.insert(&list, 0, "e").unwrap(); - doc.commit(); + change(&mut doc, |doc| { + doc.increment(ROOT, "c", 2).unwrap(); + let list = doc.put_object(ROOT, "l", ObjType::List).unwrap(); + doc.insert(&list, 0, "e").unwrap(); + }); let after = doc.get_heads(); let all = changed_paths(&mut doc, &before, &after); @@ -429,26 +425,30 @@ mod tests { fn replays_state_per_key() { // Base shared by the old document and the snapshot. let mut old = AutoCommit::new(); - let m = old.put_object(ROOT, "m", ObjType::Map).unwrap(); - old.put(&m, "keep", "base").unwrap(); - old.put(&m, "change", "base").unwrap(); - old.put(ROOT, "gone", true).unwrap(); - old.commit(); + let m = change(&mut old, |old| { + let m = old.put_object(ROOT, "m", ObjType::Map).unwrap(); + old.put(&m, "keep", "base").unwrap(); + old.put(&m, "change", "base").unwrap(); + old.put(ROOT, "gone", true).unwrap(); + m + }); let base = old.get_heads(); let mut new = AutoCommit::new(); - store::materialize_into(&old, &mut new, &|_| false).unwrap(); - // Something the new epoch already holds that the delta must not clobber. - let Some((_, m_new)) = new.get(ROOT, "m").unwrap() else { - panic!("m missing"); - }; - new.put(&m_new, "keep", "new epoch").unwrap(); - new.commit(); + change(&mut new, |new| { + store::materialize_into(&old, new, &|_| false).unwrap(); + // Something the new epoch already holds that the delta must not clobber. + let Some((_, m_new)) = new.get(ROOT, "m").unwrap() else { + panic!("m missing"); + }; + new.put(&m_new, "keep", "new epoch").unwrap(); + }); // The delta: one key changed, one key deleted. - old.put(&m, "change", "delta").unwrap(); - old.delete(ROOT, "gone").unwrap(); - old.commit(); + change(&mut old, |old| { + old.put(&m, "change", "delta").unwrap(); + old.delete(ROOT, "gone").unwrap(); + }); let after = old.get_heads(); let stats = replay(&mut old, &base, &after, &mut new, &Translator::default()); @@ -465,8 +465,7 @@ mod tests { let other = ActorId::from(&b"other-actor"[..]); let mut doc = AutoCommit::new().with_actor(own.clone()); - doc.put(ROOT, "base", 1_i64).unwrap(); - doc.commit(); + change(&mut doc, |doc| doc.put(ROOT, "base", 1_i64).unwrap()); let base = doc.get_heads(); // The snapshot contains the base only. @@ -474,14 +473,14 @@ mod tests { // A foreign change after the base (replayed by its own node) ... let mut foreign = doc.fork().with_actor(other); - foreign.put(ROOT, "theirs", 1_i64).unwrap(); - foreign.commit(); + change(&mut foreign, |foreign| { + foreign.put(ROOT, "theirs", 1_i64).unwrap() + }); doc.merge(&mut foreign).unwrap(); let with_foreign = doc.get_heads(); // ... and one of ours. - doc.put(ROOT, "mine", 1_i64).unwrap(); - doc.commit(); + change(&mut doc, |doc| doc.put(ROOT, "mine", 1_i64).unwrap()); let after = doc.get_heads(); let missing = missing_from_snapshot(&mut doc, &clock, std::slice::from_ref(&own)); @@ -505,28 +504,24 @@ mod tests { #[test] fn protocol_metadata_is_never_replayed() { let mut old = AutoCommit::new(); - old.put(ROOT, "x", 1_i64).unwrap(); - old.commit(); + change(&mut old, |old| old.put(ROOT, "x", 1_i64).unwrap()); let base = old.get_heads(); let mut new = AutoCommit::new(); - store::write_path( - &mut new, - &meta::path(&[EPOCHS, "1"]), - &json!({ "generation": 1 }), - ) - .unwrap(); - new.commit(); + change(&mut new, |new| { + store::write_path( + new, + &meta::path(&[EPOCHS, "1"]), + &json!({ "generation": 1 }), + ) + .unwrap() + }); // The old epoch replaces `_continuum` wholesale and writes a remake record. - store::write_path( - &mut old, - &meta::path(&[]), - &json!({ "forgotten": { "pk": 1 } }), - ) - .unwrap(); - store::write_path(&mut old, &meta::path(&[REMAKES, "c"]), &json!({ "x": 1 })).unwrap(); - old.commit(); + change(&mut old, |old| { + store::write_path(old, &meta::path(&[]), &json!({ "forgotten": { "pk": 1 } })).unwrap(); + store::write_path(old, &meta::path(&[REMAKES, "c"]), &json!({ "x": 1 })).unwrap(); + }); let after = old.get_heads(); replay(&mut old, &base, &after, &mut new, &Translator::default()); diff --git a/src/remake/kind.rs b/src/remake/kind.rs index ca16de0..1df03cb 100644 --- a/src/remake/kind.rs +++ b/src/remake/kind.rs @@ -591,17 +591,20 @@ mod tests { #[test] fn import_keeps_types_and_drops_protocol_data() { + use crate::document::testing::{change, try_change}; use automerge::{ObjType, ROOT, ReadDoc, transaction::Transactable}; use serde_json::json; let mut source = AutoCommit::new(); - let text = source.put_object(ROOT, "notes", ObjType::Text).unwrap(); - source.splice_text(&text, 0, 0, "hello").unwrap(); - source - .put(ROOT, "hits", automerge::ScalarValue::counter(3)) - .unwrap(); - let meta = source.put_object(ROOT, meta::ROOT, ObjType::Map).unwrap(); - source.put(&meta, "members", "elsewhere").unwrap(); + change(&mut source, |source| { + let text = source.put_object(ROOT, "notes", ObjType::Text).unwrap(); + source.splice_text(&text, 0, 0, "hello").unwrap(); + source + .put(ROOT, "hits", automerge::ScalarValue::counter(3)) + .unwrap(); + let meta = source.put_object(ROOT, meta::ROOT, ObjType::Map).unwrap(); + source.put(&meta, "members", "elsewhere").unwrap(); + }); let encoded = BASE64.encode(source.save()); assert!( @@ -620,10 +623,10 @@ mod tests { .unwrap(); let build = || { let mut target = AutoCommit::new().with_actor(automerge::ActorId::from(&b"fixed"[..])); - Import - .build(&AutoCommit::new(), prepared.content.as_deref(), &mut target) - .unwrap(); - target.commit_with(automerge::transaction::CommitOptions::default().with_time(0)); + try_change(&mut target, |target| { + Import.build(&AutoCommit::new(), prepared.content.as_deref(), target) + }) + .unwrap(); target }; let mut a = build(); @@ -648,14 +651,15 @@ mod tests { #[test] fn replace_builds_the_document_deterministically() { + use crate::document::testing::try_change; use serde_json::json; let build = |document: serde_json::Value| { let prepared = replace(json!({ "document": document })).unwrap(); let mut target = AutoCommit::new().with_actor(automerge::ActorId::from(&b"fixed"[..])); - Replace - .build(&AutoCommit::new(), prepared.content.as_deref(), &mut target) - .unwrap(); - target.commit_with(automerge::transaction::CommitOptions::default().with_time(0)); + try_change(&mut target, |target| { + Replace.build(&AutoCommit::new(), prepared.content.as_deref(), target) + }) + .unwrap(); ( target.get_heads(), store::read_path(&target, &[]).unwrap().unwrap(), diff --git a/src/remake/records.rs b/src/remake/records.rs index f22b1e5..40b563a 100644 --- a/src/remake/records.rs +++ b/src/remake/records.rs @@ -499,6 +499,7 @@ pub(crate) fn decode_hex32(hex: &str) -> Option<[u8; 32]> { #[cfg(test)] mod tests { use super::*; + use crate::document::testing::change; #[test] fn retention_covers_until_every_limit_passed() { @@ -570,16 +571,6 @@ mod tests { fn round_trip_through_the_document() { let mut doc = Document::new(); let p = proposal(10_000); - write_proposal(&mut doc, "c-1", &p).unwrap(); - write_abort_request( - &mut doc, - "c-1", - &AbortRequest { - by: "x".into(), - at: UnixMillis(5), - }, - ) - .unwrap(); let decision = Decision::Committed { to_epoch: EpochRecord { generation: 1, @@ -589,14 +580,25 @@ mod tests { snapshot_bytes: 123, decided_at: UnixMillis(11_000), }; - write_decision(&mut doc, "c-1", &decision).unwrap(); let vote = |remake: &str| Vote { remake: remake.into(), at: UnixMillis(7), }; - write_vote(&mut doc, "node-b", &vote("c-1")).unwrap(); - write_vote(&mut doc, "node-c", &vote("other")).unwrap(); - doc.commit(); + change(&mut doc, |doc| { + write_proposal(doc, "c-1", &p).unwrap(); + write_abort_request( + doc, + "c-1", + &AbortRequest { + by: "x".into(), + at: UnixMillis(5), + }, + ) + .unwrap(); + write_decision(doc, "c-1", &decision).unwrap(); + write_vote(doc, "node-b", &vote("c-1")).unwrap(); + write_vote(doc, "node-c", &vote("other")).unwrap(); + }); let all = load_all(&doc); assert_eq!(all.len(), 1); @@ -617,14 +619,11 @@ mod tests { remake: remake.into(), at: UnixMillis(at), }; - write_vote(&mut a, "node-a", &vote("x", 1)).unwrap(); - a.commit(); + change(&mut a, |a| write_vote(a, "node-a", &vote("x", 1)).unwrap()); let mut b = a.fork(); // node-b votes in both, never seeing its other vote (a lost vote). - write_vote(&mut a, "node-b", &vote("x", 2)).unwrap(); - write_vote(&mut b, "node-b", &vote("y", 3)).unwrap(); - a.commit(); - b.commit(); + change(&mut a, |a| write_vote(a, "node-b", &vote("x", 2)).unwrap()); + change(&mut b, |b| write_vote(b, "node-b", &vote("y", 3)).unwrap()); a.merge(&mut b).unwrap(); let register = load_register(&a); @@ -634,8 +633,7 @@ mod tests { assert_eq!(twice, [vote("x", 2), vote("y", 3)]); // Seen, a vote is replaced. - write_vote(&mut a, "node-b", &vote("z", 4)).unwrap(); - a.commit(); + change(&mut a, |a| write_vote(a, "node-b", &vote("z", 4)).unwrap()); assert_eq!(load_register(&a)["node-b"], [vote("z", 4)]); } @@ -686,8 +684,9 @@ mod tests { #[test] fn disagreeing_decisions_are_contested() { let mut base = Document::new(); - write_proposal(&mut base, "c-1", &proposal(10_000)).unwrap(); - base.commit(); + change(&mut base, |base| { + write_proposal(base, "c-1", &proposal(10_000)).unwrap() + }); let (mut a, mut b, mut c) = (base.fork(), base.fork(), base.fork()); let committed = Decision::Committed { to_epoch: EpochRecord { @@ -698,21 +697,20 @@ mod tests { snapshot_bytes: 1, decided_at: UnixMillis(2), }; - write_decision(&mut a, "c-1", &committed).unwrap(); - write_decision( - &mut b, - "c-1", - &Decision::Aborted { - reason: "test".into(), - decided_at: UnixMillis(3), - }, - ) - .unwrap(); + change(&mut a, |a| write_decision(a, "c-1", &committed).unwrap()); + change(&mut b, |b| { + write_decision( + b, + "c-1", + &Decision::Aborted { + reason: "test".into(), + decided_at: UnixMillis(3), + }, + ) + .unwrap() + }); // The same decision, concurrently: they agree. - write_decision(&mut c, "c-1", &committed).unwrap(); - a.commit(); - b.commit(); - c.commit(); + change(&mut c, |c| write_decision(c, "c-1", &committed).unwrap()); let mut agreeing = a.fork(); agreeing.merge(&mut c).unwrap(); assert!(!load(&agreeing, "c-1").unwrap().contested); @@ -726,14 +724,15 @@ mod tests { #[test] fn unreadable_records_are_skipped() { let mut doc = Document::new(); - store::write_path( - &mut doc, - &record_path("broken", ""), - &serde_json::json!({ "proposal": "not an object" }), - ) - .unwrap(); - write_proposal(&mut doc, "fine", &proposal(1)).unwrap(); - doc.commit(); + change(&mut doc, |doc| { + store::write_path( + doc, + &record_path("broken", ""), + &serde_json::json!({ "proposal": "not an object" }), + ) + .unwrap(); + write_proposal(doc, "fine", &proposal(1)).unwrap(); + }); let all = load_all(&doc); assert_eq!(all.len(), 1); assert_eq!(all[0].0, "fine"); diff --git a/src/remake/snapshot.rs b/src/remake/snapshot.rs index b071b74..c818af6 100644 --- a/src/remake/snapshot.rs +++ b/src/remake/snapshot.rs @@ -376,6 +376,7 @@ pub(super) fn canonical(value: JsonValue) -> JsonValue { #[cfg(test)] mod tests { use super::*; + use crate::document::testing::change; use automerge::{ObjType, ROOT, ReadDoc, ScalarValue, Value, transaction::Transactable}; fn doc(actor: &[u8]) -> AutoCommit { @@ -414,28 +415,31 @@ mod tests { fn same_view_different_history_same_snapshot() { // One history: overwrites, increments, one-shot text. let mut a = doc(b"actor-a"); - a.put(ROOT, "x", 1_i64).unwrap(); - a.commit(); - a.put(ROOT, "x", 2_i64).unwrap(); - a.put(ROOT, "c", ScalarValue::counter(0)).unwrap(); - a.increment(ROOT, "c", 5).unwrap(); - let text = a.put_object(ROOT, "t", ObjType::Text).unwrap(); - a.splice_text(&text, 0, 0, "hello").unwrap(); - let m = a.put_object(ROOT, "m", ObjType::Map).unwrap(); - a.put(&m, "k", "v").unwrap(); - a.commit(); + change(&mut a, |a| a.put(ROOT, "x", 1_i64).unwrap()); + change(&mut a, |a| { + a.put(ROOT, "x", 2_i64).unwrap(); + a.put(ROOT, "c", ScalarValue::counter(0)).unwrap(); + a.increment(ROOT, "c", 5).unwrap(); + let text = a.put_object(ROOT, "t", ObjType::Text).unwrap(); + a.splice_text(&text, 0, 0, "hello").unwrap(); + let m = a.put_object(ROOT, "m", ObjType::Map).unwrap(); + a.put(&m, "k", "v").unwrap(); + }); // Another actor, other order, other steps, same result. let mut b = doc(b"actor-b"); - let m = b.put_object(ROOT, "m", ObjType::Map).unwrap(); - b.put(&m, "k", "v").unwrap(); - let text = b.put_object(ROOT, "t", ObjType::Text).unwrap(); - b.splice_text(&text, 0, 0, "hel").unwrap(); - b.commit(); - b.splice_text(&text, 3, 0, "lo").unwrap(); - b.put(ROOT, "c", ScalarValue::counter(5)).unwrap(); - b.put(ROOT, "x", 2_i64).unwrap(); - b.commit(); + let text = change(&mut b, |b| { + let m = b.put_object(ROOT, "m", ObjType::Map).unwrap(); + b.put(&m, "k", "v").unwrap(); + let text = b.put_object(ROOT, "t", ObjType::Text).unwrap(); + b.splice_text(&text, 0, 0, "hel").unwrap(); + text + }); + change(&mut b, |b| { + b.splice_text(&text, 3, 0, "lo").unwrap(); + b.put(ROOT, "c", ScalarValue::counter(5)).unwrap(); + b.put(ROOT, "x", 2_i64).unwrap(); + }); assert_eq!(user_view(&a), user_view(&b)); @@ -452,12 +456,13 @@ mod tests { #[test] fn rebuild_is_deterministic() { let mut a = doc(b"actor-a"); - a.put(ROOT, "x", 1_i64).unwrap(); - let list = a.put_object(ROOT, "l", ObjType::List).unwrap(); - a.insert(&list, 0, "first").unwrap(); - let inner = a.insert_object(&list, 1, ObjType::Map).unwrap(); - a.put(&inner, "k", true).unwrap(); - a.commit(); + change(&mut a, |a| { + a.put(ROOT, "x", 1_i64).unwrap(); + let list = a.put_object(ROOT, "l", ObjType::List).unwrap(); + a.insert(&list, 0, "first").unwrap(); + let inner = a.insert_object(&list, 1, ObjType::Map).unwrap(); + a.put(&inner, "k", true).unwrap(); + }); // A second node holding the same changes, received in a different way. let mut b = doc(b"actor-b"); @@ -475,14 +480,16 @@ mod tests { #[test] fn conflicts_collapse_into_the_merged_view() { let mut a = doc(b"actor-a"); - let cfg = a.put_object(ROOT, "cfg", ObjType::Map).unwrap(); - a.put(&cfg, "x", 1_i64).unwrap(); - a.commit(); + change(&mut a, |a| { + let cfg = a.put_object(ROOT, "cfg", ObjType::Map).unwrap(); + a.put(&cfg, "x", 1_i64).unwrap(); + }); let mut b = doc(b"actor-b"); - let cfg = b.put_object(ROOT, "cfg", ObjType::Map).unwrap(); - b.put(&cfg, "y", 2_i64).unwrap(); - b.commit(); + change(&mut b, |b| { + let cfg = b.put_object(ROOT, "cfg", ObjType::Map).unwrap(); + b.put(&cfg, "y", 2_i64).unwrap(); + }); a.merge(&mut b).unwrap(); let (_, conflicts) = store::read_path_with_conflicts(&a, &[]).unwrap().unwrap(); @@ -507,22 +514,19 @@ mod tests { fn base_heads_bound_content_and_clock() { let mut a = doc(b"actor-a"); for i in 0..3_i64 { - a.put(ROOT, format!("a{i}"), i).unwrap(); - a.commit(); + change(&mut a, |a| a.put(ROOT, format!("a{i}"), i).unwrap()); } let mut b = doc(b"actor-b"); for i in 0..2_i64 { - b.put(ROOT, format!("b{i}"), i).unwrap(); - b.commit(); + change(&mut b, |b| b.put(ROOT, format!("b{i}"), i).unwrap()); } a.merge(&mut b).unwrap(); let base = a.get_heads(); // After the base: must not appear in the snapshot or its clock. - a.put(ROOT, "late", true).unwrap(); - a.commit(); + change(&mut a, |a| a.put(ROOT, "late", true).unwrap()); let policy = json!({}); let snap = build(&mut a, ¶ms(&base, &policy)).unwrap(); @@ -541,8 +545,9 @@ mod tests { #[test] fn epoch_of_a_backup() { let mut a = doc(b"actor-a"); - store::write_path(&mut a, &["k".into()], &json!(1)).unwrap(); - a.commit(); + change(&mut a, |a| { + store::write_path(a, &["k".into()], &json!(1)).unwrap() + }); assert_eq!(epoch_of(&mut a), Ok(Epoch::GENESIS)); let heads = a.get_heads(); @@ -553,8 +558,9 @@ mod tests { .doc .fork() .with_actor(ActorId::from(b"actor-b".as_slice())); - store::write_path(&mut later, &["k".into()], &json!(2)).unwrap(); - later.commit(); + change(&mut later, |later| { + store::write_path(later, &["k".into()], &json!(2)).unwrap() + }); let mut backup = AutoCommit::load(&later.save()).unwrap(); assert_eq!(epoch_of(&mut backup), Ok(snap.epoch)); } @@ -562,25 +568,26 @@ mod tests { #[test] fn metadata_written_and_remake_records_dropped() { let mut a = doc(b"actor-a"); - store::write_path( - &mut a, - &meta::path(&[REMAKES, "c-1"]), - &json!({ "state": "committed" }), - ) - .unwrap(); - store::write_path( - &mut a, - &meta::path(&[VOTES, "pk"]), - &json!({ "remake": "c-1", "at": 1 }), - ) - .unwrap(); - store::write_path( - &mut a, - &meta::path(&[meta::FORGOTTEN, "pk"]), - &json!({ "at": 1 }), - ) - .unwrap(); - a.commit(); + change(&mut a, |a| { + store::write_path( + a, + &meta::path(&[REMAKES, "c-1"]), + &json!({ "state": "committed" }), + ) + .unwrap(); + store::write_path( + a, + &meta::path(&[VOTES, "pk"]), + &json!({ "remake": "c-1", "at": 1 }), + ) + .unwrap(); + store::write_path( + a, + &meta::path(&[meta::FORGOTTEN, "pk"]), + &json!({ "at": 1 }), + ) + .unwrap(); + }); let heads = a.get_heads(); let policy = json!({ "replayWindow": { "epochs": 1 } }); @@ -605,16 +612,17 @@ mod tests { #[test] fn automerge_types_survive() { let mut a = doc(b"actor-a"); - a.put(ROOT, "c", ScalarValue::counter(3)).unwrap(); - a.increment(ROOT, "c", 4).unwrap(); - let text = a.put_object(ROOT, "t", ObjType::Text).unwrap(); - a.splice_text(&text, 0, 0, "abc").unwrap(); - a.put(ROOT, "bytes", ScalarValue::Bytes(vec![0, 1, 255])) - .unwrap(); - a.put(ROOT, "ts", ScalarValue::Timestamp(1_700_000_000_000)) - .unwrap(); - a.put(ROOT, "neg_zero", -0.0_f64).unwrap(); - a.commit(); + change(&mut a, |a| { + a.put(ROOT, "c", ScalarValue::counter(3)).unwrap(); + a.increment(ROOT, "c", 4).unwrap(); + let text = a.put_object(ROOT, "t", ObjType::Text).unwrap(); + a.splice_text(&text, 0, 0, "abc").unwrap(); + a.put(ROOT, "bytes", ScalarValue::Bytes(vec![0, 1, 255])) + .unwrap(); + a.put(ROOT, "ts", ScalarValue::Timestamp(1_700_000_000_000)) + .unwrap(); + a.put(ROOT, "neg_zero", -0.0_f64).unwrap(); + }); let snap = snapshot_of(&mut a); let d = &snap.doc; @@ -655,8 +663,7 @@ mod tests { #[test] fn snapshot_is_a_single_change_with_the_epoch_id() { let mut a = doc(b"actor-a"); - a.put(ROOT, "x", 1_i64).unwrap(); - a.commit(); + change(&mut a, |a| a.put(ROOT, "x", 1_i64).unwrap()); let mut snap = snapshot_of(&mut a); let heads = snap.doc.get_heads(); @@ -668,12 +675,10 @@ mod tests { #[test] fn missing_base_is_rejected() { let mut a = doc(b"actor-a"); - a.put(ROOT, "x", 1_i64).unwrap(); - a.commit(); + change(&mut a, |a| a.put(ROOT, "x", 1_i64).unwrap()); let mut other = doc(b"actor-b"); - other.put(ROOT, "y", 1_i64).unwrap(); - other.commit(); + change(&mut other, |other| other.put(ROOT, "y", 1_i64).unwrap()); let foreign = other.get_heads(); let policy = json!({}); @@ -698,8 +703,7 @@ mod tests { // Old epoch: the base, then a late write by this node. let mut late = doc(b"late-node"); - late.put(ROOT, "shared", "base").unwrap(); - late.commit(); + change(&mut late, |late| late.put(ROOT, "shared", "base").unwrap()); let base = late.get_heads(); let policy = json!({}); let mut snap = build(&mut late, ¶ms(&base, &policy)).unwrap(); @@ -709,12 +713,10 @@ mod tests { .doc .fork() .with_actor(ActorId::from(&b"swarm-node"[..])); - swarm.put(ROOT, "new", 1_i64).unwrap(); - swarm.commit(); + change(&mut swarm, |swarm| swarm.put(ROOT, "new", 1_i64).unwrap()); let bytes = swarm.save(); - late.put(ROOT, "mine", "late").unwrap(); - late.commit(); + change(&mut late, |late| late.put(ROOT, "mine", "late").unwrap()); let mut fetched = AutoCommit::load(&bytes).unwrap(); let metadata = verify_document(&mut fetched, snap.epoch).unwrap(); -- cgit v1.3.1