/
githubmirror
/
guava
Обзор
Документация
Войти
/
githubmirror
/
guava
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
android/guava-tests/test/com/google/common/graph/GraphsTest.java
776 строк
30 KB
cpovirk
Use yet more static imports.
21 апр 2026, 00:18
21 апр 2026, 00:18
f3113ad
Код
Авторство
О чём код?
/* * Copyright (C) 2014 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.graph.AbstractNetworkTest.validateNetwork; import static com.google.common.graph.Graphs.TransitiveClosureSelfLoopStrategy.ADD_SELF_LOOPS_ALWAYS; import static com.google.common.graph.Graphs.TransitiveClosureSelfLoopStrategy.ADD_SELF_LOOPS_FOR_CYCLES; import static com.google.common.graph.Graphs.copyOf; import static com.google.common.graph.Graphs.inducedSubgraph; import static com.google.common.graph.Graphs.transitiveClosure; import static com.google.common.graph.Graphs.transpose; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertThrows; import com.google.common.collect.ImmutableSet; import org.jspecify.annotations.NullUnmarked; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; /** * Tests for {@link Graphs}. Tests assume that the implementation of the method {@code addEdge} adds * the missing nodes to the graph, then adds the edge between them. */ @RunWith(JUnit4.class) @NullUnmarked public class GraphsTest { 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 E11 = "1-1"; private static final String E11_A = "1-1a"; private static final String E12 = "1-2"; private static final String E12_A = "1-2a"; private static final String E12_B = "1-2b"; private static final String E21 = "2-1"; private static final String E13 = "1-3"; private static final String E31 = "3-1"; private static final String E34 = "3-4"; private static final String E44 = "4-4"; private static final int NODE_COUNT = 20; private static final int EDGE_COUNT = 20; // TODO(user): Consider adding both error messages from here and {@link AbstractNetworkTest} // in one class (may be a utility class for error messages). private static final String ERROR_PARALLEL_EDGE = "connected by a different edge"; private static final String ERROR_NEGATIVE_COUNT = "is non-negative"; static final String ERROR_SELF_LOOP = "self-loops are not allowed"; @Test public void transitiveClosure_directedGraph_addSelfLoopsAlways() { MutableGraph<Integer> directedGraph = GraphBuilder.directed().allowsSelfLoops(false).build(); directedGraph.putEdge(N1, N2); directedGraph.putEdge(N1, N3); directedGraph.putEdge(N2, N3); directedGraph.addNode(N4); MutableGraph<Integer> expectedClosure = GraphBuilder.directed().allowsSelfLoops(true).build(); expectedClosure.putEdge(N1, N1); expectedClosure.putEdge(N1, N2); expectedClosure.putEdge(N1, N3); expectedClosure.putEdge(N2, N2); expectedClosure.putEdge(N2, N3); expectedClosure.putEdge(N3, N3); expectedClosure.putEdge(N4, N4); assertThat(transitiveClosure(directedGraph, ADD_SELF_LOOPS_ALWAYS)).isEqualTo(expectedClosure); } @Test public void transitiveClosure_directedGraph_addSelfLoopsForCycles() { MutableGraph<Integer> directedGraph = GraphBuilder.directed().allowsSelfLoops(false).build(); directedGraph.putEdge(N1, N2); directedGraph.putEdge(N1, N3); directedGraph.putEdge(N2, N3); directedGraph.addNode(N4); // the above graph is its own transitive closure MutableGraph<Integer> expectedClosure = GraphBuilder.directed().allowsSelfLoops(true).build(); expectedClosure.putEdge(N1, N2); expectedClosure.putEdge(N1, N3); expectedClosure.putEdge(N2, N3); expectedClosure.addNode(N4); assertThat(transitiveClosure(directedGraph, ADD_SELF_LOOPS_FOR_CYCLES)) .isEqualTo(expectedClosure); } @Test public void transitiveClosure_undirectedGraph_addSelfLoopsAlways() { MutableGraph<Integer> undirectedGraph = GraphBuilder.undirected().allowsSelfLoops(false).build(); undirectedGraph.putEdge(N1, N2); undirectedGraph.putEdge(N1, N3); undirectedGraph.putEdge(N2, N3); undirectedGraph.addNode(N4); MutableGraph<Integer> expectedClosure = GraphBuilder.undirected().allowsSelfLoops(true).build(); expectedClosure.putEdge(N1, N1); expectedClosure.putEdge(N1, N2); expectedClosure.putEdge(N1, N3); expectedClosure.putEdge(N2, N2); expectedClosure.putEdge(N2, N3); expectedClosure.putEdge(N3, N3); expectedClosure.putEdge(N4, N4); assertThat(transitiveClosure(undirectedGraph, ADD_SELF_LOOPS_ALWAYS)) .isEqualTo(expectedClosure); } @Test public void transitiveClosure_undirectedGraph_addSelfLoopsForCycles() { MutableGraph<Integer> undirectedGraph = GraphBuilder.undirected().allowsSelfLoops(false).build(); undirectedGraph.putEdge(N1, N2); undirectedGraph.putEdge(N1, N3); undirectedGraph.putEdge(N2, N3); undirectedGraph.addNode(N4); MutableGraph<Integer> expectedClosure = GraphBuilder.undirected().allowsSelfLoops(true).build(); expectedClosure.putEdge(N1, N1); expectedClosure.putEdge(N1, N2); expectedClosure.putEdge(N1, N3); expectedClosure.putEdge(N2, N2); expectedClosure.putEdge(N2, N3); expectedClosure.putEdge(N3, N3); expectedClosure.addNode(N4); // N4 is isolated => no incident edges in this transitive closure assertThat(transitiveClosure(undirectedGraph, ADD_SELF_LOOPS_FOR_CYCLES)) .isEqualTo(expectedClosure); } @Test public void transitiveClosure_directedPathGraph_addSelfLoopsAlways() { MutableGraph<Integer> directedGraph = GraphBuilder.directed().allowsSelfLoops(false).build(); directedGraph.putEdge(N1, N2); directedGraph.putEdge(N2, N3); directedGraph.putEdge(N3, N4); MutableGraph<Integer> expectedClosure = GraphBuilder.directed().allowsSelfLoops(true).build(); expectedClosure.putEdge(N1, N1); expectedClosure.putEdge(N1, N2); expectedClosure.putEdge(N1, N3); expectedClosure.putEdge(N1, N4); expectedClosure.putEdge(N2, N2); expectedClosure.putEdge(N2, N3); expectedClosure.putEdge(N2, N4); expectedClosure.putEdge(N3, N3); expectedClosure.putEdge(N3, N4); expectedClosure.putEdge(N4, N4); assertThat(transitiveClosure(directedGraph, ADD_SELF_LOOPS_ALWAYS)).isEqualTo(expectedClosure); } @Test public void transitiveClosure_directedPathGraph_addSelfLoopsForCycles() { MutableGraph<Integer> directedGraph = GraphBuilder.directed().allowsSelfLoops(false).build(); directedGraph.putEdge(N1, N2); directedGraph.putEdge(N2, N3); directedGraph.putEdge(N3, N4); MutableGraph<Integer> expectedClosure = GraphBuilder.directed().allowsSelfLoops(true).build(); expectedClosure.putEdge(N1, N2); expectedClosure.putEdge(N1, N3); expectedClosure.putEdge(N1, N4); expectedClosure.putEdge(N2, N3); expectedClosure.putEdge(N2, N4); expectedClosure.putEdge(N3, N4); assertThat(transitiveClosure(directedGraph, ADD_SELF_LOOPS_FOR_CYCLES)) .isEqualTo(expectedClosure); } @Test public void transitiveClosure_undirectedPathGraph() { MutableGraph<Integer> undirectedGraph = GraphBuilder.undirected().allowsSelfLoops(false).build(); undirectedGraph.putEdge(N1, N2); undirectedGraph.putEdge(N2, N3); undirectedGraph.putEdge(N3, N4); MutableGraph<Integer> expectedClosure = GraphBuilder.undirected().allowsSelfLoops(true).build(); expectedClosure.putEdge(N1, N1); expectedClosure.putEdge(N1, N2); expectedClosure.putEdge(N1, N3); expectedClosure.putEdge(N1, N4); expectedClosure.putEdge(N2, N2); expectedClosure.putEdge(N2, N3); expectedClosure.putEdge(N2, N4); expectedClosure.putEdge(N3, N3); expectedClosure.putEdge(N3, N4); expectedClosure.putEdge(N4, N4); assertThat(transitiveClosure(undirectedGraph, ADD_SELF_LOOPS_ALWAYS)) .isEqualTo(expectedClosure); } @Test public void transitiveClosure_undirectedPathGraph_addSelfLoopsForCycles() { MutableGraph<Integer> undirectedGraph = GraphBuilder.undirected().allowsSelfLoops(false).build(); undirectedGraph.putEdge(N1, N2); undirectedGraph.putEdge(N2, N3); undirectedGraph.putEdge(N3, N4); MutableGraph<Integer> expectedClosure = GraphBuilder.undirected().allowsSelfLoops(true).build(); expectedClosure.putEdge(N1, N1); expectedClosure.putEdge(N1, N2); expectedClosure.putEdge(N1, N3); expectedClosure.putEdge(N1, N4); expectedClosure.putEdge(N2, N2); expectedClosure.putEdge(N2, N3); expectedClosure.putEdge(N2, N4); expectedClosure.putEdge(N3, N3); expectedClosure.putEdge(N3, N4); expectedClosure.putEdge(N4, N4); assertThat(transitiveClosure(undirectedGraph, ADD_SELF_LOOPS_FOR_CYCLES)) .isEqualTo(expectedClosure); } @Test public void transitiveClosure_directedCycleGraph_addSelfLoopsAlways() { MutableGraph<Integer> directedGraph = GraphBuilder.directed().allowsSelfLoops(false).build(); directedGraph.putEdge(N1, N2); directedGraph.putEdge(N2, N3); directedGraph.putEdge(N3, N4); directedGraph.putEdge(N4, N1); MutableGraph<Integer> expectedClosure = GraphBuilder.directed().allowsSelfLoops(true).build(); expectedClosure.putEdge(N1, N1); expectedClosure.putEdge(N1, N2); expectedClosure.putEdge(N1, N3); expectedClosure.putEdge(N1, N4); expectedClosure.putEdge(N2, N1); expectedClosure.putEdge(N2, N2); expectedClosure.putEdge(N2, N3); expectedClosure.putEdge(N2, N4); expectedClosure.putEdge(N3, N1); expectedClosure.putEdge(N3, N2); expectedClosure.putEdge(N3, N3); expectedClosure.putEdge(N3, N4); expectedClosure.putEdge(N4, N1); expectedClosure.putEdge(N4, N2); expectedClosure.putEdge(N4, N3); expectedClosure.putEdge(N4, N4); assertThat(transitiveClosure(directedGraph, ADD_SELF_LOOPS_ALWAYS)).isEqualTo(expectedClosure); } @Test public void transitiveClosure_directedCycleGraph_addSelfLoopsForCycles() { MutableGraph<Integer> directedGraph = GraphBuilder.directed().allowsSelfLoops(false).build(); directedGraph.putEdge(N1, N2); directedGraph.putEdge(N2, N3); directedGraph.putEdge(N3, N4); directedGraph.putEdge(N4, N1); MutableGraph<Integer> expectedClosure = GraphBuilder.directed().allowsSelfLoops(true).build(); expectedClosure.putEdge(N1, N1); expectedClosure.putEdge(N1, N2); expectedClosure.putEdge(N1, N3); expectedClosure.putEdge(N1, N4); expectedClosure.putEdge(N2, N1); expectedClosure.putEdge(N2, N2); expectedClosure.putEdge(N2, N3); expectedClosure.putEdge(N2, N4); expectedClosure.putEdge(N3, N1); expectedClosure.putEdge(N3, N2); expectedClosure.putEdge(N3, N3); expectedClosure.putEdge(N3, N4); expectedClosure.putEdge(N4, N1); expectedClosure.putEdge(N4, N2); expectedClosure.putEdge(N4, N3); expectedClosure.putEdge(N4, N4); assertThat(transitiveClosure(directedGraph, ADD_SELF_LOOPS_FOR_CYCLES)) .isEqualTo(expectedClosure); } @Test public void transitiveClosure_undirectedCycleGraph_addSelfLoopsAlways() { MutableGraph<Integer> undirectedGraph = GraphBuilder.undirected().allowsSelfLoops(false).build(); undirectedGraph.putEdge(N1, N2); undirectedGraph.putEdge(N2, N3); undirectedGraph.putEdge(N3, N4); undirectedGraph.putEdge(N4, N1); MutableGraph<Integer> expectedClosure = GraphBuilder.undirected().allowsSelfLoops(true).build(); expectedClosure.putEdge(N1, N1); expectedClosure.putEdge(N1, N2); expectedClosure.putEdge(N1, N3); expectedClosure.putEdge(N1, N4); expectedClosure.putEdge(N2, N2); expectedClosure.putEdge(N2, N3); expectedClosure.putEdge(N2, N4); expectedClosure.putEdge(N3, N3); expectedClosure.putEdge(N3, N4); expectedClosure.putEdge(N4, N4); assertThat(transitiveClosure(undirectedGraph, ADD_SELF_LOOPS_ALWAYS)) .isEqualTo(expectedClosure); } @Test public void transitiveClosure_undirectedCycleGraph_addSelfLoopsForCycles() { MutableGraph<Integer> undirectedGraph = GraphBuilder.undirected().allowsSelfLoops(false).build(); undirectedGraph.putEdge(N1, N2); undirectedGraph.putEdge(N2, N3); undirectedGraph.putEdge(N3, N4); undirectedGraph.putEdge(N4, N1); MutableGraph<Integer> expectedClosure = GraphBuilder.undirected().allowsSelfLoops(true).build(); expectedClosure.putEdge(N1, N1); expectedClosure.putEdge(N1, N2); expectedClosure.putEdge(N1, N3); expectedClosure.putEdge(N1, N4); expectedClosure.putEdge(N2, N2); expectedClosure.putEdge(N2, N3); expectedClosure.putEdge(N2, N4); expectedClosure.putEdge(N3, N3); expectedClosure.putEdge(N3, N4); expectedClosure.putEdge(N4, N4); assertThat(transitiveClosure(undirectedGraph, ADD_SELF_LOOPS_FOR_CYCLES)) .isEqualTo(expectedClosure); } @Test public void transpose_undirectedGraph() { MutableGraph<Integer> undirectedGraph = GraphBuilder.undirected().build(); undirectedGraph.putEdge(N1, N2); assertThat(transpose(undirectedGraph)).isSameInstanceAs(undirectedGraph); } @Test public void transpose_directedGraph() { MutableGraph<Integer> directedGraph = GraphBuilder.directed().allowsSelfLoops(true).build(); directedGraph.putEdge(N1, N3); directedGraph.putEdge(N3, N1); directedGraph.putEdge(N1, N2); directedGraph.putEdge(N1, N1); directedGraph.putEdge(N3, N4); MutableGraph<Integer> expectedTranspose = GraphBuilder.directed().allowsSelfLoops(true).build(); expectedTranspose.putEdge(N3, N1); expectedTranspose.putEdge(N1, N3); expectedTranspose.putEdge(N2, N1); expectedTranspose.putEdge(N1, N1); expectedTranspose.putEdge(N4, N3); Graph<Integer> transpose = transpose(directedGraph); assertThat(transpose).isEqualTo(expectedTranspose); assertThat(transpose(transpose)).isSameInstanceAs(directedGraph); AbstractGraphTest.validateGraph(transpose); for (Integer node : directedGraph.nodes()) { assertThat(directedGraph.inDegree(node)).isSameInstanceAs(transpose.outDegree(node)); assertThat(directedGraph.outDegree(node)).isSameInstanceAs(transpose.inDegree(node)); } assertThat(transpose.successors(N1)).doesNotContain(N2); directedGraph.putEdge(N2, N1); // View should be updated. assertThat(transpose.successors(N1)).contains(N2); AbstractGraphTest.validateGraph(transpose); } @Test public void transpose_undirectedValueGraph() { MutableValueGraph<Integer, String> undirectedGraph = ValueGraphBuilder.undirected().build(); undirectedGraph.putEdgeValue(N1, N2, E12); assertThat(transpose(undirectedGraph)).isSameInstanceAs(undirectedGraph); } @Test public void transpose_directedValueGraph() { MutableValueGraph<Integer, String> directedGraph = ValueGraphBuilder.directed().allowsSelfLoops(true).build(); directedGraph.putEdgeValue(N1, N3, E13); directedGraph.putEdgeValue(N3, N1, E31); directedGraph.putEdgeValue(N1, N2, E12); directedGraph.putEdgeValue(N1, N1, E11); directedGraph.putEdgeValue(N3, N4, E34); MutableValueGraph<Integer, String> expectedTranspose = ValueGraphBuilder.directed().allowsSelfLoops(true).build(); expectedTranspose.putEdgeValue(N3, N1, E13); expectedTranspose.putEdgeValue(N1, N3, E31); expectedTranspose.putEdgeValue(N2, N1, E12); expectedTranspose.putEdgeValue(N1, N1, E11); expectedTranspose.putEdgeValue(N4, N3, E34); ValueGraph<Integer, String> transpose = transpose(directedGraph); assertThat(transpose).isEqualTo(expectedTranspose); assertThat(transpose(transpose)).isSameInstanceAs(directedGraph); AbstractGraphTest.validateGraph(transpose.asGraph()); assertThat(transpose.edgeValueOrDefault(N1, N2, null)).isNull(); for (Integer node : directedGraph.nodes()) { assertThat(directedGraph.inDegree(node)).isSameInstanceAs(transpose.outDegree(node)); assertThat(directedGraph.outDegree(node)).isSameInstanceAs(transpose.inDegree(node)); } directedGraph.putEdgeValue(N2, N1, E21); // View should be updated. assertThat(transpose.edgeValueOrDefault(N1, N2, null)).isEqualTo(E21); AbstractGraphTest.validateGraph(transpose.asGraph()); } @Test public void transpose_undirectedNetwork() { MutableNetwork<Integer, String> undirectedGraph = NetworkBuilder.undirected().build(); undirectedGraph.addEdge(N1, N2, E12); assertThat(transpose(undirectedGraph)).isSameInstanceAs(undirectedGraph); } @Test public void transpose_directedNetwork() { MutableNetwork<Integer, String> directedGraph = NetworkBuilder.directed().allowsParallelEdges(true).allowsSelfLoops(true).build(); directedGraph.addEdge(N1, N3, E13); directedGraph.addEdge(N3, N1, E31); directedGraph.addEdge(N1, N2, E12); directedGraph.addEdge(N1, N2, E12_A); directedGraph.addEdge(N1, N1, E11); directedGraph.addEdge(N3, N4, E34); MutableNetwork<Integer, String> expectedTranspose = NetworkBuilder.directed().allowsParallelEdges(true).allowsSelfLoops(true).build(); expectedTranspose.addEdge(N3, N1, E13); expectedTranspose.addEdge(N1, N3, E31); expectedTranspose.addEdge(N2, N1, E12); expectedTranspose.addEdge(N2, N1, E12_A); expectedTranspose.addEdge(N1, N1, E11); expectedTranspose.addEdge(N4, N3, E34); Network<Integer, String> transpose = transpose(directedGraph); assertThat(transpose).isEqualTo(expectedTranspose); assertThat(transpose(transpose)).isSameInstanceAs(directedGraph); validateNetwork(transpose); assertThat(transpose.edgesConnecting(N1, N2)).isEmpty(); assertThat(transpose.edgeConnectingOrNull(N1, N2)).isNull(); for (Integer node : directedGraph.nodes()) { assertThat(directedGraph.inDegree(node)).isSameInstanceAs(transpose.outDegree(node)); assertThat(directedGraph.outDegree(node)).isSameInstanceAs(transpose.inDegree(node)); } directedGraph.addEdge(N2, N1, E21); // View should be updated. assertThat(transpose.edgesConnecting(N1, N2)).containsExactly(E21); assertThat(transpose.edgeConnectingOrNull(N1, N2)).isEqualTo(E21); validateNetwork(transpose); } @Test public void inducedSubgraph_graph() { ImmutableSet<Integer> nodeSubset = ImmutableSet.of(N1, N2, N4); MutableGraph<Integer> directedGraph = GraphBuilder.directed().allowsSelfLoops(true).build(); directedGraph.putEdge(N1, N2); directedGraph.putEdge(N2, N1); directedGraph.putEdge(N1, N3); // only incident to one node in nodeSubset directedGraph.putEdge(N4, N4); directedGraph.putEdge(5, 6); // not incident to any node in nodeSubset MutableGraph<Integer> expectedSubgraph = GraphBuilder.directed().allowsSelfLoops(true).build(); expectedSubgraph.putEdge(N1, N2); expectedSubgraph.putEdge(N2, N1); expectedSubgraph.putEdge(N4, N4); assertThat(inducedSubgraph(directedGraph, nodeSubset)).isEqualTo(expectedSubgraph); } @Test public void inducedSubgraph_valueGraph() { ImmutableSet<Integer> nodeSubset = ImmutableSet.of(N1, N2, N4); MutableValueGraph<Integer, String> directedGraph = ValueGraphBuilder.directed().allowsSelfLoops(true).build(); directedGraph.putEdgeValue(N1, N2, E12); directedGraph.putEdgeValue(N2, N1, E21); directedGraph.putEdgeValue(N1, N3, E13); // only incident to one node in nodeSubset directedGraph.putEdgeValue(N4, N4, E44); directedGraph.putEdgeValue(5, 6, "5-6"); // not incident to any node in nodeSubset MutableValueGraph<Integer, String> expectedSubgraph = ValueGraphBuilder.directed().allowsSelfLoops(true).build(); expectedSubgraph.putEdgeValue(N1, N2, E12); expectedSubgraph.putEdgeValue(N2, N1, E21); expectedSubgraph.putEdgeValue(N4, N4, E44); assertThat(inducedSubgraph(directedGraph, nodeSubset)).isEqualTo(expectedSubgraph); } @Test public void inducedSubgraph_network() { ImmutableSet<Integer> nodeSubset = ImmutableSet.of(N1, N2, N4); MutableNetwork<Integer, String> directedGraph = NetworkBuilder.directed().allowsSelfLoops(true).build(); directedGraph.addEdge(N1, N2, E12); directedGraph.addEdge(N2, N1, E21); directedGraph.addEdge(N1, N3, E13); // only incident to one node in nodeSubset directedGraph.addEdge(N4, N4, E44); directedGraph.addEdge(5, 6, "5-6"); // not incident to any node in nodeSubset MutableNetwork<Integer, String> expectedSubgraph = NetworkBuilder.directed().allowsSelfLoops(true).build(); expectedSubgraph.addEdge(N1, N2, E12); expectedSubgraph.addEdge(N2, N1, E21); expectedSubgraph.addEdge(N4, N4, E44); assertThat(inducedSubgraph(directedGraph, nodeSubset)).isEqualTo(expectedSubgraph); } @Test public void inducedSubgraph_nodeNotInGraph() { MutableNetwork<Integer, String> undirectedGraph = NetworkBuilder.undirected().build(); assertThrows( IllegalArgumentException.class, () -> inducedSubgraph(undirectedGraph, ImmutableSet.of(N1))); } @Test public void copyOf_nullArgument() { assertThrows(NullPointerException.class, () -> copyOf((Graph<?>) null)); } @Test public void copyOf_directedGraph() { Graph<Integer> directedGraph = buildDirectedGraph(); Graph<Integer> copy = copyOf(directedGraph); assertThat(copy).isEqualTo(directedGraph); } @Test public void copyOf_undirectedGraph() { Graph<Integer> undirectedGraph = buildUndirectedGraph(); Graph<Integer> copy = copyOf(undirectedGraph); assertThat(copy).isEqualTo(undirectedGraph); } @Test public void copyOf_directedValueGraph() { ValueGraph<Integer, String> directedGraph = buildDirectedValueGraph(); ValueGraph<Integer, String> copy = copyOf(directedGraph); assertThat(copy).isEqualTo(directedGraph); } @Test public void copyOf_undirectedValueGraph() { ValueGraph<Integer, String> undirectedGraph = buildUndirectedValueGraph(); ValueGraph<Integer, String> copy = copyOf(undirectedGraph); assertThat(copy).isEqualTo(undirectedGraph); } @Test public void copyOf_directedNetwork() { Network<Integer, String> directedGraph = buildDirectedNetwork(); Network<Integer, String> copy = copyOf(directedGraph); assertThat(copy).isEqualTo(directedGraph); } @Test public void copyOf_undirectedNetwork() { Network<Integer, String> undirectedGraph = buildUndirectedNetwork(); Network<Integer, String> copy = copyOf(undirectedGraph); assertThat(copy).isEqualTo(undirectedGraph); } // Graph creation tests @Test public void createDirected() { MutableNetwork<Integer, String> directedGraph = NetworkBuilder.directed().build(); assertThat(directedGraph.nodes()).isEmpty(); assertThat(directedGraph.edges()).isEmpty(); assertThat(directedGraph.addEdge(N1, N2, E12)).isTrue(); assertThat(directedGraph.edgesConnecting(N1, N2)).isEqualTo(ImmutableSet.of(E12)); assertThat(directedGraph.edgesConnecting(N2, N1)).isEmpty(); // By default, parallel edges are not allowed. IllegalArgumentException e = assertThrows(IllegalArgumentException.class, () -> directedGraph.addEdge(N1, N2, E12_A)); assertThat(e).hasMessageThat().contains(ERROR_PARALLEL_EDGE); // By default, self-loop edges are not allowed. e = assertThrows(IllegalArgumentException.class, () -> directedGraph.addEdge(N1, N1, E11)); assertThat(e).hasMessageThat().contains(ERROR_SELF_LOOP); } @Test public void createUndirected() { MutableNetwork<Integer, String> undirectedGraph = NetworkBuilder.undirected().build(); assertThat(undirectedGraph.nodes()).isEmpty(); assertThat(undirectedGraph.edges()).isEmpty(); assertThat(undirectedGraph.addEdge(N1, N2, E12)).isTrue(); assertThat(undirectedGraph.edgesConnecting(N1, N2)).isEqualTo(ImmutableSet.of(E12)); assertThat(undirectedGraph.edgesConnecting(N2, N1)).isEqualTo(ImmutableSet.of(E12)); // By default, parallel edges are not allowed. IllegalArgumentException e = assertThrows(IllegalArgumentException.class, () -> undirectedGraph.addEdge(N1, N2, E12_A)); assertThat(e).hasMessageThat().contains(ERROR_PARALLEL_EDGE); e = assertThrows(IllegalArgumentException.class, () -> undirectedGraph.addEdge(N2, N1, E21)); assertThat(e).hasMessageThat().contains(ERROR_PARALLEL_EDGE); // By default, self-loop edges are not allowed. e = assertThrows(IllegalArgumentException.class, () -> undirectedGraph.addEdge(N1, N1, E11)); assertThat(e).hasMessageThat().contains(ERROR_SELF_LOOP); } @Test public void createDirected_multigraph() { MutableNetwork<Integer, String> directedMultigraph = NetworkBuilder.directed().allowsParallelEdges(true).build(); assertThat(directedMultigraph.addEdge(N1, N2, E12)).isTrue(); assertThat(directedMultigraph.addEdge(N1, N2, E12_A)).isTrue(); assertThat(directedMultigraph.edgesConnecting(N1, N2)).isEqualTo(ImmutableSet.of(E12, E12_A)); assertThat(directedMultigraph.edgesConnecting(N2, N1)).isEmpty(); } @Test public void createUndirected_multigraph() { MutableNetwork<Integer, String> undirectedMultigraph = NetworkBuilder.undirected().allowsParallelEdges(true).build(); assertThat(undirectedMultigraph.addEdge(N1, N2, E12)).isTrue(); assertThat(undirectedMultigraph.addEdge(N1, N2, E12_A)).isTrue(); assertThat(undirectedMultigraph.addEdge(N2, N1, E21)).isTrue(); assertThat(undirectedMultigraph.edgesConnecting(N1, N2)) .isEqualTo(ImmutableSet.of(E12, E12_A, E21)); } @Test public void createDirected_expectedNodeCount() { MutableNetwork<Integer, String> directedGraph = NetworkBuilder.directed().expectedNodeCount(NODE_COUNT).build(); assertThat(directedGraph.addEdge(N1, N2, E12)).isTrue(); assertThat(directedGraph.edgesConnecting(N1, N2)).isEqualTo(ImmutableSet.of(E12)); assertThat(directedGraph.edgesConnecting(N2, N1)).isEmpty(); } @Test public void createUndirected_expectedNodeCount() { MutableNetwork<Integer, String> undirectedGraph = NetworkBuilder.undirected().expectedNodeCount(NODE_COUNT).build(); assertThat(undirectedGraph.addEdge(N1, N2, E12)).isTrue(); assertThat(undirectedGraph.edgesConnecting(N1, N2)).isEqualTo(ImmutableSet.of(E12)); assertThat(undirectedGraph.edgesConnecting(N2, N1)).isEqualTo(ImmutableSet.of(E12)); } @Test public void builder_expectedNodeCount_negative() { IllegalArgumentException e = assertThrows( IllegalArgumentException.class, () -> NetworkBuilder.directed().expectedNodeCount(-1)); assertThat(e).hasMessageThat().contains(ERROR_NEGATIVE_COUNT); } @Test public void createDirected_expectedEdgeCount() { MutableNetwork<Integer, String> directedGraph = NetworkBuilder.directed().expectedEdgeCount(EDGE_COUNT).build(); assertThat(directedGraph.addEdge(N1, N2, E12)).isTrue(); assertThat(directedGraph.edgesConnecting(N1, N2)).isEqualTo(ImmutableSet.of(E12)); assertThat(directedGraph.edgesConnecting(N2, N1)).isEmpty(); } @Test public void createUndirected_expectedEdgeCount() { MutableNetwork<Integer, String> undirectedGraph = NetworkBuilder.undirected().expectedEdgeCount(EDGE_COUNT).build(); assertThat(undirectedGraph.addEdge(N1, N2, E12)).isTrue(); assertThat(undirectedGraph.edgesConnecting(N1, N2)).isEqualTo(ImmutableSet.of(E12)); assertThat(undirectedGraph.edgesConnecting(N2, N1)).isEqualTo(ImmutableSet.of(E12)); } @Test public void builder_expectedEdgeCount_negative() { IllegalArgumentException e = assertThrows( IllegalArgumentException.class, () -> NetworkBuilder.directed().expectedEdgeCount(-1)); assertThat(e).hasMessageThat().contains(ERROR_NEGATIVE_COUNT); } private static MutableGraph<Integer> buildDirectedGraph() { MutableGraph<Integer> directedGraph = GraphBuilder.directed().allowsSelfLoops(true).build(); directedGraph.putEdge(N1, N1); directedGraph.putEdge(N1, N2); directedGraph.putEdge(N2, N1); return directedGraph; } private static MutableGraph<Integer> buildUndirectedGraph() { MutableGraph<Integer> undirectedGraph = GraphBuilder.undirected().allowsSelfLoops(true).build(); undirectedGraph.putEdge(N1, N1); undirectedGraph.putEdge(N1, N2); undirectedGraph.putEdge(N2, N1); return undirectedGraph; } private static MutableValueGraph<Integer, String> buildDirectedValueGraph() { MutableValueGraph<Integer, String> directedGraph = ValueGraphBuilder.directed().allowsSelfLoops(true).build(); directedGraph.putEdgeValue(N1, N1, E11); directedGraph.putEdgeValue(N1, N2, E12); directedGraph.putEdgeValue(N2, N1, E21); return directedGraph; } private static MutableValueGraph<Integer, String> buildUndirectedValueGraph() { MutableValueGraph<Integer, String> undirectedGraph = ValueGraphBuilder.undirected().allowsSelfLoops(true).build(); undirectedGraph.putEdgeValue(N1, N1, E11); undirectedGraph.putEdgeValue(N1, N2, E12); undirectedGraph.putEdgeValue(N2, N1, E21); // overwrites E12 return undirectedGraph; } private static MutableNetwork<Integer, String> buildDirectedNetwork() { MutableNetwork<Integer, String> directedGraph = NetworkBuilder.directed().allowsParallelEdges(true).allowsSelfLoops(true).build(); directedGraph.addEdge(N1, N1, E11); directedGraph.addEdge(N1, N2, E12); directedGraph.addEdge(N1, N1, E11_A); directedGraph.addEdge(N1, N2, E12_A); directedGraph.addEdge(N2, N1, E21); return directedGraph; } private static MutableNetwork<Integer, String> buildUndirectedNetwork() { MutableNetwork<Integer, String> undirectedGraph = NetworkBuilder.undirected().allowsParallelEdges(true).allowsSelfLoops(true).build(); undirectedGraph.addEdge(N1, N1, E11); undirectedGraph.addEdge(N1, N2, E12); undirectedGraph.addEdge(N1, N1, E11_A); undirectedGraph.addEdge(N1, N2, E12_A); undirectedGraph.addEdge(N2, N1, E21); return undirectedGraph; } }