/*
* Copyright 2014 WANdisco
*
* WANdisco licenses this file to you 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 c5db.util;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import org.junit.Test;
import java.util.Deque;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import static c5db.util.Graph.Node;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
/**
*
*/
public class GraphTest {
@Test
public void testDoTarjan() throws Exception {
Map<NodeType, Node<NodeType>> nodes = new HashMap<>();
// create a node for each NodeType:
for (NodeType t : NodeType.values()) {
nodes.put(t, new Node<>(t));
}
// attach nodes like so:
// A -> B
// B -> C
// C -> D
// C -> E
// E -> F
// D -> F
connectFromTo(nodes, NodeType.A, NodeType.B);
connectFromTo(nodes, NodeType.B, NodeType.C);
connectFromTo(nodes, NodeType.C, NodeType.D);
connectFromTo(nodes, NodeType.C, NodeType.E);
connectFromTo(nodes, NodeType.E, NodeType.F);
connectFromTo(nodes, NodeType.D, NodeType.F);
List<ImmutableList<Node<NodeType>>> result = Graph.doTarjan(nodes.values());
System.out.println("no cycles");
Joiner joiner = Joiner.on("\n");
System.out.println(joiner.join(result));
assertEquals(nodes.size(), result.size());
// validate topo sort:
validateTopoSort(ImmutableList.of(NodeType.A, NodeType.B, NodeType.C,
NodeType.E, NodeType.D, NodeType.F), result);
// create a cycle:
connectFromTo(nodes, NodeType.F, NodeType.C);
result = Graph.doTarjan(nodes.values());
System.out.println("cycles");
System.out.println(joiner.join(result));
assertFalse(nodes.size() == result.size());
}
private void validateTopoSort(ImmutableList<NodeType> expected, List<ImmutableList<Node<NodeType>>> result) {
// reverse the expected order:
ImmutableList<NodeType> reverse = expected.reverse();
Deque<ImmutableList<Node<NodeType>>> q = new LinkedList<>(result);
for (NodeType t : reverse) {
ImmutableList<Node<NodeType>> topoNode = q.pop();
assertEquals(1, topoNode.size());
assertEquals(t, topoNode.get(0).type);
}
}
private void connectFromTo(Map<NodeType, Node<NodeType>> nodes, NodeType a, NodeType b) {
nodes.get(a).dependencies.add(nodes.get(b));
}
private static enum NodeType {
A, B, C, D, E, F
}
}