| use core::iter::once; |
| |
| use hashbrown::HashSet; |
| use petgraph_core::{ |
| edge::{marker::Directed, DetachedEdge, Direction, EdgeId}, |
| node::{DetachedNode, Node, NodeId, NodeMut}, |
| storage::GraphStorage, |
| }; |
| |
| use crate::{DinoGraph, DinoStorage}; |
| |
| // TODO: rework tests to be more encompassing and use test utils! |
| |
| #[test] |
| fn empty() { |
| let graph = DinoGraph::<(), (), Directed>::new(); |
| |
| assert_eq!(graph.num_nodes(), 0); |
| assert_eq!(graph.num_edges(), 0); |
| |
| assert_eq!(graph.nodes().count(), 0); |
| assert_eq!(graph.edges().count(), 0); |
| } |
| |
| #[test] |
| fn insert_node() { |
| let mut graph = DinoGraph::<u8, (), Directed>::new(); |
| |
| let node = graph.try_insert_node(2u8).unwrap(); |
| |
| assert_eq!(node.weight(), &2u8); |
| |
| assert_eq!(graph.num_nodes(), 1); |
| assert_eq!(graph.num_edges(), 0); |
| |
| assert_eq!(graph.nodes().count(), 1); |
| assert_eq!(graph.edges().count(), 0); |
| } |
| |
| #[test] |
| fn insert_edge() { |
| let mut graph = DinoGraph::<(), u8, Directed>::new(); |
| |
| let node = graph.try_insert_node(()).unwrap(); |
| let node = node.id(); |
| |
| let edge = graph.try_insert_edge(2u8, node, node).unwrap(); |
| |
| assert_eq!(edge.weight(), &2u8); |
| |
| assert_eq!(graph.num_nodes(), 1); |
| assert_eq!(graph.num_edges(), 1); |
| |
| assert_eq!(graph.nodes().count(), 1); |
| assert_eq!(graph.edges().count(), 1); |
| } |
| |
| #[test] |
| fn next_node_id_pure() { |
| let mut storage = DinoStorage::<(), (), Directed>::new(); |
| |
| let a = storage.next_node_id(); |
| let b = storage.next_node_id(); |
| |
| assert_eq!(a, b); |
| |
| let node = storage.insert_node(a, ()).unwrap(); |
| let node = node.id(); |
| |
| assert_eq!(node, a); |
| |
| let c = storage.next_node_id(); |
| |
| assert_ne!(a, c); |
| } |
| |
| #[test] |
| fn next_edge_id_pure() { |
| let mut storage = DinoStorage::<(), (), Directed>::new(); |
| |
| let node = storage.insert_node(storage.next_node_id(), ()).unwrap(); |
| let node = node.id(); |
| |
| let a = storage.next_edge_id(); |
| let b = storage.next_edge_id(); |
| |
| assert_eq!(a, b); |
| |
| let edge = storage.insert_edge(a, (), node, node).unwrap(); |
| let edge = edge.id(); |
| |
| assert_eq!(edge, a); |
| |
| let c = storage.next_edge_id(); |
| |
| assert_ne!(a, c); |
| } |
| |
| #[test] |
| fn remove_node() { |
| let mut graph = DinoGraph::<u8, (), Directed>::new(); |
| |
| let node = graph.try_insert_node(2u8).unwrap(); |
| let node = node.id(); |
| |
| assert_eq!(graph.remove_node(node), Some(DetachedNode::new(node, 2u8))); |
| |
| assert_eq!(graph.num_nodes(), 0); |
| assert_eq!(graph.num_edges(), 0); |
| |
| assert_eq!(graph.nodes().count(), 0); |
| assert_eq!(graph.edges().count(), 0); |
| } |
| |
| #[test] |
| fn remove_edge() { |
| let mut graph = DinoGraph::<(), u8, Directed>::new(); |
| |
| let node = graph.try_insert_node(()).unwrap(); |
| let node = node.id(); |
| |
| let edge = graph.try_insert_edge(2u8, node, node).unwrap(); |
| let edge = edge.id(); |
| |
| assert_eq!( |
| graph.remove_edge(edge), |
| Some(DetachedEdge::new(edge, 2u8, node, node)) |
| ); |
| |
| assert_eq!(graph.num_nodes(), 1); |
| assert_eq!(graph.num_edges(), 0); |
| |
| assert_eq!(graph.nodes().count(), 1); |
| assert_eq!(graph.edges().count(), 0); |
| |
| assert_eq!(graph.connections(node).count(), 0); |
| assert_eq!(graph.neighbours(node).count(), 0); |
| |
| assert_eq!( |
| graph |
| .connections_directed(node, Direction::Incoming) |
| .count(), |
| 0 |
| ); |
| assert_eq!( |
| graph |
| .connections_directed(node, Direction::Outgoing) |
| .count(), |
| 0 |
| ); |
| |
| assert_eq!( |
| graph.neighbours_directed(node, Direction::Incoming).count(), |
| 0 |
| ); |
| assert_eq!( |
| graph.neighbours_directed(node, Direction::Outgoing).count(), |
| 0 |
| ); |
| } |
| |
| #[test] |
| fn clear() { |
| let mut graph = DinoGraph::<u8, u8, Directed>::new(); |
| |
| let node = graph.try_insert_node(2u8).unwrap(); |
| let node = node.id(); |
| |
| graph.try_insert_edge(2u8, node, node).unwrap(); |
| |
| graph.clear(); |
| |
| assert_eq!(graph.num_nodes(), 0); |
| assert_eq!(graph.num_edges(), 0); |
| |
| assert_eq!(graph.nodes().count(), 0); |
| assert_eq!(graph.edges().count(), 0); |
| } |
| |
| #[test] |
| fn node() { |
| let mut graph = DinoGraph::<u8, (), Directed>::new(); |
| |
| let node = graph.try_insert_node(2u8).unwrap(); |
| let node = node.id(); |
| |
| assert_eq!( |
| graph.node(node), |
| Some(Node::new(graph.storage(), node, &2u8)) |
| ); |
| } |
| |
| #[test] |
| fn node_mut() { |
| let mut graph = DinoGraph::<u8, (), Directed>::new(); |
| |
| let node = graph.try_insert_node(2u8).unwrap(); |
| let node = node.id(); |
| |
| assert_eq!(graph.node_mut(node), Some(NodeMut::new(node, &mut 2u8))); |
| |
| let mut node = graph.node_mut(node).unwrap(); |
| *node.weight_mut() = 3u8; |
| let node = node.id(); |
| |
| assert_eq!( |
| graph.node(node), |
| Some(Node::new(graph.storage(), node, &3u8)) |
| ); |
| } |
| |
| #[test] |
| fn contains_node() { |
| let mut graph = DinoGraph::<u8, (), Directed>::new(); |
| |
| let node = graph.try_insert_node(2u8).unwrap(); |
| let node = node.id(); |
| |
| assert!(graph.storage().contains_node(node)); |
| } |
| |
| #[test] |
| fn edge() { |
| let mut graph = DinoGraph::<(), u8, Directed>::new(); |
| |
| let node = graph.try_insert_node(()).unwrap(); |
| let node = node.id(); |
| |
| let edge = graph.try_insert_edge(2u8, node, node).unwrap(); |
| let edge = edge.id(); |
| |
| assert_eq!( |
| graph.edge(edge), |
| Some(petgraph_core::edge::Edge::new( |
| graph.storage(), |
| edge, |
| &2u8, |
| node, |
| node |
| )) |
| ); |
| } |
| |
| #[test] |
| fn edge_mut() { |
| let mut graph = DinoGraph::<(), u8, Directed>::new(); |
| |
| let node = graph.try_insert_node(()).unwrap(); |
| let node = node.id(); |
| |
| let edge = graph.try_insert_edge(2u8, node, node).unwrap(); |
| let edge = edge.id(); |
| |
| assert_eq!( |
| graph.edge_mut(edge), |
| Some(petgraph_core::edge::EdgeMut::new( |
| edge, &mut 2u8, node, node |
| )) |
| ); |
| |
| let mut edge = graph.edge_mut(edge).unwrap(); |
| *edge.weight_mut() = 3u8; |
| let edge = edge.id(); |
| |
| assert_eq!( |
| graph.edge(edge), |
| Some(petgraph_core::edge::Edge::new( |
| graph.storage(), |
| edge, |
| &3u8, |
| node, |
| node |
| )) |
| ); |
| } |
| |
| #[test] |
| fn contains_edge() { |
| let mut graph = DinoGraph::<(), u8, Directed>::new(); |
| |
| let node = graph.try_insert_node(()).unwrap(); |
| let node = node.id(); |
| |
| let edge = graph.try_insert_edge(2u8, node, node).unwrap(); |
| let edge = edge.id(); |
| |
| assert!(graph.storage().contains_edge(edge)); |
| } |
| |
| struct SimpleGraph { |
| graph: DinoGraph<u8, u8, Directed>, |
| |
| a: NodeId, |
| b: NodeId, |
| c: NodeId, |
| d: NodeId, |
| |
| ab: EdgeId, |
| ba: EdgeId, |
| bc: EdgeId, |
| ac: EdgeId, |
| ca: EdgeId, |
| } |
| |
| impl SimpleGraph { |
| fn create() -> Self { |
| let mut graph = DinoGraph::new(); |
| |
| let a = graph.try_insert_node(1u8).unwrap(); |
| let a = a.id(); |
| |
| let b = graph.try_insert_node(2u8).unwrap(); |
| let b = b.id(); |
| |
| let c = graph.try_insert_node(3u8).unwrap(); |
| let c = c.id(); |
| |
| let d = graph.try_insert_node(8u8).unwrap(); |
| let d = d.id(); |
| |
| let ab = graph.try_insert_edge(4u8, a, b).unwrap(); |
| let ab = ab.id(); |
| |
| let ba = graph.try_insert_edge(5u8, b, a).unwrap(); |
| let ba = ba.id(); |
| |
| let bc = graph.try_insert_edge(6u8, b, c).unwrap(); |
| let bc = bc.id(); |
| |
| let ac = graph.try_insert_edge(7u8, a, c).unwrap(); |
| let ac = ac.id(); |
| |
| let ca = graph.try_insert_edge(8u8, c, a).unwrap(); |
| let ca = ca.id(); |
| |
| Self { |
| graph, |
| a, |
| b, |
| c, |
| d, |
| ab, |
| ba, |
| bc, |
| ac, |
| ca, |
| } |
| } |
| } |
| |
| #[test] |
| fn edges_between() { |
| let SimpleGraph { |
| graph, |
| a, |
| b, |
| ab, |
| ba, |
| .. |
| } = SimpleGraph::create(); |
| |
| assert_eq!( |
| graph |
| .edges_between(a, b) |
| .map(petgraph_core::edge::Edge::detach) |
| .collect::<HashSet<_>>(), |
| [ |
| DetachedEdge::new(ab, 4u8, a, b), |
| DetachedEdge::new(ba, 5u8, b, a), |
| ] |
| .into_iter() |
| .collect::<HashSet<_>>() |
| ); |
| } |
| |
| #[test] |
| fn edges_between_mut() { |
| let SimpleGraph { |
| mut graph, |
| a, |
| b, |
| ab, |
| ba, |
| .. |
| } = SimpleGraph::create(); |
| |
| for mut edge in graph.edges_between_mut(a, b) { |
| *edge.weight_mut() += 1; |
| } |
| |
| assert_eq!( |
| graph |
| .edges_between(a, b) |
| .map(petgraph_core::edge::Edge::detach) |
| .collect::<HashSet<_>>(), |
| [ |
| DetachedEdge::new(ab, 5u8, a, b), |
| DetachedEdge::new(ba, 6u8, b, a), |
| ] |
| .into_iter() |
| .collect::<HashSet<_>>() |
| ); |
| } |
| |
| #[test] |
| fn node_connections() { |
| let SimpleGraph { |
| graph, |
| a, |
| b, |
| c, |
| ab, |
| ba, |
| ac, |
| ca, |
| .. |
| } = SimpleGraph::create(); |
| |
| assert_eq!( |
| graph |
| .connections(a) |
| .map(petgraph_core::edge::Edge::detach) |
| .collect::<HashSet<_>>(), |
| [ |
| DetachedEdge::new(ab, 4u8, a, b), |
| DetachedEdge::new(ba, 5u8, b, a), |
| DetachedEdge::new(ac, 7u8, a, c), |
| DetachedEdge::new(ca, 8u8, c, a), |
| ] |
| .into_iter() |
| .collect::<HashSet<_>>() |
| ); |
| } |
| |
| #[test] |
| fn node_connections_mut() { |
| let SimpleGraph { |
| mut graph, |
| a, |
| b, |
| c, |
| ab, |
| ba, |
| ac, |
| ca, |
| bc, |
| .. |
| } = SimpleGraph::create(); |
| for mut connection in graph.connections_mut(a) { |
| *connection.weight_mut() += 1; |
| } |
| |
| assert_eq!( |
| graph |
| .connections(a) |
| .map(petgraph_core::edge::Edge::detach) |
| .collect::<HashSet<_>>(), |
| [ |
| DetachedEdge::new(ab, 5u8, a, b), |
| DetachedEdge::new(ba, 6u8, b, a), |
| DetachedEdge::new(ac, 8u8, a, c), |
| DetachedEdge::new(ca, 9u8, c, a), |
| ] |
| .into_iter() |
| .collect::<HashSet<_>>() |
| ); |
| |
| assert_eq!( |
| graph.edge(bc), |
| Some(petgraph_core::edge::Edge::new( |
| graph.storage(), |
| bc, |
| &6u8, |
| b, |
| c |
| )) |
| ); |
| } |
| |
| #[test] |
| fn node_neighbours() { |
| let SimpleGraph { |
| graph, a, b, c, d, .. |
| } = SimpleGraph::create(); |
| |
| assert_eq!( |
| graph |
| .neighbours(a) |
| .map(Node::detach) |
| .collect::<HashSet<_>>(), |
| [DetachedNode::new(b, 2u8), DetachedNode::new(c, 3u8)] |
| .into_iter() |
| .collect::<HashSet<_>>() |
| ); |
| |
| assert_eq!( |
| graph |
| .neighbours(b) |
| .map(Node::detach) |
| .collect::<HashSet<_>>(), |
| [DetachedNode::new(a, 1u8), DetachedNode::new(c, 3u8)] |
| .into_iter() |
| .collect::<HashSet<_>>() |
| ); |
| |
| assert_eq!( |
| graph |
| .neighbours(c) |
| .map(Node::detach) |
| .collect::<HashSet<_>>(), |
| [DetachedNode::new(a, 1u8), DetachedNode::new(b, 2u8)] |
| .into_iter() |
| .collect::<HashSet<_>>() |
| ); |
| |
| assert_eq!( |
| graph |
| .neighbours(d) |
| .map(Node::detach) |
| .collect::<HashSet<_>>(), |
| HashSet::new() |
| ); |
| } |
| |
| #[test] |
| fn node_neighbours_mut() { |
| let SimpleGraph { |
| mut graph, |
| a, |
| b, |
| c, |
| d, |
| .. |
| } = SimpleGraph::create(); |
| |
| for mut neighbour in graph.neighbours_mut(a) { |
| *neighbour.weight_mut() += 1; |
| } |
| |
| assert_eq!( |
| graph |
| .neighbours(a) |
| .map(Node::detach) |
| .collect::<HashSet<_>>(), |
| [DetachedNode::new(b, 3u8), DetachedNode::new(c, 4u8)] |
| .into_iter() |
| .collect::<HashSet<_>>() |
| ); |
| |
| assert_eq!( |
| graph |
| .neighbours(b) |
| .map(Node::detach) |
| .collect::<HashSet<_>>(), |
| [DetachedNode::new(a, 1u8), DetachedNode::new(c, 4u8)] |
| .into_iter() |
| .collect::<HashSet<_>>() |
| ); |
| |
| assert_eq!( |
| graph |
| .neighbours(c) |
| .map(Node::detach) |
| .collect::<HashSet<_>>(), |
| [DetachedNode::new(a, 1u8), DetachedNode::new(b, 3u8)] |
| .into_iter() |
| .collect::<HashSet<_>>() |
| ); |
| |
| assert_eq!( |
| graph |
| .neighbours(d) |
| .map(Node::detach) |
| .collect::<HashSet<_>>(), |
| HashSet::new() |
| ); |
| } |
| |
| #[test] |
| fn external_nodes() { |
| let SimpleGraph { graph, d, .. } = SimpleGraph::create(); |
| |
| assert_eq!( |
| graph |
| .isolated_nodes() |
| .map(Node::detach) |
| .collect::<HashSet<_>>(), |
| once(DetachedNode::new(d, 8u8)).collect::<HashSet<_>>() |
| ); |
| } |
| |
| #[test] |
| fn external_nodes_mut() { |
| let SimpleGraph { |
| mut graph, |
| a, |
| b, |
| c, |
| d, |
| .. |
| } = SimpleGraph::create(); |
| |
| for mut external in graph.isolated_nodes_mut() { |
| *external.weight_mut() += 1; |
| } |
| |
| assert_eq!( |
| graph |
| .isolated_nodes() |
| .map(Node::detach) |
| .collect::<HashSet<_>>(), |
| once(DetachedNode::new(d, 9u8)).collect::<HashSet<_>>() |
| ); |
| |
| assert_eq!(graph.node(a), Some(Node::new(graph.storage(), a, &1u8))); |
| |
| assert_eq!(graph.node(b), Some(Node::new(graph.storage(), b, &2u8))); |
| |
| assert_eq!(graph.node(c), Some(Node::new(graph.storage(), c, &3u8))); |
| } |
| |
| #[test] |
| fn nodes() { |
| let SimpleGraph { |
| graph, a, b, c, d, .. |
| } = SimpleGraph::create(); |
| |
| assert_eq!( |
| graph.nodes().map(Node::detach).collect::<HashSet<_>>(), |
| [ |
| DetachedNode::new(a, 1u8), |
| DetachedNode::new(b, 2u8), |
| DetachedNode::new(c, 3u8), |
| DetachedNode::new(d, 8u8), |
| ] |
| .into_iter() |
| .collect::<HashSet<_>>() |
| ); |
| } |
| |
| #[test] |
| fn nodes_mut() { |
| let SimpleGraph { |
| mut graph, |
| a, |
| b, |
| c, |
| d, |
| .. |
| } = SimpleGraph::create(); |
| |
| for mut node in graph.nodes_mut() { |
| *node.weight_mut() += 1; |
| } |
| |
| assert_eq!( |
| graph.nodes().map(Node::detach).collect::<HashSet<_>>(), |
| [ |
| DetachedNode::new(a, 2u8), |
| DetachedNode::new(b, 3u8), |
| DetachedNode::new(c, 4u8), |
| DetachedNode::new(d, 9u8), |
| ] |
| .into_iter() |
| .collect::<HashSet<_>>() |
| ); |
| } |
| |
| #[test] |
| fn edges() { |
| let SimpleGraph { |
| graph, |
| a, |
| b, |
| c, |
| ab, |
| ba, |
| bc, |
| ac, |
| ca, |
| .. |
| } = SimpleGraph::create(); |
| |
| assert_eq!( |
| graph |
| .edges() |
| .map(petgraph_core::edge::Edge::detach) |
| .collect::<HashSet<_>>(), |
| [ |
| DetachedEdge::new(ab, 4u8, a, b), |
| DetachedEdge::new(ba, 5u8, b, a), |
| DetachedEdge::new(bc, 6u8, b, c), |
| DetachedEdge::new(ac, 7u8, a, c), |
| DetachedEdge::new(ca, 8u8, c, a), |
| ] |
| .into_iter() |
| .collect::<HashSet<_>>() |
| ); |
| } |
| |
| #[test] |
| fn edges_mut() { |
| let SimpleGraph { |
| mut graph, |
| a, |
| b, |
| c, |
| ab, |
| ba, |
| bc, |
| ac, |
| ca, |
| .. |
| } = SimpleGraph::create(); |
| |
| for mut edge in graph.edges_mut() { |
| *edge.weight_mut() += 1; |
| } |
| |
| assert_eq!( |
| graph |
| .edges() |
| .map(petgraph_core::edge::Edge::detach) |
| .collect::<HashSet<_>>(), |
| [ |
| DetachedEdge::new(ab, 5u8, a, b), |
| DetachedEdge::new(ba, 6u8, b, a), |
| DetachedEdge::new(bc, 7u8, b, c), |
| DetachedEdge::new(ac, 8u8, a, c), |
| DetachedEdge::new(ca, 9u8, c, a), |
| ] |
| .into_iter() |
| .collect::<HashSet<_>>() |
| ); |
| } |