changeset 41:ed6737db637a

added tests
author Shoshi TAMAKI
date Tue, 29 Jan 2013 23:42:54 +0900
parents 6decea87ef88
children a545fe750a78
files src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/core/Children.java src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/error/BasicErrors.java src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/impl/ClonableChildren.java src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/impl/ClonableNode.java src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/impl/DefaultAttributes.java src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/impl/DefaultChildren.java src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/impl/TraversableNodeWrapper.java src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/impl/logger/LoggingChildren.java src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/impl/logger/LoggingNode.java src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/trasnformer/NodeEditorError.java src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/transaction/ClonableDefaultAttributes.java src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/transaction/ClonableDefaultChildren.java src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/transaction/ClonableDefaultNode.java src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/traverser/DefaultTraverser.java src/test/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/core/nodeeditor/EditableAttributesTest.java src/test/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/core/nodeeditor/EditableChildrenTest.java src/test/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/core/treeeditor/ClonableChildrenTest.java src/test/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/impl/clonable/ClonableDefaultChildrenTest.java src/test/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/impl/clonable/ClonableDefaultNodeTest.java
diffstat 19 files changed, 322 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/core/Children.java	Tue Jan 29 01:11:39 2013 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/core/Children.java	Tue Jan 29 23:42:54 2013 +0900
@@ -1,6 +1,10 @@
 package jp.ac.u_ryukyu.ie.cr.shoshi.jungle.core;
 
+import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.util.Either;
+import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.util.Error;
+
 public interface Children<T> extends Iterable<T>
 {
+	public Either<Error,T> at(int _pos);
 	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/error/BasicErrors.java	Tue Jan 29 23:42:54 2013 +0900
@@ -0,0 +1,10 @@
+package jp.ac.u_ryukyu.ie.cr.shoshi.jungle.error;
+
+import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.util.Error;
+import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.util.DefaultError;
+
+public class BasicErrors
+{
+	public static final Error NULL_VALUE_NOT_ALLOWED = new DefaultError();
+	public static final Error INDEX_OUT_OF_BOUNDS = new DefaultError();
+}
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/impl/ClonableChildren.java	Tue Jan 29 01:11:39 2013 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/impl/ClonableChildren.java	Tue Jan 29 23:42:54 2013 +0900
@@ -7,5 +7,6 @@
 
 public interface ClonableChildren<T extends EditableNode<T>> extends EditableChildren<T>
 {
+	public Either<Error,T> addNewChildAt(int _pos,T _newChild);
 	public Either<Error,T> replaceNode(int _pos,T _replacement);
 }
\ No newline at end of file
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/impl/ClonableNode.java	Tue Jan 29 01:11:39 2013 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/impl/ClonableNode.java	Tue Jan 29 23:42:54 2013 +0900
@@ -9,4 +9,6 @@
 	
 	@Override
 	public ClonableAttributes<T> getAttributes();
+	
+	public T createNewNode();
 }
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/impl/DefaultAttributes.java	Tue Jan 29 01:11:39 2013 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/impl/DefaultAttributes.java	Tue Jan 29 23:42:54 2013 +0900
@@ -41,6 +41,10 @@
 	@Override
 	public ByteBuffer get(String _key)
 	{
+		if(_key == null){
+			return null;
+		}
+		
 		Option<ByteBuffer> result = attrs.get(_key);
 		return result.isSome() ? result.some() : null;
 	}
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/impl/DefaultChildren.java	Tue Jan 29 01:11:39 2013 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/impl/DefaultChildren.java	Tue Jan 29 23:42:54 2013 +0900
@@ -5,7 +5,11 @@
 import fj.data.List;
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.core.Children;
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.core.Node;
+import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.trasnformer.NodeEditorError;
+import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.util.DefaultEither;
+import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.util.Either;
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.util.IterableWrapper;
+import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.util.Error;
 
 public class DefaultChildren implements Children<Node>
 {
@@ -70,6 +74,18 @@
 	
 	*/
 	
+	@Override
+	public Either<Error,Node> at(int _pos)
+	{
+		DefaultNode target = children.index(_pos);
+		if(target == null){
+			return DefaultEither.newA(NodeEditorError.INDEX_OUT_OF_BOUNDS); // TODO
+		}
+		Node ret = target;
+		
+		return DefaultEither.newB(ret);
+	}
+	
 	public List<DefaultNode> getChildrenAsRawList()
 	{
 		return children;
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/impl/TraversableNodeWrapper.java	Tue Jan 29 01:11:39 2013 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/impl/TraversableNodeWrapper.java	Tue Jan 29 23:42:54 2013 +0900
@@ -5,6 +5,9 @@
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.core.Children;
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.trasnformer.EditableNode;
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.traverser.TraversableNode;
+import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.util.DefaultEither;
+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.IterableConverter;
 
 public class TraversableNodeWrapper<T extends EditableNode<T>>
@@ -50,6 +53,18 @@
 			{
 				return ch.size();
 			}
+
+			@Override
+			public Either<Error, TraversableNodeWrapper<T>> at(int _pos)
+			{
+				Either<Error,T> either = ch.at(_pos);
+				if(either.isA()){
+					return DefaultEither.newA(either.a());
+				}
+				
+				T newWrap = either.b();
+				return DefaultEither.newB(new TraversableNodeWrapper<T>(newWrap));
+			}
 		};
 	}
 }
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/impl/logger/LoggingChildren.java	Tue Jan 29 01:11:39 2013 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/impl/logger/LoggingChildren.java	Tue Jan 29 23:42:54 2013 +0900
@@ -97,4 +97,29 @@
 		T newWrap = e.b();
 		return DefaultEither.newB(new LoggingNode<T>(newWrap,log));
 	}
