| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352 |
- import pytest
- import networkx as nx
- from networkx.utils import edges_equal, nodes_equal
- # Note: SubGraph views are not tested here. They have their own testing file
- class TestReverseView:
- def setup_method(self):
- self.G = nx.path_graph(9, create_using=nx.DiGraph())
- self.rv = nx.reverse_view(self.G)
- def test_pickle(self):
- import pickle
- rv = self.rv
- prv = pickle.loads(pickle.dumps(rv, -1))
- assert rv._node == prv._node
- assert rv._adj == prv._adj
- assert rv.graph == prv.graph
- def test_contains(self):
- assert (2, 3) in self.G.edges
- assert (3, 2) not in self.G.edges
- assert (2, 3) not in self.rv.edges
- assert (3, 2) in self.rv.edges
- def test_iter(self):
- expected = sorted(tuple(reversed(e)) for e in self.G.edges)
- assert sorted(self.rv.edges) == expected
- def test_exceptions(self):
- nxg = nx.graphviews
- G = nx.Graph()
- pytest.raises(nx.NetworkXNotImplemented, nxg.reverse_view, G)
- def test_subclass(self):
- class MyGraph(nx.DiGraph):
- def my_method(self):
- return "me"
- def to_directed_class(self):
- return MyGraph()
- M = MyGraph()
- M.add_edge(1, 2)
- RM = nx.reverse_view(M)
- print("RM class", RM.__class__)
- RMC = RM.copy()
- print("RMC class", RMC.__class__)
- print(RMC.edges)
- assert RMC.has_edge(2, 1)
- assert RMC.my_method() == "me"
- class TestMultiReverseView:
- def setup_method(self):
- self.G = nx.path_graph(9, create_using=nx.MultiDiGraph())
- self.G.add_edge(4, 5)
- self.rv = nx.reverse_view(self.G)
- def test_pickle(self):
- import pickle
- rv = self.rv
- prv = pickle.loads(pickle.dumps(rv, -1))
- assert rv._node == prv._node
- assert rv._adj == prv._adj
- assert rv.graph == prv.graph
- def test_contains(self):
- assert (2, 3, 0) in self.G.edges
- assert (3, 2, 0) not in self.G.edges
- assert (2, 3, 0) not in self.rv.edges
- assert (3, 2, 0) in self.rv.edges
- assert (5, 4, 1) in self.rv.edges
- assert (4, 5, 1) not in self.rv.edges
- def test_iter(self):
- expected = sorted((v, u, k) for u, v, k in self.G.edges)
- assert sorted(self.rv.edges) == expected
- def test_exceptions(self):
- nxg = nx.graphviews
- MG = nx.MultiGraph(self.G)
- pytest.raises(nx.NetworkXNotImplemented, nxg.reverse_view, MG)
- def test_generic_multitype():
- nxg = nx.graphviews
- G = nx.DiGraph([(1, 2)])
- with pytest.raises(nx.NetworkXError):
- nxg.generic_graph_view(G, create_using=nx.MultiGraph)
- G = nx.MultiDiGraph([(1, 2)])
- with pytest.raises(nx.NetworkXError):
- nxg.generic_graph_view(G, create_using=nx.DiGraph)
- class TestToDirected:
- def setup_method(self):
- self.G = nx.path_graph(9)
- self.dv = nx.to_directed(self.G)
- self.MG = nx.path_graph(9, create_using=nx.MultiGraph())
- self.Mdv = nx.to_directed(self.MG)
- def test_directed(self):
- assert not self.G.is_directed()
- assert self.dv.is_directed()
- def test_already_directed(self):
- dd = nx.to_directed(self.dv)
- Mdd = nx.to_directed(self.Mdv)
- assert edges_equal(dd.edges, self.dv.edges)
- assert edges_equal(Mdd.edges, self.Mdv.edges)
- def test_pickle(self):
- import pickle
- dv = self.dv
- pdv = pickle.loads(pickle.dumps(dv, -1))
- assert dv._node == pdv._node
- assert dv._succ == pdv._succ
- assert dv._pred == pdv._pred
- assert dv.graph == pdv.graph
- def test_contains(self):
- assert (2, 3) in self.G.edges
- assert (3, 2) in self.G.edges
- assert (2, 3) in self.dv.edges
- assert (3, 2) in self.dv.edges
- def test_iter(self):
- revd = [tuple(reversed(e)) for e in self.G.edges]
- expected = sorted(list(self.G.edges) + revd)
- assert sorted(self.dv.edges) == expected
- class TestToUndirected:
- def setup_method(self):
- self.DG = nx.path_graph(9, create_using=nx.DiGraph())
- self.uv = nx.to_undirected(self.DG)
- self.MDG = nx.path_graph(9, create_using=nx.MultiDiGraph())
- self.Muv = nx.to_undirected(self.MDG)
- def test_directed(self):
- assert self.DG.is_directed()
- assert not self.uv.is_directed()
- def test_already_directed(self):
- uu = nx.to_undirected(self.uv)
- Muu = nx.to_undirected(self.Muv)
- assert edges_equal(uu.edges, self.uv.edges)
- assert edges_equal(Muu.edges, self.Muv.edges)
- def test_pickle(self):
- import pickle
- uv = self.uv
- puv = pickle.loads(pickle.dumps(uv, -1))
- assert uv._node == puv._node
- assert uv._adj == puv._adj
- assert uv.graph == puv.graph
- assert hasattr(uv, "_graph")
- def test_contains(self):
- assert (2, 3) in self.DG.edges
- assert (3, 2) not in self.DG.edges
- assert (2, 3) in self.uv.edges
- assert (3, 2) in self.uv.edges
- def test_iter(self):
- expected = sorted(self.DG.edges)
- assert sorted(self.uv.edges) == expected
- class TestChainsOfViews:
- @classmethod
- def setup_class(cls):
- cls.G = nx.path_graph(9)
- cls.DG = nx.path_graph(9, create_using=nx.DiGraph())
- cls.MG = nx.path_graph(9, create_using=nx.MultiGraph())
- cls.MDG = nx.path_graph(9, create_using=nx.MultiDiGraph())
- cls.Gv = nx.to_undirected(cls.DG)
- cls.DGv = nx.to_directed(cls.G)
- cls.MGv = nx.to_undirected(cls.MDG)
- cls.MDGv = nx.to_directed(cls.MG)
- cls.Rv = cls.DG.reverse()
- cls.MRv = cls.MDG.reverse()
- cls.graphs = [
- cls.G,
- cls.DG,
- cls.MG,
- cls.MDG,
- cls.Gv,
- cls.DGv,
- cls.MGv,
- cls.MDGv,
- cls.Rv,
- cls.MRv,
- ]
- for G in cls.graphs:
- G.edges, G.nodes, G.degree
- def test_pickle(self):
- import pickle
- for G in self.graphs:
- H = pickle.loads(pickle.dumps(G, -1))
- assert edges_equal(H.edges, G.edges)
- assert nodes_equal(H.nodes, G.nodes)
- def test_subgraph_of_subgraph(self):
- SGv = nx.subgraph(self.G, range(3, 7))
- SDGv = nx.subgraph(self.DG, range(3, 7))
- SMGv = nx.subgraph(self.MG, range(3, 7))
- SMDGv = nx.subgraph(self.MDG, range(3, 7))
- for G in self.graphs + [SGv, SDGv, SMGv, SMDGv]:
- SG = nx.induced_subgraph(G, [4, 5, 6])
- assert list(SG) == [4, 5, 6]
- SSG = SG.subgraph([6, 7])
- assert list(SSG) == [6]
- # subgraph-subgraph chain is short-cut in base class method
- assert SSG._graph is G
- def test_restricted_induced_subgraph_chains(self):
- """Test subgraph chains that both restrict and show nodes/edges.
- A restricted_view subgraph should allow induced subgraphs using
- G.subgraph that automagically without a chain (meaning the result
- is a subgraph view of the original graph not a subgraph-of-subgraph.
- """
- hide_nodes = [3, 4, 5]
- hide_edges = [(6, 7)]
- RG = nx.restricted_view(self.G, hide_nodes, hide_edges)
- nodes = [4, 5, 6, 7, 8]
- SG = nx.induced_subgraph(RG, nodes)
- SSG = RG.subgraph(nodes)
- assert RG._graph is self.G
- assert SSG._graph is self.G
- assert SG._graph is RG
- assert edges_equal(SG.edges, SSG.edges)
- # should be same as morphing the graph
- CG = self.G.copy()
- CG.remove_nodes_from(hide_nodes)
- CG.remove_edges_from(hide_edges)
- assert edges_equal(CG.edges(nodes), SSG.edges)
- CG.remove_nodes_from([0, 1, 2, 3])
- assert edges_equal(CG.edges, SSG.edges)
- # switch order: subgraph first, then restricted view
- SSSG = self.G.subgraph(nodes)
- RSG = nx.restricted_view(SSSG, hide_nodes, hide_edges)
- assert RSG._graph is not self.G
- assert edges_equal(RSG.edges, CG.edges)
- def test_subgraph_copy(self):
- for origG in self.graphs:
- G = nx.Graph(origG)
- SG = G.subgraph([4, 5, 6])
- H = SG.copy()
- assert type(G) == type(H)
- def test_subgraph_todirected(self):
- SG = nx.induced_subgraph(self.G, [4, 5, 6])
- SSG = SG.to_directed()
- assert sorted(SSG) == [4, 5, 6]
- assert sorted(SSG.edges) == [(4, 5), (5, 4), (5, 6), (6, 5)]
- def test_subgraph_toundirected(self):
- SG = nx.induced_subgraph(self.G, [4, 5, 6])
- SSG = SG.to_undirected()
- assert list(SSG) == [4, 5, 6]
- assert sorted(SSG.edges) == [(4, 5), (5, 6)]
- def test_reverse_subgraph_toundirected(self):
- G = self.DG.reverse(copy=False)
- SG = G.subgraph([4, 5, 6])
- SSG = SG.to_undirected()
- assert list(SSG) == [4, 5, 6]
- assert sorted(SSG.edges) == [(4, 5), (5, 6)]
- def test_reverse_reverse_copy(self):
- G = self.DG.reverse(copy=False)
- H = G.reverse(copy=True)
- assert H.nodes == self.DG.nodes
- assert H.edges == self.DG.edges
- G = self.MDG.reverse(copy=False)
- H = G.reverse(copy=True)
- assert H.nodes == self.MDG.nodes
- assert H.edges == self.MDG.edges
- def test_subgraph_edgesubgraph_toundirected(self):
- G = self.G.copy()
- SG = G.subgraph([4, 5, 6])
- SSG = SG.edge_subgraph([(4, 5), (5, 4)])
- USSG = SSG.to_undirected()
- assert list(USSG) == [4, 5]
- assert sorted(USSG.edges) == [(4, 5)]
- def test_copy_subgraph(self):
- G = self.G.copy()
- SG = G.subgraph([4, 5, 6])
- CSG = SG.copy(as_view=True)
- DCSG = SG.copy(as_view=False)
- assert hasattr(CSG, "_graph") # is a view
- assert not hasattr(DCSG, "_graph") # not a view
- def test_copy_disubgraph(self):
- G = self.DG.copy()
- SG = G.subgraph([4, 5, 6])
- CSG = SG.copy(as_view=True)
- DCSG = SG.copy(as_view=False)
- assert hasattr(CSG, "_graph") # is a view
- assert not hasattr(DCSG, "_graph") # not a view
- def test_copy_multidisubgraph(self):
- G = self.MDG.copy()
- SG = G.subgraph([4, 5, 6])
- CSG = SG.copy(as_view=True)
- DCSG = SG.copy(as_view=False)
- assert hasattr(CSG, "_graph") # is a view
- assert not hasattr(DCSG, "_graph") # not a view
- def test_copy_multisubgraph(self):
- G = self.MG.copy()
- SG = G.subgraph([4, 5, 6])
- CSG = SG.copy(as_view=True)
- DCSG = SG.copy(as_view=False)
- assert hasattr(CSG, "_graph") # is a view
- assert not hasattr(DCSG, "_graph") # not a view
- def test_copy_of_view(self):
- G = nx.MultiGraph(self.MGv)
- assert G.__class__.__name__ == "MultiGraph"
- G = G.copy(as_view=True)
- assert G.__class__.__name__ == "MultiGraph"
- def test_subclass(self):
- class MyGraph(nx.DiGraph):
- def my_method(self):
- return "me"
- def to_directed_class(self):
- return MyGraph()
- for origG in self.graphs:
- G = MyGraph(origG)
- SG = G.subgraph([4, 5, 6])
- H = SG.copy()
- assert SG.my_method() == "me"
- assert H.my_method() == "me"
- assert 3 not in H or 3 in SG
|