• 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.graph.TestUtil.assertEdgeNotInGraphErrorMessage;
21 import static com.google.common.truth.Truth.assertThat;
22 import static org.junit.Assert.fail;
23 
24 import com.google.common.collect.ImmutableSet;
25 import java.util.Collections;
26 import java.util.Set;
27 import org.junit.After;
28 import org.junit.Test;
29 
30 /**
31  * Abstract base class for testing implementations of {@link Network} interface.
32  *
33  * <p>This class is responsible for testing that a directed implementation of {@link Network} is
34  * correctly handling directed edges. Implementation-dependent test cases are left to subclasses.
35  * Test cases that do not require the graph to be directed are found in superclasses.
36  */
37 public abstract class AbstractDirectedNetworkTest extends AbstractNetworkTest {
38 
39   @After
validateSourceAndTarget()40   public void validateSourceAndTarget() {
41     for (Integer node : network.nodes()) {
42       for (String inEdge : network.inEdges(node)) {
43         EndpointPair<Integer> endpointPair = network.incidentNodes(inEdge);
44         assertThat(endpointPair.source()).isEqualTo(endpointPair.adjacentNode(node));
45         assertThat(endpointPair.target()).isEqualTo(node);
46       }
47 
48       for (String outEdge : network.outEdges(node)) {
49         EndpointPair<Integer> endpointPair = network.incidentNodes(outEdge);
50         assertThat(endpointPair.source()).isEqualTo(node);
51         assertThat(endpointPair.target()).isEqualTo(endpointPair.adjacentNode(node));
52       }
53 
54       for (Integer adjacentNode : network.adjacentNodes(node)) {
55         Set<String> edges = network.edgesConnecting(node, adjacentNode);
56         Set<String> antiParallelEdges = network.edgesConnecting(adjacentNode, node);
57         assertThat(node.equals(adjacentNode) || Collections.disjoint(edges, antiParallelEdges))
58             .isTrue();
59       }
60     }
61   }
62 
63   @Test
edges_containsOrderMismatch()64   public void edges_containsOrderMismatch() {
65     addEdge(N1, N2, E12);
66     EndpointPair<Integer> endpointsN1N2 = EndpointPair.unordered(N1, N2);
67     EndpointPair<Integer> endpointsN2N1 = EndpointPair.unordered(N2, N1);
68     assertThat(network.asGraph().edges()).doesNotContain(endpointsN1N2);
69     assertThat(network.asGraph().edges()).doesNotContain(endpointsN2N1);
70   }
71 
72   @Test
edgesConnecting_orderMismatch()73   public void edgesConnecting_orderMismatch() {
74     addEdge(N1, N2, E12);
75     try {
76       Set<String> unused = network.edgesConnecting(EndpointPair.unordered(N1, N2));
77       fail("Expected IllegalArgumentException: " + ENDPOINTS_MISMATCH);
78     } catch (IllegalArgumentException e) {
79       assertThat(e).hasMessageThat().contains(ENDPOINTS_MISMATCH);
80     }
81   }
82 
83   @Test
edgeConnectingOrNull_orderMismatch()84   public void edgeConnectingOrNull_orderMismatch() {
85     addEdge(N1, N2, E12);
86     try {
87       String unused = network.edgeConnectingOrNull(EndpointPair.unordered(N1, N2));
88       fail("Expected IllegalArgumentException: " + ENDPOINTS_MISMATCH);
89     } catch (IllegalArgumentException e) {
90       assertThat(e).hasMessageThat().contains(ENDPOINTS_MISMATCH);
91     }
92   }
93 
94   @Override
95   @Test
incidentNodes_oneEdge()96   public void incidentNodes_oneEdge() {
97     addEdge(N1, N2, E12);
98     assertThat(network.incidentNodes(E12).source()).isEqualTo(N1);
99     assertThat(network.incidentNodes(E12).target()).isEqualTo(N2);
100   }
101 
102   @Test
edgesConnecting_oneEdge()103   public void edgesConnecting_oneEdge() {
104     addEdge(N1, N2, E12);
105     assertThat(network.edgesConnecting(N1, N2)).containsExactly(E12);
106     // Passed nodes should be in the correct edge direction, first is the
107     // source node and the second is the target node
108     assertThat(network.edgesConnecting(N2, N1)).isEmpty();
109   }
110 
111   @Test
inEdges_oneEdge()112   public void inEdges_oneEdge() {
113     addEdge(N1, N2, E12);
114     assertThat(network.inEdges(N2)).containsExactly(E12);
115     // Edge direction handled correctly
116     assertThat(network.inEdges(N1)).isEmpty();
117   }
118 
119   @Test
outEdges_oneEdge()120   public void outEdges_oneEdge() {
121     addEdge(N1, N2, E12);
122     assertThat(network.outEdges(N1)).containsExactly(E12);
123     // Edge direction handled correctly
124     assertThat(network.outEdges(N2)).isEmpty();
125   }
126 
127   @Test
predecessors_oneEdge()128   public void predecessors_oneEdge() {
129     addEdge(N1, N2, E12);
130     assertThat(network.predecessors(N2)).containsExactly(N1);
131     // Edge direction handled correctly
132     assertThat(network.predecessors(N1)).isEmpty();
133   }
134 
135   @Test
successors_oneEdge()136   public void successors_oneEdge() {
137     addEdge(N1, N2, E12);
138     assertThat(network.successors(N1)).containsExactly(N2);
139     // Edge direction handled correctly
140     assertThat(network.successors(N2)).isEmpty();
141   }
142 
143   @Test
source_oneEdge()144   public void source_oneEdge() {
145     addEdge(N1, N2, E12);
146     assertThat(network.incidentNodes(E12).source()).isEqualTo(N1);
147   }
148 
149   @Test
source_edgeNotInGraph()150   public void source_edgeNotInGraph() {
151     try {
152       network.incidentNodes(EDGE_NOT_IN_GRAPH).source();
153       fail(ERROR_EDGE_NOT_IN_GRAPH);
154     } catch (IllegalArgumentException e) {
155       assertEdgeNotInGraphErrorMessage(e);
156     }
157   }
158 
159   @Test
target_oneEdge()160   public void target_oneEdge() {
161     addEdge(N1, N2, E12);
162     assertThat(network.incidentNodes(E12).target()).isEqualTo(N2);
163   }
164 
165   @Test
target_edgeNotInGraph()166   public void target_edgeNotInGraph() {
167     try {
168       network.incidentNodes(EDGE_NOT_IN_GRAPH).target();
169       fail(ERROR_EDGE_NOT_IN_GRAPH);
170     } catch (IllegalArgumentException e) {
171       assertEdgeNotInGraphErrorMessage(e);
172     }
173   }
174 
175   @Test
inDegree_oneEdge()176   public void inDegree_oneEdge() {
177     addEdge(N1, N2, E12);
178     assertThat(network.inDegree(N2)).isEqualTo(1);
179     // Edge direction handled correctly
180     assertThat(network.inDegree(N1)).isEqualTo(0);
181   }
182 
183   @Test
outDegree_oneEdge()184   public void outDegree_oneEdge() {
185     addEdge(N1, N2, E12);
186     assertThat(network.outDegree(N1)).isEqualTo(1);
187     // Edge direction handled correctly
188     assertThat(network.outDegree(N2)).isEqualTo(0);
189   }
190 
191   // Element Mutation
192 
193   @Test
addEdge_existingNodes()194   public void addEdge_existingNodes() {
195     // Adding nodes initially for safety (insulating from possible future
196     // modifications to proxy methods)
197     addNode(N1);
198     addNode(N2);
199     assertThat(addEdge(N1, N2, E12)).isTrue();
200     assertThat(network.edges()).contains(E12);
201     assertThat(network.edgesConnecting(N1, N2)).containsExactly(E12);
202     // Direction of the added edge is correctly handled
203     assertThat(network.edgesConnecting(N2, N1)).isEmpty();
204   }
205 
206   @Test
addEdge_existingEdgeBetweenSameNodes()207   public void addEdge_existingEdgeBetweenSameNodes() {
208     addEdge(N1, N2, E12);
209     ImmutableSet<String> edges = ImmutableSet.copyOf(network.edges());
210     assertThat(addEdge(N1, N2, E12)).isFalse();
211     assertThat(network.edges()).containsExactlyElementsIn(edges);
212   }
213 
214   @Test
addEdge_existingEdgeBetweenDifferentNodes()215   public void addEdge_existingEdgeBetweenDifferentNodes() {
216     addEdge(N1, N2, E12);
217     try {
218       // Edge between totally different nodes
219       addEdge(N4, N5, E12);
220       fail(ERROR_ADDED_EXISTING_EDGE);
221     } catch (IllegalArgumentException e) {
222       assertThat(e).hasMessageThat().contains(ERROR_REUSE_EDGE);
223     }
224     try {
225       // Edge between same nodes but in reverse direction
226       addEdge(N2, N1, E12);
227       fail(ERROR_ADDED_EXISTING_EDGE);
228     } catch (IllegalArgumentException e) {
229       assertThat(e).hasMessageThat().contains(ERROR_REUSE_EDGE);
230     }
231   }
232 
233   @Test
addEdge_parallelEdge()234   public void addEdge_parallelEdge() {
235     addEdge(N1, N2, E12);
236     try {
237       addEdge(N1, N2, EDGE_NOT_IN_GRAPH);
238       fail(ERROR_ADDED_PARALLEL_EDGE);
239     } catch (IllegalArgumentException e) {
240       assertThat(e).hasMessageThat().contains(ERROR_PARALLEL_EDGE);
241     }
242   }
243 
244   @Test
addEdge_orderMismatch()245   public void addEdge_orderMismatch() {
246     EndpointPair<Integer> endpoints = EndpointPair.unordered(N1, N2);
247     try {
248       addEdge(endpoints, E12);
249       fail("Expected IllegalArgumentException: " + ENDPOINTS_MISMATCH);
250     } catch (IllegalArgumentException e) {
251       assertThat(e).hasMessageThat().contains(ENDPOINTS_MISMATCH);
252     }
253   }
254 }
255