minerva 0.2.0

Causal ordering for distributed systems
use crate::metis::Rhapsody;
use proptest::prelude::*;

use super::{arb_weaves, build};

proptest! {
    /// Encode-decode identity: `from_bytes(to_bytes(w)) == w` for every generated
    /// rhapsody.
    #[test]
    fn prop_rhapsody_bytes_round_trip(weaves in arb_weaves()) {
        let rhapsody = build(&weaves);
        prop_assert_eq!(Rhapsody::from_bytes(&rhapsody.to_bytes()), Ok(rhapsody));
    }

    /// Decode-encode identity: every accepted frame re-encodes to exactly its own
    /// bytes, and `from_prefix` consumes exactly the frame with an empty tail.
    #[test]
    fn prop_rhapsody_decode_then_encode_is_identity(weaves in arb_weaves()) {
        let bytes = build(&weaves).to_bytes();
        let (decoded, tail) = Rhapsody::from_prefix(&bytes).expect("own frame decodes");
        prop_assert!(tail.is_empty());
        prop_assert_eq!(decoded.to_bytes(), bytes);
    }

    /// Canonical: equal rhapsodies encode to equal bytes. We reverse the history;
    /// when both builds land on the same value, byte equality must follow.
    #[test]
    fn prop_rhapsody_bytes_are_canonical(weaves in arb_weaves()) {
        let forward = build(&weaves);
        let mut reversed = weaves;
        reversed.reverse();
        let backward = build(&reversed);
        if forward == backward {
            prop_assert_eq!(forward.to_bytes(), backward.to_bytes());
        }
    }
}