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