1 /* 2 * Copyright (C) 2017 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.AbstractNetworkTest.ERROR_MODIFIABLE_COLLECTION; 20 import static com.google.common.graph.TestUtil.ERROR_NODE_NOT_IN_GRAPH; 21 import static com.google.common.graph.TestUtil.EdgeType.DIRECTED; 22 import static com.google.common.graph.TestUtil.EdgeType.UNDIRECTED; 23 import static com.google.common.graph.TestUtil.assertNodeNotInGraphErrorMessage; 24 import static com.google.common.truth.Truth.assertThat; 25 import static org.junit.Assert.fail; 26 27 import com.google.common.graph.TestUtil.EdgeType; 28 import java.util.Arrays; 29 import java.util.Collection; 30 import java.util.Set; 31 import org.junit.Before; 32 import org.junit.Test; 33 import org.junit.runner.RunWith; 34 import org.junit.runners.Parameterized; 35 import org.junit.runners.Parameterized.Parameters; 36 37 /** 38 * Test for {@link Network} methods which have default implementations. Currently those 39 * implementations are in {@link AbstractNetwork}; in future they might be in {@link Network} 40 * itself, once we are willing to use Java 8 default methods. 41 */ 42 @AndroidIncompatible 43 // TODO(cpovirk): Figure out Android JUnit 4 support. Does it work with Gingerbread? @RunWith? 44 @RunWith(Parameterized.class) 45 public final class DefaultNetworkImplementationsTest { 46 private MutableNetwork<Integer, String> network; 47 private NetworkForTest<Integer, String> networkForTest; 48 private static final Integer N1 = 1; 49 private static final Integer N2 = 2; 50 private static final Integer NODE_NOT_IN_GRAPH = 1000; 51 private static final String E11 = "1-1"; 52 private static final String E11_A = "1-1a"; 53 private static final String E12 = "1-2"; 54 private static final String E12_A = "1-2a"; 55 private static final String E21 = "2-1"; 56 private static final String E23 = "2-3"; 57 58 @Parameters parameters()59 public static Collection<Object[]> parameters() { 60 return Arrays.asList( 61 new Object[][] { 62 {UNDIRECTED}, {DIRECTED}, 63 }); 64 } 65 66 private final EdgeType edgeType; 67 DefaultNetworkImplementationsTest(EdgeType edgeType)68 public DefaultNetworkImplementationsTest(EdgeType edgeType) { 69 this.edgeType = edgeType; 70 } 71 72 @Before setUp()73 public void setUp() throws Exception { 74 NetworkBuilder<Object, Object> builder = 75 (edgeType == EdgeType.DIRECTED) ? NetworkBuilder.directed() : NetworkBuilder.undirected(); 76 77 network = builder.allowsSelfLoops(true).allowsParallelEdges(true).build(); 78 networkForTest = NetworkForTest.from(network); 79 } 80 81 @Test edgesConnecting_disconnectedNodes()82 public void edgesConnecting_disconnectedNodes() { 83 network.addNode(N1); 84 network.addNode(N2); 85 assertThat(networkForTest.edgesConnecting(N1, N2)).isEmpty(); 86 } 87 88 @Test edgesConnecting_nodesNotInGraph()89 public void edgesConnecting_nodesNotInGraph() { 90 network.addNode(N1); 91 network.addNode(N2); 92 try { 93 networkForTest.edgesConnecting(N1, NODE_NOT_IN_GRAPH); 94 fail(ERROR_NODE_NOT_IN_GRAPH); 95 } catch (IllegalArgumentException e) { 96 assertNodeNotInGraphErrorMessage(e); 97 } 98 try { 99 networkForTest.edgesConnecting(NODE_NOT_IN_GRAPH, N2); 100 fail(ERROR_NODE_NOT_IN_GRAPH); 101 } catch (IllegalArgumentException e) { 102 assertNodeNotInGraphErrorMessage(e); 103 } 104 try { 105 networkForTest.edgesConnecting(NODE_NOT_IN_GRAPH, NODE_NOT_IN_GRAPH); 106 fail(ERROR_NODE_NOT_IN_GRAPH); 107 } catch (IllegalArgumentException e) { 108 assertNodeNotInGraphErrorMessage(e); 109 } 110 } 111 112 @Test edgesConnecting_checkReturnedSetMutability()113 public void edgesConnecting_checkReturnedSetMutability() { 114 network.addNode(N1); 115 network.addNode(N2); 116 Set<String> edgesConnecting = network.edgesConnecting(N1, N2); 117 try { 118 edgesConnecting.add(E23); 119 fail(ERROR_MODIFIABLE_COLLECTION); 120 } catch (UnsupportedOperationException e) { 121 network.addEdge(N1, N2, E12); 122 assertThat(networkForTest.edgesConnecting(N1, N2)).containsExactlyElementsIn(edgesConnecting); 123 } 124 } 125 126 @Test edgesConnecting_oneEdge()127 public void edgesConnecting_oneEdge() { 128 network.addEdge(N1, N2, E12); 129 assertThat(networkForTest.edgesConnecting(N1, N2)).containsExactly(E12); 130 if (edgeType == EdgeType.DIRECTED) { 131 assertThat(networkForTest.edgesConnecting(N2, N1)).isEmpty(); 132 } else { 133 assertThat(networkForTest.edgesConnecting(N2, N1)).containsExactly(E12); 134 } 135 } 136 137 @Test edgesConnecting_selfLoop()138 public void edgesConnecting_selfLoop() { 139 network.addEdge(N1, N1, E11); 140 assertThat(networkForTest.edgesConnecting(N1, N1)).containsExactly(E11); 141 network.addEdge(N1, N2, E12); 142 assertThat(networkForTest.edgesConnecting(N1, N2)).containsExactly(E12); 143 assertThat(networkForTest.edgesConnecting(N1, N1)).containsExactly(E11); 144 } 145 146 @Test edgesConnecting_parallelEdges()147 public void edgesConnecting_parallelEdges() { 148 network.addEdge(N1, N2, E12); 149 network.addEdge(N1, N2, E12_A); 150 network.addEdge(N2, N1, E21); 151 if (edgeType == EdgeType.DIRECTED) { 152 assertThat(networkForTest.edgesConnecting(N1, N2)).containsExactly(E12, E12_A); 153 assertThat(networkForTest.edgesConnecting(N2, N1)).containsExactly(E21); 154 } else { 155 assertThat(networkForTest.edgesConnecting(N1, N2)).containsExactly(E12, E12_A, E21); 156 assertThat(networkForTest.edgesConnecting(N2, N1)).containsExactly(E12, E12_A, E21); 157 } 158 } 159 160 @Test edgesConnecting_parallelSelfLoopEdges()161 public void edgesConnecting_parallelSelfLoopEdges() { 162 network.addEdge(N1, N1, E11); 163 network.addEdge(N1, N1, E11_A); 164 assertThat(network.edgesConnecting(N1, N1)).containsExactly(E11, E11_A); 165 } 166 167 private static class NetworkForTest<N, E> extends AbstractNetwork<N, E> { 168 private final Network<N, E> network; 169 NetworkForTest(Network<N, E> network)170 NetworkForTest(Network<N, E> network) { 171 this.network = network; 172 } 173 from(Network<N, E> network)174 static <N, E> NetworkForTest<N, E> from(Network<N, E> network) { 175 return new NetworkForTest<>(network); 176 } 177 178 @Override nodes()179 public Set<N> nodes() { 180 return network.nodes(); 181 } 182 183 @Override edges()184 public Set<E> edges() { 185 return network.edges(); 186 } 187 188 @Override isDirected()189 public boolean isDirected() { 190 return network.isDirected(); 191 } 192 193 @Override allowsParallelEdges()194 public boolean allowsParallelEdges() { 195 return network.allowsParallelEdges(); 196 } 197 198 @Override allowsSelfLoops()199 public boolean allowsSelfLoops() { 200 return network.allowsSelfLoops(); 201 } 202 203 @Override nodeOrder()204 public ElementOrder<N> nodeOrder() { 205 return network.nodeOrder(); 206 } 207 208 @Override edgeOrder()209 public ElementOrder<E> edgeOrder() { 210 return network.edgeOrder(); 211 } 212 213 @Override adjacentNodes(N node)214 public Set<N> adjacentNodes(N node) { 215 return network.adjacentNodes(node); 216 } 217 218 @Override predecessors(N node)219 public Set<N> predecessors(N node) { 220 return network.predecessors(node); 221 } 222 223 @Override successors(N node)224 public Set<N> successors(N node) { 225 return network.successors(node); 226 } 227 228 @Override incidentEdges(N node)229 public Set<E> incidentEdges(N node) { 230 return network.incidentEdges(node); 231 } 232 233 @Override inEdges(N node)234 public Set<E> inEdges(N node) { 235 return network.inEdges(node); 236 } 237 238 @Override outEdges(N node)239 public Set<E> outEdges(N node) { 240 return network.outEdges(node); 241 } 242 243 @Override incidentNodes(E edge)244 public EndpointPair<N> incidentNodes(E edge) { 245 return network.incidentNodes(edge); 246 } 247 248 @Override adjacentEdges(E edge)249 public Set<E> adjacentEdges(E edge) { 250 return network.adjacentEdges(edge); 251 } 252 253 // _don't_ override edge*Connecting*; we want the behavior from AbstractNetwork 254 } 255 } 256