Add Clone to graph models, and tests
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
use crate::testing::fixtures::MakeTestGraph;
|
||||
use crate::traits::GraphTopologyAddition;
|
||||
|
||||
#[doc(hidden)]
|
||||
#[macro_export]
|
||||
macro_rules! graph_topology_addition_clone_tests {
|
||||
($T:ty) => {
|
||||
$crate::graph_topology_addition_clone_tests!(@wrap $T,
|
||||
clone_independent,
|
||||
);
|
||||
};
|
||||
|
||||
(@wrap $T:ty, $($name:ident),* $(,)?) => {
|
||||
$(
|
||||
#[test]
|
||||
fn $name() {
|
||||
$crate::testing::graph_topology_addition_clone_testing::$name::<$T>();
|
||||
}
|
||||
)*
|
||||
};
|
||||
}
|
||||
|
||||
pub fn clone_independent<G: Clone + GraphTopologyAddition>() {
|
||||
let (mut graph, [u, v], _) = G::single_edge();
|
||||
let mut clone = graph.clone();
|
||||
|
||||
let w = clone.add_vertex();
|
||||
clone.add_edge(u, w);
|
||||
assert_eq!(clone.vertex_count(), 3, "precondition: vertex count of clone");
|
||||
assert_eq!(clone.edge_count(), 2, "precondition: edge count of clone");
|
||||
assert_eq!(
|
||||
graph.vertex_count(),
|
||||
2,
|
||||
"mutating the clone should not affect the vertex count of the original"
|
||||
);
|
||||
assert_eq!(
|
||||
graph.edge_count(),
|
||||
1,
|
||||
"mutating the clone should not affect the edge count of the original"
|
||||
);
|
||||
|
||||
let x = graph.add_vertex();
|
||||
graph.add_edge(v, x);
|
||||
assert_eq!(graph.vertex_count(), 3, "precondition: vertex count of original");
|
||||
assert_eq!(graph.edge_count(), 2, "precondition: edge count of original");
|
||||
assert_eq!(
|
||||
clone.vertex_count(),
|
||||
3,
|
||||
"mutating the original should not affect the vertex count of the clone"
|
||||
);
|
||||
assert_eq!(
|
||||
clone.edge_count(),
|
||||
2,
|
||||
"mutating the original should not affect the edge count of the clone"
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
use std::fmt::Debug;
|
||||
|
||||
use crate::testing::fixtures::MakeTestGraph;
|
||||
|
||||
#[doc(hidden)]
|
||||
#[macro_export]
|
||||
macro_rules! graph_topology_clone_tests {
|
||||
($T:ty) => {
|
||||
$crate::graph_topology_clone_tests!(@wrap $T,
|
||||
clone_preserves_vertex_and_edge_count,
|
||||
clone_handles_interchangeable,
|
||||
);
|
||||
};
|
||||
|
||||
(@wrap $T:ty, $($name:ident),* $(,)?) => {
|
||||
$(
|
||||
#[test]
|
||||
fn $name() {
|
||||
$crate::testing::graph_topology_clone_testing::$name::<$T>();
|
||||
}
|
||||
)*
|
||||
};
|
||||
}
|
||||
|
||||
pub fn clone_preserves_vertex_and_edge_count<G: Clone + MakeTestGraph>() {
|
||||
let (graph, ..) = G::standard();
|
||||
let clone = graph.clone();
|
||||
assert_eq!(
|
||||
clone.vertex_count(),
|
||||
graph.vertex_count(),
|
||||
"clone should have the same vertex count as the original"
|
||||
);
|
||||
assert_eq!(
|
||||
clone.edge_count(),
|
||||
graph.edge_count(),
|
||||
"clone should have the same edge count as the original"
|
||||
);
|
||||
}
|
||||
|
||||
/// Queries the clone using vertex and edge handles obtained from the original graph, and asserts
|
||||
/// that the results are identical to querying the original with those same handles. This is only
|
||||
/// meaningful because Vertex and Edge handles are not tied to a particular graph instance.
|
||||
pub fn clone_handles_interchangeable<G: Clone + MakeTestGraph>()
|
||||
where
|
||||
G::Vertex: Debug,
|
||||
G::Edge: Debug,
|
||||
{
|
||||
let (graph, vertices, edges, _) = G::standard();
|
||||
let clone = graph.clone();
|
||||
for &v in vertices.iter() {
|
||||
assert_eq!(
|
||||
clone.degree(v),
|
||||
graph.degree(v),
|
||||
"vertex {v:?} should have the same degree in the clone as in the original"
|
||||
);
|
||||
let mut expected: Vec<_> = graph.incidences(v).collect();
|
||||
for incidence in clone.incidences(v) {
|
||||
let pos = expected
|
||||
.iter()
|
||||
.position(|x| *x == incidence)
|
||||
.expect(&format!(
|
||||
"unexpected incidence {incidence:?} of vertex {v:?} in the clone"
|
||||
));
|
||||
expected.swap_remove(pos);
|
||||
}
|
||||
assert!(
|
||||
expected.is_empty(),
|
||||
"expected incidences {expected:?} of vertex {v:?} are missing in the clone"
|
||||
);
|
||||
}
|
||||
for &(e, u, v) in edges.iter() {
|
||||
assert_eq!(
|
||||
clone.incident_vertices(e),
|
||||
(u, v),
|
||||
"edge {e:?} should have the same incident vertices in the clone as in the original"
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user