about summary refs log tree commit diff
path: root/.venv/lib/python3.12/site-packages/networkx/classes/tests/test_graphviews.py
diff options
context:
space:
mode:
Diffstat (limited to '.venv/lib/python3.12/site-packages/networkx/classes/tests/test_graphviews.py')
-rw-r--r--.venv/lib/python3.12/site-packages/networkx/classes/tests/test_graphviews.py350
1 files changed, 350 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/networkx/classes/tests/test_graphviews.py b/.venv/lib/python3.12/site-packages/networkx/classes/tests/test_graphviews.py
new file mode 100644
index 00000000..591c760c
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/networkx/classes/tests/test_graphviews.py
@@ -0,0 +1,350 @@
+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):
+        G = nx.Graph()
+        pytest.raises(nx.NetworkXNotImplemented, nx.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):
+        MG = nx.MultiGraph(self.G)
+        pytest.raises(nx.NetworkXNotImplemented, nx.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