Package org.modeshape.jcr.query.plan

Source Code of org.modeshape.jcr.query.plan.PlanNodeTest

/*
* ModeShape (http://www.modeshape.org)
*
* Licensed 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 org.modeshape.jcr.query.plan;

import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsNull.nullValue;
import static org.hamcrest.core.IsSame.sameInstance;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.modeshape.jcr.query.model.SelectorName;
import org.modeshape.jcr.query.plan.PlanNode.Traversal;
import org.modeshape.jcr.query.plan.PlanNode.Type;

/**
*
*/
public class PlanNodeTest {

    private PlanNode node;
    private PlanNode parent;

    @Before
    public void beforeEach() {
        node = new PlanNode(Type.GROUP);
    }

    @After
    public void afterEach() {
        this.node = null;
        this.parent = null;
    }

    @Test
    public void shouldFindTypeGivenSymbolWithSameCase() {
        for (Type type : Type.values()) {
            assertThat(Type.forSymbol(type.getSymbol()), is(sameInstance(type)));
        }
    }

    @Test
    public void shouldFindTypeGivenSymbolWithLowerCase() {
        for (Type type : Type.values()) {
            assertThat(Type.forSymbol(type.getSymbol().toLowerCase()), is(sameInstance(type)));
        }
    }

    @Test
    public void shouldFindTypeGivenSymbolWithUpperCase() {
        for (Type type : Type.values()) {
            assertThat(Type.forSymbol(type.getSymbol().toUpperCase()), is(sameInstance(type)));
        }
    }

    @Test
    public void shouldFindTypeGivenSymbolWithLeadingAndTrailingWhitespace() {
        for (Type type : Type.values()) {
            assertThat(Type.forSymbol(" \t " + type.getSymbol() + " \t \n"), is(sameInstance(type)));
        }
    }

    @Test
    public void shouldCreatePlanNodeWithTypeAndNoParent() {
        for (Type type : Type.values()) {
            node = new PlanNode(type);
            assertThat(node.getType(), is(type));
            assertThat(node.getParent(), is(nullValue()));
        }
    }

    @Test
    public void shouldCreatePlanNodeWithTypeAndParent() {
        for (Type type : Type.values()) {
            parent = new PlanNode(Type.JOIN);
            node = new PlanNode(type, parent);
            assertThat(node.getType(), is(type));
            assertThat(node.getParent(), is(sameInstance(parent)));
            assertThat(parent.getFirstChild(), is(sameInstance(node)));
            assertThat(parent.getChildCount(), is(1));
        }
    }

    @Test
    public void shouldAddNodeToParentWhenConstructingChildNodeWithTypeAndParent() {
        parent = new PlanNode(Type.JOIN);
        int counter = 0;
        for (Type type : Type.values()) {
            node = new PlanNode(type, parent);
            ++counter;
            assertThat(node.getType(), is(type));
            assertThat(node.getParent(), is(sameInstance(parent)));
            assertThat(parent.getLastChild(), is(sameInstance(node)));
            assertThat(parent.getChildCount(), is(counter));
        }
    }

    @Test
    public void shouldSetType() {
        node = new PlanNode(Type.JOIN);
        for (Type type : Type.values()) {
            node.setType(type);
            assertThat(node.getType(), is(type));
        }
    }

    @Test
    public void shouldGetFirstChildAndLastChildWithOneChild() {
        parent = new PlanNode(Type.JOIN);
        node = new PlanNode(Type.ACCESS, parent);
        assertThat(parent.getFirstChild(), is(sameInstance(node)));
        assertThat(parent.getLastChild(), is(sameInstance(node)));
    }

    @Test
    public void shouldGetFirstChildAndLastChildWithTwoChildren() {
        parent = new PlanNode(Type.JOIN);
        PlanNode child1 = new PlanNode(Type.ACCESS, parent);
        PlanNode child2 = new PlanNode(Type.ACCESS, parent);
        assertThat(parent.getFirstChild(), is(sameInstance(child1)));
        assertThat(parent.getLastChild(), is(sameInstance(child2)));
    }

