• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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