use safegraph::graph::prelude::*;
use safegraph::VecGraph;
type G = VecGraph<u32, u32>;
#[test]
fn stale_pointer_creates_self_loop_in_outgoing_list() {
let mut g = G::default();
let (n0, n2) = g.scope_mut(|mut ctx| {
let n0 = ctx.insert_node(0).unwrap();
let n1 = ctx.insert_node(1).unwrap();
let n2 = ctx.insert_node(2).unwrap();
let e0 = ctx.insert_edge(100, [n1, n2]).unwrap();
let _e1 = ctx.insert_edge(101, [n0, n1]).unwrap();
let _e2 = ctx.insert_edge(102, [n0, n2]).unwrap();
let raw = (n0.inner(), n2.inner());
ctx.remove_nodes_edges(std::iter::empty(), [e0]);
raw
});
g.push_edge(103, [n0, n2]).unwrap();
g.remove_node(n0);
}
#[test]
fn stale_pointer_creates_self_loop_in_incoming_list() {
let mut g = G::default();
let (n0, n2) = g.scope_mut(|mut ctx| {
let n0 = ctx.insert_node(0).unwrap();
let n1 = ctx.insert_node(1).unwrap();
let n2 = ctx.insert_node(2).unwrap();
let e0 = ctx.insert_edge(100, [n1, n2]).unwrap();
let _e1 = ctx.insert_edge(101, [n1, n0]).unwrap();
let _e2 = ctx.insert_edge(102, [n2, n0]).unwrap();
let raw = (n0.inner(), n2.inner());
ctx.remove_nodes_edges(std::iter::empty(), [e0]);
raw
});
g.push_edge(103, [n2, n0]).unwrap();
g.remove_node(n0);
}
#[test]
fn stale_pointer_yields_wrong_edge_data() {
let mut g = G::default();
let (n0, n2, n3) = g.scope_mut(|mut ctx| {
let n0 = ctx.insert_node(0).unwrap();
let n1 = ctx.insert_node(1).unwrap();
let n2 = ctx.insert_node(2).unwrap();
let n3 = ctx.insert_node(3).unwrap();
let e0 = ctx.insert_edge(100, [n1, n2]).unwrap();
let _e1 = ctx.insert_edge(101, [n0, n1]).unwrap();
let _e2 = ctx.insert_edge(102, [n0, n2]).unwrap();
let raw = (n0.inner(), n2.inner(), n3.inner());
ctx.remove_nodes_edges(std::iter::empty(), [e0]);
raw
});
g.push_edge(999, [n3, n2]).unwrap();
let taken = g.take_node(n0);
assert_eq!(taken, 0, "take_node should return n0's data");
}
#[test]
fn stale_pointer_out_of_bounds_detected_via_take_node() {
let mut g = G::default();
let (n0, n1, n2) = g.scope_mut(|mut ctx| {
let n0 = ctx.insert_node(0).unwrap();
let n1 = ctx.insert_node(1).unwrap();
let n2 = ctx.insert_node(2).unwrap();
let e0 = ctx.insert_edge(100, [n1, n2]).unwrap();
let _e1 = ctx.insert_edge(101, [n0, n1]).unwrap();
let _e2 = ctx.insert_edge(102, [n0, n2]).unwrap();
let raw = (n0.inner(), n1.inner(), n2.inner());
ctx.remove_nodes_edges(std::iter::empty(), [e0]);
raw
});
g.push_edge(999, [n1, n2]).unwrap();
let taken = g.take_node(n0);
assert_eq!(taken, 0);
}
#[test]
fn remove_node_hangs_due_to_cyclic_edge_list() {
let mut g = G::default();
let (n0, n2) = g.scope_mut(|mut ctx| {
let n0 = ctx.insert_node(0).unwrap();
let n1 = ctx.insert_node(1).unwrap();
let n2 = ctx.insert_node(2).unwrap();
let e0 = ctx.insert_edge(100, [n1, n2]).unwrap();
let _e1 = ctx.insert_edge(101, [n0, n1]).unwrap();
let _e2 = ctx.insert_edge(102, [n0, n2]).unwrap();
let raw = (n0.inner(), n2.inner());
ctx.remove_nodes_edges(std::iter::empty(), [e0]);
raw
});
g.push_edge(103, [n0, n2]).unwrap();
g.remove_node(n0);
}
#[test]
fn take_node_internal_swap_invalidates_precollected_indices() {
let mut g = G::default();
let (n0, n3) = g.scope_mut(|mut ctx| {
let n0 = ctx.insert_node(0).unwrap();
let n1 = ctx.insert_node(1).unwrap();
let n2 = ctx.insert_node(2).unwrap();
let n3 = ctx.insert_node(3).unwrap();
let e0 = ctx.insert_edge(200, [n1, n2]).unwrap();
let _e1 = ctx.insert_edge(201, [n0, n1]).unwrap();
let _e2 = ctx.insert_edge(202, [n0, n2]).unwrap();
let _e3 = ctx.insert_edge(203, [n0, n3]).unwrap();
let raw = (n0.inner(), n3.inner());
ctx.remove_nodes_edges(std::iter::empty(), [e0]);
raw
});
g.push_edge(204, [n0, n3]).unwrap();
g.remove_node(n0);
}
#[test]
fn take_nodes_edges_swap_no_patch() {
let mut g = G::default();
let (n0, n2): (u32, u32) = g.scope_mut(|mut ctx| {
let n0 = ctx.insert_node(0).unwrap();
let n1 = ctx.insert_node(1).unwrap();
let n2 = ctx.insert_node(2).unwrap();
let e0 = ctx.insert_edge(100, [n1, n2]).unwrap();
let _e1 = ctx.insert_edge(101, [n0, n1]).unwrap();
let _e2 = ctx.insert_edge(102, [n0, n2]).unwrap();
let raw = (n0.inner(), n2.inner());
ctx.remove_nodes_edges(std::iter::empty(), [e0]);
raw
});
g.push_edge(103, [n0, n2]).unwrap();
let (_nodes, _edges): (Vec<u32>, Vec<u32>) =
g.take_nodes_edges([n0], std::iter::empty());
}