• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 The Guava Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.common.graph;
18 
19 import static com.google.common.graph.GraphConstants.ENDPOINTS_MISMATCH;
20 import static com.google.common.truth.Truth.assertThat;
21 import static com.google.common.truth.TruthJUnit.assume;
22 import static org.junit.Assert.assertThrows;
23 import static org.junit.Assert.assertTrue;
24 import static org.junit.Assert.fail;
25 
26 import com.google.common.collect.ImmutableSet;
27 import com.google.common.testing.EqualsTester;
28 import java.util.Optional;
29 import java.util.Set;
30 import org.junit.After;
31 import org.junit.Test;
32 
33 /**
34  * Abstract base class for testing undirected {@link Network} implementations defined in this
35  * package.
36  */
37 public abstract class AbstractStandardUndirectedNetworkTest extends AbstractNetworkTest {
38   private static final EndpointPair<Integer> ENDPOINTS_N1N2 = EndpointPair.ordered(N1, N2);
39   private static final EndpointPair<Integer> ENDPOINTS_N2N1 = EndpointPair.ordered(N2, N1);
40 
41   @After
validateUndirectedEdges()42   public void validateUndirectedEdges() {
43     for (Integer node : network.nodes()) {
44       new EqualsTester()
45           .addEqualityGroup(
46               network.inEdges(node), network.outEdges(node), network.incidentEdges(node))
47           .testEquals();
48       new EqualsTester()
49           .addEqualityGroup(
50               network.predecessors(node), network.successors(node), network.adjacentNodes(node))
51           .testEquals();
52 
53       for (Integer adjacentNode : network.adjacentNodes(node)) {
54         assertThat(network.edgesConnecting(node, adjacentNode))
55             .containsExactlyElementsIn(network.edgesConnecting(adjacentNode, node));
56       }
57     }
58   }
59 
60   @Override
61   @Test
nodes_checkReturnedSetMutability()62   public void nodes_checkReturnedSetMutability() {
63     Set<Integer> nodes = network.nodes();
64     UnsupportedOperationException e =
65         assertThrows(UnsupportedOperationException.class, () -> nodes.add(N2));
66     addNode(N1);
67     assertThat(network.nodes()).containsExactlyElementsIn(nodes);
68   }
69 
70   @Override
71   @Test
edges_checkReturnedSetMutability()72   public void edges_checkReturnedSetMutability() {
73     Set<String> edges = network.edges();
74     UnsupportedOperationException e =
75         assertThrows(UnsupportedOperationException.class, () -> edges.add(E12));
76     addEdge(N1, N2, E12);
77     assertThat(network.edges()).containsExactlyElementsIn(edges);
78   }
79 
80   @Override
81   @Test
incidentEdges_checkReturnedSetMutability()82   public void incidentEdges_checkReturnedSetMutability() {
83     addNode(N1);
84     Set<String> incidentEdges = network.incidentEdges(N1);
85     UnsupportedOperationException e =
86         assertThrows(UnsupportedOperationException.class, () -> incidentEdges.add(E12));
87     addEdge(N1, N2, E12);
88     assertThat(network.incidentEdges(N1)).containsExactlyElementsIn(incidentEdges);
89   }
90 
91   @Override
92   @Test
adjacentNodes_checkReturnedSetMutability()93   public void adjacentNodes_checkReturnedSetMutability() {
94     addNode(N1);
95     Set<Integer> adjacentNodes = network.adjacentNodes(N1);
96     UnsupportedOperationException e =
97         assertThrows(UnsupportedOperationException.class, () -> adjacentNodes.add(N2));
98     addEdge(N1, N2, E12);
99     assertThat(network.adjacentNodes(N1)).containsExactlyElementsIn(adjacentNodes);
100   }
101 
102   @Override
adjacentEdges_checkReturnedSetMutability()103   public void adjacentEdges_checkReturnedSetMutability() {
104     addEdge(N1, N2, E12);
105     Set<String> adjacentEdges = network.adjacentEdges(E12);
106     try {
107       adjacentEdges.add(E23);
108       fail(ERROR_MODIFIABLE_COLLECTION);
109     } catch (UnsupportedOperationException e) {
110       addEdge(N2, N3, E23);
111       assertThat(network.adjacentEdges(E12)).containsExactlyElementsIn(adjacentEdges);
112     }
113   }
114 
115   @Override
116   @Test
edgesConnecting_checkReturnedSetMutability()117   public void edgesConnecting_checkReturnedSetMutability() {
118     addNode(N1);
119     addNode(N2);
120     Set<String> edgesConnecting = network.edgesConnecting(N1, N2);
121     UnsupportedOperationException e =
122         assertThrows(UnsupportedOperationException.class, () -> edgesConnecting.add(E23));
123     addEdge(N1, N2, E12);
124     assertThat(network.edgesConnecting(N1, N2)).containsExactlyElementsIn(edgesConnecting);
125   }
126 
127   @Override
128   @Test
inEdges_checkReturnedSetMutability()129   public void inEdges_checkReturnedSetMutability() {
130     addNode(N2);
131     Set<String> inEdges = network.inEdges(N2);
132     UnsupportedOperationException e =
133         assertThrows(UnsupportedOperationException.class, () -> inEdges.add(E12));
134     addEdge(N1, N2, E12);
135     assertThat(network.inEdges(N2)).containsExactlyElementsIn(inEdges);
136   }
137 
138   @Override
139   @Test
outEdges_checkReturnedSetMutability()140   public void outEdges_checkReturnedSetMutability() {
141     addNode(N1);
142     Set<String> outEdges = network.outEdges(N1);
143     UnsupportedOperationException e =
144         assertThrows(UnsupportedOperationException.class, () -> outEdges.add(E12));
145     addEdge(N1, N2, E12);
146     assertThat(network.outEdges(N1)).containsExactlyElementsIn(outEdges);
147   }
148 
149   @Override
150   @Test
predecessors_checkReturnedSetMutability()151   public void predecessors_checkReturnedSetMutability() {
152     addNode(N2);
153     Set<Integer> predecessors = network.predecessors(N2);
154     UnsupportedOperationException e =
155         assertThrows(UnsupportedOperationException.class, () -> predecessors.add(N1));
156     addEdge(N1, N2, E12);
157     assertThat(network.predecessors(N2)).containsExactlyElementsIn(predecessors);
158   }
159 
160   @Override
161   @Test
successors_checkReturnedSetMutability()162   public void successors_checkReturnedSetMutability() {
163     addNode(N1);
164     Set<Integer> successors = network.successors(N1);
165     UnsupportedOperationException e =
166         assertThrows(UnsupportedOperationException.class, () -> successors.add(N2));
167     addEdge(N1, N2, E12);
168     assertThat(network.successors(N1)).containsExactlyElementsIn(successors);
169   }
170 
171   @Test
edges_containsOrderMismatch()172   public void edges_containsOrderMismatch() {
173     addEdge(N1, N2, E12);
174     assertThat(network.asGraph().edges()).doesNotContain(ENDPOINTS_N2N1);
175     assertThat(network.asGraph().edges()).doesNotContain(ENDPOINTS_N1N2);
176   }
177 
178   @Test
edgesConnecting_orderMismatch()179   public void edgesConnecting_orderMismatch() {
180     addEdge(N1, N2, E12);
181     IllegalArgumentException e =
182         assertThrows(
183             IllegalArgumentException.class,
184             () -> {
185               Set<String> unused = network.edgesConnecting(ENDPOINTS_N1N2);
186             });
187     assertThat(e).hasMessageThat().contains(ENDPOINTS_MISMATCH);
188   }
189 
190   @Test
edgeConnecting_orderMismatch()191   public void edgeConnecting_orderMismatch() {
192     addEdge(N1, N2, E12);
193     IllegalArgumentException e =
194         assertThrows(
195             IllegalArgumentException.class,
196             () -> {
197               Optional<String> unused = network.edgeConnecting(ENDPOINTS_N1N2);
198             });
199     assertThat(e).hasMessageThat().contains(ENDPOINTS_MISMATCH);
200   }
201 
202   @Test
edgeConnectingOrNull_orderMismatch()203   public void edgeConnectingOrNull_orderMismatch() {
204     addEdge(N1, N2, E12);
205     IllegalArgumentException e =
206         assertThrows(
207             IllegalArgumentException.class,
208             () -> {
209               String unused = network.edgeConnectingOrNull(ENDPOINTS_N1N2);
210             });
211     assertThat(e).hasMessageThat().contains(ENDPOINTS_MISMATCH);
212   }
213 
214   @Test
edgesConnecting_oneEdge()215   public void edgesConnecting_oneEdge() {
216     addEdge(N1, N2, E12);
217     assertThat(network.edgesConnecting(N1, N2)).containsExactly(E12);
218     assertThat(network.edgesConnecting(N2, N1)).containsExactly(E12);
219   }
220 
221   @Test
inEdges_oneEdge()222   public void inEdges_oneEdge() {
223     addEdge(N1, N2, E12);
224     assertThat(network.inEdges(N2)).containsExactly(E12);
225     assertThat(network.inEdges(N1)).containsExactly(E12);
226   }
227 
228   @Test
outEdges_oneEdge()229   public void outEdges_oneEdge() {
230     addEdge(N1, N2, E12);
231     assertThat(network.outEdges(N2)).containsExactly(E12);
232     assertThat(network.outEdges(N1)).containsExactly(E12);
233   }
234 
235   @Test
predecessors_oneEdge()236   public void predecessors_oneEdge() {
237     addEdge(N1, N2, E12);
238     assertThat(network.predecessors(N2)).containsExactly(N1);
239     assertThat(network.predecessors(N1)).containsExactly(N2);
240   }
241 
242   @Test
successors_oneEdge()243   public void successors_oneEdge() {
244     addEdge(N1, N2, E12);
245     assertThat(network.successors(N1)).containsExactly(N2);
246     assertThat(network.successors(N2)).containsExactly(N1);
247   }
248 
249   @Test
inDegree_oneEdge()250   public void inDegree_oneEdge() {
251     addEdge(N1, N2, E12);
252     assertThat(network.inDegree(N2)).isEqualTo(1);
253     assertThat(network.inDegree(N1)).isEqualTo(1);
254   }
255 
256   @Test
outDegree_oneEdge()257   public void outDegree_oneEdge() {
258     addEdge(N1, N2, E12);
259     assertThat(network.outDegree(N1)).isEqualTo(1);
260     assertThat(network.outDegree(N2)).isEqualTo(1);
261   }
262 
263   @Test
edges_selfLoop()264   public void edges_selfLoop() {
265     assume().that(network.allowsSelfLoops()).isTrue();
266 
267     addEdge(N1, N1, E11);
268     assertThat(network.edges()).containsExactly(E11);
269   }
270 
271   @Test
incidentEdges_selfLoop()272   public void incidentEdges_selfLoop() {
273     assume().that(network.allowsSelfLoops()).isTrue();
274 
275     addEdge(N1, N1, E11);
276     assertThat(network.incidentEdges(N1)).containsExactly(E11);
277   }
278 
279   @Test
incidentNodes_selfLoop()280   public void incidentNodes_selfLoop() {
281     assume().that(network.allowsSelfLoops()).isTrue();
282 
283     addEdge(N1, N1, E11);
284     assertThat(network.incidentNodes(E11).nodeU()).isEqualTo(N1);
285     assertThat(network.incidentNodes(E11).nodeV()).isEqualTo(N1);
286   }
287 
288   @Test
adjacentNodes_selfLoop()289   public void adjacentNodes_selfLoop() {
290     assume().that(network.allowsSelfLoops()).isTrue();
291 
292     addEdge(N1, N1, E11);
293     addEdge(N1, N2, E12);
294     assertThat(network.adjacentNodes(N1)).containsExactly(N1, N2);
295   }
296 
297   @Test
adjacentEdges_selfLoop()298   public void adjacentEdges_selfLoop() {
299     assume().that(network.allowsSelfLoops()).isTrue();
300 
301     addEdge(N1, N1, E11);
302     addEdge(N1, N2, E12);
303     assertThat(network.adjacentEdges(E11)).containsExactly(E12);
304   }
305 
306   @Test
edgesConnecting_selfLoop()307   public void edgesConnecting_selfLoop() {
308     assume().that(network.allowsSelfLoops()).isTrue();
309 
310     addEdge(N1, N1, E11);
311     assertThat(network.edgesConnecting(N1, N1)).containsExactly(E11);
312     addEdge(N1, N2, E12);
313     assertThat(network.edgesConnecting(N1, N2)).containsExactly(E12);
314     assertThat(network.edgesConnecting(N2, N1)).containsExactly(E12);
315     assertThat(network.edgesConnecting(N1, N1)).containsExactly(E11);
316   }
317 
318   @Test
inEdges_selfLoop()319   public void inEdges_selfLoop() {
320     assume().that(network.allowsSelfLoops()).isTrue();
321 
322     addEdge(N1, N1, E11);
323     assertThat(network.inEdges(N1)).containsExactly(E11);
324     addEdge(N1, N2, E12);
325     assertThat(network.inEdges(N1)).containsExactly(E11, E12);
326   }
327 
328   @Test
outEdges_selfLoop()329   public void outEdges_selfLoop() {
330     assume().that(network.allowsSelfLoops()).isTrue();
331 
332     addEdge(N1, N1, E11);
333     assertThat(network.outEdges(N1)).containsExactly(E11);
334     addEdge(N2, N1, E12);
335     assertThat(network.outEdges(N1)).containsExactly(E11, E12);
336   }
337 
338   @Test
predecessors_selfLoop()339   public void predecessors_selfLoop() {
340     assume().that(network.allowsSelfLoops()).isTrue();
341 
342     addEdge(N1, N1, E11);
343     assertThat(network.predecessors(N1)).containsExactly(N1);
344     addEdge(N1, N2, E12);
345     assertThat(network.predecessors(N1)).containsExactly(N1, N2);
346   }
347 
348   @Test
successors_selfLoop()349   public void successors_selfLoop() {
350     assume().that(network.allowsSelfLoops()).isTrue();
351 
352     addEdge(N1, N1, E11);
353     assertThat(network.successors(N1)).containsExactly(N1);
354     addEdge(N2, N1, E12);
355     assertThat(network.successors(N1)).containsExactly(N1, N2);
356   }
357 
358   @Test
degree_selfLoop()359   public void degree_selfLoop() {
360     assume().that(network.allowsSelfLoops()).isTrue();
361 
362     addEdge(N1, N1, E11);
363     assertThat(network.degree(N1)).isEqualTo(2);
364     addEdge(N1, N2, E12);
365     assertThat(network.degree(N1)).isEqualTo(3);
366   }
367 
368   @Test
inDegree_selfLoop()369   public void inDegree_selfLoop() {
370     assume().that(network.allowsSelfLoops()).isTrue();
371 
372     addEdge(N1, N1, E11);
373     assertThat(network.inDegree(N1)).isEqualTo(2);
374     addEdge(N1, N2, E12);
375     assertThat(network.inDegree(N1)).isEqualTo(3);
376   }
377 
378   @Test
outDegree_selfLoop()379   public void outDegree_selfLoop() {
380     assume().that(network.allowsSelfLoops()).isTrue();
381 
382     addEdge(N1, N1, E11);
383     assertThat(network.outDegree(N1)).isEqualTo(2);
384     addEdge(N2, N1, E12);
385     assertThat(network.outDegree(N1)).isEqualTo(3);
386   }
387 
388   // Element Mutation
389 
390   @Test
addEdge_existingNodes()391   public void addEdge_existingNodes() {
392     assume().that(graphIsMutable()).isTrue();
393 
394     // Adding nodes initially for safety (insulating from possible future
395     // modifications to proxy methods)
396     addNode(N1);
397     addNode(N2);
398     assertThat(networkAsMutableNetwork.addEdge(N1, N2, E12)).isTrue();
399     assertThat(network.edges()).contains(E12);
400     assertThat(network.edgesConnecting(N1, N2)).containsExactly(E12);
401     assertThat(network.edgesConnecting(N2, N1)).containsExactly(E12);
402   }
403 
404   @Test
addEdge_existingEdgeBetweenSameNodes()405   public void addEdge_existingEdgeBetweenSameNodes() {
406     assume().that(graphIsMutable()).isTrue();
407 
408     assertThat(networkAsMutableNetwork.addEdge(N1, N2, E12)).isTrue();
409     ImmutableSet<String> edges = ImmutableSet.copyOf(network.edges());
410     assertThat(networkAsMutableNetwork.addEdge(N1, N2, E12)).isFalse();
411     assertThat(network.edges()).containsExactlyElementsIn(edges);
412     assertThat(networkAsMutableNetwork.addEdge(N2, N1, E12)).isFalse();
413     assertThat(network.edges()).containsExactlyElementsIn(edges);
414   }
415 
416   @Test
addEdge_existingEdgeBetweenDifferentNodes()417   public void addEdge_existingEdgeBetweenDifferentNodes() {
418     assume().that(graphIsMutable()).isTrue();
419 
420     addEdge(N1, N2, E12);
421     IllegalArgumentException e =
422         assertThrows(
423             IllegalArgumentException.class, () -> networkAsMutableNetwork.addEdge(N4, N5, E12));
424     assertThat(e).hasMessageThat().contains(ERROR_REUSE_EDGE);
425   }
426 
427   @Test
addEdge_parallelEdge_notAllowed()428   public void addEdge_parallelEdge_notAllowed() {
429     assume().that(graphIsMutable()).isTrue();
430     assume().that(network.allowsParallelEdges()).isFalse();
431 
432     addEdge(N1, N2, E12);
433     IllegalArgumentException e =
434         assertThrows(
435             IllegalArgumentException.class,
436             () -> networkAsMutableNetwork.addEdge(N1, N2, EDGE_NOT_IN_GRAPH));
437     assertThat(e).hasMessageThat().contains(ERROR_PARALLEL_EDGE);
438     e =
439         assertThrows(
440             IllegalArgumentException.class,
441             () -> networkAsMutableNetwork.addEdge(N2, N1, EDGE_NOT_IN_GRAPH));
442     assertThat(e).hasMessageThat().contains(ERROR_PARALLEL_EDGE);
443   }
444 
445   @Test
addEdge_parallelEdge_allowsParallelEdges()446   public void addEdge_parallelEdge_allowsParallelEdges() {
447     assume().that(graphIsMutable()).isTrue();
448     assume().that(network.allowsParallelEdges()).isTrue();
449 
450     assertTrue(networkAsMutableNetwork.addEdge(N1, N2, E12));
451     assertTrue(networkAsMutableNetwork.addEdge(N2, N1, E21));
452     assertTrue(networkAsMutableNetwork.addEdge(N1, N2, E12_A));
453     assertThat(network.edgesConnecting(N1, N2)).containsExactly(E12, E12_A, E21);
454   }
455 
456   @Test
addEdge_orderMismatch()457   public void addEdge_orderMismatch() {
458     assume().that(graphIsMutable()).isTrue();
459 
460     EndpointPair<Integer> endpoints = EndpointPair.ordered(N1, N2);
461     IllegalArgumentException e =
462         assertThrows(
463             IllegalArgumentException.class, () -> networkAsMutableNetwork.addEdge(endpoints, E12));
464     assertThat(e).hasMessageThat().contains(ENDPOINTS_MISMATCH);
465   }
466 
467   @Test
addEdge_selfLoop_notAllowed()468   public void addEdge_selfLoop_notAllowed() {
469     assume().that(graphIsMutable()).isTrue();
470     assume().that(network.allowsSelfLoops()).isFalse();
471 
472     IllegalArgumentException e =
473         assertThrows(
474             IllegalArgumentException.class, () -> networkAsMutableNetwork.addEdge(N1, N1, E11));
475     assertThat(e).hasMessageThat().contains(ERROR_SELF_LOOP);
476   }
477 
478   /**
479    * This test checks an implementation dependent feature. It tests that the method {@code addEdge}
480    * will silently add the missing nodes to the graph, then add the edge connecting them. We are not
481    * using the proxy methods here as we want to test {@code addEdge} when the end-points are not
482    * elements of the graph.
483    */
484   @Test
addEdge_nodesNotInGraph()485   public void addEdge_nodesNotInGraph() {
486     assume().that(graphIsMutable()).isTrue();
487 
488     networkAsMutableNetwork.addNode(N1);
489     assertTrue(networkAsMutableNetwork.addEdge(N1, N5, E15));
490     assertTrue(networkAsMutableNetwork.addEdge(N4, N1, E41));
491     assertTrue(networkAsMutableNetwork.addEdge(N2, N3, E23));
492     assertThat(network.nodes()).containsExactly(N1, N5, N4, N2, N3);
493     assertThat(network.edges()).containsExactly(E15, E41, E23);
494     assertThat(network.edgesConnecting(N1, N5)).containsExactly(E15);
495     assertThat(network.edgesConnecting(N4, N1)).containsExactly(E41);
496     assertThat(network.edgesConnecting(N2, N3)).containsExactly(E23);
497     assertThat(network.edgesConnecting(N3, N2)).containsExactly(E23);
498   }
499 
500   @Test
addEdge_selfLoop()501   public void addEdge_selfLoop() {
502     assume().that(graphIsMutable()).isTrue();
503     assume().that(network.allowsSelfLoops()).isTrue();
504 
505     assertThat(networkAsMutableNetwork.addEdge(N1, N1, E11)).isTrue();
506     assertThat(network.edges()).contains(E11);
507     assertThat(network.edgesConnecting(N1, N1)).containsExactly(E11);
508   }
509 
510   @Test
addEdge_existingSelfLoopEdgeBetweenSameNodes()511   public void addEdge_existingSelfLoopEdgeBetweenSameNodes() {
512     assume().that(graphIsMutable()).isTrue();
513     assume().that(network.allowsSelfLoops()).isTrue();
514 
515     addEdge(N1, N1, E11);
516     ImmutableSet<String> edges = ImmutableSet.copyOf(network.edges());
517     assertThat(networkAsMutableNetwork.addEdge(N1, N1, E11)).isFalse();
518     assertThat(network.edges()).containsExactlyElementsIn(edges);
519   }
520 
521   @Test
addEdge_existingEdgeBetweenDifferentNodes_selfLoops()522   public void addEdge_existingEdgeBetweenDifferentNodes_selfLoops() {
523     assume().that(graphIsMutable()).isTrue();
524     assume().that(network.allowsSelfLoops()).isTrue();
525 
526     addEdge(N1, N1, E11);
527     IllegalArgumentException e =
528         assertThrows(
529             IllegalArgumentException.class, () -> networkAsMutableNetwork.addEdge(N1, N2, E11));
530     assertThat(e).hasMessageThat().contains(ERROR_REUSE_EDGE);
531     e =
532         assertThrows(
533             IllegalArgumentException.class, () -> networkAsMutableNetwork.addEdge(N2, N2, E11));
534     assertThat(e).hasMessageThat().contains(ERROR_REUSE_EDGE);
535     addEdge(N1, N2, E12);
536     e =
537         assertThrows(
538             IllegalArgumentException.class, () -> networkAsMutableNetwork.addEdge(N1, N1, E12));
539     assertThat(e).hasMessageThat().contains(ERROR_REUSE_EDGE);
540   }
541 
542   @Test
addEdge_parallelSelfLoopEdge_notAllowed()543   public void addEdge_parallelSelfLoopEdge_notAllowed() {
544     assume().that(graphIsMutable()).isTrue();
545     assume().that(network.allowsSelfLoops()).isTrue();
546     assume().that(network.allowsParallelEdges()).isFalse();
547 
548     addEdge(N1, N1, E11);
549     IllegalArgumentException e =
550         assertThrows(
551             IllegalArgumentException.class,
552             () -> networkAsMutableNetwork.addEdge(N1, N1, EDGE_NOT_IN_GRAPH));
553     assertThat(e).hasMessageThat().contains(ERROR_PARALLEL_EDGE);
554   }
555 
556   @Test
addEdge_parallelSelfLoopEdge_allowsParallelEdges()557   public void addEdge_parallelSelfLoopEdge_allowsParallelEdges() {
558     assume().that(graphIsMutable()).isTrue();
559     assume().that(network.allowsSelfLoops()).isTrue();
560     assume().that(network.allowsParallelEdges()).isTrue();
561 
562     assertTrue(networkAsMutableNetwork.addEdge(N1, N1, E11));
563     assertTrue(networkAsMutableNetwork.addEdge(N1, N1, E11_A));
564     assertThat(network.edgesConnecting(N1, N1)).containsExactly(E11, E11_A);
565   }
566 
567   @Test
removeNode_existingNodeWithSelfLoopEdge()568   public void removeNode_existingNodeWithSelfLoopEdge() {
569     assume().that(graphIsMutable()).isTrue();
570     assume().that(network.allowsSelfLoops()).isTrue();
571 
572     addNode(N1);
573     addEdge(N1, N1, E11);
574     assertThat(networkAsMutableNetwork.removeNode(N1)).isTrue();
575     assertThat(network.nodes()).isEmpty();
576     assertThat(network.edges()).doesNotContain(E11);
577   }
578 
579   @Test
removeEdge_existingSelfLoopEdge()580   public void removeEdge_existingSelfLoopEdge() {
581     assume().that(graphIsMutable()).isTrue();
582     assume().that(network.allowsSelfLoops()).isTrue();
583 
584     addEdge(N1, N1, E11);
585     assertThat(networkAsMutableNetwork.removeEdge(E11)).isTrue();
586     assertThat(network.edges()).doesNotContain(E11);
587     assertThat(network.edgesConnecting(N1, N1)).isEmpty();
588   }
589 }
590