Statistics
| Branch: | Revision:

iof-tools / networkxMiCe / networkx-master / networkx / classes / tests / test_multigraph.py @ 5cef0f13

History | View | Annotate | Download (12.8 KB)

1
#!/usr/bin/env python
2
from nose.tools import assert_equal
3
from nose.tools import assert_is
4
from nose.tools import assert_not_equal
5
from nose.tools import assert_raises
6

    
7
import networkx as nx
8
from networkx.testing.utils import *
9

    
10
from test_graph import BaseAttrGraphTester, TestGraph
11

    
12

    
13
class BaseMultiGraphTester(BaseAttrGraphTester):
14
    def test_has_edge(self):
15
        G = self.K3
16
        assert_equal(G.has_edge(0, 1), True)
17
        assert_equal(G.has_edge(0, -1), False)
18
        assert_equal(G.has_edge(0, 1, 0), True)
19
        assert_equal(G.has_edge(0, 1, 1), False)
20

    
21
    def test_get_edge_data(self):
22
        G = self.K3
23
        assert_equal(G.get_edge_data(0, 1), {0: {}})
24
        assert_equal(G[0][1], {0: {}})
25
        assert_equal(G[0][1][0], {})
26
        assert_equal(G.get_edge_data(10, 20), None)
27
        assert_equal(G.get_edge_data(0, 1, 0), {})
28

    
29
    def test_adjacency(self):
30
        G = self.K3
31
        assert_equal(dict(G.adjacency()),
32
                     {0: {1: {0: {}}, 2: {0: {}}},
33
                      1: {0: {0: {}}, 2: {0: {}}},
34
                      2: {0: {0: {}}, 1: {0: {}}}})
35

    
36
    def deepcopy_edge_attr(self, H, G):
37
        assert_equal(G[1][2][0]['foo'], H[1][2][0]['foo'])
38
        G[1][2][0]['foo'].append(1)
39
        assert_not_equal(G[1][2][0]['foo'], H[1][2][0]['foo'])
40

    
41
    def shallow_copy_edge_attr(self, H, G):
42
        assert_equal(G[1][2][0]['foo'], H[1][2][0]['foo'])
43
        G[1][2][0]['foo'].append(1)
44
        assert_equal(G[1][2][0]['foo'], H[1][2][0]['foo'])
45

    
46
    def graphs_equal(self, H, G):
47
        assert_equal(G._adj, H._adj)
48
        assert_equal(G._node, H._node)
49
        assert_equal(G.graph, H.graph)
50
        assert_equal(G.name, H.name)
51
        if not G.is_directed() and not H.is_directed():
52
            assert_is(H._adj[1][2][0], H._adj[2][1][0])
53
            assert_is(G._adj[1][2][0], G._adj[2][1][0])
54
        else:  # at least one is directed
55
            if not G.is_directed():
56
                G._pred = G._adj
57
                G._succ = G._adj
58
            if not H.is_directed():
59
                H._pred = H._adj
60
                H._succ = H._adj
61
            assert_equal(G._pred, H._pred)
62
            assert_equal(G._succ, H._succ)
63
            assert_is(H._succ[1][2][0], H._pred[2][1][0])
64
            assert_is(G._succ[1][2][0], G._pred[2][1][0])
65

    
66
    def same_attrdict(self, H, G):
67
        # same attrdict in the edgedata
68
        old_foo = H[1][2][0]['foo']
69
        H.adj[1][2][0]['foo'] = 'baz'
70
        assert_equal(G._adj, H._adj)
71
        H.adj[1][2][0]['foo'] = old_foo
72
        assert_equal(G._adj, H._adj)
73

    
74
        old_foo = H.nodes[0]['foo']
75
        H.nodes[0]['foo'] = 'baz'
76
        assert_equal(G._node, H._node)
77
        H.nodes[0]['foo'] = old_foo
78
        assert_equal(G._node, H._node)
79

    
80
    def different_attrdict(self, H, G):
81
        # used by graph_equal_but_different
82
        old_foo = H[1][2][0]['foo']
83
        H.adj[1][2][0]['foo'] = 'baz'
84
        assert_not_equal(G._adj, H._adj)
85
        H.adj[1][2][0]['foo'] = old_foo
86
        assert_equal(G._adj, H._adj)
87

    
88
        old_foo = H.nodes[0]['foo']
89
        H.nodes[0]['foo'] = 'baz'
