1import pytest 2import pickle 3 4import networkx as nx 5 6 7class TestAtlasView: 8 # node->data 9 def setup(self): 10 self.d = {0: {"color": "blue", "weight": 1.2}, 1: {}, 2: {"color": 1}} 11 self.av = nx.classes.coreviews.AtlasView(self.d) 12 13 def test_pickle(self): 14 view = self.av 15 pview = pickle.loads(pickle.dumps(view, -1)) 16 assert view == pview 17 assert view.__slots__ == pview.__slots__ 18 pview = pickle.loads(pickle.dumps(view)) 19 assert view == pview 20 assert view.__slots__ == pview.__slots__ 21 22 def test_len(self): 23 assert len(self.av) == len(self.d) 24 25 def test_iter(self): 26 assert list(self.av) == list(self.d) 27 28 def test_getitem(self): 29 assert self.av[1] is self.d[1] 30 assert self.av[2]["color"] == 1 31 pytest.raises(KeyError, self.av.__getitem__, 3) 32 33 def test_copy(self): 34 avcopy = self.av.copy() 35 assert avcopy[0] == self.av[0] 36 assert avcopy == self.av 37 assert avcopy[0] is not self.av[0] 38 assert avcopy is not self.av 39 avcopy[5] = {} 40 assert avcopy != self.av 41 42 avcopy[0]["ht"] = 4 43 assert avcopy[0] != self.av[0] 44 self.av[0]["ht"] = 4 45 assert avcopy[0] == self.av[0] 46 del self.av[0]["ht"] 47 48 assert not hasattr(self.av, "__setitem__") 49 50 def test_items(self): 51 assert sorted(self.av.items()) == sorted(self.d.items()) 52 53 def test_str(self): 54 out = str(self.d) 55 assert str(self.av) == out 56 57 def test_repr(self): 58 out = "AtlasView(" + str(self.d) + ")" 59 assert repr(self.av) == out 60 61 62class TestAdjacencyView: 63 # node->nbr->data 64 def setup(self): 65 dd = {"color": "blue", "weight": 1.2} 66 self.nd = {0: dd, 1: {}, 2: {"color": 1}} 67 self.adj = {3: self.nd, 0: {3: dd}, 1: {}, 2: {3: {"color": 1}}} 68 self.adjview = nx.classes.coreviews.AdjacencyView(self.adj) 69 70 def test_pickle(self): 71 view = self.adjview 72 pview = pickle.loads(pickle.dumps(view, -1)) 73 assert view == pview 74 assert view.__slots__ == pview.__slots__ 75 76 def test_len(self): 77 assert len(self.adjview) == len(self.adj) 78 79 def test_iter(self): 80 assert list(self.adjview) == list(self.adj) 81 82 def test_getitem(self): 83 assert self.adjview[1] is not self.adj[1] 84 assert self.adjview[3][0] is self.adjview[0][3] 85 assert self.adjview[2][3]["color"] == 1 86 pytest.raises(KeyError, self.adjview.__getitem__, 4) 87 88 def test_copy(self): 89 avcopy = self.adjview.copy() 90 assert avcopy[0] == self.adjview[0] 91 assert avcopy[0] is not self.adjview[0] 92 93 avcopy[2][3]["ht"] = 4 94 assert avcopy[2] != self.adjview[2] 95 self.adjview[2][3]["ht"] = 4 96 assert avcopy[2] == self.adjview[2] 97 del self.adjview[2][3]["ht"] 98 99 assert not hasattr(self.adjview, "__setitem__") 100 101 def test_items(self): 102 view_items = sorted((n, dict(d)) for n, d in self.adjview.items()) 103 assert view_items == sorted(self.adj.items()) 104 105 def test_str(self): 106 out = str(dict(self.adj)) 107 assert str(self.adjview) == out 108 109 def test_repr(self): 110 out = self.adjview.__class__.__name__ + "(" + str(self.adj) + ")" 111 assert repr(self.adjview) == out 112 113 114class TestMultiAdjacencyView(TestAdjacencyView): 115 # node->nbr->key->data 116 def setup(self): 117 dd = {"color": "blue", "weight": 1.2} 118 self.kd = {0: dd, 1: {}, 2: {"color": 1}} 119 self.nd = {3: self.kd, 0: {3: dd}, 1: {0: {}}, 2: {3: {"color": 1}}} 120 self.adj = {3: self.nd, 0: {3: {3: dd}}, 1: {}, 2: {3: {8: {}}}} 121 self.adjview = nx.classes.coreviews.MultiAdjacencyView(self.adj) 122 123 def test_getitem(self): 124 assert self.adjview[1] is not self.adj[1] 125 assert self.adjview[3][0][3] is self.adjview[0][3][3] 126 assert self.adjview[3][2][3]["color"] == 1 127 pytest.raises(KeyError, self.adjview.__getitem__, 4) 128 129 def test_copy(self): 130 avcopy = self.adjview.copy() 131 assert avcopy[0] == self.adjview[0] 132 assert avcopy[0] is not self.adjview[0] 133 134 avcopy[2][3][8]["ht"] = 4 135 assert avcopy[2] != self.adjview[2] 136 self.adjview[2][3][8]["ht"] = 4 137 assert avcopy[2] == self.adjview[2] 138 del self.adjview[2][3][8]["ht"] 139 140 assert not hasattr(self.adjview, "__setitem__") 141 142 143class TestUnionAtlas: 144 # node->data 145 def setup(self): 146 self.s = {0: {"color": "blue", "weight": 1.2}, 1: {}, 2: {"color": 1}} 147 self.p = {3: {"color": "blue", "weight": 1.2}, 4: {}, 2: {"watch": 2}} 148 self.av = nx.classes.coreviews.UnionAtlas(self.s, self.p) 149 150 def test_pickle(self): 151 view = self.av 152 pview = pickle.loads(pickle.dumps(view, -1)) 153 assert view == pview 154 assert view.__slots__ == pview.__slots__ 155 156 def test_len(self): 157 assert len(self.av) == len(self.s) + len(self.p) 158 159 def test_iter(self): 160 assert set(self.av) == set(self.s) | set(self.p) 161 162 def test_getitem(self): 163 assert self.av[0] is self.s[0] 164 assert self.av[4] is self.p[4] 165 assert self.av[2]["color"] == 1 166 pytest.raises(KeyError, self.av[2].__getitem__, "watch") 167 pytest.raises(KeyError, self.av.__getitem__, 8) 168 169 def test_copy(self): 170 avcopy = self.av.copy() 171 assert avcopy[0] == self.av[0] 172 assert avcopy[0] is not self.av[0] 173 assert avcopy is not self.av 174 avcopy[5] = {} 175 assert avcopy != self.av 176 177 avcopy[0]["ht"] = 4 178 assert avcopy[0] != self.av[0] 179 self.av[0]["ht"] = 4 180 assert avcopy[0] == self.av[0] 181 del self.av[0]["ht"] 182 183 assert not hasattr(self.av, "__setitem__") 184 185 def test_items(self): 186 expected = dict(self.p.items()) 187 expected.update(self.s) 188 assert sorted(self.av.items()) == sorted(expected.items()) 189 190 def test_str(self): 191 out = str(dict(self.av)) 192 assert str(self.av) == out 193 194 def test_repr(self): 195 out = f"{self.av.__class__.__name__}({self.s}, {self.p})" 196 assert repr(self.av) == out 197 198 199class TestUnionAdjacency: 200 # node->nbr->data 201 def setup(self): 202 dd = {"color": "blue", "weight": 1.2} 203 self.nd = {0: dd, 1: {}, 2: {"color": 1}} 204 self.s = {3: self.nd, 0: {}, 1: {}, 2: {3: {"color": 1}}} 205 self.p = {3: {}, 0: {3: dd}, 1: {0: {}}, 2: {1: {"color": 1}}} 206 self.adjview = nx.classes.coreviews.UnionAdjacency(self.s, self.p) 207 208 def test_pickle(self): 209 view = self.adjview 210 pview = pickle.loads(pickle.dumps(view, -1)) 211 assert view == pview 212 assert view.__slots__ == pview.__slots__ 213 214 def test_len(self): 215 assert len(self.adjview) == len(self.s) 216 217 def test_iter(self): 218 assert sorted(self.adjview) == sorted(self.s) 219 220 def test_getitem(self): 221 assert self.adjview[1] is not self.s[1] 222 assert self.adjview[3][0] is self.adjview[0][3] 223 assert self.adjview[2][3]["color"] == 1 224 pytest.raises(KeyError, self.adjview.__getitem__, 4) 225 226 def test_copy(self): 227 avcopy = self.adjview.copy() 228 assert avcopy[0] == self.adjview[0] 229 assert avcopy[0] is not self.adjview[0] 230 231 avcopy[2][3]["ht"] = 4 232 assert avcopy[2] != self.adjview[2] 233 self.adjview[2][3]["ht"] = 4 234 assert avcopy[2] == self.adjview[2] 235 del self.adjview[2][3]["ht"] 236 237 assert not hasattr(self.adjview, "__setitem__") 238 239 def test_str(self): 240 out = str(dict(self.adjview)) 241 assert str(self.adjview) == out 242 243 def test_repr(self): 244 clsname = self.adjview.__class__.__name__ 245 out = f"{clsname}({self.s}, {self.p})" 246 assert repr(self.adjview) == out 247 248 249class TestUnionMultiInner(TestUnionAdjacency): 250 # nbr->key->data 251 def setup(self): 252 dd = {"color": "blue", "weight": 1.2} 253 self.kd = {7: {}, "ekey": {}, 9: {"color": 1}} 254 self.s = {3: self.kd, 0: {7: dd}, 1: {}, 2: {"key": {"color": 1}}} 255 self.p = {3: {}, 0: {3: dd}, 1: {}, 2: {1: {"span": 2}}} 256 self.adjview = nx.classes.coreviews.UnionMultiInner(self.s, self.p) 257 258 def test_len(self): 259 assert len(self.adjview) == len(self.s) + len(self.p) 260 261 def test_getitem(self): 262 assert self.adjview[1] is not self.s[1] 263 assert self.adjview[0][7] is self.adjview[0][3] 264 assert self.adjview[2]["key"]["color"] == 1 265 assert self.adjview[2][1]["span"] == 2 266 pytest.raises(KeyError, self.adjview.__getitem__, 4) 267 pytest.raises(KeyError, self.adjview[1].__getitem__, "key") 268 269 def test_copy(self): 270 avcopy = self.adjview.copy() 271 assert avcopy[0] == self.adjview[0] 272 assert avcopy[0] is not self.adjview[0] 273 274 avcopy[2][1]["width"] = 8 275 assert avcopy[2] != self.adjview[2] 276 self.adjview[2][1]["width"] = 8 277 assert avcopy[2] == self.adjview[2] 278 del self.adjview[2][1]["width"] 279 280 assert not hasattr(self.adjview, "__setitem__") 281 assert hasattr(avcopy, "__setitem__") 282 283 284class TestUnionMultiAdjacency(TestUnionAdjacency): 285 # node->nbr->key->data 286 def setup(self): 287 dd = {"color": "blue", "weight": 1.2} 288 self.kd = {7: {}, 8: {}, 9: {"color": 1}} 289 self.nd = {3: self.kd, 0: {9: dd}, 1: {8: {}}, 2: {9: {"color": 1}}} 290 self.s = {3: self.nd, 0: {3: {7: dd}}, 1: {}, 2: {3: {8: {}}}} 291 self.p = {3: {}, 0: {3: {9: dd}}, 1: {}, 2: {1: {8: {}}}} 292 self.adjview = nx.classes.coreviews.UnionMultiAdjacency(self.s, self.p) 293 294 def test_getitem(self): 295 assert self.adjview[1] is not self.s[1] 296 assert self.adjview[3][0][9] is self.adjview[0][3][9] 297 assert self.adjview[3][2][9]["color"] == 1 298 pytest.raises(KeyError, self.adjview.__getitem__, 4) 299 300 def test_copy(self): 301 avcopy = self.adjview.copy() 302 assert avcopy[0] == self.adjview[0] 303 assert avcopy[0] is not self.adjview[0] 304 305 avcopy[2][3][8]["ht"] = 4 306 assert avcopy[2] != self.adjview[2] 307 self.adjview[2][3][8]["ht"] = 4 308 assert avcopy[2] == self.adjview[2] 309 del self.adjview[2][3][8]["ht"] 310 311 assert not hasattr(self.adjview, "__setitem__") 312 assert hasattr(avcopy, "__setitem__") 313 314 315class TestFilteredGraphs: 316 def setup(self): 317 self.Graphs = [nx.Graph, nx.DiGraph, nx.MultiGraph, nx.MultiDiGraph] 318 319 def test_hide_show_nodes(self): 320 SubGraph = nx.graphviews.subgraph_view 321 for Graph in self.Graphs: 322 G = nx.path_graph(4, Graph) 323 SG = G.subgraph([2, 3]) 324 RG = SubGraph(G, nx.filters.hide_nodes([0, 1])) 325 assert SG.nodes == RG.nodes 326 assert SG.edges == RG.edges 327 SGC = SG.copy() 328 RGC = RG.copy() 329 assert SGC.nodes == RGC.nodes 330 assert SGC.edges == RGC.edges 331 332 def test_str_repr(self): 333 SubGraph = nx.graphviews.subgraph_view 334 for Graph in self.Graphs: 335 G = nx.path_graph(4, Graph) 336 SG = G.subgraph([2, 3]) 337 RG = SubGraph(G, nx.filters.hide_nodes([0, 1])) 338 str(SG.adj) 339 str(RG.adj) 340 repr(SG.adj) 341 repr(RG.adj) 342 str(SG.adj[2]) 343 str(RG.adj[2]) 344 repr(SG.adj[2]) 345 repr(RG.adj[2]) 346 347 def test_copy(self): 348 SubGraph = nx.graphviews.subgraph_view 349 for Graph in self.Graphs: 350 G = nx.path_graph(4, Graph) 351 SG = G.subgraph([2, 3]) 352 RG = SubGraph(G, nx.filters.hide_nodes([0, 1])) 353 RsG = SubGraph(G, nx.filters.show_nodes([2, 3])) 354 assert G.adj.copy() == G.adj 355 assert G.adj[2].copy() == G.adj[2] 356 assert SG.adj.copy() == SG.adj 357 assert SG.adj[2].copy() == SG.adj[2] 358 assert RG.adj.copy() == RG.adj 359 assert RG.adj[2].copy() == RG.adj[2] 360 assert RsG.adj.copy() == RsG.adj 361 assert RsG.adj[2].copy() == RsG.adj[2] 362 363 def test_filtered_copy(self): 364 # TODO: This function can be removed when filtered.copy() 365 # deprecation expires 366 SubGraph = nx.graphviews.subgraph_view 367 for Graph in self.Graphs: 368 G = nx.path_graph(4, Graph) 369 SG = G.subgraph([2, 3]) 370 RG = SubGraph(G, nx.filters.hide_nodes([0, 1])) 371 RsG = SubGraph(G, nx.filters.show_nodes([2, 3])) 372 # test FilterAtlas & co in these subgraphs 373 assert SG._node.copy() == SG._node 374 assert SG.adj._atlas.copy() == SG.adj._atlas 375 assert SG.adj[2]._atlas.copy() == SG.adj[2]._atlas 376 assert SG.adj[2]._atlas[3].copy() == SG.adj[2]._atlas[3] 377 assert RG.adj._atlas.copy() == RG.adj._atlas 378 assert RG.adj[2]._atlas.copy() == RG.adj[2]._atlas 379 assert RG.adj[2]._atlas[3].copy() == RG.adj[2]._atlas[3] 380 assert RG._node.copy() == RG._node 381 assert RsG.adj._atlas.copy() == RsG.adj._atlas 382 assert RsG.adj[2]._atlas.copy() == RsG.adj[2]._atlas 383 assert RsG.adj[2]._atlas[3].copy() == RsG.adj[2]._atlas[3] 384 assert RsG._node.copy() == RsG._node 385 # test MultiFilterInner 386 if G.is_multigraph(): 387 assert SG.adj[2]._atlas[3][0].copy() == SG.adj[2]._atlas[3][0] 388 assert RG.adj[2]._atlas[3][0].copy() == RG.adj[2]._atlas[3][0] 389 assert RsG.adj[2]._atlas[3][0].copy() == RsG.adj[2]._atlas[3][0] 390 391 # test deprecation 392 # FilterAtlas.copy() 393 pytest.deprecated_call(SG._node.copy) 394 # FilterAdjacency.copy() 395 pytest.deprecated_call(SG.adj._atlas.copy) 396 # FilterMultiAdjacency.copy() 397 if G.is_multigraph(): 398 pytest.deprecated_call(SG.adj._atlas.copy) 399 # FilterMultiInner.copy() 400 if G.is_multigraph(): 401 pytest.deprecated_call(SG.adj[2]._atlas.copy) 402 403 SSG = SG.subgraph([2]) 404 assert list(SSG) == [2] 405 406 # check case when node_ok is small 407 G = nx.complete_graph(9, Graph) 408 SG = G.subgraph([2, 3]) 409 RG = SubGraph(G, nx.filters.hide_nodes([0, 1])) 410 RsG = SubGraph(G, nx.filters.show_nodes([2, 3, 4, 5, 6, 7, 8])) 411 assert SG.adj._atlas.copy() == SG.adj._atlas 412 assert SG.adj[2]._atlas.copy() == SG.adj[2]._atlas 413 assert SG.adj[2]._atlas[3].copy() == SG.adj[2]._atlas[3] 414 assert SG._node.copy() == SG._node 415 assert RG.adj._atlas.copy() == RG.adj._atlas 416 assert RG.adj[2]._atlas.copy() == RG.adj[2]._atlas 417 assert RG.adj[2]._atlas[3].copy() == RG.adj[2]._atlas[3] 418 assert RG._node.copy() == RG._node 419 assert RsG.adj._atlas.copy() == RsG.adj._atlas 420 assert RsG.adj[2]._atlas.copy() == RsG.adj[2]._atlas 421 assert RsG.adj[2]._atlas[3].copy() == RsG.adj[2]._atlas[3] 422 assert RsG._node.copy() == RsG._node 423 # test MultiFilterInner 424 if G.is_multigraph(): 425 assert SG.adj[2][3]._atlas.copy() == SG.adj[2][3]._atlas 426 assert RG.adj[2][3]._atlas.copy() == RG.adj[2][3]._atlas 427 assert RsG.adj[2][3]._atlas.copy() == RsG.adj[2][3]._atlas 428 429 SSG = SG.subgraph([2]) 430 assert list(SSG) == [2] 431