minerva 0.2.0

Causal ordering for distributed systems
use crate::kairos::{KAIROS_WIRE_LEN, Kairos};
use crate::metis::{Anchor, Locus, Rhapsody};
use proptest::prelude::*;

use super::super::d;

/// Rhapsody frame header: one version byte plus a `u32` locus count.
const RHAPSODY_FRAME_HEADER_LEN: usize = 5;
/// Empty visible have-set frame: one version byte plus a zero station count.
const EMPTY_VISIBLE_FRAME_LEN: usize = 5;

proptest! {
    /// The byte-accounting law behind the studio's per-dot estimate: a rhapsody
    /// of `n` dot-anchored, visible elements costs the fixed overhead plus
    /// exactly 42 bytes per dot-anchored locus.
    #[test]
    fn prop_rhapsody_dot_anchored_locus_is_42_bytes(chain in 1usize..12) {
        let mut rhapsody = Rhapsody::new();
        let mut prev: Option<crate::metis::Dot> = None;
        for k in 1..=chain {
            let index = u64::try_from(k).unwrap_or(0);
            let rank = Kairos::new(index, 0u16, 1, 0u16);
            let anchor = prev.map_or(Anchor::Origin, |dot| Anchor::After(dot.into()));
            let locus = Locus { anchor, rank };
            let wove = rhapsody.weave(d(1, index), locus);
            prop_assert!(wove);
            prev = Some(d(1, index));
        }
        let bytes = rhapsody.to_bytes();
        let rhapsody_header = RHAPSODY_FRAME_HEADER_LEN;
        let visible_frame = EMPTY_VISIBLE_FRAME_LEN + 16;
        let origin_locus = 12 + 1 + KAIROS_WIRE_LEN;
        let dot_locus = 12 + 1 + 12 + KAIROS_WIRE_LEN;
        prop_assert_eq!(origin_locus, 30);
        prop_assert_eq!(dot_locus, 42);
        let expected =
            rhapsody_header + origin_locus + (chain - 1) * dot_locus + visible_frame;
        prop_assert_eq!(bytes.len(), expected);
    }
}