minerva 0.2.0

Causal ordering for distributed systems
use super::super::super::support::{arb_history, perm_of};
use super::{arb_dots, have, is_genuine_cut};
use crate::metis::{CausalIdeal, Cut, Purview, Received, VersionVector};
use proptest::prelude::*;

proptest! {
    #[test]
    fn prop_floor_of_is_a_genuine_cut(dots in arb_dots()) {
        let have = have(&dots);
        let cut = Cut::floor_of(&have);

        prop_assert!(is_genuine_cut(&cut));
        prop_assert_eq!(cut.as_vector(), &have.floor());
    }

    #[test]
    fn prop_delivered_by_is_a_genuine_cut(
        (history, order, take) in arb_history().prop_flat_map(|h| {
            let len = h.len();
            (Just(h), perm_of(len), 0..=len)
        }),
    ) {
        let mut buffer: CausalIdeal<u32> = CausalIdeal::new();
        for &index in &order {
            buffer.insert(history[index].clone());
        }
        for _ in 0..take {
            if buffer.pop_ready().is_none() {
                break;
            }
        }

        let cut = Cut::delivered_by(&buffer);
        prop_assert!(is_genuine_cut(&cut));
        prop_assert_eq!(cut.as_vector(), buffer.delivered());
    }

    #[test]
    fn prop_common_of_is_a_genuine_cut(
        notes in prop::collection::vec(
            (1u32..=4, prop::collection::vec((1u32..=4, 1u64..6), 0..6)),
            0..16,
        ),
    ) {
        let mut view = Purview::new([1u32, 2, 3, 4]);
        for (peer, evidence) in &notes {
            view.note(&Received::trust(*peer, have(evidence))).unwrap();
        }

        let cut = Cut::common_of(&view);
        prop_assert!(is_genuine_cut(&cut));
        prop_assert_eq!(cut.as_vector(), &view.common_floor());
    }

    #[test]
    fn prop_bottom_is_a_genuine_cut(_seed in 0u8..1) {
        let bottom = Cut::bottom();
        prop_assert!(is_genuine_cut(&bottom));
        prop_assert_eq!(bottom.as_vector(), &VersionVector::new());
    }
}