From 6f03f74266314f1642b757047da5ab88b34714a4 Mon Sep 17 00:00:00 2001 From: tv Date: Sat, 31 Oct 2026 19:57:31 +0100 Subject: add save-after-rollback test --- src/document/replica.rs | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'src/document') diff --git a/src/document/replica.rs b/src/document/replica.rs index 20c02e5..27c81ad 100644 --- a/src/document/replica.rs +++ b/src/document/replica.rs @@ -225,6 +225,40 @@ mod tests { assert_eq!(local.relation_to(&epoch(3, 2)), EpochRelation::Diverged); } + /// A rolled-back write leaves its writer unused in the document; saving must not + /// trip over it (Automerge refuses to save a document with unused writers). + #[test] + fn saves_after_a_rolled_back_write() { + use crate::clock::UnixMillis; + use crate::document::store; + use serde_json::json; + + let path = vec!["a".to_owned()]; + let mut replica = Replica::new(Epoch::GENESIS, Document::new()); + + let refused: Result<(), &str> = replica.transact(UnixMillis(1), |doc| { + store::write_path(doc, &path, &json!(1)).unwrap(); + Err("refused") + }); + assert!(refused.is_err()); + let loaded = super::super::load(&super::super::save(&replica.doc)).unwrap(); + assert!(loaded.get_heads().is_empty()); + assert_eq!(store::read_path(&loaded, &path).unwrap(), None); + + // The same writer commits afterwards, and that saves too. + replica + .transact(UnixMillis(2), |doc| { + store::write_path(doc, &path, &json!(2)) + }) + .unwrap(); + replica.refresh_heads(); + let loaded = super::super::load(&super::super::save(&replica.doc)).unwrap(); + let mut heads = loaded.get_heads(); + heads.sort_unstable(); + assert_eq!(heads, replica.heads()); + assert_eq!(store::read_path(&loaded, &path).unwrap(), Some(json!(2))); + } + #[test] fn display() { assert_eq!(Epoch::GENESIS.to_string(), "0:genesis"); -- cgit v1.3.1