blob: 27028f512e0a21eb48b227cd2821b0cbbe090bb4 [file] [log] [blame]
/*
* Copyright (c) 2013, the Dart project authors.
*
* Licensed under the Eclipse Public License v1.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.eclipse.org/legal/epl-v10.html
*
* 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.dart.engine.utilities.collection;
import com.google.dart.engine.EngineTestCase;
import java.util.ArrayList;
import java.util.List;
public class DirectedGraphTest extends EngineTestCase {
/**
* Instances of the class {@code Node} represent simple nodes used for testing purposes.
*/
private static class Node {
}
public void test_addEdge() {
DirectedGraph<Node> graph = new DirectedGraph<Node>();
assertTrue(graph.isEmpty());
graph.addEdge(new Node(), new Node());
assertFalse(graph.isEmpty());
}
public void test_addNode() {
DirectedGraph<Node> graph = new DirectedGraph<Node>();
assertTrue(graph.isEmpty());
graph.addNode(new Node());
assertFalse(graph.isEmpty());
}
public void test_containsPath_noCycles() {
Node node1 = new Node();
Node node2 = new Node();
Node node3 = new Node();
DirectedGraph<Node> graph = new DirectedGraph<Node>();
graph.addEdge(node1, node2);
graph.addEdge(node2, node3);
assertTrue(graph.containsPath(node1, node1));
assertTrue(graph.containsPath(node1, node2));
assertTrue(graph.containsPath(node1, node3));
assertFalse(graph.containsPath(node2, node1));
assertTrue(graph.containsPath(node2, node2));
assertTrue(graph.containsPath(node2, node3));
assertFalse(graph.containsPath(node3, node1));
assertFalse(graph.containsPath(node3, node2));
assertTrue(graph.containsPath(node3, node3));
}
public void test_containsPath_withCycles() {
Node node1 = new Node();
Node node2 = new Node();
Node node3 = new Node();
Node node4 = new Node();
DirectedGraph<Node> graph = new DirectedGraph<Node>();
graph.addEdge(node1, node2);
graph.addEdge(node2, node1);
graph.addEdge(node1, node3);
graph.addEdge(node3, node4);
graph.addEdge(node4, node3);
assertTrue(graph.containsPath(node1, node1));
assertTrue(graph.containsPath(node1, node2));
assertTrue(graph.containsPath(node1, node3));
assertTrue(graph.containsPath(node1, node4));
assertTrue(graph.containsPath(node2, node1));
assertTrue(graph.containsPath(node2, node2));
assertTrue(graph.containsPath(node2, node3));
assertTrue(graph.containsPath(node2, node4));
assertFalse(graph.containsPath(node3, node1));
assertFalse(graph.containsPath(node3, node2));
assertTrue(graph.containsPath(node3, node3));
assertTrue(graph.containsPath(node3, node4));
assertFalse(graph.containsPath(node4, node1));
assertFalse(graph.containsPath(node4, node2));
assertTrue(graph.containsPath(node4, node3));
assertTrue(graph.containsPath(node4, node4));
}
public void test_creation() {
assertNotNull(new DirectedGraph<Node>());
}
public void test_findCycleContaining_complexCycle() {
// Two overlapping loops: (1, 2, 3) and (3, 4, 5)
Node node1 = new Node();
Node node2 = new Node();
Node node3 = new Node();
Node node4 = new Node();
Node node5 = new Node();
DirectedGraph<Node> graph = new DirectedGraph<Node>();
graph.addEdge(node1, node2);
graph.addEdge(node2, node3);
graph.addEdge(node3, node1);
graph.addEdge(node3, node4);
graph.addEdge(node4, node5);
graph.addEdge(node5, node3);
List<Node> cycle = graph.findCycleContaining(node1);
assertSizeOfList(5, cycle);
assertTrue(cycle.contains(node1));
assertTrue(cycle.contains(node2));
assertTrue(cycle.contains(node3));
assertTrue(cycle.contains(node4));
assertTrue(cycle.contains(node5));
}
public void test_findCycleContaining_cycle() {
Node node1 = new Node();
Node node2 = new Node();
Node node3 = new Node();
DirectedGraph<Node> graph = new DirectedGraph<Node>();
graph.addEdge(node1, node2);
graph.addEdge(node2, node3);
graph.addEdge(node2, new Node());
graph.addEdge(node3, node1);
graph.addEdge(node3, new Node());
List<Node> cycle = graph.findCycleContaining(node1);
assertSizeOfList(3, cycle);
assertTrue(cycle.contains(node1));
assertTrue(cycle.contains(node2));
assertTrue(cycle.contains(node3));
}
public void test_findCycleContaining_notInGraph() {
Node node = new Node();
DirectedGraph<Node> graph = new DirectedGraph<Node>();
List<Node> cycle = graph.findCycleContaining(node);
assertSizeOfList(1, cycle);
assertEquals(node, cycle.get(0));
}
public void test_findCycleContaining_null() {
DirectedGraph<Node> graph = new DirectedGraph<Node>();
try {
graph.findCycleContaining(null);
fail("Expected IllegalArgumentException");
} catch (IllegalArgumentException exception) {
// Expected
}
}
public void test_findCycleContaining_singleton() {
Node node1 = new Node();
Node node2 = new Node();
Node node3 = new Node();
DirectedGraph<Node> graph = new DirectedGraph<Node>();
graph.addEdge(node1, node2);
graph.addEdge(node2, node3);
List<Node> cycle = graph.findCycleContaining(node1);
assertSizeOfList(1, cycle);
assertEquals(node1, cycle.get(0));
}
public void test_getNodeCount() {
Node node1 = new Node();
Node node2 = new Node();
DirectedGraph<Node> graph = new DirectedGraph<Node>();
assertEquals(0, graph.getNodeCount());
graph.addNode(node1);
assertEquals(1, graph.getNodeCount());
graph.addNode(node2);
assertEquals(2, graph.getNodeCount());
graph.removeNode(node1);
assertEquals(1, graph.getNodeCount());
}
public void test_getTails() {
Node node1 = new Node();
Node node2 = new Node();
Node node3 = new Node();
DirectedGraph<Node> graph = new DirectedGraph<Node>();
assertSizeOfSet(0, graph.getTails(node1));
graph.addEdge(node1, node2);
assertSizeOfSet(1, graph.getTails(node1));
graph.addEdge(node1, node3);
assertSizeOfSet(2, graph.getTails(node1));
}
public void test_removeAllNodes() {
Node node1 = new Node();
Node node2 = new Node();
ArrayList<Node> nodes = new ArrayList<Node>();
nodes.add(node1);
nodes.add(node2);
DirectedGraph<Node> graph = new DirectedGraph<Node>();
graph.addEdge(node1, node2);
graph.addEdge(node2, node1);
assertFalse(graph.isEmpty());
graph.removeAllNodes(nodes);
assertTrue(graph.isEmpty());
}
public void test_removeEdge() {
Node node1 = new Node();
Node node2 = new Node();
Node node3 = new Node();
DirectedGraph<Node> graph = new DirectedGraph<Node>();
graph.addEdge(node1, node2);
graph.addEdge(node1, node3);
assertSizeOfSet(2, graph.getTails(node1));
graph.removeEdge(node1, node2);
assertSizeOfSet(1, graph.getTails(node1));
}
public void test_removeNode() {
Node node1 = new Node();
Node node2 = new Node();
Node node3 = new Node();
DirectedGraph<Node> graph = new DirectedGraph<Node>();
graph.addEdge(node1, node2);
graph.addEdge(node1, node3);
assertSizeOfSet(2, graph.getTails(node1));
graph.removeNode(node2);
assertSizeOfSet(1, graph.getTails(node1));
}
public void test_removeSink() {
Node node1 = new Node();
Node node2 = new Node();
DirectedGraph<Node> graph = new DirectedGraph<Node>();
graph.addEdge(node1, node2);
assertSame(node2, graph.removeSink());
assertSame(node1, graph.removeSink());
assertTrue(graph.isEmpty());
}
public void test_topologicalSort_noCycles() {
Node node1 = new Node();
Node node2 = new Node();
Node node3 = new Node();
DirectedGraph<Node> graph = new DirectedGraph<Node>();
graph.addEdge(node1, node2);
graph.addEdge(node1, node3);
graph.addEdge(node2, node3);
ArrayList<ArrayList<Node>> topologicalSort = graph.computeTopologicalSort();
assertSizeOfList(3, topologicalSort);
assertSizeOfList(1, topologicalSort.get(0));
assertEquals(node3, topologicalSort.get(0).get(0));
assertSizeOfList(1, topologicalSort.get(1));
assertEquals(node2, topologicalSort.get(1).get(0));
assertSizeOfList(1, topologicalSort.get(2));
assertEquals(node1, topologicalSort.get(2).get(0));
}
public void test_topologicalSort_withCycles() {
Node node1 = new Node();
Node node2 = new Node();
Node node3 = new Node();
Node node4 = new Node();
DirectedGraph<Node> graph = new DirectedGraph<Node>();
graph.addEdge(node1, node2);
graph.addEdge(node2, node1);
graph.addEdge(node1, node3);
graph.addEdge(node3, node4);
graph.addEdge(node4, node3);
ArrayList<ArrayList<Node>> topologicalSort = graph.computeTopologicalSort();
assertSizeOfList(2, topologicalSort);
assertContains(topologicalSort.get(0).toArray(), node3, node4);
assertContains(topologicalSort.get(1).toArray(), node1, node2);
}
}