You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by md...@apache.org on 2011/12/27 19:17:40 UTC
svn commit: r1224964 [2/2] - in
/jackrabbit/sandbox/jackrabbit-microkernel/src:
main/java/org/apache/jackrabbit/ main/java/org/apache/jackrabbit/state/
main/java/org/apache/jackrabbit/utils/ test/java/org/apache/jackrabbit/
test/java/org/apache/jackrab...
Added: jackrabbit/sandbox/jackrabbit-microkernel/src/test/java/org/apache/jackrabbit/state/TransientSpaceTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/test/java/org/apache/jackrabbit/state/TransientSpaceTest.java?rev=1224964&view=auto
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/test/java/org/apache/jackrabbit/state/TransientSpaceTest.java (added)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/test/java/org/apache/jackrabbit/state/TransientSpaceTest.java Tue Dec 27 18:17:39 2011
@@ -0,0 +1,837 @@
+package org.apache.jackrabbit.state;
+
+import org.apache.jackrabbit.Path;
+import org.apache.jackrabbit.json.FullJsonParser;
+import org.apache.jackrabbit.json.JsonValue;
+import org.apache.jackrabbit.json.JsonValue.JsonAtom;
+import org.apache.jackrabbit.json.JsonValue.JsonObject;
+import org.apache.jackrabbit.json.JsonValue.Type;
+import org.apache.jackrabbit.json.UnescapingJsonTokenizer;
+import org.apache.jackrabbit.mk.MicroKernelFactory;
+import org.apache.jackrabbit.mk.api.MicroKernel;
+import org.apache.jackrabbit.mk.api.MicroKernelException;
+import org.apache.jackrabbit.mk.store.NotFoundException;
+import org.apache.jackrabbit.state.ChangeTree.NodeDelta;
+import org.hamcrest.CoreMatchers;
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.internal.matchers.TypeSafeMatcher;
+
+import javax.jcr.ItemExistsException;
+import javax.jcr.ItemNotFoundException;
+import javax.jcr.RepositoryException;
+
+import static org.apache.jackrabbit.state.TransientSpaceTest.MicrokernelMatcher.propertyExists;
+import static org.apache.jackrabbit.state.TransientSpaceTest.MicrokernelMatcher.propertyHasValue;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+public class TransientSpaceTest {
+ private static final Path ROOT = Path.create("root");
+
+ private MicroKernel mk;
+ private TransientSpace transientSpace;
+
+ @Before
+ public void setup() {
+ mk = MicroKernelFactory.getInstance("fs:target/transient-space-test;clean");
+ mk.commit("", "+\"/root\":{}", mk.getHeadRevision(), "");
+
+ transientSpace = new TransientSpace("root", mk, mk.getHeadRevision());
+ }
+
+ @After
+ public void tearDown() {
+ mk.dispose();
+ }
+
+ @Test(expected = ItemNotFoundException.class)
+ public void getNotExistingNode() throws ItemNotFoundException {
+ transientSpace.getNode(ROOT.concat("any"));
+ }
+
+ @Test
+ public void addNode() throws RepositoryException {
+ NodeDelta root = transientSpace.getNode(ROOT);
+ root.addNode("added");
+
+ Path addedPath = ROOT.concat("added");
+ NodeDelta added = transientSpace.getNode(addedPath);
+ assertEquals(addedPath, added.getPath());
+
+ transientSpace.save();
+ added = transientSpace.getNode(addedPath);
+ assertEquals(addedPath, added.getPath());
+ }
+
+ @Test
+ public void addNodes() throws RepositoryException {
+ NodeDelta root = transientSpace.getNode(ROOT);
+ root.addNode("a").addNode("b").addNode("c");
+ transientSpace.save();
+
+ NodeDelta c = transientSpace.getNode(ROOT.concat("a/b/c"));
+ c.addNode("d").addNode("e");
+ c.addNode("f");
+
+ assertTrue(transientSpace.nodeExists(ROOT.concat("a/b/c/d/e")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("a/b/c/f")));
+
+ transientSpace.save();
+
+ assertTrue(transientSpace.nodeExists(ROOT.concat("a/b/c/d/e")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("a/b/c/f")));
+ }
+
+ @Test(expected = ItemNotFoundException.class)
+ public void removeNotExistingNode() throws RepositoryException {
+ NodeDelta root = transientSpace.getNode(ROOT);
+ root.removeNode("remove");
+ transientSpace.save();
+ }
+
+ @Test
+ public void removeExistingNode() throws RepositoryException {
+ NodeDelta root = transientSpace.getNode(ROOT);
+ root.addNode("added");
+ transientSpace.save();
+
+ Path addedPath = ROOT.concat("added");
+ assertTrue(transientSpace.nodeExists(addedPath));
+
+ root = transientSpace.getNode(ROOT);
+ root.removeNode("added");
+ assertFalse(transientSpace.nodeExists(addedPath));
+ transientSpace.save();
+ assertFalse(transientSpace.nodeExists(addedPath));
+ }
+
+ @Test
+ public void removeTransientNode() throws RepositoryException {
+ NodeDelta root = transientSpace.getNode(ROOT);
+ root.addNode("added");
+
+ Path addedPath = ROOT.concat("added");
+ assertTrue(transientSpace.nodeExists(addedPath));
+
+ root.removeNode("added");
+ assertFalse(transientSpace.nodeExists(addedPath));
+ transientSpace.save();
+ assertFalse(transientSpace.nodeExists(addedPath));
+ }
+
+ @Test(expected = ItemNotFoundException.class)
+ public void removeRemovedNode() throws RepositoryException {
+ NodeDelta root = transientSpace.getNode(ROOT);
+ root.addNode("added");
+ transientSpace.save();
+
+ Path addedPath = ROOT.concat("added");
+ NodeDelta added = transientSpace.getNode(addedPath);
+ added.addNode("added2");
+
+ assertTrue(added.hasNode("added2"));
+ added.removeNode("added2");
+ assertFalse(added.hasNode("added2"));
+ added.removeNode("added2");
+ }
+
+ @Test
+ public void moveTransient() throws RepositoryException {
+ NodeDelta root = transientSpace.getNode(ROOT);
+ root.addNode("source").addNode("node");
+ root.addNode("target");
+
+ NodeDelta sourceNode = transientSpace.getNode(ROOT.concat("source"));
+ sourceNode.moveNode("node", ROOT.concat("target/moved"));
+
+ assertFalse(transientSpace.nodeExists(ROOT.concat("source/node")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("source")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("target/moved")));
+ transientSpace.save();
+
+ assertFalse(transientSpace.nodeExists(ROOT.concat("source/node")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("source")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("target/moved")));
+ }
+
+ @Test
+ public void moveExisting() throws RepositoryException {
+ NodeDelta root = transientSpace.getNode(ROOT);
+ root.addNode("source").addNode("node");
+ root.addNode("target");
+ transientSpace.save();
+
+ NodeDelta sourceNode = transientSpace.getNode(ROOT.concat("source"));
+ sourceNode.moveNode("node", ROOT.concat("target/moved"));
+
+ assertFalse(transientSpace.nodeExists(ROOT.concat("source/node")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("source")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("target/moved")));
+ transientSpace.save();
+
+ assertFalse(transientSpace.nodeExists(ROOT.concat("source/node")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("source")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("target/moved")));
+ }
+
+ @Test(expected = ItemNotFoundException.class)
+ public void moveNotExistingSource() throws RepositoryException {
+ NodeDelta root = transientSpace.getNode(ROOT);
+ root.addNode("source");
+ root.addNode("target");
+ transientSpace.save();
+
+ NodeDelta sourceNode = transientSpace.getNode(ROOT.concat("source"));
+ sourceNode.moveNode("node", ROOT.concat("target/moved"));
+ }
+
+ @Test(expected = ItemNotFoundException.class)
+ public void moveToNotExistingTarget() throws RepositoryException {
+ NodeDelta root = transientSpace.getNode(ROOT);
+ root.addNode("source").addNode("node");
+ transientSpace.save();
+
+ NodeDelta sourceNode = transientSpace.getNode(ROOT.concat("source"));
+ sourceNode.moveNode("node", ROOT.concat("target/moved"));
+ }
+
+ @Test(expected = ItemExistsException.class)
+ public void moveToExistingTarget() throws RepositoryException {
+ NodeDelta root = transientSpace.getNode(ROOT);
+ root.addNode("source").addNode("node");
+ root.addNode("target").addNode("moved");
+ transientSpace.save();
+
+ NodeDelta sourceNode = transientSpace.getNode(ROOT.concat("source"));
+ sourceNode.moveNode("node", ROOT.concat("target/moved"));
+ }
+
+ @Test
+ public void rename() throws RepositoryException {
+ NodeDelta root = transientSpace.getNode(ROOT);
+ root.addNode("source").addNode("node");
+ transientSpace.save();
+
+ NodeDelta sourceNode = transientSpace.getNode(ROOT.concat("source"));
+ sourceNode.moveNode("node", ROOT.concat("source/moved"));
+
+ assertFalse(transientSpace.nodeExists(ROOT.concat("source/node")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("source")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("source/moved")));
+ transientSpace.save();
+
+ assertFalse(transientSpace.nodeExists(ROOT.concat("source/node")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("source")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("source/moved")));
+ }
+
+ @Test
+ public void moveSubTree() throws RepositoryException {
+ NodeDelta root = transientSpace.getNode(ROOT);
+ NodeDelta b = root.addNode("a").addNode("b");
+ b.addNode("c").addNode("d");
+ NodeDelta y = root.addNode("v").addNode("w");
+ y.addNode("x").addNode("y");
+ transientSpace.save();
+
+ b = transientSpace.getNode(ROOT.concat("a/b"));
+ b.moveNode("c", y.getPath().concat("c-moved"));
+
+ assertFalse(transientSpace.nodeExists(ROOT.concat("a/b/c")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("a/b")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("v/w/x/y")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("v/w/c-moved/d")));
+ transientSpace.save();
+
+ assertFalse(transientSpace.nodeExists(ROOT.concat("a/b/c")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("a/b")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("v/w/x/y")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("v/w/c-moved/d")));
+ }
+
+ @Test
+ public void modifyThenMove() throws RepositoryException {
+ NodeDelta root = transientSpace.getNode(ROOT);
+ root.addNode("source").addNode("node").addNode("c");
+ root.addNode("target");
+ transientSpace.save();
+
+ NodeDelta sourceNode = transientSpace.getNode(ROOT.concat("source"));
+ NodeDelta moveNode = sourceNode.getNode("node");
+ moveNode.addNode("a").addNode("b");
+ moveNode.removeNode("c");
+ sourceNode.moveNode("node", ROOT.concat("target/moved"));
+
+ assertFalse(transientSpace.nodeExists(ROOT.concat("source/node")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("source")));
+ assertFalse(transientSpace.nodeExists(ROOT.concat("target/moved/c")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("target/moved/a/b")));
+ transientSpace.save();
+
+ assertFalse(transientSpace.nodeExists(ROOT.concat("source/node")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("source")));
+ assertFalse(transientSpace.nodeExists(ROOT.concat("target/moved/c")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("target/moved/a/b")));
+ }
+
+ @Test
+ public void moveThenModify() throws RepositoryException {
+ NodeDelta root = transientSpace.getNode(ROOT);
+ root.addNode("source").addNode("node").addNode("c");
+ root.addNode("target");
+ transientSpace.save();
+
+ NodeDelta sourceNode = transientSpace.getNode(ROOT.concat("source"));
+ sourceNode.moveNode("node", ROOT.concat("target/moved"));
+ NodeDelta movedNode = transientSpace.getNode(ROOT.concat("target/moved"));
+ movedNode.addNode("a").addNode("b");
+ movedNode.removeNode("c");
+
+ assertFalse(transientSpace.nodeExists(ROOT.concat("source/node")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("source")));
+ assertFalse(transientSpace.nodeExists(ROOT.concat("target/moved/c")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("target/moved/a/b")));
+ transientSpace.save();
+
+ assertFalse(transientSpace.nodeExists(ROOT.concat("source/node")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("source")));
+ assertFalse(transientSpace.nodeExists(ROOT.concat("target/moved/c")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("target/moved/a/b")));
+ }
+
+ @Test
+ public void modifyThenMoveThenModify() throws RepositoryException {
+ NodeDelta root = transientSpace.getNode(ROOT);
+ root.addNode("source").addNode("node").addNode("c1");
+ root.getNode("source").getNode("node").addNode("c2");
+ root.addNode("target");
+ transientSpace.save();
+
+ NodeDelta sourceNode = transientSpace.getNode(ROOT.concat("source"));
+ NodeDelta moveNode = sourceNode.getNode("node");
+ moveNode.addNode("a1").addNode("b1");
+ moveNode.removeNode("c1");
+ sourceNode.moveNode("node", ROOT.concat("target/moved"));
+
+ NodeDelta movedNode = transientSpace.getNode(ROOT.concat("target/moved"));
+ movedNode.addNode("a2").addNode("b2");
+ movedNode.removeNode("c2");
+
+ assertFalse(transientSpace.nodeExists(ROOT.concat("source/node")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("source")));
+ assertFalse(transientSpace.nodeExists(ROOT.concat("target/moved/c1")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("target/moved/a1/b1")));
+ assertFalse(transientSpace.nodeExists(ROOT.concat("target/moved/c2")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("target/moved/a2/b2")));
+ transientSpace.save();
+
+ assertFalse(transientSpace.nodeExists(ROOT.concat("source/node")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("source")));
+ assertFalse(transientSpace.nodeExists(ROOT.concat("target/moved/c1")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("target/moved/a1/b1")));
+ assertFalse(transientSpace.nodeExists(ROOT.concat("target/moved/c2")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("target/moved/a2/b2")));
+ }
+
+ @Test
+ public void moveThenDelete() throws RepositoryException {
+ NodeDelta root = transientSpace.getNode(ROOT);
+ root.addNode("source").addNode("node");
+ root.addNode("target");
+ transientSpace.save();
+
+ NodeDelta sourceNode = transientSpace.getNode(ROOT.concat("source"));
+ sourceNode.moveNode("node", ROOT.concat("target/moved"));
+ root.getNode("target").removeNode("moved");
+
+ assertFalse(transientSpace.nodeExists(ROOT.concat("source/node")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("source")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("target")));
+ assertFalse(transientSpace.nodeExists(ROOT.concat("target/moved")));
+ transientSpace.save();
+
+ assertFalse(transientSpace.nodeExists(ROOT.concat("source/node")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("source")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("target")));
+ assertFalse(transientSpace.nodeExists(ROOT.concat("target/moved")));
+ }
+
+ @Test
+ public void moveFromAddedThenDelete() throws RepositoryException {
+ NodeDelta root = transientSpace.getNode(ROOT);
+ root.addNode("source");
+ root.addNode("target");
+ transientSpace.save();
+
+ root.getNode("source").addNode("node");
+ NodeDelta sourceNode = transientSpace.getNode(ROOT.concat("source"));
+ sourceNode.moveNode("node", ROOT.concat("target/moved"));
+ root.getNode("target").removeNode("moved");
+
+ assertFalse(transientSpace.nodeExists(ROOT.concat("source/node")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("source")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("target")));
+ assertFalse(transientSpace.nodeExists(ROOT.concat("target/moved")));
+ transientSpace.save();
+
+ assertFalse(transientSpace.nodeExists(ROOT.concat("source/node")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("source")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("target")));
+ assertFalse(transientSpace.nodeExists(ROOT.concat("target/moved")));
+ }
+
+ @Test
+ public void moveToAddedThenDelete() throws RepositoryException {
+ NodeDelta root = transientSpace.getNode(ROOT);
+ root.addNode("source").addNode("node");
+ transientSpace.save();
+
+ root.addNode("target");
+ NodeDelta sourceNode = transientSpace.getNode(ROOT.concat("source"));
+ sourceNode.moveNode("node", ROOT.concat("target/moved"));
+ root.getNode("target").removeNode("moved");
+
+ assertFalse(transientSpace.nodeExists(ROOT.concat("source/node")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("source")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("target")));
+ assertFalse(transientSpace.nodeExists(ROOT.concat("target/moved")));
+ transientSpace.save();
+
+ assertFalse(transientSpace.nodeExists(ROOT.concat("source/node")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("source")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("target")));
+ assertFalse(transientSpace.nodeExists(ROOT.concat("target/moved")));
+ }
+
+ @Test
+ public void moveFromAddedToAddedThenDelete() throws RepositoryException {
+ NodeDelta root = transientSpace.getNode(ROOT);
+ root.addNode("source");
+ transientSpace.save();
+
+ root.getNode("source").addNode("node");
+ root.addNode("target");
+ NodeDelta sourceNode = transientSpace.getNode(ROOT.concat("source"));
+ sourceNode.moveNode("node", ROOT.concat("target/moved"));
+ root.getNode("target").removeNode("moved");
+
+ assertFalse(transientSpace.nodeExists(ROOT.concat("source/node")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("source")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("target")));
+ assertFalse(transientSpace.nodeExists(ROOT.concat("target/moved")));
+ transientSpace.save();
+
+ assertFalse(transientSpace.nodeExists(ROOT.concat("source/node")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("source")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("target")));
+ assertFalse(transientSpace.nodeExists(ROOT.concat("target/moved")));
+ }
+
+ @Test
+ public void moveMoved() throws RepositoryException {
+ NodeDelta root = transientSpace.getNode(ROOT);
+ root.addNode("source").addNode("node");
+ root.addNode("target1");
+ root.addNode("target2");
+ transientSpace.save();
+
+ NodeDelta sourceNode = transientSpace.getNode(ROOT.concat("source"));
+ sourceNode.moveNode("node", ROOT.concat("target1/moved1"));
+ NodeDelta target1 = root.getNode("target1");
+ target1.moveNode("moved1", ROOT.concat("target2/moved2"));
+
+ assertFalse(transientSpace.nodeExists(ROOT.concat("source/node")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("source")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("target1")));
+ assertFalse(transientSpace.nodeExists(ROOT.concat("target1/moved1")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("target2/moved2")));
+ transientSpace.save();
+
+ assertFalse(transientSpace.nodeExists(ROOT.concat("source/node")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("source")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("target1")));
+ assertFalse(transientSpace.nodeExists(ROOT.concat("target1/moved1")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("target2/moved2")));
+ }
+
+ @Test
+ public void moveMovedThenDelete() throws RepositoryException {
+ NodeDelta root = transientSpace.getNode(ROOT);
+ root.addNode("source").addNode("node");
+ root.addNode("target1");
+ root.addNode("target2");
+ transientSpace.save();
+
+ NodeDelta sourceNode = transientSpace.getNode(ROOT.concat("source"));
+ sourceNode.moveNode("node", ROOT.concat("target1/moved1"));
+ NodeDelta target1 = root.getNode("target1");
+ target1.moveNode("moved1", ROOT.concat("target2/moved2"));
+ root.getNode("target2").removeNode("moved2");
+
+ assertFalse(transientSpace.nodeExists(ROOT.concat("source/node")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("source")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("target1")));
+ assertFalse(transientSpace.nodeExists(ROOT.concat("target1/moved1")));
+ assertFalse(transientSpace.nodeExists(ROOT.concat("target2/moved2")));
+ transientSpace.save();
+
+ assertFalse(transientSpace.nodeExists(ROOT.concat("source/node")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("source")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("target1")));
+ assertFalse(transientSpace.nodeExists(ROOT.concat("target1/moved1")));
+ assertFalse(transientSpace.nodeExists(ROOT.concat("target2/moved2")));
+ }
+
+ @Test
+ public void moveMovedThenDeleteTransient() throws RepositoryException {
+ NodeDelta root = transientSpace.getNode(ROOT);
+ root.addNode("source");
+ transientSpace.save();
+ root.getNode("source").addNode("node");
+ root.addNode("target1");
+ root.addNode("target2");
+
+ NodeDelta sourceNode = transientSpace.getNode(ROOT.concat("source"));
+ sourceNode.moveNode("node", ROOT.concat("target1/moved1"));
+ NodeDelta target1 = root.getNode("target1");
+ target1.moveNode("moved1", ROOT.concat("target2/moved2"));
+ root.getNode("target2").removeNode("moved2");
+
+ assertFalse(transientSpace.nodeExists(ROOT.concat("source/node")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("source")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("target1")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("target2")));
+ assertFalse(transientSpace.nodeExists(ROOT.concat("target1/moved1")));
+ assertFalse(transientSpace.nodeExists(ROOT.concat("target2/moved2")));
+ transientSpace.save();
+
+ assertFalse(transientSpace.nodeExists(ROOT.concat("source/node")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("source")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("target1")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("target2")));
+ assertFalse(transientSpace.nodeExists(ROOT.concat("target1/moved1")));
+ assertFalse(transientSpace.nodeExists(ROOT.concat("target2/moved2")));
+ }
+
+ @Test
+ public void moveForthAndBack() throws RepositoryException {
+ NodeDelta root = transientSpace.getNode(ROOT);
+ root.addNode("source").addNode("node");
+ root.addNode("target");
+ transientSpace.save();
+
+ NodeDelta sourceNode = transientSpace.getNode(ROOT.concat("source"));
+ sourceNode.moveNode("node", ROOT.concat("target/moved"));
+ NodeDelta target = root.getNode("target");
+ target.moveNode("moved", ROOT.concat("source/node"));
+
+ assertTrue(transientSpace.nodeExists(ROOT.concat("source/node")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("target")));
+ assertFalse(transientSpace.nodeExists(ROOT.concat("target/moved")));
+ transientSpace.save();
+
+ assertTrue(transientSpace.nodeExists(ROOT.concat("source/node")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("target")));
+ assertFalse(transientSpace.nodeExists(ROOT.concat("target/moved")));
+ }
+
+ @Test
+ public void moveForthAndBackTransient() throws RepositoryException {
+ NodeDelta root = transientSpace.getNode(ROOT);
+ root.addNode("source");
+ root.getNode("source").addNode("node");
+ transientSpace.save();
+ root.addNode("target");
+
+ NodeDelta sourceNode = transientSpace.getNode(ROOT.concat("source"));
+ sourceNode.moveNode("node", ROOT.concat("target/moved"));
+ NodeDelta target = root.getNode("target");
+ target.moveNode("moved", ROOT.concat("source/node"));
+
+ assertTrue(transientSpace.nodeExists(ROOT.concat("source/node")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("target")));
+ assertFalse(transientSpace.nodeExists(ROOT.concat("target/moved")));
+ transientSpace.save();
+
+ assertTrue(transientSpace.nodeExists(ROOT.concat("source/node")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("target")));
+ assertFalse(transientSpace.nodeExists(ROOT.concat("target/moved")));
+ }
+
+ @Test
+ public void moveFromTransient() throws RepositoryException {
+ NodeDelta root = transientSpace.getNode(ROOT);
+ root.addNode("target");
+ transientSpace.save();
+
+ root.addNode("source1").addNode("node");
+ NodeDelta sourceNode = transientSpace.getNode(ROOT.concat("source1"));
+ sourceNode.moveNode("node", ROOT.concat("target/moved"));
+
+ assertFalse(transientSpace.nodeExists(ROOT.concat("source/node")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("target")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("target/moved")));
+ transientSpace.save();
+
+ assertFalse(transientSpace.nodeExists(ROOT.concat("source/node")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("target")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("target/moved")));
+ }
+
+ @Test
+ public void moveIntoMove() throws RepositoryException {
+ NodeDelta root = transientSpace.getNode(ROOT);
+ root.addNode("source").addNode("node1").addNode("child");
+ root.getNode("source").addNode("node2");
+ root.addNode("target");
+ transientSpace.save();
+
+ root.getNode("source").moveNode("node1", ROOT.concat("target/moved1"));
+ root.getNode("source").moveNode("node2", ROOT.concat("target/moved1/child/moved2"));
+
+ assertFalse(transientSpace.nodeExists(ROOT.concat("source/node1")));
+ assertFalse(transientSpace.nodeExists(ROOT.concat("source/node2")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("target/moved1/child/moved2")));
+
+ transientSpace.save();
+
+ assertFalse(transientSpace.nodeExists(ROOT.concat("source/node1")));
+ assertFalse(transientSpace.nodeExists(ROOT.concat("source/node2")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("target/moved1/child/moved2")));
+ }
+
+ @Test
+ public void moveIntoMoveTransient() throws RepositoryException {
+ NodeDelta root = transientSpace.getNode(ROOT);
+ root.addNode("source").addNode("node1").addNode("child");
+ root.getNode("source").addNode("node2");
+ root.addNode("target");
+
+ root.getNode("source").moveNode("node1", ROOT.concat("target/moved1"));
+ root.getNode("source").moveNode("node2", ROOT.concat("target/moved1/child/moved2"));
+
+ assertFalse(transientSpace.nodeExists(ROOT.concat("source/node1")));
+ assertFalse(transientSpace.nodeExists(ROOT.concat("source/node2")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("target/moved1/child/moved2")));
+
+ transientSpace.save();
+
+ assertFalse(transientSpace.nodeExists(ROOT.concat("source/node1")));
+ assertFalse(transientSpace.nodeExists(ROOT.concat("source/node2")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("target/moved1/child/moved2")));
+ }
+
+ @Test
+ public void moveOutOfMove() throws RepositoryException {
+ NodeDelta root = transientSpace.getNode(ROOT);
+ root.addNode("source").addNode("node1").addNode("child");
+ root.addNode("target1");
+ root.addNode("target2");
+ transientSpace.save();
+
+ root.getNode("source").moveNode("node1", ROOT.concat("target1/moved1"));
+ root.getNode("target1").getNode("moved1").moveNode("child", ROOT.concat("target2/moved2"));
+
+ assertFalse(transientSpace.nodeExists(ROOT.concat("source/node1")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("target1/moved1")));
+ assertFalse(transientSpace.nodeExists(ROOT.concat("target1/moved1/child")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("target2/moved2")));
+
+ transientSpace.save();
+
+ assertFalse(transientSpace.nodeExists(ROOT.concat("source/node1")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("target1/moved1")));
+ assertFalse(transientSpace.nodeExists(ROOT.concat("target1/moved1/child")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("target2/moved2")));
+ }
+
+ @Test
+ public void moveOutOfMoveTransient() throws RepositoryException {
+ NodeDelta root = transientSpace.getNode(ROOT);
+ root.addNode("source").addNode("node1").addNode("child");
+ root.addNode("target1");
+ root.addNode("target2");
+
+ root.getNode("source").moveNode("node1", ROOT.concat("target1/moved1"));
+ root.getNode("target1").getNode("moved1").moveNode("child", ROOT.concat("target2/moved2"));
+
+ assertFalse(transientSpace.nodeExists(ROOT.concat("source/node1")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("target1/moved1")));
+ assertFalse(transientSpace.nodeExists(ROOT.concat("target1/moved1/child")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("target2/moved2")));
+
+ transientSpace.save();
+
+ assertFalse(transientSpace.nodeExists(ROOT.concat("source/node1")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("target1/moved1")));
+ assertFalse(transientSpace.nodeExists(ROOT.concat("target1/moved1/child")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("target2/moved2")));
+ }
+
+ @Test
+ public void moveMovedParent() throws RepositoryException {
+ NodeDelta root = transientSpace.getNode(ROOT);
+ root.addNode("source").addNode("node");
+ root.addNode("target1");
+ root.addNode("target2");
+ transientSpace.save();
+
+ root.getNode("source").moveNode("node", ROOT.concat("target1/moved"));
+ root.moveNode("target1", ROOT.concat("target2/moved-target1"));
+
+ assertTrue(transientSpace.nodeExists(ROOT.concat("source")));
+ assertFalse(transientSpace.nodeExists(ROOT.concat("source/node")));
+ assertFalse(transientSpace.nodeExists(ROOT.concat("target1")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("target2/moved-target1/moved")));
+
+ transientSpace.save();
+
+ assertTrue(transientSpace.nodeExists(ROOT.concat("source")));
+ assertFalse(transientSpace.nodeExists(ROOT.concat("source/node")));
+ assertFalse(transientSpace.nodeExists(ROOT.concat("target1")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("target2/moved-target1/moved")));
+ }
+
+ @Test
+ public void moveMovedParentTransient() throws RepositoryException {
+ NodeDelta root = transientSpace.getNode(ROOT);
+ root.addNode("source").addNode("node");
+ root.addNode("target1");
+ root.addNode("target2");
+
+ root.getNode("source").moveNode("node", ROOT.concat("target1/moved"));
+ root.moveNode("target1", ROOT.concat("target2/moved-target1"));
+
+ assertTrue(transientSpace.nodeExists(ROOT.concat("source")));
+ assertFalse(transientSpace.nodeExists(ROOT.concat("source/node")));
+ assertFalse(transientSpace.nodeExists(ROOT.concat("target1")));
+ assertTrue(transientSpace.nodeExists(ROOT.concat("target2/moved-target1/moved")));
+
+ transientSpace.save();
+
+ assertTrue(transientSpace.nodeExists(ROOT.concat("source")));
+ assertFalse(transientSpace.nodeExists(ROOT.concat("source/node")));
+ assertFalse(transientSpace.nodeExists(ROOT.concat("target1")));
+ }
+
+ @Test
+ public void setPropertyTest() throws RepositoryException {
+ // Set property
+ NodeDelta root = transientSpace.getNode(ROOT);
+ root.setValue("prop", JsonAtom.number(42));
+ transientSpace.save();
+ assertThat(mk, propertyHasValue(ROOT.concat("prop"), 42));
+
+ // Remove property
+ root.setValue("prop", null);
+ transientSpace.save();
+ assertThat(mk, CoreMatchers.not(propertyExists(ROOT.concat("prop"))));
+
+ // Transiently remove property
+ root.setValue("prop", JsonAtom.number(42));
+ root.setValue("prop", null);
+ transientSpace.save();
+ assertThat(mk, CoreMatchers.not(propertyExists(ROOT.concat("prop"))));
+
+ // Set property on transiently added parent
+ root.addNode("node1").addNode("node2").setValue("prop", JsonAtom.string("value"));
+ transientSpace.save();
+ assertThat(mk, propertyHasValue(ROOT.concat("node1/node2/prop"), "value"));
+
+ // Set property and move parent
+ root.addNode("source").addNode("node").setValue("prop1", JsonAtom.number(42));
+ root.getNode("source").getNode("node").setValue("prop2", JsonAtom.number(43));
+ root.addNode("target");
+ transientSpace.save();
+ assertThat(mk, propertyHasValue(ROOT.concat("source/node/prop1"), 42));
+ assertThat(mk, propertyHasValue(ROOT.concat("source/node/prop2"), 43));
+
+ root.getNode("source").moveNode("node", ROOT.concat("target/moved"));
+ root.getNode("target").getNode("moved").setValue("prop2", null);
+ transientSpace.save();
+ assertThat(mk, CoreMatchers.not(propertyExists(ROOT.concat("source/node/prop1"))));
+ assertThat(mk, propertyHasValue(ROOT.concat("target/moved/prop1"), 42));
+ assertThat(mk, CoreMatchers.not(propertyExists(ROOT.concat("source/node/prop2"))));
+ assertThat(mk, CoreMatchers.not(propertyExists(ROOT.concat("target/moved/prop2"))));
+ }
+
+ public static class MicrokernelMatcher {
+ private MicrokernelMatcher() { }
+
+ public static Matcher<MicroKernel> propertyHasValue(final Path path, final int value) {
+ return new TypeSafeMatcher<MicroKernel>() {
+
+ @Override
+ public boolean matchesSafely(MicroKernel mk) {
+ JsonObject node = parseJson(mk.getNodes(path.getParent().getMkPath(), mk.getHeadRevision()));
+ JsonValue prop = node.get(path.getName());
+ return prop != null && prop.type() == Type.NUMBER
+ && Integer.parseInt(prop.asAtom().value()) == value;
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText(path + " = ").appendValue(value);
+ }
+ };
+ }
+
+ public static Matcher<MicroKernel> propertyHasValue(final Path path, final String value) {
+ return new TypeSafeMatcher<MicroKernel>() {
+
+ @Override
+ public boolean matchesSafely(MicroKernel mk) {
+ JsonObject node = parseJson(mk.getNodes(path.getParent().getMkPath(), mk.getHeadRevision()));
+ JsonValue prop = node.get(path.getName());
+ return prop != null && prop.type() == Type.STRING
+ && prop.asAtom().value().equals(value);
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText(path + " = ").appendValue(value);
+ }
+ };
+ }
+
+ public static Matcher<MicroKernel> propertyExists(final Path path) {
+ return new TypeSafeMatcher<MicroKernel>() {
+
+ @Override
+ public boolean matchesSafely(MicroKernel mk) {
+ try {
+ JsonObject node = parseJson(mk.getNodes(path.getParent().getMkPath(), mk.getHeadRevision()));
+ JsonValue prop = node.get(path.getName());
+ return prop != null;
+ }
+ catch (MicroKernelException e) {
+ if (e.getCause() instanceof NotFoundException) {
+ return false;
+ }
+ else {
+ throw e;
+ }
+ }
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("Property exists").appendValue(path);
+ }
+ };
+ }
+
+ //------------------------------------------< private >---
+
+ private static JsonObject parseJson(String json) {
+ return FullJsonParser.parseObject(new UnescapingJsonTokenizer(json));
+ }
+ }
+
+}