    @Test
    public void shouldGetFirstChildAndLastChildWithMoreThanTwoChildren() {
        parent = new PlanNode(Type.JOIN);
        PlanNode child1 = new PlanNode(Type.ACCESS, parent);
        new PlanNode(Type.ACCESS, parent);
        PlanNode child3 = new PlanNode(Type.ACCESS, parent);
        assertThat(parent.getFirstChild(), is(sameInstance(child1)));
        assertThat(parent.getLastChild(), is(sameInstance(child3)));
    }

    @Test
    public void shouldGetFirstChildAndLastChildWithNoChildren() {
        parent = new PlanNode(Type.JOIN);
        assertThat(parent.getFirstChild(), is(nullValue()));
        assertThat(parent.getLastChild(), is(nullValue()));
    }

    @Test
    public void shouldRemoveNodeFromExistingParentWhenSettingParentToNull() {
        parent = new PlanNode(Type.JOIN);
        node = new PlanNode(Type.ACCESS, parent);
        assertThat(parent.getFirstChild(), is(sameInstance(node)));
        assertThat(parent.getChildCount(), is(1));
        node.setParent(null);
        assertThat(parent.getChildCount(), is(0));
        assertThat(node.getParent(), is(nullValue()));
    }

    @Test
    public void shouldInsertNewParentNodeInBetweenExistingParentAndChild() {
        parent = new PlanNode(Type.JOIN);
        PlanNode child1 = new PlanNode(Type.ACCESS, parent);
        PlanNode child2 = new PlanNode(Type.DUP_REMOVE, parent);
        PlanNode child3 = new PlanNode(Type.GROUP, parent);
        assertThat(parent.getFirstChild(), is(sameInstance(child1)));
        assertThat(parent.getChild(1), is(sameInstance(child2)));
        assertThat(parent.getLastChild(), is(sameInstance(child3)));
        assertThat(parent.getChildCount(), is(3));
        node = new PlanNode(Type.GROUP);
        child2.insertAsParent(node);
        assertThat(parent.getChildCount(), is(3));
        assertThat(parent.getFirstChild(), is(sameInstance(child1)));
        assertThat(parent.getChild(1), is(sameInstance(node)));
        assertThat(parent.getLastChild(), is(sameInstance(child3)));
        assertThat(node.getParent(), is(sameInstance(parent)));
        assertThat(child2.getParent(), is(sameInstance(node)));
    }

    @Test
    public void shouldInsertNewParentNodeInAboveNodeWithoutParent() {
        PlanNode child1 = new PlanNode(Type.ACCESS);
        node = new PlanNode(Type.GROUP);
        PlanNode nodeChild = new PlanNode(Type.JOIN, node);
        // Perform the insertAsParent ...
        child1.insertAsParent(node);
        assertThat(node.getParent(), is(nullValue()));
        assertThat(node.getChildCount(), is(2));
        assertThat(node.getFirstChild(), is(sameInstance(nodeChild)));
        assertThat(node.getLastChild(), is(sameInstance(child1)));
        assertThat(child1.getParent(), is(sameInstance(node)));
    }

    @Test
    public void shouldRemoveFromParentWhenThereIsAParent() {
        parent = new PlanNode(Type.JOIN);
        PlanNode child1 = new PlanNode(Type.ACCESS, parent);
        PlanNode child2 = new PlanNode(Type.DUP_REMOVE, parent);
        PlanNode child3 = new PlanNode(Type.GROUP, parent);
        PlanNode grandChild21 = new PlanNode(Type.LIMIT, child2);
        assertThat(parent.getFirstChild(), is(sameInstance(child1)));
        assertThat(parent.getChild(1), is(sameInstance(child2)));
        assertThat(parent.getLastChild(), is(sameInstance(child3)));
        assertThat(parent.getChildCount(), is(3));
        assertThat(child2.getFirstChild(), is(sameInstance(grandChild21)));
        // Perform the removeFromParent ...
        assertThat(child2.removeFromParent(), is(sameInstance(parent)));
        assertThat(parent.getFirstChild(), is(sameInstance(child1)));
        assertThat(parent.getLastChild(), is(sameInstance(child3)));
        assertThat(parent.getChildCount(), is(2));
        // There should still be the child in the removed node ...
        assertThat(child2.getFirstChild(), is(sameInstance(grandChild21)));
    }

