comparison env/lib/python3.9/site-packages/networkx/drawing/tests/test_agraph.py @ 0:4f3585e2f14b draft default tip

"planemo upload commit 60cee0fc7c0cda8592644e1aad72851dec82c959"
author shellac
date Mon, 22 Mar 2021 18:12:50 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:4f3585e2f14b
1 """Unit tests for PyGraphviz interface."""
2 import os
3 import tempfile
4 import pytest
5
6 pygraphviz = pytest.importorskip("pygraphviz")
7
8
9 from networkx.testing import assert_edges_equal, assert_nodes_equal, assert_graphs_equal
10
11 import networkx as nx
12
13
14 class TestAGraph:
15 def build_graph(self, G):
16 edges = [("A", "B"), ("A", "C"), ("A", "C"), ("B", "C"), ("A", "D")]
17 G.add_edges_from(edges)
18 G.add_node("E")
19 G.graph["metal"] = "bronze"
20 return G
21
22 def assert_equal(self, G1, G2):
23 assert_nodes_equal(G1.nodes(), G2.nodes())
24 assert_edges_equal(G1.edges(), G2.edges())
25 assert G1.graph["metal"] == G2.graph["metal"]
26
27 def agraph_checks(self, G):
28 G = self.build_graph(G)
29 A = nx.nx_agraph.to_agraph(G)
30 H = nx.nx_agraph.from_agraph(A)
31 self.assert_equal(G, H)
32
33 fname = tempfile.mktemp()
34 nx.drawing.nx_agraph.write_dot(H, fname)
35 Hin = nx.nx_agraph.read_dot(fname)
36 os.unlink(fname)
37 self.assert_equal(H, Hin)
38
39 (fd, fname) = tempfile.mkstemp()
40 with open(fname, "w") as fh:
41 nx.drawing.nx_agraph.write_dot(H, fh)
42
43 with open(fname) as fh:
44 Hin = nx.nx_agraph.read_dot(fh)
45 os.unlink(fname)
46 self.assert_equal(H, Hin)
47
48 def test_from_agraph_name(self):
49 G = nx.Graph(name="test")
50 A = nx.nx_agraph.to_agraph(G)
51 H = nx.nx_agraph.from_agraph(A)
52 assert G.name == "test"
53
54 @pytest.mark.parametrize(
55 "graph_class", (nx.Graph, nx.DiGraph, nx.MultiGraph, nx.MultiDiGraph)
56 )
57 def test_from_agraph_create_using(self, graph_class):
58 G = nx.path_graph(3)
59 A = nx.nx_agraph.to_agraph(G)
60 H = nx.nx_agraph.from_agraph(A, create_using=graph_class)
61 assert isinstance(H, graph_class)
62
63 def test_from_agraph_named_edges(self):
64 # Create an AGraph from an existing (non-multi) Graph
65 G = nx.Graph()
66 G.add_nodes_from([0, 1])
67 A = nx.nx_agraph.to_agraph(G)
68 # Add edge (+ name, given by key) to the AGraph
69 A.add_edge(0, 1, key="foo")
70 # Verify a.name roundtrips out to 'key' in from_agraph
71 H = nx.nx_agraph.from_agraph(A)
72 assert isinstance(H, nx.Graph)
73 assert ("0", "1", {"key": "foo"}) in H.edges(data=True)
74
75 def test_undirected(self):
76 self.agraph_checks(nx.Graph())
77
78 def test_directed(self):
79 self.agraph_checks(nx.DiGraph())
80
81 def test_multi_undirected(self):
82 self.agraph_checks(nx.MultiGraph())
83
84 def test_multi_directed(self):
85 self.agraph_checks(nx.MultiDiGraph())
86
87 def test_to_agraph_with_nodedata(self):
88 G = nx.Graph()
89 G.add_node(1, color="red")
90 A = nx.nx_agraph.to_agraph(G)
91 assert dict(A.nodes()[0].attr) == {"color": "red"}
92
93 @pytest.mark.parametrize("graph_class", (nx.Graph, nx.MultiGraph))
94 def test_to_agraph_with_edgedata(self, graph_class):
95 G = graph_class()
96 G.add_nodes_from([0, 1])
97 G.add_edge(0, 1, color="yellow")
98 A = nx.nx_agraph.to_agraph(G)
99 assert dict(A.edges()[0].attr) == {"color": "yellow"}
100
101 def test_view_pygraphviz_path(self, tmp_path):
102 G = nx.complete_graph(3)
103 input_path = str(tmp_path / "graph.png")
104 out_path, A = nx.nx_agraph.view_pygraphviz(G, path=input_path, show=False)
105 assert out_path == input_path
106 # Ensure file is not empty
107 with open(input_path, "rb") as fh:
108 data = fh.read()
109 assert len(data) > 0
110
111 def test_view_pygraphviz_file_suffix(self, tmp_path):
112 G = nx.complete_graph(3)
113 path, A = nx.nx_agraph.view_pygraphviz(G, suffix=1, show=False)
114 assert path[-6:] == "_1.png"
115
116 def test_view_pygraphviz(self):
117 G = nx.Graph() # "An empty graph cannot be drawn."
118 pytest.raises(nx.NetworkXException, nx.nx_agraph.view_pygraphviz, G)
119 G = nx.barbell_graph(4, 6)
120 nx.nx_agraph.view_pygraphviz(G, show=False)
121
122 def test_view_pygraphviz_edgelabel(self):
123 G = nx.Graph()
124 G.add_edge(1, 2, weight=7)
125 G.add_edge(2, 3, weight=8)
126 path, A = nx.nx_agraph.view_pygraphviz(G, edgelabel="weight", show=False)
127 for edge in A.edges():
128 assert edge.attr["weight"] in ("7", "8")
129
130 def test_view_pygraphviz_callable_edgelabel(self):
131 G = nx.complete_graph(3)
132
133 def foo_label(data):
134 return "foo"
135
136 path, A = nx.nx_agraph.view_pygraphviz(G, edgelabel=foo_label, show=False)
137 for edge in A.edges():
138 assert edge.attr["label"] == "foo"
139
140 def test_view_pygraphviz_multigraph_edgelabels(self):
141 G = nx.MultiGraph()
142 G.add_edge(0, 1, key=0, name="left_fork")
143 G.add_edge(0, 1, key=1, name="right_fork")
144 path, A = nx.nx_agraph.view_pygraphviz(G, edgelabel="name", show=False)
145 edges = A.edges()
146 assert len(edges) == 2
147 for edge in edges:
148 assert edge.attr["label"].strip() in ("left_fork", "right_fork")
149
150 def test_graph_with_reserved_keywords(self):
151 # test attribute/keyword clash case for #1582
152 # node: n
153 # edges: u,v
154 G = nx.Graph()
155 G = self.build_graph(G)
156 G.nodes["E"]["n"] = "keyword"
157 G.edges[("A", "B")]["u"] = "keyword"
158 G.edges[("A", "B")]["v"] = "keyword"
159 A = nx.nx_agraph.to_agraph(G)
160
161 def test_view_pygraphviz_no_added_attrs_to_input(self):
162 G = nx.complete_graph(2)
163 path, A = nx.nx_agraph.view_pygraphviz(G, show=False)
164 assert G.graph == {}
165
166 @pytest.mark.xfail(reason="known bug in clean_attrs")
167 def test_view_pygraphviz_leaves_input_graph_unmodified(self):
168 G = nx.complete_graph(2)
169 # Add entries to graph dict that to_agraph handles specially
170 G.graph["node"] = {"width": "0.80"}
171 G.graph["edge"] = {"fontsize": "14"}
172 path, A = nx.nx_agraph.view_pygraphviz(G, show=False)
173 assert G.graph == {"node": {"width": "0.80"}, "edge": {"fontsize": "14"}}
174
175 def test_graph_with_AGraph_attrs(self):
176 G = nx.complete_graph(2)
177 # Add entries to graph dict that to_agraph handles specially
178 G.graph["node"] = {"width": "0.80"}
179 G.graph["edge"] = {"fontsize": "14"}
180 path, A = nx.nx_agraph.view_pygraphviz(G, show=False)
181 # Ensure user-specified values are not lost
182 assert dict(A.node_attr)["width"] == "0.80"
183 assert dict(A.edge_attr)["fontsize"] == "14"
184
185 def test_round_trip_empty_graph(self):
186 G = nx.Graph()
187 A = nx.nx_agraph.to_agraph(G)
188 H = nx.nx_agraph.from_agraph(A)
189 # assert_graphs_equal(G, H)
190 AA = nx.nx_agraph.to_agraph(H)
191 HH = nx.nx_agraph.from_agraph(AA)
192 assert_graphs_equal(H, HH)
193 G.graph["graph"] = {}
194 G.graph["node"] = {}
195 G.graph["edge"] = {}
196 assert_graphs_equal(G, HH)
197
198 @pytest.mark.xfail(reason="integer->string node conversion in round trip")
199 def test_round_trip_integer_nodes(self):
200 G = nx.complete_graph(3)
201 A = nx.nx_agraph.to_agraph(G)
202 H = nx.nx_agraph.from_agraph(A)
203 assert_graphs_equal(G, H)
204
205 def test_graphviz_alias(self):
206 G = self.build_graph(nx.Graph())
207 pos_graphviz = nx.nx_agraph.graphviz_layout(G)
208 pos_pygraphviz = nx.nx_agraph.pygraphviz_layout(G)
209 assert pos_graphviz == pos_pygraphviz
210
211 @pytest.mark.parametrize("root", range(5))
212 def test_pygraphviz_layout_root(self, root):
213 # NOTE: test depends on layout prog being deterministic
214 G = nx.complete_graph(5)
215 A = nx.nx_agraph.to_agraph(G)
216 # Get layout with root arg is not None
217 pygv_layout = nx.nx_agraph.pygraphviz_layout(G, prog="circo", root=root)
218 # Equivalent layout directly on AGraph
219 A.layout(args=f"-Groot={root}", prog="circo")
220 # Parse AGraph layout
221 a1_pos = tuple(float(v) for v in dict(A.get_node("1").attr)["pos"].split(","))
222 assert pygv_layout[1] == a1_pos
223
224 def test_2d_layout(self):
225 G = nx.Graph()
226 G = self.build_graph(G)
227 G.graph["dimen"] = 2
228 pos = nx.nx_agraph.pygraphviz_layout(G, prog="neato")
229 pos = list(pos.values())
230 assert len(pos) == 5
231 assert len(pos[0]) == 2
232
233 def test_3d_layout(self):
234 G = nx.Graph()
235 G = self.build_graph(G)
236 G.graph["dimen"] = 3
237 pos = nx.nx_agraph.pygraphviz_layout(G, prog="neato")
238 pos = list(pos.values())
239 assert len(pos) == 5
240 assert len(pos[0]) == 3
241
242 def test_display_pygraphviz_deprecation_warning(self):
243 G = nx.complete_graph(2)
244 path_name, A = nx.nx_agraph.view_pygraphviz(G, show=False)
245 # Monkeypatch default_opener to prevent window opening
246 nx.utils.default_opener = lambda x: None
247 with pytest.warns(DeprecationWarning, match="display_pygraphviz is deprecated"):
248 with open(path_name, "wb") as fh:
249 nx.nx_agraph.display_pygraphviz(A, fh, prog="dot")