Mercurial > hg > Members > shoshi > jungle > jungle-core
changeset 43:1c91c4357228
added traverser test
author | Shoshi TAMAKI |
---|---|
date | Fri, 01 Feb 2013 00:55:02 +0900 |
parents | a545fe750a78 |
children | 449d67be0886 |
files | src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/NodePath.java src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/impl/DefaultNodePath.java src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/impl/logger/DefaultLogger.java src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/traverser/DefaultEvaluator.java src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/traverser/DefaultTraverser.java src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/traverser/Result.java src/test/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/core/nodeeditor/NodeEditorTest.java src/test/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/impl/logging/LoggingNodeTest.java src/test/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/traverse/DefaultTraverserTest.java src/test/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/traverse/TraverserTest.java |
diffstat | 10 files changed, 368 insertions(+), 27 deletions(-) [+] |
line wrap: on
line diff
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/NodePath.java Thu Jan 31 00:09:51 2013 +0900 +++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/NodePath.java Fri Feb 01 00:55:02 2013 +0900 @@ -6,4 +6,5 @@ { public NodePath add(int _pos); public Pair<Integer,NodePath> pop(); + public int size(); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/impl/DefaultNodePath.java Fri Feb 01 00:55:02 2013 +0900 @@ -0,0 +1,65 @@ +package jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.impl; + +import java.util.Iterator; + +import fj.data.List; + +import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.NodePath; +import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.util.Pair; + +public class DefaultNodePath implements NodePath +{ + private final List<Integer> path; + + public static void main(String _args[]) + { + DefaultNodePath p = new DefaultNodePath(); + p = p.add(1).add(2).add(3).add(4); + System.out.println(p.toString()); + } + + public DefaultNodePath() + { + path = List.nil(); + } + + private DefaultNodePath(List<Integer> _path) + { + path = _path; + } + + @Override + public Iterator<Integer> iterator() + { + return path.iterator(); + } + + @Override + public DefaultNodePath add(int _pos) + { + List<Integer> newPath = path.snoc(_pos); + + return new DefaultNodePath(newPath); + } + + @Override + public Pair<Integer, NodePath> pop() + { + Integer head = path.head(); + List<Integer> tail = path.tail(); + + return new Pair<Integer,NodePath>(head,new DefaultNodePath(tail)); + } + + @Override + public String toString() + { + return path.toString(); + } + + @Override + public int size() + { + return path.length(); + } +}
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/impl/logger/DefaultLogger.java Thu Jan 31 00:09:51 2013 +0900 +++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/impl/logger/DefaultLogger.java Fri Feb 01 00:55:02 2013 +0900 @@ -29,6 +29,6 @@ @Override public Logger add(Operation _op) { - return new DefaultLogger(log.cons(_op)); + return new DefaultLogger(log.snoc(_op)); } }
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/traverser/DefaultEvaluator.java Thu Jan 31 00:09:51 2013 +0900 +++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/traverser/DefaultEvaluator.java Fri Feb 01 00:55:02 2013 +0900 @@ -16,16 +16,22 @@ public <T extends TraversableNode<T>> Evaluation evaluate(T _current,int _pos) { Pair<Integer,NodePath> pop = path.pop(); - if(pop == null){ - return new DefaultEvaluation(Result.BREAK,null); + int head = pop.left(); + + if(path.size() == 1){ + if(head == _pos){ + return new DefaultEvaluation(Result.GOAL,null); + } } - DefaultEvaluator nextEvaluator = new DefaultEvaluator(pop.right()); - int head = pop.left(); - - Result result = Result.CONTINUE; + DefaultEvaluator nextEvaluator; + Result result; if(head == _pos){ result = Result.ACCEPT; + nextEvaluator = new DefaultEvaluator(pop.right()); + }else{ + result = Result.CONTINUE; + nextEvaluator = null; } return new DefaultEvaluation(result,nextEvaluator);
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/traverser/DefaultTraverser.java Thu Jan 31 00:09:51 2013 +0900 +++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/traverser/DefaultTraverser.java Fri Feb 01 00:55:02 2013 +0900 @@ -33,7 +33,9 @@ } }; - Either<Error,List<Direction<T>>> ret = _traverse(wrapper,_evaluator); + Children<T> chs = _root.getChildren(); + + Either<Error,List<Direction<T>>> ret = _traverse(chs,_evaluator); if(ret.isA()){ return DefaultEither.newA(ret.a()); } @@ -66,9 +68,12 @@ return _accept(ch,pos,e.evaluator()); } + if(r == Result.GOAL){ + return DefaultEither.newB(_goal(ch,pos)); + } + if(r == Result.BREAK){ - List<Direction<T>> nil = List.nil(); - return DefaultEither.newB(nil); + break; } if(r == Result.CONTINUE){ @@ -82,6 +87,27 @@ return DefaultEither.newA(TraverserError.PATH_NOT_FOUND); } + private <T extends TraversableNode<T>> List<Direction<T>> _goal(final T _current,final int _pos) + { + Direction<T> d = new Direction<T>(){ + @Override + public int getPosition() + { + return _pos; + } + @Override + public T getTarget() + { + return _current; + } + }; + + List<Direction<T>> list = List.nil(); + List<Direction<T>> newList = list.cons(d); + + return newList; + } + private <T extends TraversableNode<T>> Either<Error,List<Direction<T>>> _accept(final T _current,final int _pos,Evaluator _evaluator) { Children<T> chs = _current.getChildren();
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/traverser/Result.java Thu Jan 31 00:09:51 2013 +0900 +++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/traverser/Result.java Fri Feb 01 00:55:02 2013 +0900 @@ -3,11 +3,20 @@ public class Result { // for traverser - public static final Result ACCEPT = new Result(); - public static final Result CONTINUE = new Result(); - public static final Result BREAK = new Result(); + public static final Result ACCEPT = new Result("ACCEPT"); + public static final Result CONTINUE = new Result("CONTINUE"); + public static final Result BREAK = new Result("BREAK"); + public static final Result GOAL = new Result("GOAL"); + + private final String name; - private Result() + private Result(String _name) { + name = _name; + } + + public String toString() + { + return name; } }
--- a/src/test/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/core/nodeeditor/NodeEditorTest.java Thu Jan 31 00:09:51 2013 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,11 +0,0 @@ -package jp.ac.u_ryukyu.ie.cr.shoshi.jungle.core.nodeeditor; - -import junit.framework.TestCase; - -public abstract class NodeEditorTest extends TestCase -{ - public void testEdit() - { - - } -}
--- a/src/test/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/impl/logging/LoggingNodeTest.java Thu Jan 31 00:09:51 2013 +0900 +++ b/src/test/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/impl/logging/LoggingNodeTest.java Fri Feb 01 00:55:02 2013 +0900 @@ -1,14 +1,20 @@ package jp.ac.u_ryukyu.ie.cr.shoshi.jungle.impl.logging; +import java.nio.ByteBuffer; import org.junit.Assert; - +import fj.data.List; import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.core.AttributesContainer; import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.core.AttributesContainerTest; import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.core.ParentTest; +import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.Command; import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.impl.DefaultNode; import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.impl.logger.Logger; import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.impl.logger.LoggingNode; +import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.operations.Operation; +import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.operations.SetAttributeOperation; import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.transaction.ClonableDefaultNode; +import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.util.Either; +import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.util.Error; import junit.framework.TestCase; import junit.framework.TestSuite; @@ -28,6 +34,106 @@ Assert.assertNotNull(wrap); } + public void testLoggingAddNewChildAt() + { + LoggingNode<ClonableDefaultNode> instance = instance(); + Either<Error,LoggingNode<ClonableDefaultNode>> either = instance.getChildren().addNewChildAt(0); + if(either.isA()){ + Assert.fail(); + } + instance = either.b(); + + List<Command> expectOps = List.list(Command.APPEND_CHILD); + for(Operation op : instance.getLogger()){ + Command actual = op.getCommand(); + Command expect = expectOps.head(); + Assert.assertEquals(expect,actual); + expectOps = expectOps.tail(); + } + + Assert.assertEquals(0,expectOps.length()); + } + + public void testLoggingDeleteChildAt() + { + LoggingNode<ClonableDefaultNode> instance = instance(); + Either<Error,LoggingNode<ClonableDefaultNode>> either = instance.getChildren().addNewChildAt(0); + if(either.isA()){ + Assert.fail(); + } + instance = either.b(); + either = instance.getChildren().deleteChildAt(0); + if(either.isA()){ + Assert.fail(); + } + instance = either.b(); + + List<Command> expectOps = List.list(Command.APPEND_CHILD,Command.DELETE_CHILD); + for(Operation op : instance.getLogger()){ + Command actual = op.getCommand(); + Command expect = expectOps.head(); + Assert.assertEquals(expect,actual); + expectOps = expectOps.tail(); + } + + Assert.assertEquals(0,expectOps.length()); + } + + public void testPutAttributeTest() + { + String key = "KEY"; + ByteBuffer value = ByteBuffer.wrap(key.getBytes()); + LoggingNode<ClonableDefaultNode> instance = instance(); + Either<Error,LoggingNode<ClonableDefaultNode>> either = instance.getAttributes().put(key,value); + if(either.isA()){ + Assert.fail(); + } + instance = either.b(); + + List<Command> expectOps = List.list(Command.SET_ATTRIBUTE); + for(Operation op : instance.getLogger()){ + Command actual = op.getCommand(); + Command expect = expectOps.head(); + Assert.assertEquals(expect,actual); + + SetAttributeOperation sa = (SetAttributeOperation)op; + String actualKey = sa.getKey(); + ByteBuffer actualValue = sa.getValue(); + Assert.assertEquals(key,actualKey); + Assert.assertEquals(0,value.compareTo(actualValue)); + expectOps = expectOps.tail(); + } + + Assert.assertEquals(0,expectOps.length()); + } + + public void testDeleteAttributeTest() + { + String key = "KEY"; + ByteBuffer value = ByteBuffer.wrap(key.getBytes()); + LoggingNode<ClonableDefaultNode> instance = instance(); + Either<Error,LoggingNode<ClonableDefaultNode>> either = instance.getAttributes().put(key,value); + if(either.isA()){ + Assert.fail(); + } + instance = either.b(); + either = instance.getAttributes().delete(key); + if(either.isA()){ + Assert.fail(); + } + instance = either.b(); + + List<Command> expectOps = List.list(Command.SET_ATTRIBUTE,Command.DELETE_ATTRIBUTE); + for(Operation op : instance.getLogger()){ + Command actual = op.getCommand(); + Command expect = expectOps.head(); + Assert.assertEquals(expect,actual); + expectOps = expectOps.tail(); + } + + Assert.assertEquals(0,expectOps.length()); + } + public static TestSuite suite() { TestSuite suite = new TestSuite(); @@ -37,7 +143,7 @@ return suite; } - public static LoggingNode<?> instance() + public static LoggingNode<ClonableDefaultNode> instance() { return new LoggingNode<ClonableDefaultNode>(new ClonableDefaultNode(new DefaultNode())); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/test/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/traverse/DefaultTraverserTest.java Fri Feb 01 00:55:02 2013 +0900 @@ -0,0 +1,27 @@ +package jp.ac.u_ryukyu.ie.cr.shoshi.jungle.traverse; + +import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.traverser.DefaultTraverser; +import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.traverser.Traverser; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +public class DefaultTraverserTest extends TestCase +{ + public static TestSuite suite() + { + TestSuite suite = new TestSuite(); + suite.addTestSuite(TraverserTestImpl.class); + return suite; + } + + public static class TraverserTestImpl extends TraverserTest + { + + @Override + public Traverser instance() + { + return new DefaultTraverser(); + } + + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/test/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/traverse/TraverserTest.java Fri Feb 01 00:55:02 2013 +0900 @@ -0,0 +1,112 @@ +package jp.ac.u_ryukyu.ie.cr.shoshi.jungle.traverse; + +import java.nio.ByteBuffer; +import org.junit.Assert; + +import fj.data.List; + +import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.NodePath; +import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.impl.DefaultNode; +import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.impl.DefaultNodePath; +import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.impl.TraversableNodeWrapper; +import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.transaction.ClonableDefaultNode; +import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.traverser.DefaultEvaluator; +import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.traverser.Direction; +import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.traverser.Traversal; +import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.traverser.Traverser; +import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.util.Either; +import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.util.Error; +import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.util.Pair; +import junit.framework.TestCase; + +public abstract class TraverserTest extends TestCase +{ + public abstract Traverser instance(); + + public void testTraverse() + { + int maxHeight = 3; + ClonableDefaultNode root = createTree(0,0,maxHeight,new DefaultNodePath()); + + TraversableNodeWrapper<ClonableDefaultNode> traversable = new TraversableNodeWrapper<ClonableDefaultNode>(root); + Traverser traverser = instance(); + + // generate all pattern. + List<DefaultNodePath> paths = generatePathPattern(new DefaultNodePath(),0,maxHeight); + + for(DefaultNodePath path : paths){ + DefaultEvaluator evaluator = new DefaultEvaluator(path); + Either<Error,Traversal<TraversableNodeWrapper<ClonableDefaultNode>>> ret = traverser.traverse(traversable,evaluator); + if(ret.isA()){ + Assert.fail(); + } + + Traversal<TraversableNodeWrapper<ClonableDefaultNode>> traversal = ret.b(); + TraversableNodeWrapper<ClonableDefaultNode> target = traversal.destination(); + String expect = path.toString(); + ByteBuffer value = target.getWrapped().getAttributes().get(key); + String actual = new String(value.array()); + Assert.assertEquals(expect,actual); + + Pair<Integer,NodePath> pop; + NodePath estimatedPath = path; + DefaultNodePath currentPath = new DefaultNodePath(); + + for(Direction<TraversableNodeWrapper<ClonableDefaultNode>> d : traversal){ + pop = estimatedPath.pop(); + estimatedPath = pop.right(); + currentPath = currentPath.add(pop.left()); + + value = d.getTarget().getWrapped().getAttributes().get(key); + String actualCurrentPathStr = new String(value.array()); + String expectCurrentPathStr = currentPath.toString(); + Assert.assertEquals(expectCurrentPathStr,actualCurrentPathStr); + } + } + } + + public List<DefaultNodePath> generatePathPattern(DefaultNodePath _cur,int _curHeight,int _maxHeight) + { + List<DefaultNodePath> paths = List.nil(); + for(int p = 0;p <= _curHeight;p ++){ + DefaultNodePath path = _cur.add(p); + if(_curHeight != _maxHeight - 1){ + List<DefaultNodePath> newpaths = generatePathPattern(path,_curHeight+1,_maxHeight); + paths = paths.append(newpaths); + } + paths = paths.cons(path); + } + + return paths; + } + + public static String key = "KEY"; + public static ByteBuffer value = ByteBuffer.wrap(key.getBytes()); + public static ClonableDefaultNode factory = new ClonableDefaultNode(new DefaultNode()); + + public ClonableDefaultNode createTree(int _curX,int _curY,int _maxHeight,NodePath _address) + { + ClonableDefaultNode parent = factory.createNewNode(); + Either<Error,ClonableDefaultNode> either = parent.getAttributes().put(key,ByteBuffer.wrap(_address.toString().getBytes())); + if(either.isA()){ + Assert.fail(); + } + parent = either.b(); + + if(_curY == _maxHeight){ + return parent; + } + + for(int i = 0;i < _curY + 1;i ++){ + ClonableDefaultNode ch = createTree(i,_curY + 1,_maxHeight,_address.add(i)); + either = parent.getChildren().addNewChildAt(i,ch); + if(either.isA()){ + Assert.fail(); + } + + parent = either.b(); + } + + return parent; + } +}