    @Test
    public void shouldRemoveFromParentWhenThereIsNoParent() {
        node = new PlanNode(Type.JOIN);
        PlanNode child1 = new PlanNode(Type.ACCESS, node);
        assertThat(node.getFirstChild(), is(sameInstance(child1)));
        assertThat(node.getChildCount(), is(1));
        // Perform the removeFromParent ...
        assertThat(node.removeFromParent(), is(nullValue()));
        assertThat(node.getFirstChild(), is(sameInstance(child1)));
        assertThat(node.getChildCount(), is(1));
    }

    @Test
    public void shouldReturnListOfChildren() {
        parent = new PlanNode(Type.JOIN);
        PlanNode child1 = new PlanNode(Type.ACCESS, parent);
        PlanNode child2 = new PlanNode(Type.DUP_REMOVE, parent);
        PlanNode child3 = new PlanNode(Type.GROUP, parent);
        List<PlanNode> children = parent.getChildren();
        assertThat(children.get(0), is(sameInstance(child1)));
        assertThat(children.get(1), is(sameInstance(child2)));
        assertThat(children.get(2), is(sameInstance(child3)));
        assertThat(children.size(), is(3));
    }

    @Test( expected = UnsupportedOperationException.class )
    public void shouldReturnImmutableListOfChildren() {
        parent = new PlanNode(Type.JOIN);
        new PlanNode(Type.ACCESS, parent);
        new PlanNode(Type.DUP_REMOVE, parent);
        new PlanNode(Type.GROUP, parent);
        parent.getChildren().clear();
    }

    @Test
    public void shouldReturnIteratorOfChildren() {
        parent = new PlanNode(Type.JOIN);
        PlanNode child1 = new PlanNode(Type.ACCESS, parent);
        PlanNode child2 = new PlanNode(Type.DUP_REMOVE, parent);
        PlanNode child3 = new PlanNode(Type.GROUP, parent);
        Iterator<PlanNode> children = parent.iterator();
        assertThat(children.next(), is(sameInstance(child1)));
        assertThat(children.next(), is(sameInstance(child2)));
        assertThat(children.next(), is(sameInstance(child3)));
        assertThat(children.hasNext(), is(false));
    }

    @Test( expected = UnsupportedOperationException.class )
    public void shouldReturnImmutableIteratorOfChildren() {
        parent = new PlanNode(Type.JOIN);
        new PlanNode(Type.ACCESS, parent);
        new PlanNode(Type.DUP_REMOVE, parent);
        new PlanNode(Type.GROUP, parent);
        Iterator<PlanNode> iter = parent.iterator();
        iter.next();
        iter.remove();
    }

    @Test
    public void shouldRemoveAllChildrenOfParentWithNoChildrenByReturningEmptyList() {
        parent = new PlanNode(Type.JOIN);
        // Perform the remove, and verify the list has all the children ...
        List<PlanNode> children = parent.removeAllChildren();
        assertThat(children.size(), is(0));
        assertThat(parent.getChildCount(), is(0));
        // Add a new child to the parent ...
        PlanNode child1a = new PlanNode(Type.ACCESS, parent);
        assertThat(parent.getFirstChild(), is(sameInstance(child1a)));
        // The returned copy should not be modified ...
        assertThat(children.size(), is(0));
    }