90
        assert_not_equal(G._node, H._node)
91
        H.nodes[0]['foo'] = old_foo
92
        assert_equal(G._node, H._node)
93

    
94
    def test_to_undirected(self):
95
        G = self.K3
96
        self.add_attributes(G)
97
        H = nx.MultiGraph(G)
98
        self.is_shallow_copy(H, G)
99
        H = G.to_undirected()
100
        self.is_deepcopy(H, G)
101

    
102
    def test_to_directed(self):
103
        G = self.K3
104
        self.add_attributes(G)
105
        H = nx.MultiDiGraph(G)
106
        self.is_shallow_copy(H, G)
107
        H = G.to_directed()
108
        self.is_deepcopy(H, G)
109

    
110
    def test_number_of_edges_selfloops(self):
111
        G = self.K3
112
        G.add_edge(0, 0)
113
        G.add_edge(0, 0)
114
        G.add_edge(0, 0, key='parallel edge')
115
        G.remove_edge(0, 0, key='parallel edge')
116
        assert_equal(G.number_of_edges(0, 0), 2)
117
        G.remove_edge(0, 0)
118
        assert_equal(G.number_of_edges(0, 0), 1)
119

    
120
    def test_edge_lookup(self):
121
        G = self.Graph()
122
        G.add_edge(1, 2, foo='bar')
123
        G.add_edge(1, 2, 'key', foo='biz')
124
        assert_edges_equal(G.edges[1, 2, 0], {'foo': 'bar'})
125
        assert_edges_equal(G.edges[1, 2, 'key'], {'foo': 'biz'})
126

    
127
    def test_edge_attr4(self):
128
        G = self.Graph()
129
        G.add_edge(1, 2, key=0, data=7, spam='bar', bar='foo')
130
        assert_edges_equal(G.edges(data=True),
131
                           [(1, 2, {'data': 7, 'spam': 'bar', 'bar': 'foo'})])
132
        G[1][2][0]['data'] = 10  # OK to set data like this
133
        assert_edges_equal(G.edges(data=True),
134
                           [(1, 2, {'data': 10, 'spam': 'bar', 'bar': 'foo'})])
135

    
136
        G.adj[1][2][0]['data'] = 20
137
        assert_edges_equal(G.edges(data=True),
138
                           [(1, 2, {'data': 20, 'spam': 'bar', 'bar': 'foo'})])
139
        G.edges[1, 2, 0]['data'] = 21  # another spelling, "edge"
140
        assert_edges_equal(G.edges(data=True),
141
                           [(1, 2, {'data': 21, 'spam': 'bar', 'bar': 'foo'})])
142
        G.adj[1][2][0]['listdata'] = [20, 200]
143
        G.adj[1][2][0]['weight'] = 20
144
        assert_edges_equal(G.edges(data=True),
145
                           [(1, 2, {'data': 21, 'spam': 'bar', 'bar': 'foo',
146
                                    'listdata': [20, 200], 'weight':20})])
147

    
148

    
149
class TestMultiGraph(BaseMultiGraphTester, TestGraph):
150
    def setUp(self):
151
        self.Graph = nx.MultiGraph
152
        # build K3
153
        ed1, ed2, ed3 = ({0: {}}, {0: {}}, {0: {}})
154
        self.k3adj = {0: {1: ed1, 2: ed2},
155
                      1: {0: ed1, 2: ed3},
156
                      2: {0: ed2, 1: ed3}}
157
        self.k3edges = [(0, 1), (0, 2), (1, 2)]
158
        self.k3nodes = [0, 1, 2]
159
        self.K3 = self.Graph()
160
        self.K3._adj = self.k3adj
161
        self.K3._node = {}
162
        self.K3._node[0] = {}
163
        self.K3._node[1] = {}
164
        self.K3._node[2] = {}
165

    
166
    def test_data_input(self):
167
        G = self.Graph({1: [2], 2: [1]}, name="test")
168
        assert_equal(G.name, "test")
169
        expected = [(1, {2: {0: {}}}), (2, {1: {0: {}}})]
170
        assert_equal(sorted(G.adj.items()), expected)
171

    
172
    def test_getitem(self):
173
        G = self.K3
174
        assert_equal(G[0], {1: {0: {}}, 2: {0: {}}})
175
        assert_raises(KeyError, G.__getitem__, 'j')
176
        assert_raises((TypeError, nx.NetworkXError), G.__getitem__, ['A'])
