minerva 0.2.0

Causal ordering for distributed systems
extern crate alloc;

use super::{Doc, Op, SCRIBES, arb_ops, observed};
use crate::metis::{Composer, DotMap, DotSet, Dotted};
use alloc::vec::Vec;
use proptest::prelude::*;

proptest! {
    #[test]
    fn prop_every_returned_delta_is_covered(ops in arb_ops()) {
        let mut composers: Vec<Composer<Doc>> = (0..SCRIBES)
            .map(|i| Composer::new(u32::try_from(i).unwrap()))
            .collect();
        for op in &ops {
            let delta = match *op {
                Op::Add { composer, key } => {
                    composers[composer]
                        .compose(move |assigned| {
                            let mut held = DotSet::new();
                            let _ = held.insert(assigned);
                            (DotMap::singleton(key, held), DotSet::new())
                        })
                        .1
                }
                Op::Remove { composer, key } => {
                    let seen = observed(composers[composer].state(), key);
                    composers[composer].retract(seen)
                }
                Op::Gossip { from, to } => {
                    let delta = composers[from].owed_to(composers[to].state().context());
                    let station = u32::try_from(from).unwrap();
                    let _ = composers[to].absorb(station, &delta);
                    delta
                }
            };
            let rebuilt = Dotted::try_new(delta.store().clone(), delta.context().clone());
            prop_assert!(rebuilt.is_ok());
        }
    }
}