    @Test
    public void shouldRemoveAllChildrenAndReturnCopyOfListOfChildren() {
        parent = new PlanNode(Type.JOIN);
        PlanNode child1 = new PlanNode(Type.ACCESS, parent);
        PlanNode child2 = new PlanNode(Type.DUP_REMOVE, parent);
        PlanNode child3 = new PlanNode(Type.GROUP, parent);
        // Perform the remove, and verify the list has all the children ...
        List<PlanNode> children = parent.removeAllChildren();
        assertThat(children.get(0), is(sameInstance(child1)));
        assertThat(children.get(1), is(sameInstance(child2)));
        assertThat(children.get(2), is(sameInstance(child3)));
        assertThat(children.size(), is(3));
        assertThat(parent.getChildCount(), is(0));
        // Add a new child to the parent ...
        PlanNode child1a = new PlanNode(Type.ACCESS, parent);
        assertThat(parent.getFirstChild(), is(sameInstance(child1a)));
        // The returned copy should not be modified ...
        assertThat(children.get(0), is(sameInstance(child1)));
        assertThat(children.get(1), is(sameInstance(child2)));
        assertThat(children.get(2), is(sameInstance(child3)));
        assertThat(children.size(), is(3));
    }

    @Test
    public void shouldReturnCorrectChildCount() {
        parent = new PlanNode(Type.JOIN);
        assertThat(parent.getChildCount(), is(0));
        for (int i = 0; i != 10; ++i) {
            new PlanNode(Type.ACCESS, parent);
            assertThat(parent.getChildCount(), is(i + 1));
        }
    }

    @Test
    public void shouldAddChildrenAtEnd() {
        parent = new PlanNode(Type.JOIN);
        List<PlanNode> children = new ArrayList<PlanNode>();
        children.add(new PlanNode(Type.ACCESS, parent));
        children.add(new PlanNode(Type.GROUP, parent));
        children.add(new PlanNode(Type.NULL, parent));
        parent.addChildren(children);
        int index = 0;
        for (PlanNode child : children) {
            assertThat(parent.getChild(index++), is(sameInstance(child)));
        }
    }

    @Test
    public void shouldRemoveChild() {
        parent = new PlanNode(Type.JOIN);
        PlanNode child1 = new PlanNode(Type.ACCESS, parent);
        PlanNode child2 = new PlanNode(Type.DUP_REMOVE, parent);
        PlanNode child3 = new PlanNode(Type.GROUP, parent);
        assertThat(parent.getChild(0), is(sameInstance(child1)));
        assertThat(parent.getChild(1), is(sameInstance(child2)));
        assertThat(parent.getChild(2), is(sameInstance(child3)));
        // Perform the remove, and verify children have changed ...
        assertThat(parent.removeChild(child2), is(true));
        assertThat(parent.getChild(0), is(sameInstance(child1)));
        assertThat(parent.getChild(1), is(sameInstance(child3)));
    }

    @Test
    public void shouldNotRemoveChildIfNotReallyAChild() {
        node = new PlanNode(Type.PROJECT);
        parent = new PlanNode(Type.JOIN);
        PlanNode child1 = new PlanNode(Type.ACCESS, parent);
        PlanNode child2 = new PlanNode(Type.DUP_REMOVE, parent);
        PlanNode child3 = new PlanNode(Type.GROUP, parent);
        assertThat(parent.getChild(0), is(sameInstance(child1)));
        assertThat(parent.getChild(1), is(sameInstance(child2)));
        assertThat(parent.getChild(2), is(sameInstance(child3)));
        // Try to remove the non-child, and verify the children have no changed ...
        assertThat(parent.removeChild(node), is(false));
        assertThat(parent.getChild(0), is(sameInstance(child1)));
        assertThat(parent.getChild(1), is(sameInstance(child2)));
        assertThat(parent.getChild(2), is(sameInstance(child3)));
    }