177

    
178
    def test_remove_node(self):
179
        G = self.K3
180
        G.remove_node(0)
181
        assert_equal(G.adj, {1: {2: {0: {}}}, 2: {1: {0: {}}}})
182
        assert_raises((KeyError, nx.NetworkXError), G.remove_node, -1)
183

    
184
    def test_add_edge(self):
185
        G = self.Graph()
186
        G.add_edge(0, 1)
187
        assert_equal(G.adj, {0: {1: {0: {}}}, 1: {0: {0: {}}}})
188
        G = self.Graph()
189
        G.add_edge(*(0, 1))
190
        assert_equal(G.adj, {0: {1: {0: {}}}, 1: {0: {0: {}}}})
191

    
192
    def test_add_edge_conflicting_key(self):
193
        G = self.Graph()
194
        G.add_edge(0, 1, key=1)
195
        G.add_edge(0, 1)
196
        assert_equal(G.number_of_edges(), 2)
197
        G = self.Graph()
198
        G.add_edges_from([(0, 1, 1, {})])
199
        G.add_edges_from([(0, 1)])
200
        assert_equal(G.number_of_edges(), 2)
201

    
202
    def test_add_edges_from(self):
203
        G = self.Graph()
204
        G.add_edges_from([(0, 1), (0, 1, {'weight': 3})])
205
        assert_equal(G.adj, {0: {1: {0: {}, 1: {'weight': 3}}},
206
                             1: {0: {0: {}, 1: {'weight': 3}}}})
207
        G.add_edges_from([(0, 1), (0, 1, {'weight': 3})], weight=2)
208
        assert_equal(G.adj, {0: {1: {0: {}, 1: {'weight': 3},
209
                                     2: {'weight': 2}, 3: {'weight': 3}}},
210
                             1: {0: {0: {}, 1: {'weight': 3},
211
                                     2: {'weight': 2}, 3: {'weight': 3}}}})
212
        G = self.Graph()
213
        edges = [(0, 1, {'weight': 3}), (0, 1, (('weight', 2),)),
214
                 (0, 1, 5), (0, 1, 's')]
215
        G.add_edges_from(edges)
216
        keydict = {0: {'weight': 3}, 1: {'weight': 2}, 5: {}, 's': {}}
217
        assert_equal(G._adj, {0: {1: keydict}, 1: {0: keydict}})
218

    
219
        # too few in tuple
220
        assert_raises(nx.NetworkXError, G.add_edges_from, [(0,)])
221
        # too many in tuple
222
        assert_raises(nx.NetworkXError, G.add_edges_from, [(0, 1, 2, 3, 4)])
223
        # not a tuple
224
        assert_raises(TypeError, G.add_edges_from, [0])
225

    
226
    def test_remove_edge(self):
227
        G = self.K3
228
        G.remove_edge(0, 1)
229
        assert_equal(G.adj, {0: {2: {0: {}}},
230
                             1: {2: {0: {}}},
231
                             2: {0: {0: {}},
232
                                 1: {0: {}}}})
233

    
234
        assert_raises((KeyError, nx.NetworkXError), G.remove_edge, -1, 0)
235
        assert_raises((KeyError, nx.NetworkXError), G.remove_edge, 0, 2,
236
                      key=1)
237

    
238
    def test_remove_edges_from(self):
239
        G = self.K3.copy()
240
        G.remove_edges_from([(0, 1)])
241
        kd = {0: {}}
242
        assert_equal(G.adj, {0: {2: kd}, 1: {2: kd}, 2: {0: kd, 1: kd}})
243
        G.remove_edges_from([(0, 0)])  # silent fail
244
        self.K3.add_edge(0, 1)
245
        G = self.K3.copy()
246
        G.remove_edges_from(list(G.edges(data=True, keys=True)))
247
        assert_equal(G.adj, {0: {}, 1: {}, 2: {}})
248
        G = self.K3.copy()
249
        G.remove_edges_from(list(G.edges(data=False, keys=True)))
250
        assert_equal(G.adj, {0: {}, 1: {}, 2: {}})
251
        G = self.K3.copy()
252
        G.remove_edges_from(list(G.edges(data=False, keys=False)))
253
        assert_equal(G.adj, {0: {}, 1: {}, 2: {}})
254
        G = self.K3.copy()
255
        G.remove_edges_from([(0, 1, 0), (0, 2, 0, {}), (1, 2)])
