blob: b0424740212239c9f8d38929f21517389a963290 [file] [log] [blame]
use core::iter::once;
use hashbrown::HashSet;
use petgraph_core::{
attributes::NoValue,
edge::{marker::Directed, DetachedEdge, Direction},
node::{DetachedNode, Node, NodeMut},
storage::GraphStorage,
};
use crate::{DinoGraph, DinoStorage, EdgeId, NodeId};
// 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(NoValue::new());
let b = storage.next_node_id(NoValue::new());
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(NoValue::new());
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(NoValue::new()), ())
.unwrap();
let node = *node.id();
let a = storage.next_edge_id(NoValue::new());
let b = storage.next_edge_id(NoValue::new());
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(NoValue::new());
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<_>>()
);
}