    @Test
    public void shouldNotRemoveChildIfReferenceIsNull() {
        parent = new PlanNode(Type.JOIN);
        PlanNode child1 = new PlanNode(Type.ACCESS, parent);
        PlanNode child2 = new PlanNode(Type.DUP_REMOVE, parent);
        PlanNode child3 = new PlanNode(Type.GROUP, parent);
        assertThat(parent.getChild(0), is(sameInstance(child1)));
        assertThat(parent.getChild(1), is(sameInstance(child2)));
        assertThat(parent.getChild(2), is(sameInstance(child3)));
        // Try to remove the non-child, and verify the children have no changed ...
        assertThat(parent.removeChild(null), is(false));
        assertThat(parent.getChild(0), is(sameInstance(child1)));
        assertThat(parent.getChild(1), is(sameInstance(child2)));
        assertThat(parent.getChild(2), is(sameInstance(child3)));
    }

    @Test
    public void shouldExtractChildByRemovingIfChildHasNoChildren() {
        parent = new PlanNode(Type.JOIN);
        PlanNode child1 = new PlanNode(Type.ACCESS, parent);
        PlanNode child2 = new PlanNode(Type.DUP_REMOVE, parent);
        PlanNode child3 = new PlanNode(Type.GROUP, parent);
        assertThat(parent.getChild(0), is(sameInstance(child1)));
        assertThat(parent.getChild(1), is(sameInstance(child2)));
        assertThat(parent.getChild(2), is(sameInstance(child3)));
        // Perform the extraction ...
        parent.extractChild(child2);
        assertThat(parent.getChild(0), is(sameInstance(child1)));
        assertThat(parent.getChild(1), is(sameInstance(child3)));
        assertThat(parent.getChildCount(), is(2));
    }

    @Test
    public void shouldExtractChildByReplacingWithFirstGrandchild() {
        parent = new PlanNode(Type.JOIN);
        PlanNode child1 = new PlanNode(Type.ACCESS, parent);
        PlanNode child2 = new PlanNode(Type.DUP_REMOVE, parent);
        PlanNode child3 = new PlanNode(Type.GROUP, parent);
        PlanNode grandChild1 = new PlanNode(Type.SELECT, child2);
        PlanNode grandChild2 = new PlanNode(Type.SET_OPERATION, child2);
        assertThat(parent.getChild(0), is(sameInstance(child1)));
        assertThat(parent.getChild(1), is(sameInstance(child2)));
        assertThat(parent.getChild(2), is(sameInstance(child3)));
        // Perform the extraction ...
        parent.extractChild(child2);
        assertThat(parent.getChild(0), is(sameInstance(child1)));
        assertThat(parent.getChild(1), is(sameInstance(grandChild1)));
        assertThat(parent.getChild(2), is(sameInstance(child3)));
        assertThat(parent.getChildCount(), is(3));
        // The old child should still contain just the remaining child(ren) ...
        assertThat(child2.getFirstChild(), is(sameInstance(grandChild2)));
        assertThat(child2.getParent(), is(nullValue()));
    }

    @Test
    public void shouldReplaceChild() {
        PlanNode parentOfReplacement = new PlanNode(Type.SORT);
        PlanNode replacement = new PlanNode(Type.SELECT, parentOfReplacement);
        parent = new PlanNode(Type.JOIN);
        PlanNode child1 = new PlanNode(Type.ACCESS, parent);
        PlanNode child2 = new PlanNode(Type.DUP_REMOVE, parent);
        PlanNode child3 = new PlanNode(Type.GROUP, parent);
        assertThat(parent.getChild(0), is(sameInstance(child1)));
        assertThat(parent.getChild(1), is(sameInstance(child2)));
        assertThat(parent.getChild(2), is(sameInstance(child3)));
        // Perform the replacement ...
        assertThat(parent.replaceChild(child2, replacement), is(true));
        assertThat(parent.getChild(0), is(sameInstance(child1)));
        assertThat(parent.getChild(1), is(sameInstance(replacement)));
        assertThat(parent.getChild(2), is(sameInstance(child3)));
        assertThat(replacement.getParent(), is(sameInstance(parent)));
        assertThat(child1.getParent(), is(sameInstance(parent)));
        assertThat(child2.getParent(), is(nullValue()));
        assertThat(child3.getParent(), is(sameInstance(parent)));
        // The replacement should no longer be a child of its former parent ...
        assertThat(parentOfReplacement.getChildCount(), is(0));
    }

