use std::collections::HashMap;
use automerge::{Automerge, AutomergeError, ROOT, transaction::Transactable};
use samod_core::{CompactionHash, DocumentId, StorageKey};
use samod_test_harness::{Network, RunningDocIds};
fn init_logging() {
let _ = tracing_subscriber::fmt()
.with_env_filter(tracing_subscriber::EnvFilter::from_default_env())
.try_init();
}
#[test]
fn many_changes_are_compacted() {
init_logging();
let mut network = Network::new();
let alice = network.create_samod("alice");
let RunningDocIds { actor_id, doc_id } = network.samod(&alice).create_document();
for i in 0..100 {
network
.samod(&alice)
.with_document_by_actor(actor_id, |doc| {
doc.transact(|tx| {
tx.put(ROOT, i.to_string(), i)?;
Ok::<_, AutomergeError>(())
})
.unwrap();
})
.unwrap();
}
let doc_heads = network
.samod(&alice)
.with_document_by_actor(actor_id, |doc| doc.get_heads())
.unwrap();
let num_changes = network.samod(&alice).storage().len();
assert!(
num_changes < 100,
"Expected less than 100 changes, found {num_changes}"
);
let alice_storage = network.samod(&alice).storage().clone();
let alice2 = network.create_samod_with_storage("alice2", alice_storage);
let alice2_actor = network.samod(&alice2).find_document(&doc_id).unwrap();
let heads_on_alice2 = network
.samod(&alice2)
.with_document_by_actor(alice2_actor, |doc| doc.get_heads())
.unwrap();
assert_eq!(doc_heads, heads_on_alice2);
}
#[test]
fn many_changes_compact_but_do_not_delete_existing_snapshot() {
let mut storage = HashMap::new();
let doc_id = DocumentId::new(&mut rand::rng());
let mut doc = Automerge::new();
for i in 0..100 {
doc.transact(|tx| {
tx.put(ROOT, "foo", format!("bar {}", i))?;
Ok::<_, AutomergeError>(())
})
.unwrap();
let change = doc.get_last_local_change().unwrap();
storage.insert(
StorageKey::incremental_path(&doc_id, change.hash()),
change.raw_bytes().to_vec(),
);
}
let snapshot = doc.save();
let snapshot_hash = CompactionHash::new(&doc.get_heads());
storage.insert(StorageKey::snapshot_path(&doc_id, &snapshot_hash), snapshot);
let mut network = Network::new();
let alice = network.create_samod_with_storage("alice", storage);
let _actor_id = network.samod(&alice).find_document(&doc_id).unwrap();
let alice_storage = network.samod(&alice).storage().clone();
let bob = network.create_samod_with_storage("bob", alice_storage);
let _actor_id = network
.samod(&bob)
.find_document(&doc_id)
.expect("bob should have the document");
}