from nose.tools import assert_equal, assert_not_equal, \ assert_is, assert_true, assert_false, assert_raises import networkx as nx class TestSubGraphView(object): gview = nx.graphviews.SubGraph graph = nx.Graph hide_edges_filter = staticmethod(nx.filters.hide_edges) show_edges_filter = staticmethod(nx.filters.show_edges) def setUp(self): self.G = nx.path_graph(9, create_using=self.graph()) self.hide_edges_w_hide_nodes = {(3, 4), (4, 5), (5, 6)} def test_hidden_nodes(self): hide_nodes = [4, 5, 111] nodes_gone = nx.filters.hide_nodes(hide_nodes) G = self.gview(self.G, filter_node=nodes_gone) assert_equal(self.G.nodes - G.nodes, {4, 5}) assert_equal(self.G.edges - G.edges, self.hide_edges_w_hide_nodes) if G.is_directed(): assert_equal(list(G[3]), []) assert_equal(list(G[2]), [3]) else: assert_equal(list(G[3]), [2]) assert_equal(set(G[2]), {1, 3}) assert_raises(KeyError, G.__getitem__, 4) assert_raises(KeyError, G.__getitem__, 112) assert_raises(KeyError, G.__getitem__, 111) assert_equal(G.degree(3), 3 if G.is_multigraph() else 1) assert_equal(G.size(), 7 if G.is_multigraph() else 5) def test_hidden_edges(self): hide_edges = [(2, 3), (8, 7), (222, 223)] edges_gone = self.hide_edges_filter(hide_edges) G = self.gview(self.G, filter_edge=edges_gone) assert_equal(self.G.nodes, G.nodes) if G.is_directed(): assert_equal(self.G.edges - G.edges, {(2, 3)}) assert_equal(list(G[2]), []) assert_equal(list(G.pred[3]), []) assert_equal(list(G.pred[2]), [1]) assert_equal(G.size(), 7) else: assert_equal(self.G.edges - G.edges, {(2, 3), (7, 8)}) assert_equal(list(G[2]), [1]) assert_equal(G.size(), 6) assert_equal(list(G[3]), [4]) assert_raises(KeyError, G.__getitem__, 221) assert_raises(KeyError, G.__getitem__, 222) assert_equal(G.degree(3), 1) def test_shown_node(self): induced_subgraph = nx.filters.show_nodes([2, 3, 111]) G = self.gview(self.G, filter_node=induced_subgraph) assert_equal(set(G.nodes), {2, 3}) if G.is_directed(): assert_equal(list(G[3]), []) else: assert_equal(list(G[3]), [2]) assert_equal(list(G[2]), [3]) assert_raises(KeyError, G.__getitem__, 4) assert_raises(KeyError, G.__getitem__, 112) assert_raises(KeyError, G.__getitem__, 111) assert_equal(G.degree(3), 3 if G.is_multigraph() else 1) assert_equal(G.size(), 3 if G.is_multigraph() else 1) def test_shown_edges(self): show_edges = [(2, 3), (8, 7), (222, 223)] edge_subgraph = self.show_edges_filter(show_edges) G = self.gview(self.G, filter_edge=edge_subgraph) assert_equal(self.G.nodes, G.nodes) if G.is_directed(): assert_equal(G.edges, {(2, 3)}) assert_equal(list(G[3]), []) assert_equal(list(G[2]), [3]) assert_equal(list(G.pred[3]), [2]) assert_equal(list(G.pred[2]), []) assert_equal(G.size(), 1) else: assert_equal(G.edges, {(2, 3), (7, 8)}) assert_equal(list(G[3]), [2]) assert_equal(list(G[2]), [3]) assert_equal(G.size(), 2) assert_raises(KeyError, G.__getitem__, 221) assert_raises(KeyError, G.__getitem__, 222) assert_equal(G.degree(3), 1) class TestSubDiGraphView(TestSubGraphView): gview = nx.graphviews.SubDiGraph graph = nx.DiGraph hide_edges_filter = staticmethod(nx.filters.hide_diedges) show_edges_filter = staticmethod(nx.filters.show_diedges) hide_edges = [(2, 3), (8, 7), (222, 223)] excluded = {(2, 3), (3, 4), (4, 5), (5, 6)} def test_inoutedges(self): edges_gone = self.hide_edges_filter(self.hide_edges) hide_nodes = [4, 5, 111] nodes_gone = nx.filters.hide_nodes(hide_nodes) G = self.gview(self.G, nodes_gone, edges_gone) assert_equal(self.G.in_edges - G.in_edges, self.excluded) assert_equal(self.G.out_edges - G.out_edges, self.excluded) def test_pred(self): edges_gone = self.hide_edges_filter(self.hide_edges) hide_nodes = [4, 5, 111] nodes_gone = nx.filters.hide_nodes(hide_nodes) G = self.gview(self.G, nodes_gone, edges_gone) assert_equal(list(G.pred[2]), [1]) assert_equal(list(G.pred[6]), []) def test_inout_degree(self): edges_gone = self.hide_edges_filter(self.hide_edges) hide_nodes = [4, 5, 111] nodes_gone = nx.filters.hide_nodes(hide_nodes) G = self.gview(self.G, nodes_gone, edges_gone) assert_equal(G.degree(2), 1) assert_equal(G.out_degree(2), 0) assert_equal(G.in_degree(2), 1) assert_equal(G.size(), 4) # multigraph class TestMultiGraphView(TestSubGraphView): gview = nx.graphviews.SubMultiGraph graph = nx.MultiGraph hide_edges_filter = staticmethod(nx.filters.hide_multiedges) show_edges_filter = staticmethod(nx.filters.show_multiedges) def setUp(self): self.G = nx.path_graph(9, create_using=self.graph()) multiedges = {(2, 3, 4), (2, 3, 5)} self.G.add_edges_from(multiedges) self.hide_edges_w_hide_nodes = {(3, 4, 0), (4, 5, 0), (5, 6, 0)} def test_hidden_edges(self): hide_edges = [(2, 3, 4), (2, 3, 3), (8, 7, 0), (222, 223, 0)] edges_gone = self.hide_edges_filter(hide_edges) G = self.gview(self.G, filter_edge=edges_gone) assert_equal(self.G.nodes, G.nodes) if G.is_directed(): assert_equal(self.G.edges - G.edges, {(2, 3, 4)}) assert_equal(list(G[3]), [4]) assert_equal(list(G[2]), [3]) assert_equal(list(G.pred[3]), [2]) # only one 2 but two edges assert_equal(list(G.pred[2]), [1]) assert_equal(G.size(), 9) else: assert_equal(self.G.edges - G.edges, {(2, 3, 4), (7, 8, 0)}) assert_equal(list(G[3]), [2, 4]) assert_equal(list(G[2]), [1, 3]) assert_equal(G.size(), 8) assert_equal(G.degree(3), 3) assert_raises(KeyError, G.__getitem__, 221) assert_raises(KeyError, G.__getitem__, 222) def test_shown_edges(self): show_edges = [(2, 3, 4), (2, 3, 3), (8, 7, 0), (222, 223, 0)] edge_subgraph = self.show_edges_filter(show_edges) G = self.gview(self.G, filter_edge=edge_subgraph) assert_equal(self.G.nodes, G.nodes) if G.is_directed(): assert_equal(G.edges, {(2, 3, 4)}) assert_equal(list(G[3]), []) assert_equal(list(G.pred[3]), [2]) assert_equal(list(G.pred[2]), []) assert_equal(G.size(), 1) else: assert_equal(G.edges, {(2, 3, 4), (7, 8, 0)}) assert_equal(G.size(), 2) assert_equal(list(G[3]), [2]) assert_equal(G.degree(3), 1) assert_equal(list(G[2]), [3]) assert_raises(KeyError, G.__getitem__, 221) assert_raises(KeyError, G.__getitem__, 222) # multidigraph class TestMultiDiGraphView(TestMultiGraphView, TestSubDiGraphView): gview = nx.graphviews.SubMultiDiGraph graph = nx.MultiDiGraph hide_edges_filter = staticmethod(nx.filters.hide_multidiedges) show_edges_filter = staticmethod(nx.filters.show_multidiedges) hide_edges = [(2, 3, 0), (8, 7, 0), (222, 223, 0)] excluded = {(2, 3, 0), (3, 4, 0), (4, 5, 0), (5, 6, 0)} def test_inout_degree(self): edges_gone = self.hide_edges_filter(self.hide_edges) hide_nodes = [4, 5, 111] nodes_gone = nx.filters.hide_nodes(hide_nodes) G = self.gview(self.G, nodes_gone, edges_gone) assert_equal(G.degree(2), 3) assert_equal(G.out_degree(2), 2) assert_equal(G.in_degree(2), 1) assert_equal(G.size(), 6) # induced_subgraph class TestInducedSubGraph(object): def setUp(self): self.K3 = G = nx.complete_graph(3) G.graph['foo'] = [] G.nodes[0]['foo'] = [] G.remove_edge(1, 2) ll = [] G.add_edge(1, 2, foo=ll) G.add_edge(2, 1, foo=ll) def test_full_graph(self): G = self.K3 H = nx.induced_subgraph(G, [0, 1, 2, 5]) assert_equal(H.name, G.name) self.graphs_equal(H, G) self.same_attrdict(H, G) def test_partial_subgraph(self): G = self.K3 H = nx.induced_subgraph(G, 0) assert_equal(dict(H.adj), {0: {}}) assert_not_equal(dict(G.adj), {0: {}}) H = nx.induced_subgraph(G, [0, 1]) assert_equal(dict(H.adj), {0: {1: {}}, 1: {0: {}}}) def same_attrdict(self, H, G): old_foo = H[1][2]['foo'] H.edges[1, 2]['foo'] = 'baz' assert_equal(G.edges, H.edges) H.edges[1, 2]['foo'] = old_foo assert_equal(G.edges, H.edges) old_foo = H.nodes[0]['foo'] H.nodes[0]['foo'] = 'baz' assert_equal(G.nodes, H.nodes) H.nodes[0]['foo'] = old_foo assert_equal(G.nodes, H.nodes) def graphs_equal(self, H, G): assert_equal(G._adj, H._adj) assert_equal(G._node, H._node) assert_equal(G.graph, H.graph) assert_equal(G.name, H.name) if not G.is_directed() and not H.is_directed(): assert_true(H._adj[1][2] is H._adj[2][1]) assert_true(G._adj[1][2] is G._adj[2][1]) 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_equal(G._pred, H._pred) assert_equal(G._succ, H._succ) assert_true(H._succ[1][2] is H._pred[2][1]) assert_true(G._succ[1][2] is G._pred[2][1]) # edge_subgraph class TestEdgeSubGraph(object): def setup(self): # Create a path graph on five nodes. self.G = G = nx.path_graph(5) # Add some node, edge, and graph attributes. for i in range(5): G.nodes[i]['name'] = 'node{}'.format(i) G.edges[0, 1]['name'] = 'edge01' G.edges[3, 4]['name'] = 'edge34' G.graph['name'] = 'graph' # Get the subgraph induced by the first and last edges. self.H = nx.edge_subgraph(G, [(0, 1), (3, 4)]) def test_correct_nodes(self): """Tests that the subgraph has the correct nodes.""" assert_equal([0, 1, 3, 4], sorted(self.H.nodes)) def test_correct_edges(self): """Tests that the subgraph has the correct edges.""" assert_equal([(0, 1, 'edge01'), (3, 4, 'edge34')], sorted(self.H.edges(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_equal([0, 1, 3, 4], sorted(self.H.nodes)) self.G.remove_node(5) def test_remove_node(self): """Tests that removing a node in the original graph removes the nodes of the subgraph. """ self.G.remove_node(0) assert_equal([1, 3, 4], sorted(self.H.nodes)) self.G.add_edge(0, 1) 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_equal(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_equal(self.G.nodes[0], self.H.nodes[0]) self.H.nodes[1]['name'] = 'bar' assert_equal(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 in self.H.edges(): assert_equal(self.G.edges[u, v], self.H.edges[u, v]) # Making a change to G should make a change in H and vice versa. self.G.edges[0, 1]['name'] = 'foo' assert_equal(self.G.edges[0, 1]['name'], self.H.edges[0, 1]['name']) self.H.edges[3, 4]['name'] = 'bar' assert_equal(self.G.edges[3, 4]['name'], self.H.edges[3, 4]['name']) def test_graph_attr_dict(self): """Tests that the graph attribute dictionary of the two graphs is the same object. """ assert_is(self.G.graph, self.H.graph) def test_readonly(self): """Tests that the subgraph cannot change the graph structure""" assert_raises(nx.NetworkXError, self.H.add_node, 5) assert_raises(nx.NetworkXError, self.H.remove_node, 0) assert_raises(nx.NetworkXError, self.H.add_edge, 5, 6) assert_raises(nx.NetworkXError, self.H.remove_edge, 0, 1)