minerva 0.2.0

Causal ordering for distributed systems
use crate::kairos::{DecodeError, Kairos};

#[test]
fn test_to_bytes_layout() {
    // physical=1, logical=2, kairotic=3, station_id=4. `new` takes station_id
    // before kairotic, hence new(1, 2, 4, 3). This pins the exact wire bytes:
    // version 0x01 then the big-endian payload in field-priority order.
    let k = Kairos::new(1, 2, 4, 3u16);
    let bytes = k.to_bytes();
    assert_eq!(
        bytes,
        [
            0x01, // version
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, // physical, u64 BE
            0x00, 0x02, // logical, u16 BE
            0x00, 0x03, // kairotic, u16 BE
            0x00, 0x00, 0x00, 0x04, // station_id, u32 BE
        ],
    );
    assert_eq!(Kairos::from_bytes(&bytes), Ok(k));
}

#[test]
fn test_from_bytes_rejects_unknown_version() {
    let mut frame = Kairos::new(1, 2, 3, 4u16).to_bytes();
    frame[0] = 0x02;
    assert_eq!(
        Kairos::from_bytes(&frame),
        Err(DecodeError::UnknownVersion(0x02)),
    );
}

#[test]
fn test_from_bytes_rejects_bad_length() {
    let frame = Kairos::new(1, 2, 3, 4u16).to_bytes();
    assert_eq!(
        Kairos::from_bytes(&frame[..16]),
        Err(DecodeError::UnexpectedLength {
            expected: 17,
            found: 16
        }),
    );
    let mut long = [0u8; 18];
    long[..17].copy_from_slice(&frame);
    assert_eq!(
        Kairos::from_bytes(&long),
        Err(DecodeError::UnexpectedLength {
            expected: 17,
            found: 18
        }),
    );
    assert_eq!(
        Kairos::from_bytes(&[]),
        Err(DecodeError::UnexpectedLength {
            expected: 17,
            found: 0
        }),
    );
}