Package org.neo4j.kernel.impl.traversal

Source Code of org.neo4j.kernel.impl.traversal.TestTraversal

/**
* Copyright (c) 2002-2011 "Neo Technology,"
* Network Engine for Objects in Lund AB [http://neotechnology.com]
*
* This file is part of Neo4j.
*
* Neo4j is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.neo4j.kernel.impl.traversal;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.neo4j.graphdb.Traverser.Order.BREADTH_FIRST;
import static org.neo4j.graphdb.Traverser.Order.DEPTH_FIRST;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.junit.Test;
import org.neo4j.graphdb.Direction;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.NotFoundException;
import org.neo4j.graphdb.Relationship;
import org.neo4j.graphdb.RelationshipType;
import org.neo4j.graphdb.ReturnableEvaluator;
import org.neo4j.graphdb.StopEvaluator;
import org.neo4j.graphdb.TraversalPosition;
import org.neo4j.graphdb.Traverser;
import org.neo4j.graphdb.Traverser.Order;
import org.neo4j.kernel.impl.AbstractNeo4jTestCase;
import org.neo4j.kernel.impl.MyRelTypes;

public class TestTraversal extends AbstractNeo4jTestCase
{
    // Tests the traverser factory for sanity checks with corrupted input
    @Test
    public void testSanityChecks1() throws Exception
    {
        // Valid data
        Node root = getGraphDb().createNode();
        RelationshipType[] traversableRels = new RelationshipType[] { MyRelTypes.TEST, };
        // Null traversable relationships
        this.sanityCheckTraverser( "Sanity check failed: null traversable "
            + "rels should throw an " + "IllegalArgumentException",
            BREADTH_FIRST, root, null, Direction.OUTGOING,
            StopEvaluator.END_OF_GRAPH, ReturnableEvaluator.ALL );

        // Null stop evaluator
        this.sanityCheckTraverser( "Sanity check failed: null stop eval "
            + "should throw an IllegalArgumentException", BREADTH_FIRST, root,
            traversableRels[0], Direction.OUTGOING, null,
            ReturnableEvaluator.ALL );

        // Null returnable evaluator
        this.sanityCheckTraverser( "Sanity check failed: null returnable "
            + "evaluator should throw an " + "IllegalArgumentException",
            BREADTH_FIRST, root, traversableRels[0], Direction.OUTGOING,
            StopEvaluator.END_OF_GRAPH, null );
        root.delete();
    }

    @Test
    public void testSanityChecks2() throws Exception
    {
        // ------------- with traverser direction -------------
        // Valid data
        Node root = getGraphDb().createNode();
        RelationshipType[] traversableRels = new RelationshipType[] { MyRelTypes.TEST, };
        Direction[] traversableDirs = new Direction[] { Direction.OUTGOING };

        // Null traversable relationships
        this.sanityCheckTraverser( "Sanity check failed: null traversable "
            + "rels should throw an " + "IllegalArgumentException",
            BREADTH_FIRST, root, null, traversableDirs[0],
            StopEvaluator.END_OF_GRAPH, ReturnableEvaluator.ALL );

        // Null traversable directions
        this.sanityCheckTraverser( "Sanity check failed: null traversable "
            + "rels should throw an " + "IllegalArgumentException",
            BREADTH_FIRST, root, traversableRels[0], null,
            StopEvaluator.END_OF_GRAPH, ReturnableEvaluator.ALL );

        // Null stop evaluator
        this.sanityCheckTraverser( "Sanity check failed: null stop eval "
            + "should throw an IllegalArgumentException", BREADTH_FIRST, root,
            traversableRels[0], traversableDirs[0], null,
            ReturnableEvaluator.ALL );

        // Null returnable evaluator
        this.sanityCheckTraverser( "Sanity check failed: null returnable "
            + "evaluator should throw an " + "IllegalArgumentException",
            BREADTH_FIRST, root, traversableRels[0], traversableDirs[0],
            StopEvaluator.END_OF_GRAPH, null );
        // traversable relationships length not equal to traversable directions
        // length
        this.sanityCheckTraverser( "Sanity check failed: null returnable "
            + "evaluator should throw an " + "IllegalArgumentException",
            BREADTH_FIRST, root, traversableRels[0], null,
            StopEvaluator.END_OF_GRAPH, null );
        this.sanityCheckTraverser( "Sanity check failed: null returnable "
            + "evaluator should throw an " + "IllegalArgumentException",
            BREADTH_FIRST, root, null, traversableDirs[0],
            StopEvaluator.END_OF_GRAPH, null );
        root.delete();
    }

    // Tests the traverser factory for simple corrupted (null) input, used
    // by testSanityChecks()
    private void sanityCheckTraverser( String failMessage, Order type,
        Node startNode, RelationshipType traversableRel, Direction direction,
        StopEvaluator stopEval, ReturnableEvaluator retEval )
    {
        try
        {
            startNode.traverse( type, stopEval, retEval, traversableRel,
                direction );
            fail( failMessage );
        }
        catch ( IllegalArgumentException iae )
        {
            // This is ok
        }
    }

    // Traverses the full test "ise-tree-like" population breadth first
    // and verifies that it is returned in correct order
    @Test
    public void testBruteBreadthTraversal() throws Exception
    {
        Node root = this.buildIseTreePopulation();
        RelationshipType[] traversableRels = new RelationshipType[] {
            MyRelTypes.TEST, MyRelTypes.TEST_TRAVERSAL };
        Traverser traverser = root.traverse( BREADTH_FIRST,
            StopEvaluator.END_OF_GRAPH, ReturnableEvaluator.ALL,
            traversableRels[0], Direction.BOTH, traversableRels[1],
            Direction.BOTH );

        try
        {
            this.assertLevelsOfNodes( traverser, new String[][] {
                    new String[] { "1" },
                    new String[] { "2", "3", "4" },
                    new String[] { "5", "6", "7", "8", "9" },
                    new String[] { "10", "11", "12", "13", "14" }
            } );
            assertTrue( "Too many nodes returned from traversal", traverser
                .iterator().hasNext() == false );
        }
        catch ( java.util.NoSuchElementException nsee )
        {
            fail( "Too few nodes returned from traversal" );
        }
        finally
        {
            this.deleteNodeTreeRecursively( root, 0 );
        }
    }
   
    private void assertNodes( Traverser traverser, String... expectedNodes )
    {
        Set<String> set = new HashSet<String>( Arrays.asList( expectedNodes ) );
        for ( Node node : traverser )
        {
            assertTrue( set.remove( node.getProperty( "node.test.id" ) ) );
        }
        assertTrue( set.isEmpty() );
    }

    private void assertLevelsOfNodes( Traverser traverser, String[][] nodes )
    {
        Map<Integer, Collection<String>> map = new HashMap<Integer, Collection<String>>();
        for ( Node node : traverser )
        {
            Collection<String> collection = map.get( traverser.currentPosition().depth() );
            if ( collection == null )
            {
                collection = new ArrayList<String>();
                map.put( traverser.currentPosition().depth(), collection );
            }
            String name = (String) node.getProperty( "node.test.id" );
            collection.add( name );
        }
       
        for ( int i = 0; i < nodes.length; i++ )
        {
            Collection<String> expected = Arrays.asList( nodes[i] );
            assertEquals( expected, map.get( i ) );
        }
    }

    // Traverses the test "ise-tree-like" population breadth first,
    // but only traverses "ise" (TEST) relationships (the population also
    // contains
    // "ise_clone" (TEST_TRAVERSAL) rels)
    @Test
    public void testMultiRelBreadthTraversal() throws Exception
    {
        Node root = this.buildIseTreePopulation();
        RelationshipType[] traversableRels = new RelationshipType[] { MyRelTypes.TEST };
        Traverser traverser = root.traverse( BREADTH_FIRST,
            StopEvaluator.END_OF_GRAPH, ReturnableEvaluator.ALL,
            traversableRels[0], Direction.BOTH );

        try
        {
            this.assertLevelsOfNodes( traverser, new String[][] {
                new String[] { "1" },
                new String[] { "2", "3", "4" },
                new String[] { "5", "6", "7" },
                new String[] { "10", "11", "12", "13" },
            } );
            assertTrue( "Too many nodes returned from traversal", traverser
                .iterator().hasNext() == false );
        }
        catch ( java.util.NoSuchElementException nsee )
        {
            fail( "Too few nodes returned from traversal" );
        }
        finally
        {
            this.deleteNodeTreeRecursively( root, 0 );
        }
    }

    // Traverses the test "ise-tree-like" population breadth first,
    // starting in the middle of the tree and traversing only in the
    // "forward" direction
    @Test
    public void testDirectedBreadthTraversal() throws Exception
    {
        // Build test population
        Node root = this.buildIseTreePopulation();
        Node startNode = null;

        // Get a node in the middle of the tree:
        try
        {
            // a) Construct a returnable evaluator that returns node 2
            ReturnableEvaluator returnEvaluator = new ReturnableEvaluator()
            {
                public boolean isReturnableNode( TraversalPosition pos )
                {
                    try
                    {
                        Node node = pos.currentNode();
                        String key = "node.test.id";
                        String nodeId = (String) node.getProperty( key );
                        return nodeId.equals( "2" );
                    }
                    catch ( Exception e )
                    {
                        return false;
                    }
                }
            };

            // b) create a traverser
            Traverser toTheMiddleTraverser = root.traverse( BREADTH_FIRST,
                StopEvaluator.END_OF_GRAPH, returnEvaluator, MyRelTypes.TEST,
                Direction.BOTH );

            // c) get the first node it returns
            startNode = toTheMiddleTraverser.iterator().next();
            assertEquals( "2", startNode.getProperty( "node.test.id" ) );
        }
        catch ( Exception e )
        {
            e.printStackTrace();
            fail( "Something went wrong when trying to get a start node "
                + "in the middle of the tree: " + e );
        }

        // Construct the real traverser
        Traverser traverser = startNode.traverse( BREADTH_FIRST,
            StopEvaluator.END_OF_GRAPH, ReturnableEvaluator.ALL,
            MyRelTypes.TEST, Direction.OUTGOING );
        try
        {
            this.assertNextNodeId( traverser, "2" );
            this.assertNextNodeId( traverser, "5" );
            this.assertNextNodeId( traverser, "6" );
            this.assertNextNodeId( traverser, "10" );
            this.assertNextNodeId( traverser, "11" );
            this.assertNextNodeId( traverser, "12" );
            this.assertNextNodeId( traverser, "13" );
            assertTrue( "Too many nodes returned from traversal", traverser
                .iterator().hasNext() == false );
        }
        catch ( java.util.NoSuchElementException nsee )
        {
            nsee.printStackTrace();
            fail( "Too few nodes returned from traversal" );
        }
        finally
        {
            this.deleteNodeTreeRecursively( root, 0 );
        }
    }

    // Traverses the full test "ise-tree-like" population depth first
    // and verifies that it is returned in correct order
    @Test
    public void testBruteDepthTraversal() throws Exception
    {
        Node root = this.buildIseTreePopulation();
        RelationshipType[] traversableRels = new RelationshipType[] {
            MyRelTypes.TEST, MyRelTypes.TEST_TRAVERSAL };
        Traverser traverser = root.traverse( DEPTH_FIRST,
            StopEvaluator.END_OF_GRAPH, ReturnableEvaluator.ALL,
            traversableRels[0], Direction.BOTH, traversableRels[1],
            Direction.BOTH );

        try
        {
            this.assertNodes( traverser, "1", "2", "3", "4", "5", "6", "7",
                    "8", "9", "10", "11", "12", "13", "14" );
            assertTrue( "Too many nodes returned from traversal", traverser
                .iterator().hasNext() == false );
        }
        catch ( java.util.NoSuchElementException nsee )
        {
            fail( "Too few nodes returned from traversal" );
        }
        finally
        {
            this.deleteNodeTreeRecursively( root, 0 );
        }
    }

    // Traverses the test "ise-tree-like" population depth first,
    // but only traverses "ise" relationships (the population also contains
    // "ise_clone" rels)
    @Test
    public void testMultiRelDepthTraversal() throws Exception
    {
        Node root = this.buildIseTreePopulation();
        RelationshipType[] traversableRels = new RelationshipType[] { MyRelTypes.TEST };
        Traverser traverser = root.traverse( DEPTH_FIRST,
            StopEvaluator.END_OF_GRAPH, ReturnableEvaluator.ALL,
            traversableRels[0], Direction.BOTH );

        try
        {
            assertNodes( traverser, "1", "2", "3", "4", "5", "6", "7",
                    "10", "11", "12", "13" );
            assertTrue( "Too many nodes returned from traversal", traverser
                .iterator().hasNext() == false );
        }
        catch ( java.util.NoSuchElementException nsee )
        {
            fail( "Too few nodes returned from traversal" );
        }
        finally
        {
            this.deleteNodeTreeRecursively( root, 0 );
        }
    }

    // Verifies that the stop evaluator can stop based on the current node
    @Test
    public void testStopOnCurrentNode() throws Exception
    {
        // Build ise tree
        Node root = this.buildIseTreePopulation();

        // Traverse only ISE relationships
        RelationshipType[] traversableRels = new RelationshipType[] { MyRelTypes.TEST };

        // Construct a stop evaluator that stops on nodes 5, 6, 3 and 4
        StopEvaluator stopEvaluator = new StopEvaluator()
        {
            public boolean isStopNode( TraversalPosition position )
            {
                try
                {
                    Node node = position.currentNode();

                    String nodeId = (String) node.getProperty( "node.test.id" );
                    return nodeId.equals( "5" ) || nodeId.equals( "6" )
                        || nodeId.equals( "3" ) || nodeId.equals( "4" );
                }
                catch ( Exception e )
                {
                    return false;
                }
            }
        };

        // Create a traverser
        Traverser traverser = root.traverse( BREADTH_FIRST, stopEvaluator,
            ReturnableEvaluator.ALL, traversableRels[0], Direction.BOTH );

        try
        {
            this.assertNextNodeId( traverser, "1" );
            this.assertNextNodeId( traverser, "2" );
            this.assertNextNodeId( traverser, "3" );
            this.assertNextNodeId( traverser, "4" );
            this.assertNextNodeId( traverser, "5" );
            this.assertNextNodeId( traverser, "6" );

            assertTrue( "Too many nodes returned from traversal", traverser
                .iterator().hasNext() == false );
        }
        catch ( java.util.NoSuchElementException nsee )
        {
            fail( "Too few nodes returned from traversal" );
        }
        finally
        {
            this.deleteNodeTreeRecursively( root, 0 );
        }
    }

    // Verifies that the stop evaluator can stop based on the previous node
    @Test
    public void testStopOnPreviousNode() throws Exception
    {
        // Build ise tree
        Node root = this.buildIseTreePopulation();

        // Traverse only ISE relationships
        RelationshipType[] traversableRels = new RelationshipType[] { MyRelTypes.TEST };

        // Construct a stop evaluator that stops on nodes 2, 3, and 4
        // (ie root's children)
        StopEvaluator stopEvaluator = new StopEvaluator()
        {
            public boolean isStopNode( TraversalPosition position )
            {
                try
                {
                    Node node = position.previousNode();
                    String nodeId = (String) node.getProperty( "node.test.id" );
                    return nodeId.equals( "1" );
                }
                catch ( Exception e )
                {
                    return false;
                }
            }
        };

        // Create a traverser
        Traverser traverser = root.traverse( BREADTH_FIRST, stopEvaluator,
            ReturnableEvaluator.ALL, traversableRels[0], Direction.BOTH );

        try
        {
            this.assertNextNodeId( traverser, "1" );
            this.assertNextNodeId( traverser, "2" );
            this.assertNextNodeId( traverser, "3" );
            this.assertNextNodeId( traverser, "4" );

            assertTrue( "Too many nodes returned from traversal", traverser
                .iterator().hasNext() == false );
        }
        catch ( java.util.NoSuchElementException nsee )
        {
            fail( "Too few nodes returned from traversal" );
        }
        finally
        {
            // Delete ise tree and commmit work
            this.deleteNodeTreeRecursively( root, 0 );
        }
    }

    // Verifies that the stop evaluator can stop based on the current depth
    @Test
    public void testStopOnDepth() throws Exception
    {
        // Build ise tree
        Node root = this.buildIseTreePopulation();

        // Traverse only ISE relationships
        RelationshipType[] traversableRels = new RelationshipType[] { MyRelTypes.TEST };

        // Construct a stop evaluator that stops on depth 2
        StopEvaluator stopEvaluator = new StopEvaluator()
        {
            public boolean isStopNode( TraversalPosition position )
            {
                return position.depth() >= 2;
            }
        };

        // Create a traverser
        Traverser traverser = root.traverse( BREADTH_FIRST, stopEvaluator,
            ReturnableEvaluator.ALL, traversableRels[0], Direction.BOTH );

        try
        {
            this.assertNextNodeId( traverser, "1" );
            this.assertNextNodeId( traverser, "2" );
            this.assertNextNodeId( traverser, "3" );
            this.assertNextNodeId( traverser, "4" );
            this.assertNextNodeId( traverser, "5" );
            this.assertNextNodeId( traverser, "6" );
            this.assertNextNodeId( traverser, "7" );

            assertTrue( "Too many nodes returned from traversal", traverser
                .iterator().hasNext() == false );
        }
        catch ( java.util.NoSuchElementException nsee )
        {
            fail( "Too few nodes returned from traversal" );
        }
        finally
        {
            // Delete ise tree and commmit work
            this.deleteNodeTreeRecursively( root, 0 );
        }
    }

    // Verifies that the stop evaluator can stop based on the amount of
    // returned nodes
    @Test
    public void testStopOnReturnedNodes() throws Exception
    {
        // Build ise tree
        Node root = this.buildIseTreePopulation();

        // Traverse only ISE relationships
        RelationshipType[] traversableRels = new RelationshipType[] { MyRelTypes.TEST };

        // Construct stop- and returnable evaluators that return 5 nodes
        StopEvaluator stopEvaluator = new StopEvaluator()
        {
            public boolean isStopNode( TraversalPosition position )
            {
                // Stop traversing when we've returned 5 nodes
                return position.returnedNodesCount() >= 5;
            }
        };
        ReturnableEvaluator returnEvaluator = new ReturnableEvaluator()
        {
            public boolean isReturnableNode( TraversalPosition position )
            {
                // Return nodes until we've reached 5 nodes or end of graph
                return position.returnedNodesCount() < 5;
            }
        };

        // Create a traverser
        Traverser traverser = root.traverse( BREADTH_FIRST, stopEvaluator,
            returnEvaluator, traversableRels[0], Direction.BOTH );

        try
        {
            this.assertLevelsOfNodes( traverser, new String[][] {
                new String[] { "1" },
                new String[] { "2", "3", "4" },
                new String[] { "5" },
            } );

            assertTrue( "Too many nodes returned from traversal", traverser
                .iterator().hasNext() == false );
        }
        catch ( java.util.NoSuchElementException nsee )
        {
            fail( "Too few nodes returned from traversal" );
        }
        finally
        {
            // Delete ise tree and commmit work
            this.deleteNodeTreeRecursively( root, 0 );
        }
    }

    // Verifies that the stop evaluator can stop based on the last
    // traversed relationship
    @Test
    public void testStopOnLastRelationship() throws Exception
    {
        // Build ise tree
        Node root = this.buildIseTreePopulation();

        // Traverse only ISE relationships
        RelationshipType[] traversableRels = new RelationshipType[] {
            MyRelTypes.TEST, MyRelTypes.TEST_TRAVERSAL };

        // Construct stop- and returnable evaluators that return 5 nodes
        StopEvaluator stopEvaluator = new StopEvaluator()
        {
            public boolean isStopNode( TraversalPosition position )
            {
                // Stop when we got here by traversing a clone relationship
                Relationship rel = position.lastRelationshipTraversed();
                return rel != null && rel.isType( MyRelTypes.TEST_TRAVERSAL );
            }
        };

        // Create a traverser
        Traverser traverser = root.traverse( BREADTH_FIRST, stopEvaluator,
            ReturnableEvaluator.ALL, traversableRels[0], Direction.BOTH,
            traversableRels[1], Direction.BOTH );

        try
        {
            this.assertLevelsOfNodes( traverser, new String[][] {
                new String[] { "1" },
                new String[] { "2", "3", "4" },
                new String[] { "5", "6", "7", "8", "9" },
                new String[] { "10", "11", "12", "13" }
            } );

            assertTrue( "Too many nodes returned from traversal", traverser
                .iterator().hasNext() == false );
        }
        catch ( java.util.NoSuchElementException nsee )
        {
            fail( "Too few nodes returned from traversal" );
        }
        finally
        {
            // Delete ise tree and commmit work
            this.deleteNodeTreeRecursively( root, 0 );
        }
    }

    // -- Utility operations

    private Node buildIseTreePopulation() throws Exception
    {
        // Create population
        Node[] nodeSpace = new Node[] { null, // empty
            getGraphDb().createNode(), // 1 [root]
            getGraphDb().createNode(), // 2
            getGraphDb().createNode(), // 3
            getGraphDb().createNode(), // 4
            getGraphDb().createNode(), // 5
            getGraphDb().createNode(), // 6
            getGraphDb().createNode(), // 7
            getGraphDb().createNode(), // 8
            getGraphDb().createNode(), // 9
            getGraphDb().createNode(), // 10
            getGraphDb().createNode(), // 11
            getGraphDb().createNode(), // 12
            getGraphDb().createNode(), // 13
            getGraphDb().createNode(), // 14
        };

        String key = "node.test.id";
        for ( int i = 1; i < nodeSpace.length; i++ )
        {
            nodeSpace[i].setProperty( key, "" + i );
        }

        RelationshipType ise = MyRelTypes.TEST;
        RelationshipType clone = MyRelTypes.TEST_TRAVERSAL;

        // Bind it together
        //
        //               ----(1)-------
        //              /      \       \
        //          --(2)--    (3)     (4)--
        //         /       \     \      |   \
        //     --(5)----- (6)---(7)   (8)  (9)
        //    /   |   \  \                  |
        //  (10) (11)(12)(13)              (14)
        //
       
        nodeSpace[1].createRelationshipTo( nodeSpace[2], ise );
        nodeSpace[2].createRelationshipTo( nodeSpace[5], ise );
        nodeSpace[5].createRelationshipTo( nodeSpace[10], ise );
        nodeSpace[5].createRelationshipTo( nodeSpace[11], ise );
        nodeSpace[5].createRelationshipTo( nodeSpace[12], ise );
        nodeSpace[5].createRelationshipTo( nodeSpace[13], ise );
        nodeSpace[2].createRelationshipTo( nodeSpace[6], ise );
        nodeSpace[1].createRelationshipTo( nodeSpace[3], ise );
        nodeSpace[1].createRelationshipTo( nodeSpace[4], ise );
        nodeSpace[3].createRelationshipTo( nodeSpace[7], ise );

        nodeSpace[6].createRelationshipTo( nodeSpace[7], clone );
        nodeSpace[4].createRelationshipTo( nodeSpace[8], clone );
        nodeSpace[4].createRelationshipTo( nodeSpace[9], clone );
        nodeSpace[9].createRelationshipTo( nodeSpace[14], clone );

        return nodeSpace[1]; // root
    }

    // Deletes a tree-like structure of nodes, starting with 'currentNode'.
    // Works fine with trees, dies horribly on cyclic structures.
    private void deleteNodeTreeRecursively( Node currentNode, int depth )
    {
        if ( depth > 100 )
        {
            throw new RuntimeException( "Recursive guard: depth = " + depth );
        }

        if ( currentNode == null )
        {
            return;
        }

        Iterable<Relationship> rels = currentNode.getRelationships();
        for ( Relationship rel : rels )
        {
            if ( !rel.getStartNode().equals( currentNode ) )
            {
                continue;
            }
            Node endNode = rel.getEndNode();
            rel.delete();
            this.deleteNodeTreeRecursively( endNode, depth + 1 );
        }
        String msg = "Deleting " + currentNode + "\t[";
        String id = (String) currentNode.getProperty( "node.test.id" );
        msg += id + "]";

        Iterable<Relationship> allRels = currentNode.getRelationships();
        for ( Relationship rel : allRels )
        {
            rel.delete();
        }
        currentNode.delete();
    }

    private void assertNextNodeId( Traverser traverser, String property )
        throws NotFoundException
    {
        Node node = traverser.iterator().next();
        assertEquals( property, node.getProperty( "node.test.id" ) );
    }
}
TOP

Related Classes of org.neo4j.kernel.impl.traversal.TestTraversal

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.