/*
* GeoTools - The Open Source Java GIS Toolkit
* http://geotools.org
*
* (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
package org.geotools.graph.traverse.standard;
import junit.framework.TestCase;
import org.geotools.graph.GraphTestUtil;
import org.geotools.graph.build.GraphBuilder;
import org.geotools.graph.build.basic.BasicGraphBuilder;
import org.geotools.graph.structure.Graph;
import org.geotools.graph.structure.GraphVisitor;
import org.geotools.graph.structure.Graphable;
import org.geotools.graph.structure.Node;
import org.geotools.graph.traverse.GraphTraversal;
import org.geotools.graph.traverse.basic.BasicGraphTraversal;
import org.geotools.graph.traverse.basic.CountingWalker;
public class NoBifurcationIteratorTest extends TestCase {
private GraphBuilder m_builder;
public NoBifurcationIteratorTest(String name) {
super(name);
}
protected void setUp() throws Exception {
super.setUp();
m_builder = createBuilder();
}
/**
* Create a simple graph which has no bifurcations and do a normal traversal.
* <BR>
* <BR>
* Expected: 1. Every node should be visited.
* 2. Nodes should be visited in order.
*/
public void test_0() {
int nnodes = 100;
Node[] ends = GraphTestUtil.buildNoBifurcations(builder(), nnodes);
CountingWalker walker = new CountingWalker() {
public int visit(Graphable element, GraphTraversal traversal) {
super.visit(element, traversal);
element.setCount(getCount()-1);
//nodes should be visited in order
assertTrue(element.getID() == getCount()-1);
return(GraphTraversal.CONTINUE);
}
};
NoBifurcationIterator iterator = createIterator();
iterator.setSource(ends[0]);
BasicGraphTraversal traversal = new BasicGraphTraversal(
builder().getGraph(), walker, iterator
);
traversal.init();
traversal.traverse();
//every node should have been visited
assertTrue(walker.getCount() == builder().getGraph().getNodes().size());
}
/**
* Create a simple graph which has no bifurcations and do a traversal
* suspending at some intermediate node. Then continue traversal.
*
* Expected: After suspend:
* 1. Every node of with an id greater than the id of the suspending
* node should not be visited.
* After continue:
* 1. First node visited after continue should have id =
* id + suspend node + 1
* 2. Every node should be visited.
*
*/
public void test_1() {
int nnodes = 100;
Node[] ends = GraphTestUtil.buildNoBifurcations(builder(), nnodes);
final int suspend = 50;;
CountingWalker walker = new CountingWalker() {
private int m_mode = 0;
public int visit(Graphable element, GraphTraversal traversal) {
super.visit(element, traversal);
if (m_mode == 0) {
//check for stopping node
if (element.getID() == suspend) {
m_mode++;
return(GraphTraversal.SUSPEND);
}
}
else if (m_mode == 1) {
//check first node after continue
assertTrue(element.getID() == suspend + 1);
m_mode++;
}
return(GraphTraversal.CONTINUE);
}
};
NoBifurcationIterator iterator = createIterator();
iterator.setSource(ends[0]);
BasicGraphTraversal traversal = new BasicGraphTraversal(
builder().getGraph(), walker, iterator
);
traversal.init();
traversal.traverse();
//stopping node should be visited and nodes with greater id should not
GraphVisitor visitor = new GraphVisitor() {
public int visit(Graphable component) {
if (component.getID() <= suspend) assertTrue(component.isVisited());
else assertTrue(!component.isVisited());
return(0);
}
};
builder().getGraph().visitNodes(visitor);
assertTrue(walker.getCount() == nnodes-suspend+1);
traversal.traverse();
//every node should now be visited
visitor = new GraphVisitor() {
public int visit(Graphable component) {
assertTrue(component.isVisited());
return(0);
}
};
builder().getGraph().visitNodes(visitor);
assertTrue(walker.getCount() == nnodes);
}
/**
* Create a simple graph which has no bifurcations and do a kill branch at
* some intermediate node. Then continue the traversal.
*
* Expected: After kill:
* 1. Every node of with an id greater than the id of the killing
* node should not be visited.
* After continue:
* 2. No more nodes should be visited.
*
*/
public void test_2() {
int nnodes = 100;
Node[] ends = GraphTestUtil.buildNoBifurcations(builder(), 100);
final int kill = 50;
CountingWalker walker = new CountingWalker() {
private int m_mode = 0;
public int visit(Graphable element, GraphTraversal traversal) {
super.visit(element, traversal);
if (m_mode == 0) {
//check for stopping node
if (element.getID() == kill) {
m_mode++;
return(GraphTraversal.KILL_BRANCH);
}
}
else if (m_mode == 1) {
//should never get here
assertTrue(false);
}
return(GraphTraversal.CONTINUE);
}
};
NoBifurcationIterator iterator = createIterator();
iterator.setSource(ends[0]);
BasicGraphTraversal traversal = new BasicGraphTraversal(
builder().getGraph(), walker, iterator
);
traversal.init();
traversal.traverse();
//kill node should be visited and nodes with greater id should not
GraphVisitor visitor = new GraphVisitor() {
public int visit(Graphable component) {
if (component.getID() <= kill) assertTrue(component.isVisited());
else assertTrue(!component.isVisited());
return(0);
}
};
builder().getGraph().visitNodes(visitor);
assertTrue(walker.getCount() == nnodes-kill+1);
//continue, no more nodes should be visited
traversal.traverse();
}
/**
* Create a simple graph with a single bifurcation and do a full traversal.
*
* Exepected: 1. The traversal should stop at the bifurcating node.
* 2. Every node after the bifurcating node should not be visited.
*/
public void test_3() {
int nnodes = 100;
final int bif = 50;
Node[] ends = GraphTestUtil.buildSingleBifurcation(builder(), nnodes, bif);
CountingWalker walker = new CountingWalker();
NoBifurcationIterator iterator = createIterator();
iterator.setSource(ends[0]);
BasicGraphTraversal traversal = new BasicGraphTraversal(
builder().getGraph(), walker, iterator
);
traversal.init();
traversal.traverse();
GraphVisitor visitor = new GraphVisitor() {
public int visit(Graphable component) {
if (component.getID() < bif) {
assertTrue(component.isVisited());
}
else if (component.getID() >= bif) {
assertTrue(!component.isVisited());
}
return(0);
}
};
builder().getGraph().visitNodes(visitor);
assertTrue(walker.getCount() == nnodes-bif);
}
/**
* Create a graph that contains a cycle and do a full traversal.<BR>
* <BR>
* Expected: 1. All nodes visited.
*/
public void test_4() {
int nnodes = 100;
GraphTestUtil.buildCircular(builder(), nnodes);
GraphVisitor visitor = new GraphVisitor() {
public int visit(Graphable component) {
if (component.getID() == 50) return(Graph.PASS_AND_CONTINUE);
return(Graph.FAIL_QUERY);
}
};
Node source = (Node)builder().getGraph().queryNodes(visitor).get(0);
CountingWalker walker = new CountingWalker();
NoBifurcationIterator iterator = createIterator();
iterator.setSource(source);
BasicGraphTraversal traversal = new BasicGraphTraversal(
builder().getGraph(), walker, iterator
);
traversal.init();
traversal.traverse();
//ensure all nodes visisited
visitor = new GraphVisitor() {
public int visit(Graphable component) {
assertTrue(component.isVisited());
return(0);
}
};
builder().getGraph().visitNodes(visitor);
assertTrue(walker.getCount() == nnodes);
}
protected GraphBuilder createBuilder() {
return(new BasicGraphBuilder());
}
protected GraphBuilder builder() {
return(m_builder);
}
protected NoBifurcationIterator createIterator() {
return(new NoBifurcationIterator());
}
}