use chrono::Duration;
use tiny_counter::EventStore;
#[test]
fn merge_event_combines_counts() {
let store1 = EventStore::new();
store1.record_count("event", 100);
let store2 = EventStore::new();
store2.record_count("event", 50);
let exported = store2.export_all().unwrap();
let counter = exported.get("event").unwrap().clone();
store1.merge_event("event", counter).unwrap();
assert_eq!(store1.query("event").last_days(1).sum(), Some(150));
}
#[test]
fn merge_all_combines_multiple_events() {
let store1 = EventStore::new();
store1.record_count("event1", 10);
store1.record_count("event2", 20);
let store2 = EventStore::new();
store2.record_count("event1", 5);
store2.record_count("event3", 30);
let exported = store2.export_all().unwrap();
store1.merge_all(exported).unwrap();
assert_eq!(store1.query("event1").last_days(1).sum(), Some(15)); assert_eq!(store1.query("event2").last_days(1).sum(), Some(20)); assert_eq!(store1.query("event3").last_days(1).sum(), Some(30)); }
#[test]
fn merge_with_empty_store_is_identity() {
let store = EventStore::new();
store.record_count("event", 100);
let sum_before = store.query("event").last_days(1).sum();
let empty_store = EventStore::new();
let exported = empty_store.export_all().unwrap();
store.merge_all(exported).unwrap();
let sum_after = store.query("event").last_days(1).sum();
assert_eq!(sum_before, sum_after);
}
#[test]
fn merge_is_commutative() {
let store_a1 = EventStore::new();
store_a1.record_count("event", 50);
let store_b1 = EventStore::new();
store_b1.record_count("event", 30);
let exported_b = store_b1.export_all().unwrap();
store_a1.merge_all(exported_b).unwrap();
let sum_ab = store_a1.query("event").last_days(1).sum();
let store_a2 = EventStore::new();
store_a2.record_count("event", 50);
let store_b2 = EventStore::new();
store_b2.record_count("event", 30);
let exported_a = store_a2.export_all().unwrap();
store_b2.merge_all(exported_a).unwrap();
let sum_ba = store_b2.query("event").last_days(1).sum();
assert_eq!(sum_ab, sum_ba);
}
#[test]
fn merge_is_associative() {
let store_a1 = EventStore::new();
store_a1.record_count("event", 10);
let store_b1 = EventStore::new();
store_b1.record_count("event", 20);
let store_c1 = EventStore::new();
store_c1.record_count("event", 30);
let exported_b1 = store_b1.export_all().unwrap();
store_a1.merge_all(exported_b1).unwrap();
let exported_c1 = store_c1.export_all().unwrap();
store_a1.merge_all(exported_c1).unwrap();
let sum_abc = store_a1.query("event").last_days(1).sum();
let store_a2 = EventStore::new();
store_a2.record_count("event", 10);
let store_b2 = EventStore::new();
store_b2.record_count("event", 20);
let store_c2 = EventStore::new();
store_c2.record_count("event", 30);
let exported_c2 = store_c2.export_all().unwrap();
store_b2.merge_all(exported_c2).unwrap();
let exported_bc = store_b2.export_all().unwrap();
store_a2.merge_all(exported_bc).unwrap();
let sum_abc2 = store_a2.query("event").last_days(1).sum();
assert_eq!(sum_abc, sum_abc2);
}
#[test]
fn merge_preserves_first_seen() {
use std::sync::Arc;
use tiny_counter::TestClock;
let fixed_time = chrono::Utc::now();
let clock = TestClock::build_for_testing_at(fixed_time);
let store1 = EventStore::builder()
.with_clock(Arc::new(clock.clone()))
.build()
.unwrap();
store1.record("event");
clock.advance(Duration::hours(6));
let store2 = EventStore::builder()
.with_clock(Arc::new(clock.clone()))
.build()
.unwrap();
store2.record("event");
let exported = store2.export_all().unwrap();
store1.merge_all(exported).unwrap();
let first_seen = store1.query("event").first_seen();
assert!(first_seen.is_some());
let duration = first_seen.unwrap();
assert!(duration.num_hours() >= 5 && duration.num_hours() <= 7);
}