+
+	@Override
+	public Either<Error,LoggingNode<T>> at(int _pos)
+	{
+		Either<Error,T> either = wrap.at(_pos);
+		if(either.isA()){
+			return DefaultEither.newA(either.a());
+		}
+		
+		T newWrap = either.b();
+		return DefaultEither.newB(new LoggingNode<T>(newWrap,log));
+	}
+
+	@Override
+	public Either<Error, LoggingNode<T>> addNewChildAt(int _pos,LoggingNode<T> _newChild)
+	{
+		Either<Error,T> either = wrap.addNewChildAt(_pos,_newChild.getWrapper());
+		if(either.isA()){
+			return DefaultEither.newA(either.a());
+		}
+		
+		T newWrap = either.b();
+		LoggingNode<T> newLoggingNode = new LoggingNode<T>(newWrap,log);
+		return DefaultEither.newB(newLoggingNode);
+	}
 }
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/impl/logger/LoggingNode.java	Tue Jan 29 01:11:39 2013 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/impl/logger/LoggingNode.java	Tue Jan 29 23:42:54 2013 +0900
@@ -36,6 +36,13 @@
 		return new LoggingChildren<T>(wrap.getChildren(),log);
 	}
 	
+	@Override
+	public LoggingNode<T> createNewNode()
+	{
+		T newWrap = wrap.createNewNode();
+		return new LoggingNode<T>(newWrap,log);
+	}
+	
 	public Logger getLogger()
 	{
 		return log;
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/trasnformer/NodeEditorError.java	Tue Jan 29 01:11:39 2013 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/store/trasnformer/NodeEditorError.java	Tue Jan 29 23:42:54 2013 +0900
@@ -7,4 +7,5 @@
 {
 	public static final Error INDEX_OUT_OF_BOUNDS = new DefaultError();
 	public static final Error DELETE_KEY_NOT_FOUND = new DefaultError();
+	public static final Error NULL_VALUE_NOT_ALLOWED = new DefaultError();
 }
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/transaction/ClonableDefaultAttributes.java	Tue Jan 29 01:11:39 2013 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/transaction/ClonableDefaultAttributes.java	Tue Jan 29 23:42:54 2013 +0900
@@ -24,6 +24,10 @@
 	@Override
 	public Either<Error,ClonableDefaultNode> delete(String _key)
 	{
+		if(_key == null){
+			return DefaultEither.newA(NodeEditorError.NULL_VALUE_NOT_ALLOWED);
+		}
+		
 		DefaultAttributes attrs = wrap.getAttributes();
 		DefaultChildren children = wrap.getChildren();
 		
@@ -42,6 +46,10 @@
 	@Override
 	public Either<Error, ClonableDefaultNode> put(String _key, ByteBuffer _value)
 	{
+		if(_key == null || _value == null){
+			return DefaultEither.newA(NodeEditorError.NULL_VALUE_NOT_ALLOWED);
+		}
+		
 		DefaultAttributes attrs = wrap.getAttributes();
 		DefaultChildren children = wrap.getChildren();
 		
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/transaction/ClonableDefaultChildren.java	Tue Jan 29 01:11:39 2013 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/transaction/ClonableDefaultChildren.java	Tue Jan 29 23:42:54 2013 +0900
@@ -6,6 +6,7 @@
 import fj.data.List;
 import fj.data.TreeMap;
 
+import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.core.Node;
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.impl.ClonableChildren;
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.impl.DefaultAttributes;
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.impl.DefaultChildren;
@@ -21,7 +22,7 @@
 	public static void main(String _args[])
 	{
 		List<Integer> list = List.range(0,5);
-		P2<List<Integer>, List<Integer>> split = list.splitAt(3);
+		P2<List<Integer>, List<Integer>> split = list.splitAt(0);
 		System.out.println(split._1().length());
 		System.out.println(split._2().length());
 		
@@ -109,13 +110,14 @@
 	@Override
 	public Either<Error,ClonableDefaultNode> replaceNode(int _pos,ClonableDefaultNode _replacement)
 	{
-		if(!boundaryCheck(_pos)){
+		int size = node.getChildren().size();
+		if(!(0 <= _pos && _pos < size)){
 			return DefaultEither.newA(NodeEditorError.INDEX_OUT_OF_BOUNDS);
 		}
 		DefaultNode replacement = _replacement.getWrapped();
 		
 		List<DefaultNode> rawList = node.getChildren().getChildrenAsRawList();
-		P2<List<DefaultNode>,List<DefaultNode>> split = rawList.splitAt(_pos);
+		P2<List<DefaultNode>,List<DefaultNode>> split = rawList.splitAt(_pos + 1);
 		List<DefaultNode> init = split._1().init();
 		List<DefaultNode> newInit = init.snoc(replacement);
 		List<DefaultNode> newList = newInit.append(split._2());
@@ -123,4 +125,34 @@
 		
 		return DefaultEither.newB(new ClonableDefaultNode(new DefaultNode(newList,rawMap)));
 	}
+
+	@Override
+	public Either<Error,ClonableDefaultNode> at(int _pos)
+	{
+		List<DefaultNode> rawList = node.getChildren().getChildrenAsRawList();
+		DefaultNode ch = rawList.index(_pos);
+		if(ch == null){
+			return DefaultEither.newA(NodeEditorError.INDEX_OUT_OF_BOUNDS);
+		}
+		
+		return DefaultEither.newB(new ClonableDefaultNode(ch));
+	}
+
+	@Override
+	public Either<Error, ClonableDefaultNode> addNewChildAt(int _pos,ClonableDefaultNode _newChild)
+	{
+		if(!boundaryCheck(_pos) || _pos < 0){
+			return DefaultEither.newA(NodeEditorError.INDEX_OUT_OF_BOUNDS);
+		}
+		DefaultNode newChild = _newChild.getWrapped();
+		
+		List<DefaultNode> raw = node.getChildren().getChildrenAsRawList();
+		TreeMap<String, ByteBuffer> rawMap = node.getAttributes().getAttributesAsRawMap();
+		
+		P2<List<DefaultNode>,List<DefaultNode>> split = raw.splitAt(_pos);
+		List<DefaultNode> newChildren = split._1().snoc(newChild).append(split._2());
+		DefaultNode newNode = new DefaultNode(newChildren,rawMap);
+		
+		return DefaultEither.newB(new ClonableDefaultNode(newNode));
+	}
 }
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/transaction/ClonableDefaultNode.java	Tue Jan 29 01:11:39 2013 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/transaction/ClonableDefaultNode.java	Tue Jan 29 23:42:54 2013 +0900
@@ -24,6 +24,12 @@
 		return new ClonableDefaultAttributes(wrap);
 	}
 	
+	@Override
+	public ClonableDefaultNode createNewNode()
+	{
+		return new ClonableDefaultNode(new DefaultNode());
+	}
+	
 	public DefaultNode getWrapped()
 	{
 		return wrap;
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/traverser/DefaultTraverser.java	Tue Jan 29 01:11:39 2013 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/traverser/DefaultTraverser.java	Tue Jan 29 23:42:54 2013 +0900
@@ -3,6 +3,7 @@
 import java.util.Iterator;
 
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.core.Children;
+import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.trasnformer.NodeEditorError;
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.util.DefaultEither;
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.util.Either;
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.util.Error;
@@ -23,6 +24,13 @@
 			public int size(){
 				return 1;
 			}
+			@Override
+			public Either<Error,T> at(int _pos){
+				if(_pos != 0){
+					return DefaultEither.newA(NodeEditorError.INDEX_OUT_OF_BOUNDS);
+				}
+				return DefaultEither.newB(_root);
+			}
 		};
 		
 		Either<Error,List<Direction<T>>> ret = _traverse(wrapper,_evaluator);
--- a/src/test/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/core/nodeeditor/EditableAttributesTest.java	Tue Jan 29 01:11:39 2013 +0900
+++ b/src/test/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/core/nodeeditor/EditableAttributesTest.java	Tue Jan 29 23:42:54 2013 +0900
@@ -7,6 +7,7 @@
 import fj.data.List;
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.trasnformer.EditableAttributes;
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.trasnformer.EditableNode;
+import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.trasnformer.NodeEditorError;
 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;
@@ -41,6 +42,26 @@
 		return attr;
 	}
 	
+	public void testPutDoesNotAcceptNullValue()
+	{
+		EditableAttributes<T> instance = instance();
+		
+		Either<Error,T> either = instance.put("KEY",null);
+		if(!either.isA()){
+			Assert.fail("put must returns NULL_VALUE_NOT_ALLOWED when the value was null.");
+		}
+		
+		Assert.assertEquals(NodeEditorError.NULL_VALUE_NOT_ALLOWED,either.a());
+		
+		either = instance.put(null,ByteBuffer.wrap("VALUE".getBytes()));
+		
+		if(!either.isA()){
+			Assert.fail("put must returns NULL_VALUE_NOT_ALLOWED when the key was null.");
+		}
+		
+		Assert.assertEquals(NodeEditorError.NULL_VALUE_NOT_ALLOWED,either.a());
+	}
+	
 	public void testPut()
 	{
 		createTestData();
--- a/src/test/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/core/nodeeditor/EditableChildrenTest.java	Tue Jan 29 01:11:39 2013 +0900
+++ b/src/test/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/core/nodeeditor/EditableChildrenTest.java	Tue Jan 29 23:42:54 2013 +0900
@@ -1,7 +1,7 @@
 package jp.ac.u_ryukyu.ie.cr.shoshi.jungle.core.nodeeditor;
 
+import java.nio.ByteBuffer;
 import org.junit.Assert;
-
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.trasnformer.EditableChildren;
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.trasnformer.EditableNode;
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.trasnformer.NodeEditorError;
@@ -13,6 +13,9 @@
 {
 	public abstract EditableChildren<T> instance();
 	
+	public static final String KEY = "KEY";
+	public static final ByteBuffer VALUE = ByteBuffer.wrap("VALUE".getBytes());
+	
 	public void testAddNewChildAtMuinusValue()
 	{
 		EditableChildren<T> children = instance();
@@ -40,6 +43,7 @@
 	public void testAddNewChildAtMiddle()
 	{
 		EditableChildren<T> children = instance();
+		
 		for(int i = 0;i < 3;i ++){
 			Either<Error,T> either = children.addNewChildAt(0);
 			if(either.isA()){
@@ -117,7 +121,7 @@
 		if(either.isA()){
 			Assert.fail("error during add new child to head");
 		}
-		children = either.b().getChildren();
+		children = either.b().getAttributes().put(KEY,VALUE).b().getChildren();
 		Assert.assertEquals(size + 1,children.size());
 		
 		either = children.deleteChildAt(0);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/test/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/core/treeeditor/ClonableChildrenTest.java	Tue Jan 29 23:42:54 2013 +0900
@@ -0,0 +1,131 @@
+package jp.ac.u_ryukyu.ie.cr.shoshi.jungle.core.treeeditor;
+
+import java.nio.ByteBuffer;
+import org.junit.Assert;
+import fj.data.List;
+import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.impl.ClonableChildren;
+import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.impl.ClonableNode;
+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;
+
+public abstract class ClonableChildrenTest<T extends ClonableNode<T>> extends TestCase
+{
+	public abstract ClonableNode<T> instance();
+	
+	public void testAddNewChildAtWithNode()
+	{
+		int count = 5;
+		for(Integer pos : List.range(0,5)){
+			_testAddNewChildAtWithNode(count,pos);
+		}
+	}
+	
+	public void _testAddNewChildAtWithNode(int _count,int _pos)
+	{
+		ClonableNode<T> instance = instance();
+		
+		Either<Error, T> either;
+		for(int i = 0;i < _count;i ++){
+			either = instance.getChildren().addNewChildAt(0);
+			if(either.isA()){
+				Assert.fail();
+			}
+			instance = either.b();
+		}
+		
+		T newNode = instance.createNewNode();
+		String key = "KEY";
+		ByteBuffer value = ByteBuffer.wrap("VALUE".getBytes());
+		
+		either = newNode.getAttributes().put(key,value);
+		if(either.isA()){
+			Assert.fail();
+		}
+		newNode = either.b();
+		
+		either = instance.getChildren().addNewChildAt(_pos,newNode);
+		if(either.isA()){
+			Assert.fail();
+		}
+		instance = either.b();
+		
+		// check 
+		either = instance.getChildren().at(_pos);
+		if(either.isA()){
+			Assert.fail();
+		}
+		
+		T checkTarget = either.b();
+		ByteBuffer actual = checkTarget.getAttributes().get(key);
+		Assert.assertEquals(0,value.compareTo(actual));
+	}
+	
+	public void testReplaceAt()
+	{
+		int count = 5;
+		for(Integer pos : List.range(0,count)){
+			_testReplaceAt(count,pos);
+		}
+	}
+	
+	public void _testReplaceAt(int _count,int _pos)
+	{
+		ClonableNode<T> instance = instance();
+		String key = "KEY";
+		ByteBuffer value = ByteBuffer.wrap("VALUE".getBytes());
+		
+		// prepare
+		
+		for(int i = 0;i < _count;i ++){
+			T newNode = instance.createNewNode();
+			Either<Error,T> either = newNode.getAttributes().put(key,value);
+			if(either.isA()){
+				Assert.fail("failed to put attributes to child");
+			}
+			
+			newNode = either.b();
+			either = instance.getChildren().addNewChildAt(0,newNode);
+			if(either.isA()){
+				Assert.fail("failed to add child to instance");
+			}
+			
+			instance = either.b();
+		}
+		
+		int size = instance.getChildren().size();
+		Assert.assertEquals(_count,size);
+		
+		// create node for replacement.
+		
+		ByteBuffer replaceNodeValue = ByteBuffer.wrap("EULAV".getBytes());
+		T replacement = instance.createNewNode();
+		Either<Error,T> either = replacement.getAttributes().put(key,replaceNodeValue);
+		if(either.isA()){
+			Assert.fail("failed to create replacement node");
+		}
+		replacement = either.b();
+		
+		// replace
+		
+		either = instance.getChildren().replaceNode(_pos,replacement);
+		if(either.isA()){
+			Assert.fail("failed to replace node.");
+		}
+		instance = either.b();
+		
+		ClonableChildren<T> children = instance.getChildren();
+		for(Integer pos : List.range(0,_count)){
+			either = children.at(pos.intValue());
+			if(either.isA()){
+				Assert.fail("failed to get node.");
+			}
+			
+			T ch = either.b();
+			ByteBuffer expect = (_pos != pos) ? value : replaceNodeValue;
+			ByteBuffer actual = ch.getAttributes().get(key);
+			
+			Assert.assertEquals(0,expect.compareTo(actual));
+		}
+	}
+}
--- a/src/test/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/impl/clonable/ClonableDefaultChildrenTest.java	Tue Jan 29 01:11:39 2013 +0900
+++ b/src/test/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/impl/clonable/ClonableDefaultChildrenTest.java	Tue Jan 29 23:42:54 2013 +0900
@@ -1,9 +1,9 @@
 package jp.ac.u_ryukyu.ie.cr.shoshi.jungle.impl.clonable;
 
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.core.nodeeditor.EditableChildrenTest;
+import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.core.treeeditor.ClonableChildrenTest;
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.impl.DefaultNode;
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.trasnformer.EditableChildren;
-import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.transaction.ClonableDefaultChildren;
 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.transaction.ClonableDefaultNode;
 import junit.framework.TestCase;
 import junit.framework.TestSuite;
@@ -14,12 +14,22 @@
 	{
 		TestSuite suite = new TestSuite();
 		suite.addTestSuite(EditableChildrenTestImpl.class);
+		suite.addTestSuite(ClonableChildrenTestImpl.class);
 		return suite;
 	}
 	
-	public static ClonableDefaultChildren instance()
+	public static ClonableDefaultNode instance()
 	{
-		return new ClonableDefaultNode(new DefaultNode()).getChildren();
+		return new ClonableDefaultNode(new DefaultNode());
+	}
+	
+	public static class ClonableChildrenTestImpl extends ClonableChildrenTest<ClonableDefaultNode>
+	{
+		@Override
+		public ClonableDefaultNode instance()
+		{
+			return ClonableDefaultChildrenTest.instance();
+		}
 	}
 	
 	public static class EditableChildrenTestImpl extends EditableChildrenTest<ClonableDefaultNode>
@@ -27,7 +37,7 @@
 		@Override
 		public EditableChildren<ClonableDefaultNode> instance()
 		{
-			return ClonableDefaultChildrenTest.instance();
+			return ClonableDefaultChildrenTest.instance().getChildren();
 		}
 	}
 }
--- a/src/test/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/impl/clonable/ClonableDefaultNodeTest.java	Tue Jan 29 01:11:39 2013 +0900
+++ b/src/test/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/impl/clonable/ClonableDefaultNodeTest.java	Tue Jan 29 23:42:54 2013 +0900
@@ -33,6 +33,14 @@
 		Assert.assertNotNull(wrapped);
 	}
 	
+	public void testCreateNewNode()
+	{
+		ClonableDefaultNode instance = instance();
+		ClonableDefaultNode node = instance.createNewNode();
+		
+		Assert.assertNotNull(node);
+	}
+	
 	public static class AttributesContaierTestImpl extends AttributesContainerTest
 	{
 		@Override