256
        assert_equal(G.adj, {0: {1: {1: {}}}, 1: {0: {1: {}}}, 2: {}})
257

    
258
    def test_remove_multiedge(self):
259
        G = self.K3
260
        G.add_edge(0, 1, key='parallel edge')
261
        G.remove_edge(0, 1, key='parallel edge')
262
        assert_equal(G.adj, {0: {1: {0: {}}, 2: {0: {}}},
263
                             1: {0: {0: {}}, 2: {0: {}}},
264
                             2: {0: {0: {}}, 1: {0: {}}}})
265
        G.remove_edge(0, 1)
266
        kd = {0: {}}
267
        assert_equal(G.adj, {0: {2: kd}, 1: {2: kd}, 2: {0: kd, 1: kd}})
268
        assert_raises((KeyError, nx.NetworkXError), G.remove_edge, -1, 0)
269

    
270

    
271
class TestEdgeSubgraph(object):
272
    """Unit tests for the :meth:`MultiGraph.edge_subgraph` method."""
273

    
274
    def setup(self):
275
        # Create a doubly-linked path graph on five nodes.
276
        G = nx.MultiGraph()
277
        nx.add_path(G, range(5))
278
        nx.add_path(G, range(5))
279
        # Add some node, edge, and graph attributes.
280
        for i in range(5):
281
            G.nodes[i]['name'] = 'node{}'.format(i)
282
        G.adj[0][1][0]['name'] = 'edge010'
283
        G.adj[0][1][1]['name'] = 'edge011'
284
        G.adj[3][4][0]['name'] = 'edge340'
285
        G.adj[3][4][1]['name'] = 'edge341'
286
        G.graph['name'] = 'graph'
287
        # Get the subgraph induced by one of the first edges and one of
288
        # the last edges.
289
        self.G = G
290
        self.H = G.edge_subgraph([(0, 1, 0), (3, 4, 1)])
291

    
292
    def test_correct_nodes(self):
293
        """Tests that the subgraph has the correct nodes."""
294
        assert_equal([0, 1, 3, 4], sorted(self.H.nodes()))
295

    
296
    def test_correct_edges(self):
297
        """Tests that the subgraph has the correct edges."""
298
        assert_equal([(0, 1, 0, 'edge010'), (3, 4, 1, 'edge341')],
299
                     sorted(self.H.edges(keys=True, data='name')))
300

    
301
    def test_add_node(self):
302
        """Tests that adding a node to the original graph does not
303
        affect the nodes of the subgraph.
304

305
        """
306
        self.G.add_node(5)
307
        assert_equal([0, 1, 3, 4], sorted(self.H.nodes()))
308

    
309
    def test_remove_node(self):
310
        """Tests that removing a node in the original graph does
311
        affect the nodes of the subgraph.
312

313
        """
314
        self.G.remove_node(0)
315
        assert_equal([1, 3, 4], sorted(self.H.nodes()))
316

    
317
    def test_node_attr_dict(self):
318
        """Tests that the node attribute dictionary of the two graphs is
319
        the same object.
320

321
        """
322
        for v in self.H:
323
            assert_equal(self.G.nodes[v], self.H.nodes[v])
324
        # Making a change to G should make a change in H and vice versa.
325
        self.G.nodes[0]['name'] = 'foo'
326
        assert_equal(self.G.nodes[0], self.H.nodes[0])
327
        self.H.nodes[1]['name'] = 'bar'
328
        assert_equal(self.G.nodes[1], self.H.nodes[1])
329

    
330
    def test_edge_attr_dict(self):
331
        """Tests that the edge attribute dictionary of the two graphs is
332
        the same object.
333

334
        """
335
        for u, v, k in self.H.edges(keys=True):
336
            assert_equal(self.G._adj[u][v][k], self.H._adj[u][v][k])
337
        # Making a change to G should make a change in H and vice versa.
338
        self.G._adj[0][1][0]['name'] = 'foo'
339
        assert_equal(self.G._adj[0][1][0]['name'],
340
                     self.H._adj[0][1][0]['name'])
341
        self.H._adj[3][4][1]['name'] = 'bar'
342
        assert_equal(self.G._adj[3][4][1]['name'],
343
                     self.H._adj[3][4][1]['name'])
344

    
345
    def test_graph_attr_dict(self):
346
        """Tests that the graph attribute dictionary of the two graphs
347
        is the same object.
348

349
        """
350
        assert_is(self.G.graph, self.H.graph)