use std::sync::Arc;
use reconcile::{replicated_map::Config, InMemoryNetwork, ReplicatedMap};
fn isolated_store(addr: &str) -> ReplicatedMap<i32, i32> {
let network = InMemoryNetwork::new();
let transport = Arc::new(network.bind(format!("{addr}:8300").parse().unwrap()));
ReplicatedMap::new_with_transport(Config::default().with_insecure_no_key(), transport)
}
#[test]
fn empty_store_reads() {
let store = isolated_store("127.0.0.1");
assert_eq!(store.len(), 0);
assert!(store.is_empty());
assert!(!store.contains_key(&1));
assert!(store.to_vec().is_empty());
assert!(store.range_to_vec(..).is_empty());
assert!(store.keys().is_empty());
assert!(store.values().is_empty());
assert_eq!(store.first_key_value(), None);
assert_eq!(store.last_key_value(), None);
let mut seen = 0;
store.for_each(|_, _| seen += 1);
assert_eq!(seen, 0);
}
#[test]
fn live_reads_and_ranges() {
let store = isolated_store("127.0.0.2");
for k in 1..=5 {
store.just_insert(k, k * 10);
}
assert_eq!(store.len(), 5);
assert!(!store.is_empty());
assert!(store.contains_key(&3));
assert!(!store.contains_key(&99));
assert_eq!(
store.to_vec(),
vec![(1, 10), (2, 20), (3, 30), (4, 40), (5, 50)]
);
assert_eq!(store.keys(), vec![1, 2, 3, 4, 5]);
assert_eq!(store.values(), vec![10, 20, 30, 40, 50]);
assert_eq!(store.first_key_value(), Some((1, 10)));
assert_eq!(store.last_key_value(), Some((5, 50)));
let mut collected = Vec::new();
store.for_each(|k, v| collected.push((*k, *v)));
assert_eq!(collected, store.to_vec());
assert_eq!(store.range_to_vec(2..4), vec![(2, 20), (3, 30)]);
assert_eq!(store.range_to_vec(2..=4), vec![(2, 20), (3, 30), (4, 40)]);
assert_eq!(store.range_to_vec(..3), vec![(1, 10), (2, 20)]);
assert_eq!(store.range_to_vec(4..), vec![(4, 40), (5, 50)]);
assert_eq!(store.range_to_vec(..).len(), 5);
let mut in_range = Vec::new();
store.for_each_in_range(2..=4, |k, v| in_range.push((*k, *v)));
assert_eq!(in_range, vec![(2, 20), (3, 30), (4, 40)]);
}
#[test]
fn tombstoned_entries_are_excluded() {
let store = isolated_store("127.0.0.3");
for k in 1..=3 {
store.just_insert(k, k * 10);
}
store.just_remove(&2);
assert_eq!(store.len(), 2);
assert!(!store.is_empty());
assert!(!store.contains_key(&2));
assert!(store.contains_key(&1));
assert_eq!(store.to_vec(), vec![(1, 10), (3, 30)]);
assert_eq!(store.keys(), vec![1, 3]);
assert_eq!(store.values(), vec![10, 30]);
assert_eq!(store.range_to_vec(..), vec![(1, 10), (3, 30)]);
assert!(store.range_to_vec(2..3).is_empty());
let mut collected = Vec::new();
store.for_each(|k, v| collected.push((*k, *v)));
assert_eq!(collected, vec![(1, 10), (3, 30)]);
store.just_remove(&1);
store.just_remove(&3);
assert_eq!(store.len(), 0);
assert!(store.is_empty());
assert!(store.to_vec().is_empty());
}
#[test]
fn first_and_last_key_value_skip_boundary_tombstones() {
let store = isolated_store("127.0.0.4");
for k in 1..=5 {
store.just_insert(k, k * 10);
}
assert_eq!(store.first_key_value(), Some((1, 10)));
assert_eq!(store.last_key_value(), Some((5, 50)));
store.just_remove(&1);
store.just_remove(&5);
assert_eq!(store.first_key_value(), Some((2, 20)));
assert_eq!(store.last_key_value(), Some((4, 40)));
store.just_remove(&2);
store.just_remove(&4);
assert_eq!(store.first_key_value(), Some((3, 30)));
assert_eq!(store.last_key_value(), Some((3, 30)));
store.just_remove(&3);
assert_eq!(store.first_key_value(), None);
assert_eq!(store.last_key_value(), None);
}