extern crate alloc;
use alloc::vec::Vec;
use crate::metis::{Dot, DotSet, Extent, Retired, Verge};
use super::{Seq, clock, delete, insert, weave_at};
use crate::metis::dot::RawDot;
fn type_forward(replica: &mut Seq, station: u32, n: usize) -> Vec<Dot> {
let clk = clock(station);
let mut dots = Vec::new();
let mut caret = None;
for _ in 0..n {
let dot = insert(replica, &clk, station, caret);
dots.push(dot);
caret = Some(dot);
}
dots
}
#[test]
fn test_extent_covers_the_span_between_two_verges() {
let mut replica = Seq::new();
let d = type_forward(&mut replica, 1, 5); let store = replica.store();
assert_eq!(
store.extent(Verge::Before(d[1].into()), Verge::After(d[3].into())),
Extent::Covered([d[1], d[2], d[3]].into()),
);
assert_eq!(
store.extent(Verge::After(d[1].into()), Verge::Before(d[3].into())),
Extent::Covered([d[2]].into()),
);
assert_eq!(
store.extent(Verge::Origin, Verge::Terminus),
Extent::Covered(store.order()),
);
assert_eq!(
store.extent(Verge::Before(d[2].into()), Verge::After(d[2].into())),
Extent::Covered([d[2]].into()),
);
}
#[test]
fn test_an_empty_span_is_a_covered_verdict_not_an_error() {
let mut replica = Seq::new();
let d = type_forward(&mut replica, 1, 3);
assert_eq!(
replica
.store()
.extent(Verge::After(d[1].into()), Verge::Before(d[2].into())),
Extent::Covered(Vec::new()),
);
assert_eq!(
replica
.store()
.extent(Verge::After(d[1].into()), Verge::After(d[1].into())),
Extent::Covered(Vec::new()),
);
delete(&mut replica, d[1]);
assert_eq!(
replica
.store()
.extent(Verge::After(d[0].into()), Verge::Before(d[2].into())),
Extent::Covered(Vec::new()),
);
}
#[test]
fn test_edge_inserts_respect_the_sides() {
let mut replica = Seq::new();
let d = type_forward(&mut replica, 1, 2); let (a, b) = (d[0], d[1]);
let clk = clock(2);
let anchor = replica.store().anchor_for_visual_insert(Some(a.into()));
if let Some(top) = replica.store().children_of(anchor).next()
&& let Some(locus) = replica.store().locus(top)
{
clk.observe(locus.rank);
}
let x = weave_at(&mut replica, &clk, 2, anchor);
assert_eq!(replica.store().order(), [a, x, b]);
let store = replica.store();
assert!(matches!(
store.extent(Verge::After(a.into()), Verge::Terminus),
Extent::Covered(ref covered) if covered.contains(&x),
));
assert_eq!(
store.extent(Verge::Before(b.into()), Verge::Terminus),
Extent::Covered([b].into()),
);
assert_eq!(
store.extent(Verge::Origin, Verge::Before(b.into())),
Extent::Covered([a, x].into()),
);
assert_eq!(
store.extent(Verge::Origin, Verge::After(a.into())),
Extent::Covered([a].into()),
);
}
#[test]
fn test_a_deleted_boundary_element_still_bounds() {
let mut replica = Seq::new();
let d = type_forward(&mut replica, 1, 3);
delete(&mut replica, d[1]);
let store = replica.store();
assert_eq!(
store.extent(Verge::Before(d[1].into()), Verge::After(d[1].into())),
Extent::Covered(Vec::new()),
);
assert_eq!(
store.extent(Verge::After(d[0].into()), Verge::After(d[1].into())),
Extent::Covered(Vec::new()),
);
assert_eq!(
store.extent(Verge::After(d[1].into()), Verge::Terminus),
Extent::Covered([d[2]].into()),
);
}
#[test]
fn test_dangling_ends_are_surfaced() {
let mut replica = Seq::new();
let d = type_forward(&mut replica, 1, 2);
let unwoven = RawDot::new(7, 1);
assert_eq!(
replica
.store()
.extent(Verge::After(unwoven), Verge::Terminus),
Extent::Dangling {
start: true,
end: false,
},
);
assert_eq!(
replica
.store()
.extent(Verge::Origin, Verge::Before(unwoven)),
Extent::Dangling {
start: false,
end: true,
},
);
assert_eq!(
replica.store().extent(
Verge::After(RawDot {
station: 1,
counter: 0
}),
Verge::Before(unwoven)
),
Extent::Dangling {
start: true,
end: true,
},
);
assert!(matches!(
replica
.store()
.extent(Verge::Before(d[0].into()), Verge::After(d[1].into())),
Extent::Covered(_),
));
}
#[test]
fn test_condense_excision_dangles_the_verge() {
let mut replica = Seq::new();
let d = type_forward(&mut replica, 1, 3);
delete(&mut replica, d[2]);
let mut claim = DotSet::new();
assert!(claim.insert(d[2]));
let mut rhapsody = replica.store().clone();
assert_eq!(rhapsody.condense(&Retired::trust(claim)), 1);
let replica = crate::metis::Dotted::try_new(rhapsody, replica.context().clone()).unwrap();
assert_eq!(
replica
.store()
.extent(Verge::After(d[0].into()), Verge::Before(d[2].into())),
Extent::Dangling {
start: false,
end: true,
},
);
}
#[test]
fn test_inverted_ends_are_surfaced() {
let mut replica = Seq::new();
let d = type_forward(&mut replica, 1, 3); let store = replica.store();
assert_eq!(
store.extent(Verge::After(d[2].into()), Verge::After(d[0].into())),
Extent::Inverted,
);
assert_eq!(
store.extent(Verge::Before(d[1].into()), Verge::Before(d[0].into())),
Extent::Inverted,
);
assert_eq!(
store.extent(Verge::Terminus, Verge::Origin),
Extent::Inverted
);
assert_eq!(
store.extent(Verge::Before(d[0].into()), Verge::Origin),
Extent::Inverted,
);
assert_eq!(
store.extent(Verge::After(d[1].into()), Verge::Before(d[1].into())),
Extent::Inverted,
);
}
#[test]
fn test_overlap_is_a_derivation_over_extents() {
let mut replica = Seq::new();
let d = type_forward(&mut replica, 1, 5); let store = replica.store();
let left = store.extent(Verge::Before(d[0].into()), Verge::After(d[2].into()));
let mid = store.extent(Verge::Before(d[2].into()), Verge::After(d[4].into()));
let right = store.extent(Verge::Before(d[3].into()), Verge::After(d[4].into()));
let overlaps = |a: &Extent, b: &Extent| -> bool {
match (a.covered(), b.covered()) {
(Some(xs), Some(ys)) => xs.iter().any(|x| ys.contains(x)),
_ => false,
}
};
assert!(overlaps(&left, &mid), "c is under both");
assert!(!overlaps(&left, &right), "disjoint spans do not overlap");
}