| /* |
| * 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); |
| } |
| } |