minerva 0.2.0

Causal ordering for distributed systems
use crate::metis::{Anchor, Locus, Rhapsody};

use super::super::d;
use super::rank;
use crate::metis::dot::RawDot;

#[test]
fn test_rhapsody_to_bytes_layout() {
    let mut rhapsody = Rhapsody::new();
    assert!(rhapsody.weave(
        d(1, 1),
        Locus {
            anchor: Anchor::Origin,
            rank: rank(7)
        }
    ));
    assert!(rhapsody.weave(
        d(1, 2),
        Locus {
            anchor: Anchor::After(RawDot {
                station: 1,
                counter: 1
            }),
            rank: rank(9),
        }
    ));
    let frame = rhapsody.to_bytes();
    assert_eq!(
        frame,
        [
            0x02, // version (v2)
            0x00, 0x00, 0x00, 0x02, // locus_count = 2
            // locus (1, 1): dot, origin anchor, rank physical 7
            0x00, 0x00, 0x00, 0x01, // station = 1
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, // index = 1
            0x00, // anchor tag = origin
            0x01, // rank version
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, // rank physical = 7
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, // rank station = 1
            // locus (1, 2): dot, after anchor (1, 1), rank physical 9
            0x00, 0x00, 0x00, 0x01, // station = 1
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, // index = 2
            0x01, // anchor tag = after
            0x00, 0x00, 0x00, 0x01, // anchor station = 1
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, // anchor index = 1
            0x01, // rank version
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, // rank physical = 9
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, // rank station = 1
            // trailing visible have-set frame: station 1, floor 2, no runs
            0x01, // have-set version
            0x00, 0x00, 0x00, 0x01, // station_count = 1
            0x00, 0x00, 0x00, 0x01, // station_id = 1
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, // floor = 2
            0x00, 0x00, 0x00, 0x00, // run_count = 0
        ]
    );
    assert_eq!(Rhapsody::from_bytes(&frame), Ok(rhapsody));
}

#[test]
fn test_rhapsody_before_anchor_round_trips() {
    let mut rhapsody = Rhapsody::new();
    assert!(rhapsody.weave(
        d(1, 1),
        Locus {
            anchor: Anchor::Origin,
            rank: rank(7)
        }
    ));
    assert!(rhapsody.weave(
        d(1, 2),
        Locus {
            anchor: Anchor::Before(RawDot {
                station: 1,
                counter: 1
            }),
            rank: rank(9),
        }
    ));
    let frame = rhapsody.to_bytes();
    assert_eq!(
        frame[47], 0x02,
        "the before-anchored locus carries tag 0x02"
    );
    assert_eq!(rhapsody.order(), [d(1, 2), d(1, 1)]);

    let decoded = Rhapsody::from_bytes(&frame).expect("a before-anchored frame decodes");
    assert_eq!(decoded, rhapsody);
    assert_eq!(decoded.to_bytes(), frame);
}