minerva 0.2.0

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

use super::super::super::d;
use super::super::{Seq, clock, delete, woven};
use crate::metis::dot::RawDot;

#[test]
fn test_is_reachable_tracks_the_anchor_chain() {
    // `is_reachable` walks UP the anchor chain to the origin. A dangling child
    // is unreachable until its anchor arrives; a deleted-but-placed dot stays
    // reachable; a never-woven dot is unreachable. The non-dot 0 no longer
    // reaches this door: the identity type carries the law (ruling R-91).
    let clk = clock(1);
    let mut r: Seq = Dotted::new();

    // Child (1, 2) anchored to the not-yet-woven (1, 1): dangling, unreachable.
    let child_rank = clk.now(0u16);
    let anchor_rank = clk.now(0u16);
    r = r.merge(&woven(
        d(1, 2),
        Locus {
            anchor: Anchor::After(RawDot {
                station: 1,
                counter: 1,
            }),
            rank: child_rank,
        },
    ));
    assert!(
        !r.store().is_reachable(d(1, 2)),
        "dangling child is unreachable"
    );
    assert!(
        !r.store().is_reachable(d(1, 1)),
        "the missing anchor has no locus"
    );
    assert!(
        !r.store().is_reachable(d(1, 99)),
        "a never-woven dot is unreachable"
    );
    assert!(
        Dot::from_parts(1, 0).is_err(),
        "the non-dot 0 is no longer an identity to ask about"
    );

    // The anchor arrives at the origin: now the chain reaches it.
    r = r.merge(&woven(
        d(1, 1),
        Locus {
            anchor: Anchor::Origin,
            rank: anchor_rank,
        },
    ));
    assert!(r.store().is_reachable(d(1, 1)));
    assert!(
        r.store().is_reachable(d(1, 2)),
        "repaired: the chain reaches the origin"
    );

    // Deleting (1, 2) leaves it placed (a tombstone), so still reachable.
    delete(&mut r, d(1, 2));
    assert!(!r.store().is_visible(d(1, 2)));
    assert!(
        r.store().is_reachable(d(1, 2)),
        "a placed tombstone stays reachable"
    );
}