package org.neo4j.remote.test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Callable;
import org.junit.Test;
import org.neo4j.graphdb.Direction;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Relationship;
import org.neo4j.graphdb.RelationshipType;
import org.neo4j.graphdb.ReturnableEvaluator;
import org.neo4j.graphdb.StopEvaluator;
import org.neo4j.graphdb.Transaction;
import org.neo4j.graphdb.TraversalPosition;
import org.neo4j.graphdb.Traverser;
import org.neo4j.graphdb.Traverser.Order;
import org.neo4j.index.IndexService;
import org.neo4j.remote.AbstractTestBase;
import org.neo4j.remote.RemoteGraphDatabase;
public class TheMatrixTest extends AbstractTestBase
{
public TheMatrixTest( Callable<RemoteGraphDatabase> factory )
{
super( factory );
}
public @Test
void testTheMatrix() throws Exception
{
Transaction tx = graphDb().beginTx();
try
{
defineMatrix( graphDb(), indexService() );
tx.success();
}
finally
{
tx.finish();
}
tx = graphDb().beginTx();
try
{
verifyFriendsOf( indexService().getSingleNode( "name",
"Thomas Andersson" ) );
verifyHackersInNetworkOf( indexService().getSingleNode( "name",
"Thomas Andersson" ) );
tx.success();
}
finally
{
tx.finish();
}
}
private static enum MatrixRelation implements RelationshipType
{
KNOWS,
CODED_BY,
LOVES
}
private static void defineMatrix( GraphDatabaseService graphDb,
IndexService index ) throws Exception
{
// Define nodes
Node mrAndersson, morpheus, trinity, cypher, agentSmith, theArchitect;
mrAndersson = graphDb.createNode();
morpheus = graphDb.createNode();
trinity = graphDb.createNode();
cypher = graphDb.createNode();
agentSmith = graphDb.createNode();
theArchitect = graphDb.createNode();
// Define relationships
@SuppressWarnings( "unused" ) Relationship aKm, aKt, mKt, mKc, cKs, sCa, tLa;
aKm = mrAndersson.createRelationshipTo( morpheus, MatrixRelation.KNOWS );
aKt = mrAndersson.createRelationshipTo( trinity, MatrixRelation.KNOWS );
mKt = morpheus.createRelationshipTo( trinity, MatrixRelation.KNOWS );
mKc = morpheus.createRelationshipTo( cypher, MatrixRelation.KNOWS );
cKs = cypher.createRelationshipTo( agentSmith, MatrixRelation.KNOWS );
sCa = agentSmith.createRelationshipTo( theArchitect,
MatrixRelation.CODED_BY );
tLa = trinity.createRelationshipTo( mrAndersson, MatrixRelation.LOVES );
// Define node properties
mrAndersson.setProperty( "name", "Thomas Andersson" );
morpheus.setProperty( "name", "Morpheus" );
trinity.setProperty( "name", "Trinity" );
cypher.setProperty( "name", "Cypher" );
agentSmith.setProperty( "name", "Agent Smith" );
theArchitect.setProperty( "name", "The Architect" );
// Define relationship properties
// Index nodes
indexNodes( index, "name", mrAndersson, morpheus, trinity, cypher,
agentSmith, theArchitect );
}
private static void indexNodes( IndexService index, String key,
Node... nodes )
{
for ( Node node : nodes )
{
index.index( node, key, node.getProperty( key ) );
}
}
@SuppressWarnings( "deprecation" )
private static void verifyFriendsOf( Node thomas ) throws Exception
{
Traverser traverser = thomas.traverse( Order.BREADTH_FIRST,
StopEvaluator.END_OF_GRAPH,
ReturnableEvaluator.ALL_BUT_START_NODE, MatrixRelation.KNOWS,
Direction.OUTGOING );
Set<String> actual = new HashSet<String>();
for ( Node friend : traverser )
{
assertTrue( "Same friend added twice.",
actual.add( (String) friend.getProperty( "name" ) ) );
}
assertEquals( "Thomas Anderssons friends are incorrect.",
new HashSet<String>( Arrays.asList( "Trinity", "Morpheus",
"Cypher", "Agent Smith" ) ), actual );
}
@SuppressWarnings( { "serial", "deprecation" } )
private static void verifyHackersInNetworkOf( Node thomas )
throws Exception
{
Traverser traverser = thomas.traverse( Order.BREADTH_FIRST,
StopEvaluator.END_OF_GRAPH, new ReturnableEvaluator()
{
public boolean isReturnableNode( TraversalPosition pos )
{
return pos.notStartNode()
&& pos.lastRelationshipTraversed().isType(
MatrixRelation.CODED_BY );
}
}, MatrixRelation.CODED_BY, Direction.OUTGOING,
MatrixRelation.KNOWS, Direction.OUTGOING );
Map<String, Integer> actual = new HashMap<String, Integer>();
for ( Node hacker : traverser )
{
assertNull( "Same hacker found twice.", actual.put(
(String) hacker.getProperty( "name" ),
traverser.currentPosition().depth() ) );
}
assertEquals( "", new HashMap<String, Integer>()
{
{
put( "The Architect", 4 );
}
}, actual );
}
}