    @Test
    public void shouldReplaceChildWithAnotherChildToSwapPositions() {
        parent = new PlanNode(Type.JOIN);
        PlanNode child1 = new PlanNode(Type.ACCESS, parent);
        PlanNode child2 = new PlanNode(Type.DUP_REMOVE, parent);
        PlanNode child3 = new PlanNode(Type.GROUP, parent);
        assertThat(parent.getChild(0), is(sameInstance(child1)));
        assertThat(parent.getChild(1), is(sameInstance(child2)));
        assertThat(parent.getChild(2), is(sameInstance(child3)));
        // Perform the replacement ...
        assertThat(parent.replaceChild(child2, child3), is(true));
        assertThat(parent.getChild(0), is(sameInstance(child1)));
        assertThat(parent.getChild(1), is(sameInstance(child3)));
        assertThat(parent.getChild(2), is(sameInstance(child2)));
        assertThat(child1.getParent(), is(sameInstance(parent)));
        assertThat(child2.getParent(), is(sameInstance(parent)));
        assertThat(child3.getParent(), is(sameInstance(parent)));
    }

    @Test
    public void shouldNotReplaceChildIfChildNodeIsNotReallyAChild() {
        PlanNode nonChild = new PlanNode(Type.PROJECT);
        PlanNode replacement = new PlanNode(Type.SELECT);
        parent = new PlanNode(Type.JOIN);
        PlanNode child1 = new PlanNode(Type.ACCESS, parent);
        PlanNode child2 = new PlanNode(Type.DUP_REMOVE, parent);
        PlanNode child3 = new PlanNode(Type.GROUP, parent);
        assertThat(parent.getChild(0), is(sameInstance(child1)));
        assertThat(parent.getChild(1), is(sameInstance(child2)));
        assertThat(parent.getChild(2), is(sameInstance(child3)));
        assertThat(parent.replaceChild(nonChild, replacement), is(false));
    }

    @Test
    public void shouldGetPathThatIncludesStartAndEndNodes() {
        PlanNode root = new PlanNode(Type.JOIN);
        PlanNode node1 = new PlanNode(Type.ACCESS, root);
        PlanNode node2 = new PlanNode(Type.DUP_REMOVE, node1);
        PlanNode node3 = new PlanNode(Type.GROUP, node2);
        PlanNode node4 = new PlanNode(Type.SELECT, node3);
        PlanNode node5 = new PlanNode(Type.SET_OPERATION, node4);
        assertThat(root.getPathTo(root), is(path(root)));
        assertThat(root.getPathTo(node1), is(path(root, node1)));
        assertThat(root.getPathTo(node2), is(path(root, node1, node2)));
        assertThat(root.getPathTo(node3), is(path(root, node1, node2, node3)));
        assertThat(root.getPathTo(node4), is(path(root, node1, node2, node3, node4)));
        assertThat(root.getPathTo(node5), is(path(root, node1, node2, node3, node4, node5)));

        assertThat(node1.getPathTo(node1), is(path(node1)));
        assertThat(node1.getPathTo(node2), is(path(node1, node2)));
        assertThat(node1.getPathTo(node3), is(path(node1, node2, node3)));
        assertThat(node1.getPathTo(node4), is(path(node1, node2, node3, node4)));
        assertThat(node1.getPathTo(node5), is(path(node1, node2, node3, node4, node5)));

        assertThat(node2.getPathTo(node2), is(path(node2)));
        assertThat(node2.getPathTo(node3), is(path(node2, node3)));
        assertThat(node2.getPathTo(node4), is(path(node2, node3, node4)));
        assertThat(node2.getPathTo(node5), is(path(node2, node3, node4, node5)));
    }

    protected LinkedList<PlanNode> path( PlanNode... expectedNodes ) {
        LinkedList<PlanNode> result = new LinkedList<PlanNode>();
        for (PlanNode node : expectedNodes) {
            result.add(node);
        }
        return result;
    }

