251 lines
9.6 KiB
Java
251 lines
9.6 KiB
Java
/*
|
|
* Copyright (C) 2016 The Guava Authors
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package com.google.common.graph;
|
|
|
|
import static com.google.common.truth.Truth.assertThat;
|
|
import static org.junit.Assert.fail;
|
|
|
|
import com.google.common.collect.ImmutableList;
|
|
import com.google.common.collect.ImmutableSet;
|
|
import com.google.common.testing.EqualsTester;
|
|
import java.util.Collection;
|
|
import java.util.Set;
|
|
import org.junit.Test;
|
|
import org.junit.runner.RunWith;
|
|
import org.junit.runners.JUnit4;
|
|
|
|
/** Tests for {@link EndpointPair} and {@link Graph#edges()}. */
|
|
@RunWith(JUnit4.class)
|
|
public final class EndpointPairTest {
|
|
private static final Integer N0 = 0;
|
|
private static final Integer N1 = 1;
|
|
private static final Integer N2 = 2;
|
|
private static final Integer N3 = 3;
|
|
private static final Integer N4 = 4;
|
|
private static final String E12 = "1-2";
|
|
private static final String E12_A = "1-2a";
|
|
private static final String E21 = "2-1";
|
|
private static final String E13 = "1-3";
|
|
private static final String E44 = "4-4";
|
|
|
|
// Test for EndpointPair class
|
|
|
|
@Test
|
|
public void testOrderedEndpointPair() {
|
|
EndpointPair<String> ordered = EndpointPair.ordered("source", "target");
|
|
assertThat(ordered.isOrdered()).isTrue();
|
|
assertThat(ordered).containsExactly("source", "target").inOrder();
|
|
assertThat(ordered.source()).isEqualTo("source");
|
|
assertThat(ordered.target()).isEqualTo("target");
|
|
assertThat(ordered.nodeU()).isEqualTo("source");
|
|
assertThat(ordered.nodeV()).isEqualTo("target");
|
|
assertThat(ordered.adjacentNode("source")).isEqualTo("target");
|
|
assertThat(ordered.adjacentNode("target")).isEqualTo("source");
|
|
assertThat(ordered.toString()).isEqualTo("<source -> target>");
|
|
}
|
|
|
|
@Test
|
|
public void testUnorderedEndpointPair() {
|
|
EndpointPair<String> unordered = EndpointPair.unordered("chicken", "egg");
|
|
assertThat(unordered.isOrdered()).isFalse();
|
|
assertThat(unordered).containsExactly("chicken", "egg");
|
|
assertThat(ImmutableSet.of(unordered.nodeU(), unordered.nodeV()))
|
|
.containsExactly("chicken", "egg");
|
|
assertThat(unordered.adjacentNode(unordered.nodeU())).isEqualTo(unordered.nodeV());
|
|
assertThat(unordered.adjacentNode(unordered.nodeV())).isEqualTo(unordered.nodeU());
|
|
assertThat(unordered.toString()).contains("chicken");
|
|
assertThat(unordered.toString()).contains("egg");
|
|
}
|
|
|
|
@Test
|
|
public void testSelfLoop() {
|
|
EndpointPair<String> unordered = EndpointPair.unordered("node", "node");
|
|
assertThat(unordered.isOrdered()).isFalse();
|
|
assertThat(unordered).containsExactly("node", "node");
|
|
assertThat(unordered.nodeU()).isEqualTo("node");
|
|
assertThat(unordered.nodeV()).isEqualTo("node");
|
|
assertThat(unordered.adjacentNode("node")).isEqualTo("node");
|
|
assertThat(unordered.toString()).isEqualTo("[node, node]");
|
|
}
|
|
|
|
@Test
|
|
public void testAdjacentNode_nodeNotIncident() {
|
|
ImmutableList<MutableNetwork<Integer, String>> testNetworks =
|
|
ImmutableList.of(
|
|
NetworkBuilder.directed().<Integer, String>build(),
|
|
NetworkBuilder.undirected().<Integer, String>build());
|
|
for (MutableNetwork<Integer, String> network : testNetworks) {
|
|
network.addEdge(1, 2, "1-2");
|
|
EndpointPair<Integer> endpointPair = network.incidentNodes("1-2");
|
|
try {
|
|
endpointPair.adjacentNode(3);
|
|
fail("Should have rejected adjacentNode() called with a node not incident to edge.");
|
|
} catch (IllegalArgumentException expected) {
|
|
}
|
|
}
|
|
}
|
|
|
|
@Test
|
|
public void testEquals() {
|
|
EndpointPair<String> ordered = EndpointPair.ordered("a", "b");
|
|
EndpointPair<String> orderedMirror = EndpointPair.ordered("b", "a");
|
|
EndpointPair<String> unordered = EndpointPair.unordered("a", "b");
|
|
EndpointPair<String> unorderedMirror = EndpointPair.unordered("b", "a");
|
|
|
|
new EqualsTester()
|
|
.addEqualityGroup(ordered)
|
|
.addEqualityGroup(orderedMirror)
|
|
.addEqualityGroup(unordered, unorderedMirror)
|
|
.testEquals();
|
|
}
|
|
|
|
// Tests for Graph.edges() and Network.asGraph().edges() methods
|
|
// TODO(user): Move these to a more appropriate location in the test suite.
|
|
|
|
@Test
|
|
public void endpointPair_directedGraph() {
|
|
MutableGraph<Integer> directedGraph = GraphBuilder.directed().allowsSelfLoops(true).build();
|
|
directedGraph.addNode(N0);
|
|
directedGraph.putEdge(N1, N2);
|
|
directedGraph.putEdge(N2, N1);
|
|
directedGraph.putEdge(N1, N3);
|
|
directedGraph.putEdge(N4, N4);
|
|
containsExactlySanityCheck(
|
|
directedGraph.edges(),
|
|
EndpointPair.ordered(N1, N2),
|
|
EndpointPair.ordered(N2, N1),
|
|
EndpointPair.ordered(N1, N3),
|
|
EndpointPair.ordered(N4, N4));
|
|
}
|
|
|
|
@Test
|
|
public void endpointPair_undirectedGraph() {
|
|
MutableGraph<Integer> undirectedGraph = GraphBuilder.undirected().allowsSelfLoops(true).build();
|
|
undirectedGraph.addNode(N0);
|
|
undirectedGraph.putEdge(N1, N2);
|
|
undirectedGraph.putEdge(N2, N1); // does nothing
|
|
undirectedGraph.putEdge(N1, N3);
|
|
undirectedGraph.putEdge(N4, N4);
|
|
containsExactlySanityCheck(
|
|
undirectedGraph.edges(),
|
|
EndpointPair.unordered(N1, N2),
|
|
EndpointPair.unordered(N1, N3),
|
|
EndpointPair.unordered(N4, N4));
|
|
}
|
|
|
|
@Test
|
|
public void endpointPair_directedNetwork() {
|
|
MutableNetwork<Integer, String> directedNetwork =
|
|
NetworkBuilder.directed().allowsSelfLoops(true).build();
|
|
directedNetwork.addNode(N0);
|
|
directedNetwork.addEdge(N1, N2, E12);
|
|
directedNetwork.addEdge(N2, N1, E21);
|
|
directedNetwork.addEdge(N1, N3, E13);
|
|
directedNetwork.addEdge(N4, N4, E44);
|
|
containsExactlySanityCheck(
|
|
directedNetwork.asGraph().edges(),
|
|
EndpointPair.ordered(N1, N2),
|
|
EndpointPair.ordered(N2, N1),
|
|
EndpointPair.ordered(N1, N3),
|
|
EndpointPair.ordered(N4, N4));
|
|
}
|
|
|
|
@Test
|
|
public void endpointPair_undirectedNetwork() {
|
|
MutableNetwork<Integer, String> undirectedNetwork =
|
|
NetworkBuilder.undirected().allowsParallelEdges(true).allowsSelfLoops(true).build();
|
|
undirectedNetwork.addNode(N0);
|
|
undirectedNetwork.addEdge(N1, N2, E12);
|
|
undirectedNetwork.addEdge(N2, N1, E12_A); // adds parallel edge, won't be in Graph edges
|
|
undirectedNetwork.addEdge(N1, N3, E13);
|
|
undirectedNetwork.addEdge(N4, N4, E44);
|
|
containsExactlySanityCheck(
|
|
undirectedNetwork.asGraph().edges(),
|
|
EndpointPair.unordered(N1, N2),
|
|
EndpointPair.unordered(N1, N3),
|
|
EndpointPair.unordered(N4, N4));
|
|
}
|
|
|
|
@Test
|
|
public void endpointPair_unmodifiableView() {
|
|
MutableGraph<Integer> directedGraph = GraphBuilder.directed().build();
|
|
Set<EndpointPair<Integer>> edges = directedGraph.edges();
|
|
|
|
directedGraph.putEdge(N1, N2);
|
|
containsExactlySanityCheck(edges, EndpointPair.ordered(N1, N2));
|
|
|
|
directedGraph.putEdge(N2, N1);
|
|
containsExactlySanityCheck(edges, EndpointPair.ordered(N1, N2), EndpointPair.ordered(N2, N1));
|
|
|
|
directedGraph.removeEdge(N1, N2);
|
|
directedGraph.removeEdge(N2, N1);
|
|
containsExactlySanityCheck(edges);
|
|
|
|
try {
|
|
edges.add(EndpointPair.ordered(N1, N2));
|
|
fail("Set returned by edges() should be unmodifiable");
|
|
} catch (UnsupportedOperationException expected) {
|
|
}
|
|
}
|
|
|
|
@Test
|
|
public void endpointPair_undirected_contains() {
|
|
MutableGraph<Integer> undirectedGraph = GraphBuilder.undirected().allowsSelfLoops(true).build();
|
|
undirectedGraph.putEdge(N1, N1);
|
|
undirectedGraph.putEdge(N1, N2);
|
|
Set<EndpointPair<Integer>> edges = undirectedGraph.edges();
|
|
|
|
assertThat(edges).hasSize(2);
|
|
assertThat(edges).contains(EndpointPair.unordered(N1, N1));
|
|
assertThat(edges).contains(EndpointPair.unordered(N1, N2));
|
|
assertThat(edges).contains(EndpointPair.unordered(N2, N1)); // equal to unordered(N1, N2)
|
|
|
|
// ordered endpoints OK for undirected graph (because ordering is irrelevant)
|
|
assertThat(edges).contains(EndpointPair.ordered(N1, N2));
|
|
|
|
assertThat(edges).doesNotContain(EndpointPair.unordered(N2, N2)); // edge not present
|
|
assertThat(edges).doesNotContain(EndpointPair.unordered(N3, N4)); // nodes not in graph
|
|
}
|
|
|
|
@Test
|
|
public void endpointPair_directed_contains() {
|
|
MutableGraph<Integer> directedGraph = GraphBuilder.directed().allowsSelfLoops(true).build();
|
|
directedGraph.putEdge(N1, N1);
|
|
directedGraph.putEdge(N1, N2);
|
|
Set<EndpointPair<Integer>> edges = directedGraph.edges();
|
|
|
|
assertThat(edges).hasSize(2);
|
|
assertThat(edges).contains(EndpointPair.ordered(N1, N1));
|
|
assertThat(edges).contains(EndpointPair.ordered(N1, N2));
|
|
|
|
// unordered endpoints not OK for directed graph (undefined behavior)
|
|
assertThat(edges).doesNotContain(EndpointPair.unordered(N1, N2));
|
|
|
|
assertThat(edges).doesNotContain(EndpointPair.ordered(N2, N1)); // wrong order
|
|
assertThat(edges).doesNotContain(EndpointPair.ordered(N2, N2)); // edge not present
|
|
assertThat(edges).doesNotContain(EndpointPair.ordered(N3, N4)); // nodes not in graph
|
|
}
|
|
|
|
private static void containsExactlySanityCheck(Collection<?> collection, Object... varargs) {
|
|
assertThat(collection).hasSize(varargs.length);
|
|
for (Object obj : varargs) {
|
|
assertThat(collection).contains(obj);
|
|
}
|
|
assertThat(collection).containsExactly(varargs);
|
|
}
|
|
}
|