use petgraph::{csr::IndexType, graph::NodeIndex, Graph};
use crate::{
BoundedDiGraph, BoundedGraph, BoundedGraphError, BoundedUnGraph, EdgeBounds, SimpleEdgeBounds,
SymmetricFixedEdgeCount,
};
#[test]
fn test_deref_and_asref() {
#[derive(Debug, Default)]
pub struct TestNode {
name: String,
max_edges: usize,
}
impl TestNode {
pub fn new(name: String, max_edges: usize) -> Self {
Self { name, max_edges }
}
}
impl<Ix: IndexType> EdgeBounds<Ix> for TestNode {
fn max_incoming_edges(&self) -> Ix {
Ix::new(self.max_edges)
}
fn max_outgoing_edges(&self) -> Ix {
Ix::new(self.max_edges)
}
}
impl SimpleEdgeBounds for TestNode {}
let mut graph = BoundedGraph::<TestNode, &str>::new();
let n1 = graph.add_node(TestNode::new("node1".to_string(), 2));
let n2 = graph.add_node(TestNode::new("node2".to_string(), 2));
let n3 = graph.add_node(TestNode::new("node3".to_string(), 2));
graph.add_edge(n1, n2, "edge1").unwrap();
graph.add_edge(n2, n3, "edge2").unwrap();
assert_eq!(graph.node_count(), 3);
assert_eq!(graph.edge_count(), 2);
assert!(graph.contains_edge(n1, n2));
assert!(graph.contains_edge(n2, n3));
assert!(!graph.contains_edge(n1, n3));
assert_eq!(graph.node_weight(n1).unwrap().name, "node1");
assert_eq!(graph.neighbors(n2).count(), 1);
fn count_edges<N, E, Ty, Ix>(g: &impl AsRef<Graph<N, E, Ty, Ix>>) -> usize
where
Ty: petgraph::EdgeType,
Ix: IndexType,
{
g.as_ref().edge_count()
}
assert_eq!(count_edges(&graph), 2);
}
#[test]
fn test_inner() {
use crate::FixedEdgeCount;
let mut graph = BoundedGraph::<FixedEdgeCount<3>, i32>::new();
let n1 = graph.add_node(FixedEdgeCount::empty());
let n2 = graph.add_node(FixedEdgeCount::empty());
let e = graph.add_edge(n1, n2, 42).unwrap();
let inner = graph.inner();
assert_eq!(inner.node_count(), 2);
assert_eq!(inner.edge_count(), 1);
assert_eq!(*inner.edge_weight(e).unwrap(), 42);
assert!(inner.contains_edge(n1, n2));
assert!(!inner.contains_edge(n2, n1));
let inner_graph = graph.into_inner();
assert_eq!(inner_graph.node_count(), 2);
assert_eq!(inner_graph.edge_count(), 1);
}
#[test]
fn test_type_aliases() {
let mut digraph = BoundedDiGraph::<SymmetricFixedEdgeCount<2>, ()>::new();
let n1 = digraph.add_node(SymmetricFixedEdgeCount::empty());
let n2 = digraph.add_node(SymmetricFixedEdgeCount::empty());
digraph.add_edge(n1, n2, ()).unwrap();
assert_eq!(digraph.node_count(), 2);
assert_eq!(digraph.edge_count(), 1);
assert!(digraph.is_directed());
let mut ungraph = BoundedUnGraph::<SymmetricFixedEdgeCount<2>, ()>::new();
let n1 = ungraph.add_node(SymmetricFixedEdgeCount::empty());
let n2 = ungraph.add_node(SymmetricFixedEdgeCount::empty());
ungraph.add_edge(n1, n2, ()).unwrap();
assert_eq!(ungraph.node_count(), 2);
assert_eq!(ungraph.edge_count(), 1);
assert!(!ungraph.is_directed());
}
#[test]
fn test_update_edge_error_handling() {
let mut graph = BoundedGraph::<SymmetricFixedEdgeCount<1>, &str>::new();
let n1 = graph.add_node(SymmetricFixedEdgeCount::empty());
let n2 = graph.add_node(SymmetricFixedEdgeCount::empty());
let n3 = graph.add_node(SymmetricFixedEdgeCount::empty());
assert!(graph.add_edge(n1, n2, "edge1").is_ok());
assert!(graph.update_edge(n1, n2, "updated").is_ok());
assert_eq!(graph.edge_count(), 1);
let result = graph.update_edge(n1, n3, "edge2");
assert!(result.is_err());
assert!(matches!(
result.unwrap_err(),
BoundedGraphError::EdgeRejected {
source_rejected: true,
target_rejected: false,
..
}
));
assert_eq!(graph.edge_count(), 1);
assert!(!graph.contains_edge(n1, n3));
let result = graph.add_edge(n1, n3, "edge3");
assert!(result.is_err());
assert_eq!(graph.edge_count(), 1);
}
#[test]
fn test_no_panic_on_capacity_errors() {
let mut graph = BoundedGraph::<SymmetricFixedEdgeCount<0>, ()>::new();
let n1 = graph.add_node(SymmetricFixedEdgeCount::empty());
let n2 = graph.add_node(SymmetricFixedEdgeCount::empty());
let result = graph.add_edge(n1, n2, ());
assert!(result.is_err());
assert!(matches!(
result.unwrap_err(),
BoundedGraphError::EdgeRejected {
source_rejected: true,
target_rejected: true,
..
}
));
let result = graph.update_edge(n1, n2, ());
assert!(result.is_err());
assert_eq!(graph.edge_count(), 0);
assert_eq!(graph.node_count(), 2);
}
#[test]
fn test_can_add_edge_invalid_nodes() {
let mut graph = BoundedGraph::<SymmetricFixedEdgeCount<2>, ()>::new();
let n1 = graph.add_node(SymmetricFixedEdgeCount::empty());
let n2 = graph.add_node(SymmetricFixedEdgeCount::empty());
assert!(graph.can_add_edge(n1, n2));
let invalid = NodeIndex::new(999);
assert!(!graph.can_add_edge(invalid, n2));
assert!(!graph.can_add_edge(n1, invalid));
assert!(!graph.can_add_edge(invalid, invalid));
graph.add_edge(n1, n2, ()).unwrap();
assert!(graph.can_add_edge(n1, n2)); }
#[test]
fn test_try_extend_with_edges_success() {
let mut graph = BoundedGraph::<SymmetricFixedEdgeCount<3>, i32>::new();
let _ = graph.add_node(SymmetricFixedEdgeCount::empty());
let _ = graph.add_node(SymmetricFixedEdgeCount::empty());
let _ = graph.add_node(SymmetricFixedEdgeCount::empty());
let edges = vec![(0u32, 1u32, 10), (1u32, 2u32, 20), (2u32, 0u32, 30)];
let result = graph.try_extend_with_edges(&edges);
assert!(result.is_ok());
let added = result.unwrap();
assert_eq!(added.len(), 3);
assert_eq!(graph.edge_count(), 3);
assert_eq!(*graph.edge_weight(added[0]).unwrap(), 10);
assert_eq!(*graph.edge_weight(added[1]).unwrap(), 20);
assert_eq!(*graph.edge_weight(added[2]).unwrap(), 30);
}
#[test]
fn test_try_extend_with_edges_partial_success() {
#[derive(Debug, Default)]
pub struct TestNode {
max_edges: usize,
}
impl<Ix: IndexType> EdgeBounds<Ix> for TestNode {
fn max_incoming_edges(&self) -> Ix {
Ix::new(self.max_edges)
}
fn max_outgoing_edges(&self) -> Ix {
Ix::new(self.max_edges)
}
}
impl SimpleEdgeBounds for TestNode {}
let mut graph = BoundedGraph::<TestNode, i32>::new();
let _ = graph.add_node(TestNode { max_edges: 2 }); let _ = graph.add_node(TestNode { max_edges: 5 });
let _ = graph.add_node(TestNode { max_edges: 5 });
let edges = vec![(0u32, 1u32, 10), (0u32, 2u32, 20), (0u32, 1u32, 30)];
let result = graph.try_extend_with_edges(&edges);
assert!(result.is_err());
let (added, err) = result.unwrap_err();
assert_eq!(added.len(), 2);
assert_eq!(graph.edge_count(), 2);
assert!(matches!(
err,
BoundedGraphError::EdgeRejected {
source_rejected: true,
target_rejected: false,
..
}
));
assert_eq!(*graph.edge_weight(added[0]).unwrap(), 10);
assert_eq!(*graph.edge_weight(added[1]).unwrap(), 20);
}
#[test]
fn test_try_extend_with_edges_immediate_failure() {
#[derive(Debug, Default)]
pub struct TestNode {
max_edges: usize,
}
impl<Ix: IndexType> EdgeBounds<Ix> for TestNode {
fn max_incoming_edges(&self) -> Ix {
Ix::new(self.max_edges)
}
fn max_outgoing_edges(&self) -> Ix {
Ix::new(self.max_edges)
}
}
impl SimpleEdgeBounds for TestNode {}
let mut graph = BoundedGraph::<TestNode, i32>::new();
let _ = graph.add_node(TestNode { max_edges: 0 }); let _ = graph.add_node(TestNode { max_edges: 5 });
let edges = vec![(0u32, 1u32, 10), (1u32, 0u32, 20)];
let result = graph.try_extend_with_edges(&edges);
assert!(result.is_err());
let (added, err) = result.unwrap_err();
assert_eq!(added.len(), 0);
assert_eq!(graph.edge_count(), 0);
assert!(matches!(
err,
BoundedGraphError::EdgeRejected {
source_rejected: true,
target_rejected: false,
..
}
));
}
#[test]
fn test_try_extend_with_edges_creates_nodes() {
#[derive(Debug)]
pub struct TestNode {
max_edges: usize,
}
impl Default for TestNode {
fn default() -> Self {
Self { max_edges: 10 } }
}
impl<Ix: IndexType> EdgeBounds<Ix> for TestNode {
fn max_incoming_edges(&self) -> Ix {
Ix::new(self.max_edges)
}
fn max_outgoing_edges(&self) -> Ix {
Ix::new(self.max_edges)
}
}
impl SimpleEdgeBounds for TestNode {}
let mut graph = BoundedGraph::<TestNode, i32>::new();
assert_eq!(graph.node_count(), 0);
let edges = vec![(0u32, 1u32, 10), (1u32, 2u32, 20)];
let result = graph.try_extend_with_edges(&edges);
assert!(result.is_ok());
assert_eq!(graph.node_count(), 3); assert_eq!(graph.edge_count(), 2);
}
#[test]
fn test_try_extend_with_edges_empty() {
#[derive(Debug, Default)]
pub struct TestNode {
max_edges: usize,
}
impl<Ix: IndexType> EdgeBounds<Ix> for TestNode {
fn max_incoming_edges(&self) -> Ix {
Ix::new(self.max_edges)
}
fn max_outgoing_edges(&self) -> Ix {
Ix::new(self.max_edges)
}
}
impl SimpleEdgeBounds for TestNode {}
let mut graph = BoundedGraph::<TestNode, i32>::new();
let edges: Vec<(u32, u32, i32)> = vec![];
let result = graph.try_extend_with_edges(&edges);
assert!(result.is_ok());
let added = result.unwrap();
assert_eq!(added.len(), 0);
assert_eq!(graph.edge_count(), 0);
}
#[test]
fn test_add_edge_error_variants() {
#[derive(Debug, Default)]
pub struct TestNode {
max_in: usize,
max_out: usize,
}
impl<Ix: IndexType> EdgeBounds<Ix> for TestNode {
fn max_incoming_edges(&self) -> Ix {
Ix::new(self.max_in)
}
fn max_outgoing_edges(&self) -> Ix {
Ix::new(self.max_out)
}
}
impl SimpleEdgeBounds for TestNode {}
let mut graph = BoundedGraph::<TestNode, ()>::new();
let n1 = graph.add_node(TestNode {
max_in: 2,
max_out: 1,
});
let n2 = graph.add_node(TestNode {
max_in: 1,
max_out: 2,
});
let n3 = graph.add_node(TestNode {
max_in: 0,
max_out: 0,
});
let n4 = graph.add_node(TestNode {
max_in: 2,
max_out: 2,
});
assert!(graph.add_edge(n1, n2, ()).is_ok());
let result = graph.add_edge(n1, n4, ());
assert!(result.is_err());
assert!(matches!(
result.unwrap_err(),
BoundedGraphError::EdgeRejected {
source_rejected: true,
target_rejected: false,
..
}
));
let result = graph.add_edge(n4, n2, ());
assert!(result.is_err());
assert!(matches!(
result.unwrap_err(),
BoundedGraphError::EdgeRejected {
source_rejected: false,
target_rejected: true,
..
}
));
let result = graph.add_edge(n3, n3, ());
assert!(result.is_err());
assert!(matches!(
result.unwrap_err(),
BoundedGraphError::EdgeRejected {
source_rejected: true,
target_rejected: true,
..
}
));
let invalid = NodeIndex::new(999);
let result = graph.add_edge(n1, invalid, ());
assert!(result.is_err());
assert!(matches!(
result.unwrap_err(),
BoundedGraphError::NodeNotFound {
source: Some(_),
target: None
}
));
let result = graph.add_edge(invalid, n1, ());
assert!(result.is_err());
assert!(matches!(
result.unwrap_err(),
BoundedGraphError::NodeNotFound {
source: None,
target: Some(_)
}
));
}
#[test]
fn test_from_edges() {
let edges = vec![(0, 1), (1, 2), (2, 0), (0, 2)];
let graph = BoundedGraph::<SymmetricFixedEdgeCount<5>, ()>::from_edges(&edges);
assert_eq!(graph.node_count(), 3);
assert_eq!(graph.edge_count(), 4);
assert!(graph.contains_edge(NodeIndex::new(0), NodeIndex::new(1)));
assert!(graph.contains_edge(NodeIndex::new(1), NodeIndex::new(2)));
assert!(graph.contains_edge(NodeIndex::new(2), NodeIndex::new(0)));
assert!(graph.contains_edge(NodeIndex::new(0), NodeIndex::new(2)));
}
#[test]
fn test_from_edges_with_bounds_violation() {
let edges = vec![(0, 1), (0, 2), (0, 3)]; let graph = BoundedGraph::<SymmetricFixedEdgeCount<2>, ()>::from_edges(&edges);
assert_eq!(graph.node_count(), 4);
assert_eq!(graph.edge_count(), 2); }
#[test]
fn test_with_capacity() {
let mut graph = BoundedGraph::<SymmetricFixedEdgeCount<3>, i32>::with_capacity(10, 20);
assert_eq!(graph.node_count(), 0);
assert_eq!(graph.edge_count(), 0);
let n1 = graph.add_node(SymmetricFixedEdgeCount::empty());
let n2 = graph.add_node(SymmetricFixedEdgeCount::empty());
assert!(graph.add_edge(n1, n2, 42).is_ok());
assert_eq!(graph.node_count(), 2);
assert_eq!(graph.edge_count(), 1);
use crate::{BoundedDiGraph, BoundedStableDiGraph};
let graph_based = BoundedDiGraph::<SymmetricFixedEdgeCount<2>, ()>::with_capacity(5, 10);
assert_eq!(graph_based.node_count(), 0);
let stable_based = BoundedStableDiGraph::<SymmetricFixedEdgeCount<2>, ()>::with_capacity(5, 10);
assert_eq!(stable_based.node_count(), 0);
}
#[test]
fn test_map() {
let mut graph = BoundedGraph::<SymmetricFixedEdgeCount<2, i32>, &str>::new();
let n1 = graph.add_node(SymmetricFixedEdgeCount::new(10));
let n2 = graph.add_node(SymmetricFixedEdgeCount::new(20));
let e1 = graph.add_edge(n1, n2, "edge").unwrap();
let mapped = graph.map(
|_idx, node| SymmetricFixedEdgeCount::<2, i32>::new(node.data * 2),
|_idx, edge| edge.len(),
);
assert_eq!(mapped.node_count(), 2);
assert_eq!(mapped.edge_count(), 1);
assert_eq!(mapped[n1].data, 20);
assert_eq!(mapped[n2].data, 40);
assert_eq!(mapped[e1], 4); }
#[test]
fn test_filter_map() {
let mut graph = BoundedGraph::<SymmetricFixedEdgeCount<3, i32>, i32>::new();
let n1 = graph.add_node(SymmetricFixedEdgeCount::new(10));
let n2 = graph.add_node(SymmetricFixedEdgeCount::new(20));
let n3 = graph.add_node(SymmetricFixedEdgeCount::new(5));
graph.add_edge(n1, n2, 100).unwrap();
graph.add_edge(n2, n3, 50).unwrap();
graph.add_edge(n1, n3, 25).unwrap();
let filtered = graph.filter_map(
|_idx, node| {
if node.data >= 10 {
Some(SymmetricFixedEdgeCount::<3, i32>::new(node.data))
} else {
None
}
},
|_idx, edge| {
if *edge >= 50 {
Some(*edge)
} else {
None
}
},
);
assert_eq!(filtered.node_count(), 2); assert_eq!(filtered.edge_count(), 1);
}
#[test]
fn test_into_edge_type() {
use petgraph::Undirected;
let mut digraph = BoundedGraph::<SymmetricFixedEdgeCount<3>, i32>::new();
let n1 = digraph.add_node(SymmetricFixedEdgeCount::empty());
let n2 = digraph.add_node(SymmetricFixedEdgeCount::empty());
digraph.add_edge(n1, n2, 42).unwrap();
assert!(digraph.is_directed());
assert_eq!(digraph.edge_count(), 1);
let inner_graph = digraph.into_inner().into_edge_type::<Undirected>();
let ungraph = BoundedGraph {
graph: inner_graph,
_phantom: std::marker::PhantomData,
};
assert!(!ungraph.is_directed());
assert_eq!(ungraph.edge_count(), 1);
assert_eq!(ungraph.node_count(), 2);
}
#[test]
fn test_self_loops() {
let mut graph = BoundedGraph::<SymmetricFixedEdgeCount<2>, ()>::new();
let n1 = graph.add_node(SymmetricFixedEdgeCount::empty());
assert!(graph.can_add_edge(n1, n1));
assert!(graph.add_edge(n1, n1, ()).is_ok());
assert_eq!(graph.edge_count(), 1);
assert!(graph.can_add_edge(n1, n1));
assert!(graph.add_edge(n1, n1, ()).is_ok());
assert_eq!(graph.edge_count(), 2);
assert!(!graph.can_add_edge(n1, n1));
let result = graph.add_edge(n1, n1, ());
assert!(result.is_err());
}
#[test]
fn test_undirected_graph_constraints() {
let mut graph = BoundedUnGraph::<SymmetricFixedEdgeCount<2>, ()>::new();
let n1 = graph.add_node(SymmetricFixedEdgeCount::empty());
let n2 = graph.add_node(SymmetricFixedEdgeCount::empty());
let n3 = graph.add_node(SymmetricFixedEdgeCount::empty());
assert!(graph.add_edge(n1, n2, ()).is_ok());
assert!(graph.add_edge(n1, n3, ()).is_ok());
let n4 = graph.add_node(SymmetricFixedEdgeCount::empty());
let result = graph.add_edge(n1, n4, ());
assert!(result.is_err());
assert!(graph.add_edge(n2, n3, ()).is_ok());
}
#[test]
fn test_default_constructor() {
let graph = BoundedDiGraph::<SymmetricFixedEdgeCount<5>, i32>::default();
assert_eq!(graph.node_count(), 0);
assert_eq!(graph.edge_count(), 0);
}
#[test]
fn test_node_weight_mutation() {
let mut graph = BoundedGraph::<SymmetricFixedEdgeCount<2, i32>, ()>::new();
let n1 = graph.add_node(SymmetricFixedEdgeCount::new(100));
assert_eq!(graph[n1].data, 100);
if let Some(weight) = graph.graph.node_weight_mut(n1) {
weight.data = 200;
}
assert_eq!(graph[n1].data, 200);
graph[n1].data += 50;
assert_eq!(graph[n1].data, 250);
}
#[test]
fn test_edge_weight_mutation() {
let mut graph = BoundedGraph::<SymmetricFixedEdgeCount<2>, i32>::new();
let n1 = graph.add_node(SymmetricFixedEdgeCount::empty());
let n2 = graph.add_node(SymmetricFixedEdgeCount::empty());
let e1 = graph.add_edge(n1, n2, 42).unwrap();
assert_eq!(graph[e1], 42);
if let Some(weight) = graph.graph.edge_weight_mut(e1) {
*weight = 100;
}
assert_eq!(graph[e1], 100);
graph[e1] += 50;
assert_eq!(graph[e1], 150);
}
#[test]
fn test_stable_graph_compatibility() {
use crate::{BoundedStableDiGraph, BoundedStableUnGraph};
let mut stable_digraph = BoundedStableDiGraph::<SymmetricFixedEdgeCount<3>, i32>::new();
let n1 = stable_digraph.add_node(SymmetricFixedEdgeCount::empty());
let n2 = stable_digraph.add_node(SymmetricFixedEdgeCount::empty());
let n3 = stable_digraph.add_node(SymmetricFixedEdgeCount::empty());
stable_digraph.add_edge(n1, n2, 10).unwrap();
stable_digraph.add_edge(n2, n3, 20).unwrap();
stable_digraph.add_edge(n1, n3, 30).unwrap();
assert_eq!(stable_digraph.node_count(), 3);
assert_eq!(stable_digraph.edge_count(), 3);
assert!(stable_digraph.is_directed());
stable_digraph.add_edge(n1, n2, 40).unwrap(); let result = stable_digraph.add_edge(n1, n2, 50);
assert!(
result.is_err(),
"Should fail - n1 already has 3 outgoing edges"
);
let mut stable_ungraph = BoundedStableUnGraph::<SymmetricFixedEdgeCount<2>, &str>::new();
let u1 = stable_ungraph.add_node(SymmetricFixedEdgeCount::empty());
let u2 = stable_ungraph.add_node(SymmetricFixedEdgeCount::empty());
let u3 = stable_ungraph.add_node(SymmetricFixedEdgeCount::empty());
stable_ungraph.add_edge(u1, u2, "edge1").unwrap();
stable_ungraph.add_edge(u2, u3, "edge2").unwrap();
assert_eq!(stable_ungraph.node_count(), 3);
assert_eq!(stable_ungraph.edge_count(), 2);
assert!(!stable_ungraph.is_directed());
stable_ungraph.add_edge(u1, u3, "edge3").unwrap();
let result = stable_ungraph.add_edge(u1, u2, "edge4");
assert!(
result.is_err(),
"Should fail - u1 already has 2 edges in undirected graph"
);
}
#[test]
fn test_stable_graph_node_removal() {
use crate::BoundedStableDiGraph;
let mut graph = BoundedStableDiGraph::<SymmetricFixedEdgeCount<5>, i32>::new();
let n0 = graph.add_node(SymmetricFixedEdgeCount::empty());
let n1 = graph.add_node(SymmetricFixedEdgeCount::empty());
let n2 = graph.add_node(SymmetricFixedEdgeCount::empty());
let n3 = graph.add_node(SymmetricFixedEdgeCount::empty());
graph.add_edge(n0, n1, 1).unwrap();
graph.add_edge(n1, n2, 2).unwrap();
graph.add_edge(n2, n3, 3).unwrap();
graph.graph.remove_node(n1);
assert_eq!(graph.node_count(), 3);
assert!(graph.graph.node_weight(n0).is_some());
assert!(graph.graph.node_weight(n1).is_none()); assert!(graph.graph.node_weight(n2).is_some());
assert!(graph.graph.node_weight(n3).is_some());
let result = graph.add_edge(n0, n2, 4);
assert!(result.is_ok());
}
#[test]
fn test_stable_graph_with_capacity() {
use crate::BoundedStableDiGraph;
let graph = BoundedStableDiGraph::<SymmetricFixedEdgeCount<3>, ()>::with_capacity(10, 20);
assert_eq!(graph.node_count(), 0);
assert_eq!(graph.edge_count(), 0);
let mut graph = graph;
let n1 = graph.add_node(SymmetricFixedEdgeCount::empty());
let n2 = graph.add_node(SymmetricFixedEdgeCount::empty());
assert!(graph.add_edge(n1, n2, ()).is_ok());
}
#[test]
fn test_edge_count_trait() {
use petgraph::visit::EdgeCount;
let mut graph = BoundedDiGraph::<SymmetricFixedEdgeCount<5>, ()>::new();
let n1 = graph.add_node(SymmetricFixedEdgeCount::empty());
let n2 = graph.add_node(SymmetricFixedEdgeCount::empty());
let n3 = graph.add_node(SymmetricFixedEdgeCount::empty());
assert_eq!(EdgeCount::edge_count(&graph), 0);
graph.add_edge(n1, n2, ()).unwrap();
assert_eq!(EdgeCount::edge_count(&graph), 1);
graph.add_edge(n2, n3, ()).unwrap();
assert_eq!(EdgeCount::edge_count(&graph), 2);
graph.add_edge(n1, n3, ()).unwrap();
assert_eq!(EdgeCount::edge_count(&graph), 3);
let mut ungraph = BoundedUnGraph::<SymmetricFixedEdgeCount<3>, ()>::new();
let u1 = ungraph.add_node(SymmetricFixedEdgeCount::empty());
let u2 = ungraph.add_node(SymmetricFixedEdgeCount::empty());
let u3 = ungraph.add_node(SymmetricFixedEdgeCount::empty());
assert_eq!(EdgeCount::edge_count(&ungraph), 0);
ungraph.add_edge(u1, u2, ()).unwrap();
ungraph.add_edge(u2, u3, ()).unwrap();
assert_eq!(EdgeCount::edge_count(&ungraph), 2);
}
#[test]
fn test_node_count_trait() {
use petgraph::visit::NodeCount;
let mut graph = BoundedDiGraph::<SymmetricFixedEdgeCount<5>, ()>::new();
assert_eq!(NodeCount::node_count(&graph), 0);
let n1 = graph.add_node(SymmetricFixedEdgeCount::empty());
assert_eq!(NodeCount::node_count(&graph), 1);
let n2 = graph.add_node(SymmetricFixedEdgeCount::empty());
assert_eq!(NodeCount::node_count(&graph), 2);
let n3 = graph.add_node(SymmetricFixedEdgeCount::empty());
assert_eq!(NodeCount::node_count(&graph), 3);
graph.add_edge(n1, n2, ()).unwrap();
graph.add_edge(n2, n3, ()).unwrap();
assert_eq!(NodeCount::node_count(&graph), 3);
let mut ungraph = BoundedUnGraph::<SymmetricFixedEdgeCount<3>, ()>::new();
assert_eq!(NodeCount::node_count(&ungraph), 0);
let u1 = ungraph.add_node(SymmetricFixedEdgeCount::empty());
let u2 = ungraph.add_node(SymmetricFixedEdgeCount::empty());
let u3 = ungraph.add_node(SymmetricFixedEdgeCount::empty());
let _u4 = ungraph.add_node(SymmetricFixedEdgeCount::empty());
assert_eq!(NodeCount::node_count(&ungraph), 4);
ungraph.add_edge(u1, u2, ()).unwrap();
ungraph.add_edge(u2, u3, ()).unwrap();
assert_eq!(NodeCount::node_count(&ungraph), 4);
}
#[test]
fn test_try_from_graph_success() {
use crate::FixedEdgeCount;
use std::convert::TryFrom;
let mut pg = Graph::new();
let n1 = pg.add_node(FixedEdgeCount::<3, 3>::empty());
let n2 = pg.add_node(FixedEdgeCount::<3, 3>::empty());
let n3 = pg.add_node(FixedEdgeCount::<3, 3>::empty());
pg.add_edge(n1, n2, ());
pg.add_edge(n2, n3, ());
let bounded = BoundedGraph::try_from(pg).unwrap();
assert_eq!(bounded.node_count(), 3);
assert_eq!(bounded.edge_count(), 2);
assert!(bounded.contains_edge(n1, n2));
assert!(bounded.contains_edge(n2, n3));
}
#[test]
fn test_try_from_graph_violates_outgoing_capacity() {
use crate::FixedEdgeCount;
use std::convert::TryFrom;
let mut pg = Graph::new();
let n1 = pg.add_node(FixedEdgeCount::<2, 2>::empty()); let n2 = pg.add_node(FixedEdgeCount::<2, 2>::empty());
let n3 = pg.add_node(FixedEdgeCount::<2, 2>::empty());
let n4 = pg.add_node(FixedEdgeCount::<2, 2>::empty());
pg.add_edge(n1, n2, ());
pg.add_edge(n1, n3, ());
pg.add_edge(n1, n4, ());
let result = BoundedGraph::try_from(pg);
assert!(result.is_err());
assert!(matches!(
result.unwrap_err(),
BoundedGraphError::EdgeRejected {
source_rejected: true,
..
}
));
}
#[test]
fn test_try_from_graph_violates_incoming_capacity() {
use crate::FixedEdgeCount;
use std::convert::TryFrom;
let mut pg = Graph::new();
let n1 = pg.add_node(FixedEdgeCount::<2, 2>::empty());
let n2 = pg.add_node(FixedEdgeCount::<2, 2>::empty());
let n3 = pg.add_node(FixedEdgeCount::<2, 2>::empty());
let n4 = pg.add_node(FixedEdgeCount::<2, 2>::empty());
pg.add_edge(n1, n4, ());
pg.add_edge(n2, n4, ());
pg.add_edge(n3, n4, ());
let result = BoundedGraph::try_from(pg);
assert!(result.is_err());
assert!(matches!(
result.unwrap_err(),
BoundedGraphError::EdgeRejected {
target_rejected: true,
..
}
));
}
#[test]
fn test_try_from_graph_empty() {
use crate::FixedEdgeCount;
use std::convert::TryFrom;
let pg = Graph::<FixedEdgeCount<2, 2>, ()>::new();
let bounded = BoundedGraph::try_from(pg).unwrap();
assert_eq!(bounded.node_count(), 0);
assert_eq!(bounded.edge_count(), 0);
}
#[test]
fn test_try_from_graph_asymmetric_limits() {
use crate::FixedEdgeCount;
use std::convert::TryFrom;
let mut pg = Graph::new();
let n1 = pg.add_node(FixedEdgeCount::<3, 5>::empty()); let n2 = pg.add_node(FixedEdgeCount::<3, 5>::empty());
let n3 = pg.add_node(FixedEdgeCount::<3, 5>::empty());
pg.add_edge(n1, n2, ());
pg.add_edge(n1, n3, ());
let bounded = BoundedGraph::try_from(pg).unwrap();
assert_eq!(bounded.edge_count(), 2);
}
#[test]
fn test_try_from_stable_graph_success() {
use crate::FixedEdgeCount;
use petgraph::stable_graph::StableGraph;
use std::convert::TryFrom;
let mut pg = StableGraph::new();
let n1 = pg.add_node(FixedEdgeCount::<3, 3>::empty());
let n2 = pg.add_node(FixedEdgeCount::<3, 3>::empty());
pg.add_edge(n1, n2, ());
let bounded = BoundedGraph::try_from(pg).unwrap();
assert_eq!(bounded.node_count(), 2);
assert_eq!(bounded.edge_count(), 1);
}
#[test]
fn test_try_from_stable_graph_violates_capacity() {
use crate::FixedEdgeCount;
use petgraph::stable_graph::StableGraph;
use std::convert::TryFrom;
let mut pg = StableGraph::new();
let n1 = pg.add_node(FixedEdgeCount::<1, 1>::empty()); let n2 = pg.add_node(FixedEdgeCount::<1, 1>::empty());
let n3 = pg.add_node(FixedEdgeCount::<1, 1>::empty());
pg.add_edge(n1, n2, ());
pg.add_edge(n1, n3, ());
let result = BoundedGraph::try_from(pg);
assert!(result.is_err());
}
#[test]
fn test_try_from_with_self_loops() {
use crate::FixedEdgeCount;
use std::convert::TryFrom;
let mut pg = Graph::new();
let n1 = pg.add_node(FixedEdgeCount::<2, 2>::empty());
pg.add_edge(n1, n1, ());
let bounded = BoundedGraph::try_from(pg).unwrap();
assert_eq!(bounded.edge_count(), 1);
}
#[test]
fn test_try_from_preserves_node_data() {
use crate::FixedEdgeCount;
use std::convert::TryFrom;
let mut pg = Graph::new();
let n1 = pg.add_node(FixedEdgeCount::<2, 2, String>::new("Node1".to_string()));
let n2 = pg.add_node(FixedEdgeCount::<2, 2, String>::new("Node2".to_string()));
pg.add_edge(n1, n2, "Edge");
let bounded = BoundedGraph::try_from(pg).unwrap();
assert_eq!(bounded[n1].data, "Node1");
assert_eq!(bounded[n2].data, "Node2");
assert_eq!(bounded[bounded.find_edge(n1, n2).unwrap()], "Edge");
}