minerva 0.2.0

Causal ordering for distributed systems
use super::{arb_dots, have};
use crate::metis::DotSet;
use proptest::prelude::*;

proptest! {
    #[test]
    fn prop_have_set_from_bytes_never_panics(
        bytes in prop::collection::vec(any::<u8>(), 0..96),
    ) {
        if let Ok(set) = DotSet::from_bytes(&bytes) {
            let reencoded = set.to_bytes();
            prop_assert_eq!(&reencoded, &bytes);
        }
        if let Ok((set, tail)) = DotSet::from_prefix(&bytes) {
            let consumed = bytes.len() - tail.len();
            let reencoded = set.to_bytes();
            prop_assert_eq!(reencoded.as_slice(), &bytes[..consumed]);
        }
    }

    #[test]
    fn prop_have_set_truncation_never_panics(dots in arb_dots(), keep in any::<usize>()) {
        let bytes = have(&dots).to_bytes();
        let cut = keep % (bytes.len() + 1);
        let prefix = &bytes[..cut];
        if let Ok(set) = DotSet::from_bytes(prefix) {
            let reencoded = set.to_bytes();
            prop_assert_eq!(reencoded.as_slice(), prefix);
        }
        if let Ok((set, tail)) = DotSet::from_prefix(prefix) {
            let consumed = prefix.len() - tail.len();
            let reencoded = set.to_bytes();
            prop_assert_eq!(reencoded.as_slice(), &prefix[..consumed]);
        }
    }

    #[test]
    fn prop_have_set_flip_byte_stays_total(
        dots in arb_dots(),
        offset in any::<usize>(),
        xor in 1u8..=u8::MAX,
    ) {
        let mut bytes = have(&dots).to_bytes();
        let len = bytes.len();
        bytes[offset % len] ^= xor;
        if let Ok(set) = DotSet::from_bytes(&bytes) {
            let reencoded = set.to_bytes();
            prop_assert_eq!(&reencoded, &bytes);
        }
    }
}