comparison env/lib/python3.9/site-packages/networkx/classes/tests/test_multigraph.py @ 0:4f3585e2f14b draft default tip

"planemo upload commit 60cee0fc7c0cda8592644e1aad72851dec82c959"
author shellac
date Mon, 22 Mar 2021 18:12:50 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:4f3585e2f14b
1 import pytest
2
3 import networkx as nx
4 from networkx.testing.utils import assert_edges_equal
5
6 from .test_graph import BaseAttrGraphTester
7 from .test_graph import TestGraph as _TestGraph
8
9
10 class BaseMultiGraphTester(BaseAttrGraphTester):
11 def test_has_edge(self):
12 G = self.K3
13 assert G.has_edge(0, 1)
14 assert not G.has_edge(0, -1)
15 assert G.has_edge(0, 1, 0)
16 assert not G.has_edge(0, 1, 1)
17
18 def test_get_edge_data(self):
19 G = self.K3
20 assert G.get_edge_data(0, 1) == {0: {}}
21 assert G[0][1] == {0: {}}
22 assert G[0][1][0] == {}
23 assert G.get_edge_data(10, 20) is None
24 assert G.get_edge_data(0, 1, 0) == {}
25
26 def test_adjacency(self):
27 G = self.K3
28 assert dict(G.adjacency()) == {
29 0: {1: {0: {}}, 2: {0: {}}},
30 1: {0: {0: {}}, 2: {0: {}}},
31 2: {0: {0: {}}, 1: {0: {}}},
32 }
33
34 def deepcopy_edge_attr(self, H, G):
35 assert G[1][2][0]["foo"] == H[1][2][0]["foo"]
36 G[1][2][0]["foo"].append(1)
37 assert G[1][2][0]["foo"] != H[1][2][0]["foo"]
38
39 def shallow_copy_edge_attr(self, H, G):
40 assert G[1][2][0]["foo"] == H[1][2][0]["foo"]
41 G[1][2][0]["foo"].append(1)
42 assert G[1][2][0]["foo"] == H[1][2][0]["foo"]
43
44 def graphs_equal(self, H, G):
45 assert G._adj == H._adj
46 assert G._node == H._node
47 assert G.graph == H.graph
48 assert G.name == H.name
49 if not G.is_directed() and not H.is_directed():
50 assert H._adj[1][2][0] is H._adj[2][1][0]
51 assert G._adj[1][2][0] is G._adj[2][1][0]
52 else: # at least one is directed
53 if not G.is_directed():
54 G._pred = G._adj
55 G._succ = G._adj
56 if not H.is_directed():
57 H._pred = H._adj
58 H._succ = H._adj
59 assert G._pred == H._pred
60 assert G._succ == H._succ
61 assert H._succ[1][2][0] is H._pred[2][1][0]
62 assert G._succ[1][2][0] is G._pred[2][1][0]
63
64 def same_attrdict(self, H, G):
65 # same attrdict in the edgedata
66 old_foo = H[1][2][0]["foo"]
67 H.adj[1][2][0]["foo"] = "baz"
68 assert G._adj == H._adj
69 H.adj[1][2][0]["foo"] = old_foo
70 assert G._adj == H._adj
71
72 old_foo = H.nodes[0]["foo"]
73 H.nodes[0]["foo"] = "baz"
74 assert G._node == H._node
75 H.nodes[0]["foo"] = old_foo
76 assert G._node == H._node
77
78 def different_attrdict(self, H, G):
79 # used by graph_equal_but_different
80 old_foo = H[1][2][0]["foo"]
81 H.adj[1][2][0]["foo"] = "baz"
82 assert G._adj != H._adj
83 H.adj[1][2][0]["foo"] = old_foo
84 assert G._adj == H._adj
85
86 old_foo = H.nodes[0]["foo"]
87 H.nodes[0]["foo"] = "baz"
88 assert G._node != H._node
89 H.nodes[0]["foo"] = old_foo
90 assert G._node == H._node
91
92 def test_to_undirected(self):
93 G = self.K3
94 self.add_attributes(G)
95 H = nx.MultiGraph(G)
96 self.is_shallow_copy(H, G)
97 H = G.to_undirected()
98 self.is_deepcopy(H, G)
99
100 def test_to_directed(self):
101 G = self.K3
102 self.add_attributes(G)
103 H = nx.MultiDiGraph(G)
104 self.is_shallow_copy(H, G)
105 H = G.to_directed()
106 self.is_deepcopy(H, G)
107
108 def test_number_of_edges_selfloops(self):
109 G = self.K3
110 G.add_edge(0, 0)
111 G.add_edge(0, 0)
112 G.add_edge(0, 0, key="parallel edge")
113 G.remove_edge(0, 0, key="parallel edge")
114 assert G.number_of_edges(0, 0) == 2
115 G.remove_edge(0, 0)
116 assert G.number_of_edges(0, 0) == 1
117
118 def test_edge_lookup(self):
119 G = self.Graph()
120 G.add_edge(1, 2, foo="bar")
121 G.add_edge(1, 2, "key", foo="biz")
122 assert_edges_equal(G.edges[1, 2, 0], {"foo": "bar"})
123 assert_edges_equal(G.edges[1, 2, "key"], {"foo": "biz"})
124
125 def test_edge_attr4(self):
126 G = self.Graph()
127 G.add_edge(1, 2, key=0, data=7, spam="bar", bar="foo")
128 assert_edges_equal(
129 G.edges(data=True), [(1, 2, {"data": 7, "spam": "bar", "bar": "foo"})]
130 )
131 G[1][2][0]["data"] = 10 # OK to set data like this
132 assert_edges_equal(
133 G.edges(data=True), [(1, 2, {"data": 10, "spam": "bar", "bar": "foo"})]
134 )
135
136 G.adj[1][2][0]["data"] = 20
137 assert_edges_equal(
138 G.edges(data=True), [(1, 2, {"data": 20, "spam": "bar", "bar": "foo"})]
139 )
140 G.edges[1, 2, 0]["data"] = 21 # another spelling, "edge"
141 assert_edges_equal(
142 G.edges(data=True), [(1, 2, {"data": 21, "spam": "bar", "bar": "foo"})]
143 )
144 G.adj[1][2][0]["listdata"] = [20, 200]
145 G.adj[1][2][0]["weight"] = 20
146 assert_edges_equal(
147 G.edges(data=True),
148 [
149 (
150 1,
151 2,
152 {
153 "data": 21,
154 "spam": "bar",
155 "bar": "foo",
156 "listdata": [20, 200],
157 "weight": 20,
158 },
159 )
160 ],
161 )
162
163
164 class TestMultiGraph(BaseMultiGraphTester, _TestGraph):
165 def setup_method(self):
166 self.Graph = nx.MultiGraph
167 # build K3
168 ed1, ed2, ed3 = ({0: {}}, {0: {}}, {0: {}})
169 self.k3adj = {0: {1: ed1, 2: ed2}, 1: {0: ed1, 2: ed3}, 2: {0: ed2, 1: ed3}}
170 self.k3edges = [(0, 1), (0, 2), (1, 2)]
171 self.k3nodes = [0, 1, 2]
172 self.K3 = self.Graph()
173 self.K3._adj = self.k3adj
174 self.K3._node = {}
175 self.K3._node[0] = {}
176 self.K3._node[1] = {}
177 self.K3._node[2] = {}
178
179 def test_data_input(self):
180 G = self.Graph({1: [2], 2: [1]}, name="test")
181 assert G.name == "test"
182 expected = [(1, {2: {0: {}}}), (2, {1: {0: {}}})]
183 assert sorted(G.adj.items()) == expected
184
185 def test_getitem(self):
186 G = self.K3
187 assert G[0] == {1: {0: {}}, 2: {0: {}}}
188 with pytest.raises(KeyError):
189 G.__getitem__("j")
190 with pytest.raises(TypeError):
191 G.__getitem__(["A"])
192
193 def test_remove_node(self):
194 G = self.K3
195 G.remove_node(0)
196 assert G.adj == {1: {2: {0: {}}}, 2: {1: {0: {}}}}
197 with pytest.raises(nx.NetworkXError):
198 G.remove_node(-1)
199
200 def test_add_edge(self):
201 G = self.Graph()
202 G.add_edge(0, 1)
203 assert G.adj == {0: {1: {0: {}}}, 1: {0: {0: {}}}}
204 G = self.Graph()
205 G.add_edge(*(0, 1))
206 assert G.adj == {0: {1: {0: {}}}, 1: {0: {0: {}}}}
207
208 def test_add_edge_conflicting_key(self):
209 G = self.Graph()
210 G.add_edge(0, 1, key=1)
211 G.add_edge(0, 1)
212 assert G.number_of_edges() == 2
213 G = self.Graph()
214 G.add_edges_from([(0, 1, 1, {})])
215 G.add_edges_from([(0, 1)])
216 assert G.number_of_edges() == 2
217
218 def test_add_edges_from(self):
219 G = self.Graph()
220 G.add_edges_from([(0, 1), (0, 1, {"weight": 3})])
221 assert G.adj == {
222 0: {1: {0: {}, 1: {"weight": 3}}},
223 1: {0: {0: {}, 1: {"weight": 3}}},
224 }
225 G.add_edges_from([(0, 1), (0, 1, {"weight": 3})], weight=2)
226 assert G.adj == {
227 0: {1: {0: {}, 1: {"weight": 3}, 2: {"weight": 2}, 3: {"weight": 3}}},
228 1: {0: {0: {}, 1: {"weight": 3}, 2: {"weight": 2}, 3: {"weight": 3}}},
229 }
230 G = self.Graph()
231 edges = [
232 (0, 1, {"weight": 3}),
233 (0, 1, (("weight", 2),)),
234 (0, 1, 5),
235 (0, 1, "s"),
236 ]
237 G.add_edges_from(edges)
238 keydict = {0: {"weight": 3}, 1: {"weight": 2}, 5: {}, "s": {}}
239 assert G._adj == {0: {1: keydict}, 1: {0: keydict}}
240
241 # too few in tuple
242 with pytest.raises(nx.NetworkXError):
243 G.add_edges_from([(0,)])
244 # too many in tuple
245 with pytest.raises(nx.NetworkXError):
246 G.add_edges_from([(0, 1, 2, 3, 4)])
247 # not a tuple
248 with pytest.raises(TypeError):
249 G.add_edges_from([0])
250
251 def test_remove_edge(self):
252 G = self.K3
253 G.remove_edge(0, 1)
254 assert G.adj == {0: {2: {0: {}}}, 1: {2: {0: {}}}, 2: {0: {0: {}}, 1: {0: {}}}}
255
256 with pytest.raises(nx.NetworkXError):
257 G.remove_edge(-1, 0)
258 with pytest.raises(nx.NetworkXError):
259 G.remove_edge(0, 2, key=1)
260
261 def test_remove_edges_from(self):
262 G = self.K3.copy()
263 G.remove_edges_from([(0, 1)])
264 kd = {0: {}}
265 assert G.adj == {0: {2: kd}, 1: {2: kd}, 2: {0: kd, 1: kd}}
266 G.remove_edges_from([(0, 0)]) # silent fail
267 self.K3.add_edge(0, 1)
268 G = self.K3.copy()
269 G.remove_edges_from(list(G.edges(data=True, keys=True)))
270 assert G.adj == {0: {}, 1: {}, 2: {}}
271 G = self.K3.copy()
272 G.remove_edges_from(list(G.edges(data=False, keys=True)))
273 assert G.adj == {0: {}, 1: {}, 2: {}}
274 G = self.K3.copy()
275 G.remove_edges_from(list(G.edges(data=False, keys=False)))
276 assert G.adj == {0: {}, 1: {}, 2: {}}
277 G = self.K3.copy()
278 G.remove_edges_from([(0, 1, 0), (0, 2, 0, {}), (1, 2)])
279 assert G.adj == {0: {1: {1: {}}}, 1: {0: {1: {}}}, 2: {}}
280
281 def test_remove_multiedge(self):
282 G = self.K3
283 G.add_edge(0, 1, key="parallel edge")
284 G.remove_edge(0, 1, key="parallel edge")
285 assert G.adj == {
286 0: {1: {0: {}}, 2: {0: {}}},
287 1: {0: {0: {}}, 2: {0: {}}},
288 2: {0: {0: {}}, 1: {0: {}}},
289 }
290 G.remove_edge(0, 1)
291 kd = {0: {}}
292 assert G.adj == {0: {2: kd}, 1: {2: kd}, 2: {0: kd, 1: kd}}
293 with pytest.raises(nx.NetworkXError):
294 G.remove_edge(-1, 0)
295
296
297 class TestEdgeSubgraph:
298 """Unit tests for the :meth:`MultiGraph.edge_subgraph` method."""
299
300 def setup_method(self):
301 # Create a doubly-linked path graph on five nodes.
302 G = nx.MultiGraph()
303 nx.add_path(G, range(5))
304 nx.add_path(G, range(5))
305 # Add some node, edge, and graph attributes.
306 for i in range(5):
307 G.nodes[i]["name"] = f"node{i}"
308 G.adj[0][1][0]["name"] = "edge010"
309 G.adj[0][1][1]["name"] = "edge011"
310 G.adj[3][4][0]["name"] = "edge340"
311 G.adj[3][4][1]["name"] = "edge341"
312 G.graph["name"] = "graph"
313 # Get the subgraph induced by one of the first edges and one of
314 # the last edges.
315 self.G = G
316 self.H = G.edge_subgraph([(0, 1, 0), (3, 4, 1)])
317
318 def test_correct_nodes(self):
319 """Tests that the subgraph has the correct nodes."""
320 assert [0, 1, 3, 4] == sorted(self.H.nodes())
321
322 def test_correct_edges(self):
323 """Tests that the subgraph has the correct edges."""
324 assert [(0, 1, 0, "edge010"), (3, 4, 1, "edge341")] == sorted(
325 self.H.edges(keys=True, data="name")
326 )
327
328 def test_add_node(self):
329 """Tests that adding a node to the original graph does not
330 affect the nodes of the subgraph.
331
332 """
333 self.G.add_node(5)
334 assert [0, 1, 3, 4] == sorted(self.H.nodes())
335
336 def test_remove_node(self):
337 """Tests that removing a node in the original graph does
338 affect the nodes of the subgraph.
339
340 """
341 self.G.remove_node(0)
342 assert [1, 3, 4] == sorted(self.H.nodes())
343
344 def test_node_attr_dict(self):
345 """Tests that the node attribute dictionary of the two graphs is
346 the same object.
347
348 """
349 for v in self.H:
350 assert self.G.nodes[v] == self.H.nodes[v]
351 # Making a change to G should make a change in H and vice versa.
352 self.G.nodes[0]["name"] = "foo"
353 assert self.G.nodes[0] == self.H.nodes[0]
354 self.H.nodes[1]["name"] = "bar"
355 assert self.G.nodes[1] == self.H.nodes[1]
356
357 def test_edge_attr_dict(self):
358 """Tests that the edge attribute dictionary of the two graphs is
359 the same object.
360
361 """
362 for u, v, k in self.H.edges(keys=True):
363 assert self.G._adj[u][v][k] == self.H._adj[u][v][k]
364 # Making a change to G should make a change in H and vice versa.
365 self.G._adj[0][1][0]["name"] = "foo"
366 assert self.G._adj[0][1][0]["name"] == self.H._adj[0][1][0]["name"]
367 self.H._adj[3][4][1]["name"] = "bar"
368 assert self.G._adj[3][4][1]["name"] == self.H._adj[3][4][1]["name"]
369
370 def test_graph_attr_dict(self):
371 """Tests that the graph attribute dictionary of the two graphs
372 is the same object.
373
374 """
375 assert self.G.graph is self.H.graph