extern crate alloc;
use alloc::vec::Vec;
use super::super::d;
use super::{Seq, clock, insert, woven};
use crate::metis::dot::RawDot;
use crate::metis::{Anchor, Dot, DotSet, Dotted, Locus, Rhapsody};
fn delete(replica: &mut Seq, victim: Dot) {
let mut ctx = DotSet::new();
let _ = ctx.insert(victim);
*replica = replica.merge(&Dotted::from_context(ctx));
}
fn suffix_of(seq: &Seq, at: Dot) -> Vec<Dot> {
seq.store()
.order_walk_after(at)
.expect("a placed element resumes")
.collect()
}
#[test]
fn test_walk_after_yields_the_order_suffix_at_every_slot() {
let clk = clock(1);
let mut seq = Seq::new();
let a = insert(&mut seq, &clk, 1, None);
let b = insert(&mut seq, &clk, 1, Some(a));
let c = insert(&mut seq, &clk, 1, Some(b));
let order = seq.store().order();
assert_eq!(order, alloc::vec![a, b, c]);
assert_eq!(suffix_of(&seq, a), alloc::vec![b, c]);
assert_eq!(suffix_of(&seq, b), alloc::vec![c]);
assert_eq!(suffix_of(&seq, c), Vec::new());
}
#[test]
fn test_walk_takes_a_window_without_reading_the_document() {
let clk = clock(1);
let mut seq = Seq::new();
let mut prev = None;
let mut dots = Vec::new();
for _ in 0..10 {
let dot = insert(&mut seq, &clk, 1, prev);
dots.push(dot);
prev = Some(dot);
}
let order = seq.store().order();
let front: Vec<Dot> = seq.store().order_walk().take(3).collect();
assert_eq!(front, order[..3]);
let window: Vec<Dot> = seq
.store()
.order_walk_after(dots[3])
.expect("a placed element resumes")
.take(3)
.collect();
assert_eq!(window, order[4..7]);
}
#[test]
fn test_walk_resumes_after_an_order_tombstone() {
let clk = clock(1);
let mut seq = Seq::new();
let a = insert(&mut seq, &clk, 1, None);
let b = insert(&mut seq, &clk, 1, Some(a));
let c = insert(&mut seq, &clk, 1, Some(b));
delete(&mut seq, b);
assert_eq!(seq.store().order(), alloc::vec![a, c]);
assert_eq!(suffix_of(&seq, b), alloc::vec![c]);
assert_eq!(suffix_of(&seq, a), alloc::vec![c]);
}
#[test]
fn test_walk_resumes_through_before_anchors() {
let clk = clock(1);
let mut seq = Seq::new();
let x = seq.next_dot(1);
seq = seq.merge(&woven(
x,
Locus {
anchor: Anchor::Origin,
rank: clk.now(0u16),
},
));
let y = seq.next_dot(1);
seq = seq.merge(&woven(
y,
Locus {
anchor: Anchor::Before(x.into()),
rank: clk.now(0u16),
},
));
let z = seq.next_dot(1);
seq = seq.merge(&woven(
z,
Locus {
anchor: Anchor::Before(y.into()),
rank: clk.now(0u16),
},
));
let w = seq.next_dot(1);
seq = seq.merge(&woven(
w,
Locus {
anchor: Anchor::After(x.into()),
rank: clk.now(0u16),
},
));
let order = seq.store().order();
assert_eq!(order, alloc::vec![z, y, x, w]);
assert_eq!(suffix_of(&seq, z), alloc::vec![y, x, w]);
assert_eq!(suffix_of(&seq, y), alloc::vec![x, w]);
assert_eq!(suffix_of(&seq, x), alloc::vec![w]);
assert_eq!(suffix_of(&seq, w), Vec::new());
}
#[test]
fn test_walk_refuses_a_dot_with_no_place() {
let clk = clock(1);
let mut seq = Seq::new();
let a = insert(&mut seq, &clk, 1, None);
assert!(seq.store().order_walk_after(d(1, 99)).is_none());
assert!(Dot::from_parts(1, 0).is_err());
assert!(seq.store().order_walk_after(d(7, 1)).is_none());
let mut bare = Rhapsody::new();
assert!(bare.weave(
d(2, 1),
Locus {
anchor: Anchor::After(RawDot {
station: 9,
counter: 9
}),
rank: clock(2).now(0u16),
},
));
let mut ctx = DotSet::new();
let _ = ctx.insert(d(2, 1));
seq = seq.merge(&Dotted::try_new(bare, ctx).unwrap());
assert!(!seq.store().is_reachable(d(2, 1)));
assert!(seq.store().order_walk_after(d(2, 1)).is_none());
let mut incremental = Seq::new();
incremental.merge_from(&seq);
assert!(!incremental.store().is_reachable(d(2, 1)));
assert!(incremental.store().order_walk_after(d(2, 1)).is_none());
let mut repair = Rhapsody::new();
assert!(repair.weave(
d(9, 9),
Locus {
anchor: Anchor::After(a.into()),
rank: clock(9).now(0u16),
},
));
let mut repair_ctx = DotSet::new();
let _ = repair_ctx.insert(d(9, 9));
seq = seq.merge(&Dotted::try_new(repair, repair_ctx).unwrap());
assert!(seq.store().is_reachable(d(2, 1)));
assert_eq!(suffix_of(&seq, a), alloc::vec![d(9, 9), d(2, 1)]);
assert_eq!(suffix_of(&seq, d(9, 9)), alloc::vec![d(2, 1)]);
assert_eq!(suffix_of(&seq, d(2, 1)), Vec::new());
let mut incremental = Seq::new();
incremental.merge_from(&seq);
assert!(incremental.store().is_reachable(d(2, 1)));
assert_eq!(suffix_of(&incremental, d(9, 9)), alloc::vec![d(2, 1)]);
}