194 lines
5.6 KiB
Rust
194 lines
5.6 KiB
Rust
use std::fmt::Debug;
|
|
|
|
use crate::traits::GraphTopologyAddition;
|
|
|
|
#[doc(hidden)]
|
|
#[macro_export]
|
|
macro_rules! graph_topology_addition_tests {
|
|
($T:ty) => {
|
|
$crate::graph_topology_addition_tests!(@wrap $T,
|
|
reserve_vertices_increases_capacity,
|
|
reserve_vertices_prevents_reallocation_on_add,
|
|
reserve_vertices_does_not_affect_edge_capacity,
|
|
reserve_edges_increases_capacity,
|
|
reserve_edges_prevents_reallocation_on_add,
|
|
reserve_edges_does_not_affect_vertex_capacity,
|
|
add_vertex,
|
|
add_edge,
|
|
sync_vertex_map_after_add,
|
|
sync_edge_map_after_add,
|
|
sync_vertex_map_preserves_values,
|
|
sync_edge_map_preserves_values,
|
|
);
|
|
};
|
|
|
|
(@wrap $T:ty, $($name:ident),* $(,)?) => {
|
|
$(
|
|
#[test]
|
|
fn $name() {
|
|
$crate::testing::graph_topology_addition_testing::$name::<$T>();
|
|
}
|
|
)*
|
|
};
|
|
}
|
|
|
|
pub fn reserve_vertices_increases_capacity<G: GraphTopologyAddition>() {
|
|
let mut graph = G::default();
|
|
let capacity_before = graph.vertex_capacity();
|
|
graph.reserve_vertices(capacity_before + 10);
|
|
assert!(
|
|
graph.vertex_capacity() > capacity_before,
|
|
"expected sufficient capacity increase after reserve"
|
|
);
|
|
}
|
|
|
|
pub fn reserve_vertices_prevents_reallocation_on_add<G: GraphTopologyAddition>() {
|
|
const N: usize = 10;
|
|
let mut graph = G::default();
|
|
graph.reserve_vertices(N);
|
|
let capacity_before = graph.vertex_capacity();
|
|
for _ in 0..N {
|
|
graph.add_vertex();
|
|
}
|
|
assert_eq!(
|
|
graph.vertex_capacity(),
|
|
capacity_before,
|
|
"writes within reserved capacity should not reallocate"
|
|
);
|
|
}
|
|
|
|
pub fn reserve_vertices_does_not_affect_edge_capacity<G: GraphTopologyAddition>() {
|
|
let mut graph = G::default();
|
|
let capacity_before = graph.edge_capacity();
|
|
graph.reserve_vertices(10);
|
|
assert_eq!(
|
|
graph.edge_capacity(),
|
|
capacity_before,
|
|
"reserve_vertices must not change edge capacity"
|
|
);
|
|
}
|
|
|
|
pub fn reserve_edges_increases_capacity<G: GraphTopologyAddition>() {
|
|
let mut graph = G::default();
|
|
let capacity_before = graph.edge_capacity();
|
|
graph.reserve_edges(capacity_before + 10);
|
|
assert!(
|
|
graph.edge_capacity() > capacity_before,
|
|
"expected sufficient capacity increase after reserve"
|
|
);
|
|
}
|
|
|
|
pub fn reserve_edges_prevents_reallocation_on_add<G: GraphTopologyAddition>() {
|
|
const N: usize = 10;
|
|
let mut graph = G::default();
|
|
let u = graph.add_vertex();
|
|
let v = graph.add_vertex();
|
|
graph.reserve_edges(N);
|
|
let capacity_before = graph.edge_capacity();
|
|
for _ in 0..N {
|
|
graph.add_edge(u, v);
|
|
}
|
|
assert_eq!(
|
|
graph.edge_capacity(),
|
|
capacity_before,
|
|
"writes within reserved capacity should not reallocate"
|
|
);
|
|
}
|
|
|
|
pub fn reserve_edges_does_not_affect_vertex_capacity<G: GraphTopologyAddition>() {
|
|
let mut graph = G::default();
|
|
let capacity_before = graph.vertex_capacity();
|
|
graph.reserve_edges(10);
|
|
assert_eq!(
|
|
graph.vertex_capacity(),
|
|
capacity_before,
|
|
"reserve_edges must not change vertex capacity"
|
|
);
|
|
}
|
|
|
|
pub fn add_vertex<G: GraphTopologyAddition>()
|
|
where
|
|
G::Vertex: Debug,
|
|
{
|
|
let mut graph = G::default();
|
|
let v = graph.add_vertex();
|
|
assert_ne!(graph.add_vertex(), v, "unexpected duplicate vertex");
|
|
}
|
|
|
|
pub fn add_edge<G: GraphTopologyAddition>()
|
|
where
|
|
G::Edge: Debug,
|
|
{
|
|
let mut graph = G::default();
|
|
let u = graph.add_vertex();
|
|
let v = graph.add_vertex();
|
|
let e = graph.add_edge(u, v);
|
|
assert_ne!(graph.add_edge(u, v), e, "unexpected duplicate edge");
|
|
}
|
|
|
|
pub fn sync_vertex_map_after_add<G: GraphTopologyAddition>() {
|
|
let mut graph = G::default();
|
|
let mut map = graph.vertex_map(27);
|
|
let u = graph.add_vertex();
|
|
let v = graph.add_vertex();
|
|
graph.sync_vertex_map(&mut map);
|
|
assert_eq!(
|
|
map[u], 27,
|
|
"unexpected value from default map read for new vertex"
|
|
);
|
|
map[u] = 9;
|
|
assert_eq!(
|
|
map[u], 9,
|
|
"unexpected value from map read after write for new vertex"
|
|
);
|
|
assert_eq!(
|
|
map[v], 27,
|
|
"unexpected value from default map read for second new vertex"
|
|
);
|
|
}
|
|
|
|
pub fn sync_edge_map_after_add<G: GraphTopologyAddition>() {
|
|
let mut graph = G::default();
|
|
let u = graph.add_vertex();
|
|
let v = graph.add_vertex();
|
|
let mut map = graph.edge_map(28);
|
|
let e = graph.add_edge(u, v);
|
|
let f = graph.add_edge(u, v);
|
|
graph.sync_edge_map(&mut map);
|
|
assert_eq!(
|
|
map[e], 28,
|
|
"unexpected value from default map read for new edge"
|
|
);
|
|
map[e] = 8;
|
|
assert_eq!(
|
|
map[e], 8,
|
|
"unexpected value from map read after write for new edge"
|
|
);
|
|
assert_eq!(
|
|
map[f], 28,
|
|
"unexpected value from default map read for second new edge"
|
|
);
|
|
}
|
|
|
|
pub fn sync_vertex_map_preserves_values<G: GraphTopologyAddition>() {
|
|
let mut graph = G::default();
|
|
let v = graph.add_vertex();
|
|
let mut map = graph.vertex_map(0);
|
|
map[v] = 5;
|
|
graph.reserve_vertices(20);
|
|
graph.sync_vertex_map(&mut map);
|
|
assert_eq!(map[v], 5, "sync should not change existing map values");
|
|
}
|
|
|
|
pub fn sync_edge_map_preserves_values<G: GraphTopologyAddition>() {
|
|
let mut graph = G::default();
|
|
let u = graph.add_vertex();
|
|
let v = graph.add_vertex();
|
|
let e = graph.add_edge(u, v);
|
|
let mut map = graph.edge_map(0);
|
|
map[e] = 6;
|
|
graph.reserve_edges(20);
|
|
graph.sync_edge_map(&mut map);
|
|
assert_eq!(map[e], 6, "sync should not change existing map values");
|
|
}
|