Skip to content

Commit

Permalink
Added a traverse method on the NodeMixin and its RSpecs [#19]
Browse files Browse the repository at this point in the history
  • Loading branch information
andreasronge committed Jan 13, 2009
1 parent 65f36b2 commit eaf0d94
Show file tree
Hide file tree
Showing 3 changed files with 160 additions and 4 deletions.
29 changes: 27 additions & 2 deletions lib/neo4j/mixins/node.rb
Expand Up @@ -263,14 +263,39 @@ def classname=(value)
end


# Returns a relation traverser for traversing all types of relation from and to this node
# @see Neo4j::Relations::RelationTraverser
# Returns a Neo4j::Relations::RelationTraverser object for accessing relations from and to this node.
# The Neo4j::Relations::RelationTraverser is an Enumerable that returns Neo4j::RelationMixin objects.
#
# ==== See Also
# * Neo4j::Relations::RelationTraverser
# * Neo4j::RelationMixin
#
# ==== Example
#
# person_node.relations.outgoing(:friends).each { ... }
#
# :api: public
def relations
Relations::RelationTraverser.new(@internal_node)
end


# Returns a Neo4j::Relations::NodeTraverser object for traversing nodes from and to this node.
# The Neo4j::Relations::NodeTraverser is an Enumerable that returns Neo4j::NodeMixin objects.
#
# ==== See Also
# Neo4j::Relations::NodeTraverser
#
# ==== Example
#
# person_node.traverse.outgoing(:friends).each { ... }
#
# :api: public
def traverse
Relations::NodeTraverser.new(@internal_node)
end


# Mark this node to be reindex by lucene after the transaction finishes
#
# @api private
Expand Down
4 changes: 2 additions & 2 deletions lib/neo4j/relations/node_traverser.rb
Expand Up @@ -2,7 +2,7 @@ module Neo4j
module Relations

# Enables traversing nodes
#
# TODO duplicated code, see RelationTraverser, Inheritance ?
class NodeTraverser
include Enumerable

Expand Down Expand Up @@ -41,7 +41,7 @@ def each
iter = iterator
while (iter.hasNext) do
n = iter.next
yield Neo4j.load(n)
yield Neo4j.load(n.get_id)
end
end
end
Expand Down
131 changes: 131 additions & 0 deletions test/neo4j/node_traverser_spec.rb
@@ -0,0 +1,131 @@
$LOAD_PATH << File.expand_path(File.dirname(__FILE__) + "/../../lib")
$LOAD_PATH << File.expand_path(File.dirname(__FILE__) + "/..")

require 'neo4j'
require 'neo4j/spec_helper'




describe "NodeTraverser" do
before(:all) do
start
end

after(:all) do
stop
end



# ----------------------------------------------------------------------------
# traversing outgoing and incoming nodes
#

describe 'traversing outgoing and incoming nodes' do
before(:all) do
undefine_class :TestNode # make sure it is not already defined

class TestNode
include Neo4j::NodeMixin
has_n :friends
has_n :parents
end
end

it "should find all outgoing nodes" do
# given
t1 = TestNode.new
t2 = TestNode.new
t1.friends << t2

# when
outgoing = t1.traverse.outgoing(:friends).to_a

# then
outgoing.size.should == 1
outgoing[0].should == t2
end

it "should find all incoming nodes" do
# given
t1 = TestNode.new
t2 = TestNode.new
t1.friends << t2

# when
t2_incoming = t2.traverse.incoming(:friends).to_a

# then
t2_incoming.size.should == 1
t2_incoming[0].should == t1
end

it "should find no incoming or outgoing nodes when there are none" do
# given
t1 = TestNode.new
t2 = TestNode.new

# when and then
t2.traverse.incoming(:friends).to_a.size.should == 0
t2.traverse.outgoing(:friends).to_a.size.should == 0
end

it "should make sure that incoming nodes are not found in outcoming nodes" do
# given
t1 = TestNode.new
t2 = TestNode.new
t1.friends << t2

# when and then
t1.traverse.incoming(:friends).to_a.size.should == 0
t2.traverse.outgoing(:friends).to_a.size.should == 0
end


it "should find both incoming and outgoing nodes" do
# given
t1 = TestNode.new
t2 = TestNode.new
t1.friends << t2

# when and then
t1.traverse.both(:friends).to_a.should include(t2)
t2.traverse.both(:friends).to_a.should include(t1)
end

it "should find several both incoming and outgoing nodes" do
# given
t1 = TestNode.new
t2 = TestNode.new
t3 = TestNode.new

t1.friends << t2
t1.friends << t3

# when and then
t1.traverse.both(:friends).to_a.should include(t2,t3)
t1.traverse.outgoing(:friends).to_a.should include(t2,t3)
t2.traverse.incoming(:friends).to_a.should include(t1)
t3.traverse.incoming(:friends).to_a.should include(t1)
t1.traverse.both(:friends).to_a.size.should == 2
end

it "should find incoming nodes of a specific type" do
# given
t1 = TestNode.new
t2 = TestNode.new
t3 = TestNode.new

t1.friends << t2
t1.friends << t3

# when and then
t1.traverse.outgoing(:friends).to_a.should include(t2,t3)
t2.traverse.incoming(:friends).to_a.should include(t1)
t3.traverse.incoming(:friends).to_a.should include(t1)
end
end


end

0 comments on commit eaf0d94

Please sign in to comment.