use std::collections::BTreeSet;
use safegraph::graph::capability::{InsertEdge, InsertNode, RemoveNode};
use safegraph::graph::context::NodeIx as ScopedNIx;
use safegraph::graph::edge::{Endpoints, Map};
use safegraph::graph::prelude::*;
use safegraph::HyperGraph;
fn run_all<G>()
where
G: Default + 'static,
G: Graph + InsertNode + InsertEdge + RemoveNode,
G: GraphProperty<Node = u32, Edge = u32>,
G::Endpoints: for<'scope> Map<ScopedNIx<'scope, <G as GraphProperty>::NodeIx>>,
G::NodeIx: std::fmt::Debug + Ord,
G::EdgeIx: std::fmt::Debug + Ord,
{
{
let mut g = G::default();
g.scope_mut(|mut ctx| {
let a = ctx.insert_node(10).expect("insert a");
let b = ctx.insert_node(20).expect("insert b");
let c = ctx.insert_node(30).expect("insert c");
let d = ctx.insert_node(40).expect("insert d");
let ep_e0 = <_ as Endpoints>::try_from_node_indices([a, b, c]).expect("ep_e0");
let ep_e1 = <_ as Endpoints>::try_from_node_indices([b, d]).expect("ep_e1");
let e0 = ctx.insert_edge(100, ep_e0).expect("insert e0");
let e1 = ctx.insert_edge(200, ep_e1).expect("insert e1");
assert_eq!(ctx.nodes().count(), 4);
assert_eq!(ctx.edges().count(), 2);
assert_eq!(*ctx.node(a), 10);
assert_eq!(*ctx.node(d), 40);
assert_eq!(*ctx.edge(e0), 100);
assert_eq!(*ctx.edge(e1), 200);
let ep0: BTreeSet<_> = ctx.endpoints(e0).into_iter().collect();
let want_e0: BTreeSet<_> = [a, b, c].into_iter().collect();
assert_eq!(ep0, want_e0);
let ep1: BTreeSet<_> = ctx.endpoints(e1).into_iter().collect();
let want_e1: BTreeSet<_> = [b, d].into_iter().collect();
assert_eq!(ep1, want_e1);
let from_a: BTreeSet<_> = ctx.edge_indices_from(a).collect();
assert_eq!(from_a, [e0].into_iter().collect::<BTreeSet<_>>());
let from_b: BTreeSet<_> = ctx.edge_indices_from(b).collect();
assert_eq!(from_b, [e0, e1].into_iter().collect::<BTreeSet<_>>());
let from_d: BTreeSet<_> = ctx.edge_indices_from(d).collect();
assert_eq!(from_d, [e1].into_iter().collect::<BTreeSet<_>>());
let walks_a: Vec<_> =
ctx.walks_from(a).map(|w| w.get()).map(|(eix, _, nix)| (eix, nix)).collect();
assert_eq!(walks_a.len(), 2);
for (eix, _) in &walks_a {
assert_eq!(*eix, e0);
}
let neighbors: BTreeSet<_> = walks_a.iter().map(|(_, nix)| *nix).collect();
assert_eq!(neighbors, [b, c].into_iter().collect::<BTreeSet<_>>());
});
}
{
let mut g = G::default();
g.scope_mut(|mut ctx| {
let a = ctx.insert_node(10).unwrap();
let b = ctx.insert_node(20).unwrap();
let c = ctx.insert_node(30).unwrap();
let d = ctx.insert_node(40).unwrap();
let ep_e0 = <_ as Endpoints>::try_from_node_indices([a, b, c]).unwrap();
let ep_e1 = <_ as Endpoints>::try_from_node_indices([b, d]).unwrap();
let e0 = ctx.insert_edge(100, ep_e0).unwrap();
let _e1 = ctx.insert_edge(200, ep_e1).unwrap();
ctx.remove_nodes_edges(None, Some(e0));
});
let (n, e) = g.scope(|ctx| (ctx.nodes().count(), ctx.edges().count()));
assert_eq!((n, e), (4, 1), "after removing one hyperedge");
}
{
let mut g = G::default();
g.scope_mut(|mut ctx| {
let a = ctx.insert_node(10).unwrap();
let b = ctx.insert_node(20).unwrap();
let c = ctx.insert_node(30).unwrap();
let d = ctx.insert_node(40).unwrap();
let ep_e0 = <_ as Endpoints>::try_from_node_indices([a, b, c]).unwrap();
let ep_e1 = <_ as Endpoints>::try_from_node_indices([b, d]).unwrap();
let _e0 = ctx.insert_edge(100, ep_e0).unwrap();
let _e1 = ctx.insert_edge(200, ep_e1).unwrap();
ctx.remove_nodes_edges(Some(b), None);
});
let (n, e) = g.scope(|ctx| (ctx.nodes().count(), ctx.edges().count()));
assert_eq!((n, e), (3, 0), "after removing shared node");
}
}
macro_rules! backend {
($name:ident, $G:ty) => {
#[test]
fn $name() {
run_all::<$G>();
}
};
}
backend!(seq_hash_hyper_graph, HyperGraph<u32, u32>);