This repository has been archived on 2023-03-25. You can view files and clone it, but cannot push or open issues or pull requests.
mightyscape-1.1-deprecated/extensions/networkx/classes/tests/test_multigraph.py

357 lines
12 KiB
Python
Raw Normal View History

2020-07-30 01:16:18 +02:00
#!/usr/bin/env python
import pytest
import networkx as nx
from networkx.testing.utils import *
from .test_graph import BaseAttrGraphTester, TestGraph
class BaseMultiGraphTester(BaseAttrGraphTester):
def test_has_edge(self):
G = self.K3
assert G.has_edge(0, 1) == True
assert G.has_edge(0, -1) == False
assert G.has_edge(0, 1, 0) == True
assert G.has_edge(0, 1, 1) == False
def test_get_edge_data(self):
G = self.K3
assert G.get_edge_data(0, 1) == {0: {}}
assert G[0][1] == {0: {}}
assert G[0][1][0] == {}
assert G.get_edge_data(10, 20) == None
assert G.get_edge_data(0, 1, 0) == {}
def test_adjacency(self):
G = self.K3
assert (dict(G.adjacency()) ==
{0: {1: {0: {}}, 2: {0: {}}},
1: {0: {0: {}}, 2: {0: {}}},
2: {0: {0: {}}, 1: {0: {}}}})
def deepcopy_edge_attr(self, H, G):
assert G[1][2][0]['foo'] == H[1][2][0]['foo']
G[1][2][0]['foo'].append(1)
assert G[1][2][0]['foo'] != H[1][2][0]['foo']
def shallow_copy_edge_attr(self, H, G):
assert G[1][2][0]['foo'] == H[1][2][0]['foo']
G[1][2][0]['foo'].append(1)
assert G[1][2][0]['foo'] == H[1][2][0]['foo']
def graphs_equal(self, H, G):
assert G._adj == H._adj
assert G._node == H._node
assert G.graph == H.graph
assert G.name == H.name
if not G.is_directed() and not H.is_directed():
assert H._adj[1][2][0] is H._adj[2][1][0]
assert G._adj[1][2][0] is G._adj[2][1][0]
else: # at least one is directed
if not G.is_directed():
G._pred = G._adj
G._succ = G._adj
if not H.is_directed():
H._pred = H._adj
H._succ = H._adj
assert G._pred == H._pred
assert G._succ == H._succ
assert H._succ[1][2][0] is H._pred[2][1][0]
assert G._succ[1][2][0] is G._pred[2][1][0]
def same_attrdict(self, H, G):
# same attrdict in the edgedata
old_foo = H[1][2][0]['foo']
H.adj[1][2][0]['foo'] = 'baz'
assert G._adj == H._adj
H.adj[1][2][0]['foo'] = old_foo
assert G._adj == H._adj
old_foo = H.nodes[0]['foo']
H.nodes[0]['foo'] = 'baz'
assert G._node == H._node
H.nodes[0]['foo'] = old_foo
assert G._node == H._node
def different_attrdict(self, H, G):
# used by graph_equal_but_different
old_foo = H[1][2][0]['foo']
H.adj[1][2][0]['foo'] = 'baz'
assert G._adj != H._adj
H.adj[1][2][0]['foo'] = old_foo
assert G._adj == H._adj
old_foo = H.nodes[0]['foo']
H.nodes[0]['foo'] = 'baz'
assert G._node != H._node
H.nodes[0]['foo'] = old_foo
assert G._node == H._node
def test_to_undirected(self):
G = self.K3
self.add_attributes(G)
H = nx.MultiGraph(G)
self.is_shallow_copy(H, G)
H = G.to_undirected()
self.is_deepcopy(H, G)
def test_to_directed(self):
G = self.K3
self.add_attributes(G)
H = nx.MultiDiGraph(G)
self.is_shallow_copy(H, G)
H = G.to_directed()
self.is_deepcopy(H, G)
def test_number_of_edges_selfloops(self):
G = self.K3
G.add_edge(0, 0)
G.add_edge(0, 0)
G.add_edge(0, 0, key='parallel edge')
G.remove_edge(0, 0, key='parallel edge')
assert G.number_of_edges(0, 0) == 2
G.remove_edge(0, 0)
assert G.number_of_edges(0, 0) == 1
def test_edge_lookup(self):
G = self.Graph()
G.add_edge(1, 2, foo='bar')
G.add_edge(1, 2, 'key', foo='biz')
assert_edges_equal(G.edges[1, 2, 0], {'foo': 'bar'})
assert_edges_equal(G.edges[1, 2, 'key'], {'foo': 'biz'})
def test_edge_attr4(self):
G = self.Graph()
G.add_edge(1, 2, key=0, data=7, spam='bar', bar='foo')
assert_edges_equal(G.edges(data=True),
[(1, 2, {'data': 7, 'spam': 'bar', 'bar': 'foo'})])
G[1][2][0]['data'] = 10 # OK to set data like this
assert_edges_equal(G.edges(data=True),
[(1, 2, {'data': 10, 'spam': 'bar', 'bar': 'foo'})])
G.adj[1][2][0]['data'] = 20
assert_edges_equal(G.edges(data=True),
[(1, 2, {'data': 20, 'spam': 'bar', 'bar': 'foo'})])
G.edges[1, 2, 0]['data'] = 21 # another spelling, "edge"
assert_edges_equal(G.edges(data=True),
[(1, 2, {'data': 21, 'spam': 'bar', 'bar': 'foo'})])
G.adj[1][2][0]['listdata'] = [20, 200]
G.adj[1][2][0]['weight'] = 20
assert_edges_equal(G.edges(data=True),
[(1, 2, {'data': 21, 'spam': 'bar', 'bar': 'foo',
'listdata': [20, 200], 'weight':20})])
class TestMultiGraph(BaseMultiGraphTester, TestGraph):
def setup_method(self):
self.Graph = nx.MultiGraph
# build K3
ed1, ed2, ed3 = ({0: {}}, {0: {}}, {0: {}})
self.k3adj = {0: {1: ed1, 2: ed2},
1: {0: ed1, 2: ed3},
2: {0: ed2, 1: ed3}}
self.k3edges = [(0, 1), (0, 2), (1, 2)]
self.k3nodes = [0, 1, 2]
self.K3 = self.Graph()
self.K3._adj = self.k3adj
self.K3._node = {}
self.K3._node[0] = {}
self.K3._node[1] = {}
self.K3._node[2] = {}
def test_data_input(self):
G = self.Graph({1: [2], 2: [1]}, name="test")
assert G.name == "test"
expected = [(1, {2: {0: {}}}), (2, {1: {0: {}}})]
assert sorted(G.adj.items()) == expected
def test_getitem(self):
G = self.K3
assert G[0] == {1: {0: {}}, 2: {0: {}}}
with pytest.raises(KeyError):
G.__getitem__('j')
with pytest.raises(TypeError):
G.__getitem__(['A'])
def test_remove_node(self):
G = self.K3
G.remove_node(0)
assert G.adj == {1: {2: {0: {}}}, 2: {1: {0: {}}}}
with pytest.raises(nx.NetworkXError):
G.remove_node(-1)
def test_add_edge(self):
G = self.Graph()
G.add_edge(0, 1)
assert G.adj == {0: {1: {0: {}}}, 1: {0: {0: {}}}}
G = self.Graph()
G.add_edge(*(0, 1))
assert G.adj == {0: {1: {0: {}}}, 1: {0: {0: {}}}}
def test_add_edge_conflicting_key(self):
G = self.Graph()
G.add_edge(0, 1, key=1)
G.add_edge(0, 1)
assert G.number_of_edges() == 2
G = self.Graph()
G.add_edges_from([(0, 1, 1, {})])
G.add_edges_from([(0, 1)])
assert G.number_of_edges() == 2
def test_add_edges_from(self):
G = self.Graph()
G.add_edges_from([(0, 1), (0, 1, {'weight': 3})])
assert G.adj == {0: {1: {0: {}, 1: {'weight': 3}}},
1: {0: {0: {}, 1: {'weight': 3}}}}
G.add_edges_from([(0, 1), (0, 1, {'weight': 3})], weight=2)
assert G.adj == {0: {1: {0: {}, 1: {'weight': 3},
2: {'weight': 2}, 3: {'weight': 3}}},
1: {0: {0: {}, 1: {'weight': 3},
2: {'weight': 2}, 3: {'weight': 3}}}}
G = self.Graph()
edges = [(0, 1, {'weight': 3}), (0, 1, (('weight', 2),)),
(0, 1, 5), (0, 1, 's')]
G.add_edges_from(edges)
keydict = {0: {'weight': 3}, 1: {'weight': 2}, 5: {}, 's': {}}
assert G._adj == {0: {1: keydict}, 1: {0: keydict}}
# too few in tuple
with pytest.raises(nx.NetworkXError):
G.add_edges_from([(0,)])
# too many in tuple
with pytest.raises(nx.NetworkXError):
G.add_edges_from([(0, 1, 2, 3, 4)])
# not a tuple
with pytest.raises(TypeError):
G.add_edges_from([0])
def test_remove_edge(self):
G = self.K3
G.remove_edge(0, 1)
assert G.adj == {0: {2: {0: {}}},
1: {2: {0: {}}},
2: {0: {0: {}},
1: {0: {}}}}
with pytest.raises(nx.NetworkXError):
G.remove_edge(-1, 0)
with pytest.raises(nx.NetworkXError):
G.remove_edge(0, 2, key=1)
def test_remove_edges_from(self):
G = self.K3.copy()
G.remove_edges_from([(0, 1)])
kd = {0: {}}
assert G.adj == {0: {2: kd}, 1: {2: kd}, 2: {0: kd, 1: kd}}
G.remove_edges_from([(0, 0)]) # silent fail
self.K3.add_edge(0, 1)
G = self.K3.copy()
G.remove_edges_from(list(G.edges(data=True, keys=True)))
assert G.adj == {0: {}, 1: {}, 2: {}}
G = self.K3.copy()
G.remove_edges_from(list(G.edges(data=False, keys=True)))
assert G.adj == {0: {}, 1: {}, 2: {}}
G = self.K3.copy()
G.remove_edges_from(list(G.edges(data=False, keys=False)))
assert G.adj == {0: {}, 1: {}, 2: {}}
G = self.K3.copy()
G.remove_edges_from([(0, 1, 0), (0, 2, 0, {}), (1, 2)])
assert G.adj == {0: {1: {1: {}}}, 1: {0: {1: {}}}, 2: {}}
def test_remove_multiedge(self):
G = self.K3
G.add_edge(0, 1, key='parallel edge')
G.remove_edge(0, 1, key='parallel edge')
assert G.adj == {0: {1: {0: {}}, 2: {0: {}}},
1: {0: {0: {}}, 2: {0: {}}},
2: {0: {0: {}}, 1: {0: {}}}}
G.remove_edge(0, 1)
kd = {0: {}}
assert G.adj == {0: {2: kd}, 1: {2: kd}, 2: {0: kd, 1: kd}}
with pytest.raises(nx.NetworkXError):
G.remove_edge(-1, 0)
class TestEdgeSubgraph(object):
"""Unit tests for the :meth:`MultiGraph.edge_subgraph` method."""
def setup_method(self):
# Create a doubly-linked path graph on five nodes.
G = nx.MultiGraph()
nx.add_path(G, range(5))
nx.add_path(G, range(5))
# Add some node, edge, and graph attributes.
for i in range(5):
G.nodes[i]['name'] = 'node{}'.format(i)
G.adj[0][1][0]['name'] = 'edge010'
G.adj[0][1][1]['name'] = 'edge011'
G.adj[3][4][0]['name'] = 'edge340'
G.adj[3][4][1]['name'] = 'edge341'
G.graph['name'] = 'graph'
# Get the subgraph induced by one of the first edges and one of
# the last edges.
self.G = G
self.H = G.edge_subgraph([(0, 1, 0), (3, 4, 1)])
def test_correct_nodes(self):
"""Tests that the subgraph has the correct nodes."""
assert [0, 1, 3, 4] == sorted(self.H.nodes())
def test_correct_edges(self):
"""Tests that the subgraph has the correct edges."""
assert ([(0, 1, 0, 'edge010'), (3, 4, 1, 'edge341')] ==
sorted(self.H.edges(keys=True, data='name')))
def test_add_node(self):
"""Tests that adding a node to the original graph does not
affect the nodes of the subgraph.
"""
self.G.add_node(5)
assert [0, 1, 3, 4] == sorted(self.H.nodes())
def test_remove_node(self):
"""Tests that removing a node in the original graph does
affect the nodes of the subgraph.
"""
self.G.remove_node(0)
assert [1, 3, 4] == sorted(self.H.nodes())
def test_node_attr_dict(self):
"""Tests that the node attribute dictionary of the two graphs is
the same object.
"""
for v in self.H:
assert self.G.nodes[v] == self.H.nodes[v]
# Making a change to G should make a change in H and vice versa.
self.G.nodes[0]['name'] = 'foo'
assert self.G.nodes[0] == self.H.nodes[0]
self.H.nodes[1]['name'] = 'bar'
assert self.G.nodes[1] == self.H.nodes[1]
def test_edge_attr_dict(self):
"""Tests that the edge attribute dictionary of the two graphs is
the same object.
"""
for u, v, k in self.H.edges(keys=True):
assert self.G._adj[u][v][k] == self.H._adj[u][v][k]
# Making a change to G should make a change in H and vice versa.
self.G._adj[0][1][0]['name'] = 'foo'
assert (self.G._adj[0][1][0]['name'] ==
self.H._adj[0][1][0]['name'])
self.H._adj[3][4][1]['name'] = 'bar'
assert (self.G._adj[3][4][1]['name'] ==
self.H._adj[3][4][1]['name'])
def test_graph_attr_dict(self):
"""Tests that the graph attribute dictionary of the two graphs
is the same object.
"""
assert self.G.graph is self.H.graph