From 74204e8b17349a135e11f942ba4378e8faeb1a05 Mon Sep 17 00:00:00 2001 From: maxdemarzi Date: Tue, 7 Dec 2010 13:56:57 -0800 Subject: [PATCH] adding relationship tests --- README.rdoc | 69 +++++++++++------- lib/neography.rb | 4 + lib/neography/node_relationship.rb | 38 ++++++++-- lib/neography/node_traverser.rb | 23 ++++++ lib/neography/relationship.rb | 2 +- lib/neography/rest.rb | 14 ++-- spec/integration/relationship_spec.rb | 85 +++++++++++++++------- spec/integration/rest_bulk_spec.rb | 6 +- spec/integration/rest_experimental_spec.rb | 23 ++++++ 9 files changed, 196 insertions(+), 68 deletions(-) create mode 100644 lib/neography/node_traverser.rb create mode 100644 spec/integration/rest_experimental_spec.rb diff --git a/README.rdoc b/README.rdoc index e922522..fb11887 100644 --- a/README.rdoc +++ b/README.rdoc @@ -120,39 +120,54 @@ Experimental: === Phase 2 (work in progress): +Trying to mimic the Neo4j.rb API. + Now we are returning full objects. The properties of the node or relationship can be accessed directly (node.name). The Neo4j ID is available by using node.neo_id . @neo2 = Neography::Rest.new ('http://', '192.168.10.1') - Neography::Node.create # Create an empty node - Neography::Node.create("age" => 31, "name" => "Max") # Create a node with some properties - Neography::Node.create(@neo2, {"age" => 31, "name" => "Max"}) # Create a node on the server defined in @neo2 - Neography::Node.create({"age" => 31, "name" => "Max"}, @neo2) # Same as above, but different order - - Neography::Node.load(5) # Get a node and its properties by id - Neography::Node.load(existing_node) # Get a node and its properties by Node - Neography::Node.load("http://localhost:7474/db/data/node/2") # Get a node and its properties by String - - Neography::Node.load(@neo2, 5) # Get a node on the server defined in @neo2 - Neography::Node.load(5, @neo2) # Same as above, but different order - - my_node = Node.create - my_node.del # Deletes the node - my_node.exist? # returns true/false if node exists in Neo4j - - my_node = Node.create("age" => 31, "name" => "Max") - my_node[:age] #returns 31 # Get a node property using [:key] - my_node.name #returns "Max" # Get a node property as a method - my_node[:age] = 24 # Set a node property using [:key] = - my_node.name = "Alex" # Set a node property as a method - my_node[:hair] = "black" # Add a node property using [:key] = - my_node.weight = 190 # Add a node property as a method - my_node[:name] = nil # Delete a node property using [:key] = nil - my_node.name = nil # Delete a node property by setting it to nil + Neography::Node.create # Create an empty node + Neography::Node.create("age" => 31, "name" => "Max") # Create a node with some properties + Neography::Node.create(@neo2, {"age" => 31, "name" => "Max"}) # Create a node on the server defined in @neo2 + Neography::Node.create({"age" => 31, "name" => "Max"}, @neo2) # Same as above, but different order + + Neography::Node.load(5) # Get a node and its properties by id + Neography::Node.load(existing_node) # Get a node and its properties by Node + Neography::Node.load("http://localhost:7474/db/data/node/2") # Get a node and its properties by String + + Neography::Node.load(@neo2, 5) # Get a node on the server defined in @neo2 + Neography::Node.load(5, @neo2) # Same as above, but different order + + n1 = Node.create + n1.del # Deletes the node + n1.exist? # returns true/false if node exists in Neo4j + + n1 = Node.create("age" => 31, "name" => "Max") + n1[:age] #returns 31 # Get a node property using [:key] + n1.name #returns "Max" # Get a node property as a method + n1[:age] = 24 # Set a node property using [:key] = + n1.name = "Alex" # Set a node property as a method + n1[:hair] = "black" # Add a node property using [:key] = + n1.weight = 190 # Add a node property as a method + n1[:name] = nil # Delete a node property using [:key] = nil + n1.name = nil # Delete a node property by setting it to nil - node2 = Neography::Node.create - new_rel = Neography::Relationship.create(:family, my_node, node2) # Create a relationship from my_node to node2 + n2 = Neography::Node.create + new_rel = Neography::Relationship.create(:family, n1, n2) # Create a relationship from my_node to node2 + new_rel.start_node # Get the start/from node of a relationship + new_rel.end_node # Get the end/to node of a relationship + existing_rel = Neography::Relationship.load(12) # Get an existing relationship by id + existing_rel.del # Delete a relationship + + Neography::Relationship.create(:friends, n1, n2) + n1.rel?(:friends) # Has a friends relationship + n1.rel?(:outgoing, :friends) # Has outgoing friends relationship + n1.rel?(:friends, :outgoing) # same, just the other way + n1.rel?(:outgoing) # Has any outgoing relationships + n1.rel?(:both) # Has any relationships + n1.rel?(:all) # same as above + n1.rel? # same as above See Neo4j API for: diff --git a/lib/neography.rb b/lib/neography.rb index c2e8f52..9e03d19 100644 --- a/lib/neography.rb +++ b/lib/neography.rb @@ -15,6 +15,8 @@ def find_and_require_user_defined_code end end +DIRECTIONS = ["incoming", "in", "outgoing", "out", "all", "both"] + require 'httparty' require 'json' @@ -28,6 +30,8 @@ def find_and_require_user_defined_code require 'neography/property_container' require 'neography/property' require 'neography/node_relationship' +require 'neography/relationship_traverser' +require 'neography/node_traverser' require 'neography/equal' diff --git a/lib/neography/node_relationship.rb b/lib/neography/node_relationship.rb index 1aa5ac4..b5fdbdd 100644 --- a/lib/neography/node_relationship.rb +++ b/lib/neography/node_relationship.rb @@ -1,16 +1,44 @@ module Neography module NodeRelationship - def rels(*type) - RelationshipTraverser.new(self, type, :both) + def outgoing(types=nil) + if types + NodeTraverser.new(self).outgoing(types) + else + NodeTraverser.new(self).outgoing + end + end + + def incoming(types=nil) + if types + NodeTraverser.new(self).incoming(types) + else + NodeTraverser.new(self).incoming + end + end + + def both(types=nil) + if types + NodeTraverser.new(self).both(types) + else + NodeTraverser.new(self) # default is both + end + end + + def rels(*types) + Neography::RelationshipTraverser.new(self, types, :both) end def rel(dir, type) - RelationshipTraverser.new(self, type, dir) + Neography::RelationshipTraverser.new(self, type, dir).first end - def rel? (type=nil, dir=:both) - self.neo_server.get_node_relationships(self, dir, type).empty? + def rel?(dir=nil, type=nil) + if DIRECTIONS.include?(dir.to_s) + !self.neo_server.get_node_relationships(self, dir, type).nil? + else + !self.neo_server.get_node_relationships(self, type, dir).nil? + end end end diff --git a/lib/neography/node_traverser.rb b/lib/neography/node_traverser.rb new file mode 100644 index 0000000..0ee4a51 --- /dev/null +++ b/lib/neography/node_traverser.rb @@ -0,0 +1,23 @@ +module Neography + class NodeTraverser + include Enumerable + + attr_accessor :order, :uniqueness, :depth, :prune, :filter + + def initialize(from, types = nil, dir=nil) + @from = from + @depth = 1 + @order = "depth first" + @uniqueness = "none" + if types.nil? || dir.nil? +# @td = org.neo4j.kernel.impl.traversal.TraversalDescriptionImpl.new.breadth_first() + else +# @types = type_to_java(type) +# @dir = dir_to_java(dir) +# @td = org.neo4j.kernel.impl.traversal.TraversalDescriptionImpl.new.breadth_first().relationships(@type, @dir) + end + end + + end + +end \ No newline at end of file diff --git a/lib/neography/relationship.rb b/lib/neography/relationship.rb index 394c642..005f1af 100644 --- a/lib/neography/relationship.rb +++ b/lib/neography/relationship.rb @@ -39,7 +39,7 @@ def initialize(hash=nil, neo_server=nil) end def del - self.start_node.delete_relationship(self.neo_id) + self.start_node.neo_server.delete_relationship(self.neo_id) end def other_node(node) diff --git a/lib/neography/rest.rb b/lib/neography/rest.rb index 92b37f3..6c76028 100644 --- a/lib/neography/rest.rb +++ b/lib/neography/rest.rb @@ -96,7 +96,7 @@ def get_node(id) def get_nodes(*nodes) gotten_nodes = Array.new - nodes.to_a.flatten.each do |node| + Array(nodes).flatten.each do |node| gotten_nodes << get_node(node) end gotten_nodes @@ -112,7 +112,7 @@ def get_node_properties(id, properties = nil) get("/node/#{get_id(id)}/properties") else node_properties = Hash.new - properties.to_a.each do |property| + Array(properties).each do |property| value = get("/node/#{get_id(id)}/properties/#{property}") node_properties[property] = value unless value.nil? end @@ -125,7 +125,7 @@ def remove_node_properties(id, properties = nil) if properties.nil? delete("/node/#{get_id(id)}/properties") else - properties.to_a.each do |property| + Array(properties).each do |property| delete("/node/#{get_id(id)}/properties/#{property}") end end @@ -161,7 +161,7 @@ def get_relationship_properties(id, properties = nil) get("/relationship/#{get_id(id)}/properties") else relationship_properties = Hash.new - properties.to_a.each do |property| + Array(properties).each do |property| value = get("/relationship/#{get_id(id)}/properties/#{property}") relationship_properties[property] = value unless value.nil? end @@ -174,7 +174,7 @@ def remove_relationship_properties(id, properties = nil) if properties.nil? delete("/relationship/#{get_id(id)}/properties") else - properties.to_a.each do |property| + Array(properties).each do |property| delete("/relationship/#{get_id(id)}/properties/#{property}") end end @@ -197,7 +197,7 @@ def get_node_relationships(id, dir=nil, types=nil) if types.nil? node_relationships = get("/node/#{get_id(id)}/relationships/#{dir}") || Array.new else - node_relationships = get("/node/#{get_id(id)}/relationships/#{dir}/#{types.to_a.join('&')}") || Array.new + node_relationships = get("/node/#{get_id(id)}/relationships/#{dir}/#{Array(types).join('&')}") || Array.new end return nil if node_relationships.empty? node_relationships @@ -298,7 +298,7 @@ def get_id(id) id["self"].split('/').last when String id.split('/').last - when Neography::Node || Neography::Relationship + when Neography::Node, Neography::Relationship id.neo_id else id diff --git a/spec/integration/relationship_spec.rb b/spec/integration/relationship_spec.rb index f5b204c..d85fbe2 100644 --- a/spec/integration/relationship_spec.rb +++ b/spec/integration/relationship_spec.rb @@ -1,36 +1,71 @@ require File.join(File.dirname(__FILE__), '..', 'spec_helper') describe Neography::Relationship do - it "#new(:family, p1, p2) creates a new relationship between to nodes of given type" do - p1 = Neography::Node.create - p2 = Neography::Node.create - - new_rel = Neography::Relationship.create(:family, p1, p2) - puts new_rel.inspect - new_rel.start_node.should == p1 - new_rel.end_node.should == p2 -# p1.outgoing(:family).should include(p2) -# p2.incoming(:family).should include(p1) - end + describe "create relationship" do + it "#new(:family, p1, p2) creates a new relationship between to nodes of given type" do + p1 = Neography::Node.create + p2 = Neography::Node.create + + new_rel = Neography::Relationship.create(:family, p1, p2) + puts new_rel.inspect + new_rel.start_node.should == p1 + new_rel.end_node.should == p2 + + +# p1.outgoing(:family).should include(p2) +# p2.incoming(:family).should include(p1) + end - it "#new(:family, p1, p2, :since => '1998', :colour => 'blue') creates relationship and sets its properties" do - p1 = Neography::Node.create - p2 = Neography::Node.create + it "#new(:family, p1, p2, :since => '1998', :colour => 'blue') creates relationship and sets its properties" do + p1 = Neography::Node.create + p2 = Neography::Node.create + + rel = Neography::Relationship.create(:family, p1, p2, :since => 1998, :colour => 'blue') + rel[:since].should == 1998 + rel[:colour].should == 'blue' + rel.since.should == 1998 + rel.colourshould == 'blue' + end - rel = Neography::Relationship.create(:family, p1, p2, :since => 1998, :colour => 'blue') - rel[:since].should == 1998 - rel[:colour].should == 'blue' - rel.since.should == 1998 - rel.colourshould == 'blue' + it "#outgoing(:friends).create(other) creates a new relationship between self and other node" do + p1 = Neography::Node.create + p2 = Neography::Node.create + + rel = p1.outgoing(:foo).create(p2) + p1.outgoing(:foo).first.should == p2 + rel.should be_kind_of(Neography::Relationship) + end end - it "#outgoing(:friends).new(other) creates a new relationship between self and other node" do - p1 = Neography::Node.create - p2 = Neography::Node.create + describe "rel?" do + it "#rel? returns true if there are any relationships" do + n1 = Neography::Node.create + n2 = Neography::Node.create + new_rel = Neography::Relationship.create(:foo, n1, n2) + n1.rel?.should be_true + n1.rel?(:bar).should be_false + n1.rel?(:foo).should be_true + n1.rel?(:incoming, :foo).should be_false + n1.rel?(:outgoing, :foo).should be_true + n1.rel?(:foo, :incoming).should be_false + n1.rel?(:foo, :outgoing).should be_true - rel = p1.outgoing(:foo).create(p2) - p1.outgoing(:foo).first.should == p2 - rel.should be_kind_of(Neography::Relationship) + n1.rel?(:incoming).should be_false + n1.rel?(:outgoing).should be_true + n1.rel?(:both).should be_true + n1.rel?(:all).should be_true + n1.rel?.should be_true + end end + + describe "delete relationship" do + it "can delete an existing relationship" do + p1 = Neography::Node.create + p2 = Neography::Node.create + new_rel = Neography::Relationship.create(:family, p1, p2) + new_rel.del + Neography::Relationship.load(new_rel).should be_nil + end + end end \ No newline at end of file diff --git a/spec/integration/rest_bulk_spec.rb b/spec/integration/rest_bulk_spec.rb index 7b76e7b..9577626 100644 --- a/spec/integration/rest_bulk_spec.rb +++ b/spec/integration/rest_bulk_spec.rb @@ -14,9 +14,9 @@ it "is faster than non-threaded?" do Benchmark.bm do |x| - x.report("create 5000 nodes ") { @not_threaded = @neo.create_nodes(5000) } - x.report("create 5000 nodes threaded") { @threaded = @neo.create_nodes_threaded(5000) } - x.report("create 100000 nodes threaded") { @threaded2c = @neo.create_nodes_threaded(10000) } + x.report("create 500 nodes ") { @not_threaded = @neo.create_nodes(500) } + x.report("create 500 nodes threaded") { @threaded = @neo.create_nodes_threaded(500) } + x.report("create 1000 nodes threaded") { @threaded2c = @neo.create_nodes_threaded(1000) } end @not_threaded[99].should_not be_nil diff --git a/spec/integration/rest_experimental_spec.rb b/spec/integration/rest_experimental_spec.rb new file mode 100644 index 0000000..a169634 --- /dev/null +++ b/spec/integration/rest_experimental_spec.rb @@ -0,0 +1,23 @@ +require File.join(File.dirname(__FILE__), '..', 'spec_helper') + +describe Neography::Rest do + before(:each) do + @neo = Neography::Rest.new + end + + + describe "get_nodes" do + it "can get nodes that exists" do + existing_nodes = @neo.get_nodes + existing_nodes.should_not be_nil + puts existing_nodes.inspect + end + + it "can get all nodes that exists the ugly way" do + new_node = @neo.create_node + last_node_id = new_node["self"].split('/').last.to_i + existing_nodes = @neo.get_nodes((1..last_node_id).to_a) + existing_nodes.should_not be_nil + end + end +end \ No newline at end of file