    @Test
    public void shouldNotAddNullSelectorNames() {
        Collection<SelectorName> names = Collections.singletonList(null);
        node.addSelectors(names);
        assertThat(node.getSelectors().isEmpty(), is(true));
        node.addSelector(null);
        assertThat(node.getSelectors().isEmpty(), is(true));
        SelectorName name = new SelectorName("something");
        node.addSelector(name, null);
        assertThat(node.getSelectors().size(), is(1));
        assertThat(node.getSelectors().contains(name), is(true));
    }

    @Test
    public void shouldCorrectlyDetermineIfAncestorHasType() {
        PlanNode root = new PlanNode(Type.JOIN);
        PlanNode node1 = new PlanNode(Type.ACCESS, root);
        PlanNode node2 = new PlanNode(Type.DUP_REMOVE, node1);
        PlanNode node3 = new PlanNode(Type.GROUP, node2);
        PlanNode node4 = new PlanNode(Type.SELECT, node3);
        PlanNode node5 = new PlanNode(Type.SET_OPERATION, node4);
        assertThat(node5.hasAncestorOfType(Type.SET_OPERATION), is(false)); // no ancestor, just self
        assertThat(node5.hasAncestorOfType(Type.SOURCE), is(false));
        assertThat(node5.hasAncestorOfType(Type.DUP_REMOVE), is(true));
        assertThat(node5.hasAncestorOfType(Type.DUP_REMOVE, Type.SELECT), is(true));
        assertThat(node5.hasAncestorOfType(Type.DUP_REMOVE, Type.SELECT, Type.SOURCE), is(true));
    }

    @Test
    public void shouldFindAllNodesInSubtreeUsingPreorder() {
        PlanNode root = new PlanNode(Type.SELECT);
        PlanNode node1 = new PlanNode(Type.JOIN, root);
        PlanNode node11 = new PlanNode(Type.ACCESS, node1);
        PlanNode node12 = new PlanNode(Type.DUP_REMOVE, node11);
        PlanNode node21 = new PlanNode(Type.ACCESS, node1);
        PlanNode node22 = new PlanNode(Type.DUP_REMOVE, node21);
        List<PlanNode> nodes = root.findAllAtOrBelow(Traversal.PRE_ORDER);
        assertThat(nodes.remove(0), is(sameInstance(root)));
        assertThat(nodes.remove(0), is(sameInstance(node1)));
        assertThat(nodes.remove(0), is(sameInstance(node11)));
        assertThat(nodes.remove(0), is(sameInstance(node12)));
        assertThat(nodes.remove(0), is(sameInstance(node21)));
        assertThat(nodes.remove(0), is(sameInstance(node22)));
        assertTrue(nodes.isEmpty());
    }

    @Test
    public void shouldFindAllNodesInSubtreeUsingPostorder() {
        PlanNode root = new PlanNode(Type.SELECT);
        PlanNode node1 = new PlanNode(Type.JOIN, root);
        PlanNode node11 = new PlanNode(Type.ACCESS, node1);
        PlanNode node111 = new PlanNode(Type.DUP_REMOVE, node11);
        PlanNode node21 = new PlanNode(Type.ACCESS, node1);
        PlanNode node211 = new PlanNode(Type.DUP_REMOVE, node21);
        List<PlanNode> nodes = root.findAllAtOrBelow(Traversal.POST_ORDER);
        assertThat(nodes.remove(0), is(sameInstance(node211)));
        assertThat(nodes.remove(0), is(sameInstance(node21)));
        assertThat(nodes.remove(0), is(sameInstance(node111)));
        assertThat(nodes.remove(0), is(sameInstance(node11)));
        assertThat(nodes.remove(0), is(sameInstance(node1)));
        assertThat(nodes.remove(0), is(sameInstance(root)));
        assertTrue(nodes.isEmpty());
    }
}
TOP

Related Classes of org.modeshape.jcr.query.plan.PlanNodeTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.