1 #![cfg(feature = "stable_graph")]
2 
3 extern crate itertools;
4 extern crate petgraph;
5 #[macro_use]
6 extern crate defmac;
7 
8 use itertools::assert_equal;
9 use petgraph::algo::{kosaraju_scc, min_spanning_tree, tarjan_scc};
10 use petgraph::dot::Dot;
11 use petgraph::prelude::*;
12 use petgraph::stable_graph::node_index as n;
13 use petgraph::visit::{IntoEdgeReferences, IntoNodeReferences, NodeIndexable};
14 use petgraph::EdgeType;
15 
16 #[test]
node_indices()17 fn node_indices() {
18     let mut g = StableGraph::<_, ()>::new();
19     let a = g.add_node(0);
20     let b = g.add_node(1);
21     let c = g.add_node(2);
22     g.remove_node(b);
23     let mut iter = g.node_indices();
24     assert_eq!(iter.next(), Some(a));
25     assert_eq!(iter.next(), Some(c));
26     assert_eq!(iter.next(), None);
27 }
28 
29 #[test]
node_bound()30 fn node_bound() {
31     let mut g = StableGraph::<_, ()>::new();
32     assert_eq!(g.node_bound(), g.node_count());
33     for i in 0..10 {
34         g.add_node(i);
35         assert_eq!(g.node_bound(), g.node_count());
36     }
37     let full_count = g.node_count();
38     g.remove_node(n(0));
39     g.remove_node(n(2));
40     assert_eq!(g.node_bound(), full_count);
41     g.clear();
42     assert_eq!(g.node_bound(), 0);
43 }
44 
45 #[test]
clear_edges()46 fn clear_edges() {
47     let mut gr = scc_graph();
48     gr.remove_node(n(1));
49     gr.clear_edges();
50     // check that we use the free list for the vacancies
51     assert_eq!(gr.add_node(()), n(1));
52     assert_eq!(gr.add_node(()), n(4));
53     assert!(gr.edge_references().next().is_none());
54     assert!(gr.node_indices().all(|i| gr.neighbors(i).next().is_none()));
55 }
56 
assert_sccs_eq(mut res: Vec<Vec<NodeIndex>>, normalized: Vec<Vec<NodeIndex>>)57 fn assert_sccs_eq(mut res: Vec<Vec<NodeIndex>>, normalized: Vec<Vec<NodeIndex>>) {
58     // normalize the result and compare with the answer.
59     for scc in &mut res {
60         scc.sort();
61     }
62     // sort by minimum element
63     res.sort_by(|v, w| v[0].cmp(&w[0]));
64     assert_eq!(res, normalized);
65 }
66 
scc_graph() -> StableGraph<(), ()>67 fn scc_graph() -> StableGraph<(), ()> {
68     let mut gr: StableGraph<(), ()> = StableGraph::from_edges(&[
69         (6, 0),
70         (0, 3),
71         (3, 6),
72         (8, 6),
73         (8, 2),
74         (2, 5),
75         (5, 8),
76         (7, 5),
77         (1, 7),
78         (7, 4),
79         (4, 1),
80     ]);
81     // make an identical replacement of n(4) and leave a hole
82     let x = gr.add_node(());
83     gr.add_edge(n(7), x, ());
84     gr.add_edge(x, n(1), ());
85     gr.remove_node(n(4));
86     gr
87 }
88 
89 #[test]
test_scc()90 fn test_scc() {
91     let gr = scc_graph();
92     println!("{:?}", gr);
93 
94     let x = n(gr.node_bound() - 1);
95     assert_sccs_eq(
96         kosaraju_scc(&gr),
97         vec![
98             vec![n(0), n(3), n(6)],
99             vec![n(1), n(7), x],
100             vec![n(2), n(5), n(8)],
101         ],
102     );
103 }
104 
105 #[test]
test_tarjan_scc()106 fn test_tarjan_scc() {
107     let gr = scc_graph();
108 
109     let x = n(gr.node_bound() - 1);
110     assert_sccs_eq(
111         tarjan_scc(&gr),
112         vec![
113             vec![n(0), n(3), n(6)],
114             vec![n(1), n(7), x],
115             vec![n(2), n(5), n(8)],
116         ],
117     );
118 }
119 
make_graph<Ty>() -> StableGraph<(), i32, Ty> where Ty: EdgeType,120 fn make_graph<Ty>() -> StableGraph<(), i32, Ty>
121 where
122     Ty: EdgeType,
123 {
124     let mut gr = StableGraph::default();
125     let mut c = 0..;
126     let mut e = || -> i32 { c.next().unwrap() };
127     gr.extend_with_edges(&[
128         (6, 0, e()),
129         (0, 3, e()),
130         (3, 6, e()),
131         (8, 6, e()),
132         (8, 2, e()),
133         (2, 5, e()),
134         (5, 8, e()),
135         (7, 5, e()),
136         (1, 7, e()),
137         (7, 4, e()),
138         (8, 6, e()), // parallel edge
139         (4, 1, e()),
140     ]);
141     // make an identical replacement of n(4) and leave a hole
142     let x = gr.add_node(());
143     gr.add_edge(n(7), x, e());
144     gr.add_edge(x, n(1), e());
145     gr.add_edge(x, x, e()); // make two self loops
146     let rm_self_loop = gr.add_edge(x, x, e());
147     gr.add_edge(x, x, e());
148     gr.remove_node(n(4));
149     gr.remove_node(n(6));
150     gr.remove_edge(rm_self_loop);
151     gr
152 }
153 
154 defmac!(edges ref gr, x => gr.edges(x).map(|r| (r.target(), *r.weight())));
155 
156 #[test]
test_edges_directed()157 fn test_edges_directed() {
158     let gr = make_graph::<Directed>();
159     let x = n(9);
160     assert_equal(edges!(gr, x), vec![(x, 16), (x, 14), (n(1), 13)]);
161     assert_equal(edges!(gr, n(0)), vec![(n(3), 1)]);
162     assert_equal(edges!(gr, n(4)), vec![]);
163 }
164 
165 #[test]
test_edge_references()166 fn test_edge_references() {
167     let gr = make_graph::<Directed>();
168     assert_eq!(gr.edge_count(), gr.edge_references().count());
169 }
170 
171 #[test]
test_edges_undirected()172 fn test_edges_undirected() {
173     let gr = make_graph::<Undirected>();
174     let x = n(9);
175     assert_equal(
176         edges!(gr, x),
177         vec![(x, 16), (x, 14), (n(1), 13), (n(7), 12)],
178     );
179     assert_equal(edges!(gr, n(0)), vec![(n(3), 1)]);
180     assert_equal(edges!(gr, n(4)), vec![]);
181 }
182 
183 #[test]
test_edge_iterators_directed()184 fn test_edge_iterators_directed() {
185     let gr = make_graph::<Directed>();
186     for i in gr.node_indices() {
187         itertools::assert_equal(gr.edges_directed(i, Outgoing), gr.edges(i));
188         for edge in gr.edges_directed(i, Outgoing) {
189             assert_eq!(
190                 edge.source(),
191                 i,
192                 "outgoing edges should have a fixed source"
193             );
194         }
195     }
196     let mut incoming = vec![Vec::new(); gr.node_bound()];
197 
198     for i in gr.node_indices() {
199         for j in gr.neighbors(i) {
200             incoming[j.index()].push(i);
201         }
202     }
203 
204     println!("{:#?}", gr);
205     for i in gr.node_indices() {
206         itertools::assert_equal(
207             gr.edges_directed(i, Incoming).map(|e| e.source()),
208             incoming[i.index()].iter().rev().cloned(),
209         );
210         for edge in gr.edges_directed(i, Incoming) {
211             assert_eq!(
212                 edge.target(),
213                 i,
214                 "incoming edges should have a fixed target"
215             );
216         }
217     }
218 }
219 
220 #[test]
test_edge_iterators_undir()221 fn test_edge_iterators_undir() {
222     let gr = make_graph::<Undirected>();
223     for i in gr.node_indices() {
224         itertools::assert_equal(gr.edges_directed(i, Outgoing), gr.edges(i));
225         for edge in gr.edges_directed(i, Outgoing) {
226             assert_eq!(
227                 edge.source(),
228                 i,
229                 "outgoing edges should have a fixed source"
230             );
231         }
232     }
233     for i in gr.node_indices() {
234         itertools::assert_equal(gr.edges_directed(i, Incoming), gr.edges(i));
235         for edge in gr.edges_directed(i, Incoming) {
236             assert_eq!(
237                 edge.target(),
238                 i,
239                 "incoming edges should have a fixed target"
240             );
241         }
242     }
243 }
244 
245 #[test]
246 #[should_panic(expected = "is not a node")]
add_edge_vacant()247 fn add_edge_vacant() {
248     let mut g = StableGraph::<_, _>::new();
249     let a = g.add_node(0);
250     let b = g.add_node(1);
251     let _ = g.add_node(2);
252     let _ = g.remove_node(b);
253     g.add_edge(a, b, 1);
254 }
255 
256 #[test]
257 #[should_panic(expected = "is not a node")]
add_edge_oob()258 fn add_edge_oob() {
259     let mut g = StableGraph::<_, _>::new();
260     let a = g.add_node(0);
261     let _ = g.add_node(1);
262     let _ = g.add_node(2);
263     g.add_edge(a, n(4), 1);
264 }
265 
266 #[test]
test_node_references()267 fn test_node_references() {
268     let gr = scc_graph();
269 
270     itertools::assert_equal(gr.node_references().map(|(i, _)| i), gr.node_indices());
271 }
272 
273 #[test]
iterators_undir()274 fn iterators_undir() {
275     let mut g = StableUnGraph::<_, _>::default();
276     let a = g.add_node(0);
277     let b = g.add_node(1);
278     let c = g.add_node(2);
279     let d = g.add_node(3);
280     g.extend_with_edges(&[(a, b, 1), (a, c, 2), (b, c, 3), (c, c, 4), (a, d, 5)]);
281     g.remove_node(b);
282 
283     itertools::assert_equal(g.neighbors(a), vec![d, c]);
284     itertools::assert_equal(g.neighbors(c), vec![c, a]);
285     itertools::assert_equal(g.neighbors(d), vec![a]);
286 
287     // the node that was removed
288     itertools::assert_equal(g.neighbors(b), vec![]);
289 
290     // remove one more
291     g.remove_node(c);
292     itertools::assert_equal(g.neighbors(c), vec![]);
293 }
294 
295 #[test]
dot()296 fn dot() {
297     let mut gr = StableGraph::new();
298     let a = gr.add_node("x");
299     let b = gr.add_node("y");
300     gr.add_edge(a, a, "10");
301     gr.add_edge(a, b, "20");
302     let dot_output = format!("{}", Dot::new(&gr));
303     assert_eq!(
304         dot_output,
305         r#"digraph {
306     0 [ label = "x" ]
307     1 [ label = "y" ]
308     0 -> 0 [ label = "10" ]
309     0 -> 1 [ label = "20" ]
310 }
311 "#
312     );
313 }
314 
315 defmac!(iter_eq a, b => a.eq(b));
316 defmac!(nodes_eq ref a, ref b => a.node_references().eq(b.node_references()));
317 defmac!(edgew_eq ref a, ref b => a.edge_references().eq(b.edge_references()));
318 defmac!(edges_eq ref a, ref b =>
319         iter_eq!(
320             a.edge_references().map(|e| (e.source(), e.target())),
321             b.edge_references().map(|e| (e.source(), e.target()))));
322 
323 #[test]
from()324 fn from() {
325     let mut gr1 = StableGraph::new();
326     let a = gr1.add_node(1);
327     let b = gr1.add_node(2);
328     let c = gr1.add_node(3);
329     gr1.add_edge(a, a, 10);
330     gr1.add_edge(a, b, 20);
331     gr1.add_edge(b, c, 30);
332     gr1.add_edge(a, c, 40);
333 
334     let gr2 = Graph::from(gr1.clone());
335     let gr3 = StableGraph::from(gr2);
336     assert!(nodes_eq!(gr1, gr3));
337     assert!(edgew_eq!(gr1, gr3));
338     assert!(edges_eq!(gr1, gr3));
339 
340     gr1.remove_node(b);
341 
342     let gr4 = Graph::from(gr1);
343     let gr5 = StableGraph::from(gr4.clone());
344 
345     let mut ans = StableGraph::new();
346     let a = ans.add_node(1);
347     let c = ans.add_node(3);
348     ans.add_edge(a, a, 10);
349     ans.add_edge(a, c, 40);
350 
351     assert!(nodes_eq!(gr4, ans));
352     assert!(edges_eq!(gr4, ans));
353 
354     assert!(nodes_eq!(gr5, ans));
355     assert!(edgew_eq!(gr5, ans));
356     assert!(edges_eq!(gr5, ans));
357 }
358 
359 use petgraph::data::FromElements;
360 use petgraph::stable_graph::StableGraph;
361 
362 #[test]
from_min_spanning_tree()363 fn from_min_spanning_tree() {
364     let mut g = StableGraph::new();
365     let mut nodes = Vec::new();
366     for _ in 0..6 {
367         nodes.push(g.add_node(()));
368     }
369     let es = [(4, 5), (3, 4), (3, 5)];
370     for &(a, b) in es.iter() {
371         g.add_edge(NodeIndex::new(a), NodeIndex::new(b), ());
372     }
373     for i in 0..3 {
374         let _ = g.remove_node(nodes[i]);
375     }
376     let _ = StableGraph::<(), (), Undirected, usize>::from_elements(min_spanning_tree(&g));
377 }
378 
379 #[test]
weights_mut_iterator()380 fn weights_mut_iterator() {
381     let mut gr = StableGraph::new();
382     let a = gr.add_node(1);
383     let b = gr.add_node(2);
384     let c = gr.add_node(3);
385     let e1 = gr.add_edge(a, a, 10);
386     let e2 = gr.add_edge(a, b, 20);
387     let e3 = gr.add_edge(b, c, 30);
388     let e4 = gr.add_edge(a, c, 40);
389 
390     for n in gr.node_weights_mut() {
391         *n += 1;
392     }
393     assert_eq!(gr[a], 2);
394     assert_eq!(gr[b], 3);
395     assert_eq!(gr[c], 4);
396 
397     for e in gr.edge_weights_mut() {
398         *e -= 1;
399     }
400     assert_eq!(gr[e1], 9);
401     assert_eq!(gr[e2], 19);
402     assert_eq!(gr[e3], 29);
403     assert_eq!(gr[e4], 39);
404 
405     // test on deletion
406     gr.remove_node(b);
407     assert_eq!(gr.node_weights_mut().count(), gr.node_count());
408     assert_eq!(gr.edge_weights_mut().count(), gr.edge_count());
409 }
410