neography 0.0.31 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +3 -0
- data/.travis.yml +1 -1
- data/CONTRIBUTORS +2 -1
- data/README.md +247 -0
- data/Rakefile +1 -2
- data/lib/neography/config.rb +48 -16
- data/lib/neography/connection.rb +151 -0
- data/lib/neography/errors.rb +42 -0
- data/lib/neography/node.rb +17 -14
- data/lib/neography/node_relationship.rb +3 -1
- data/lib/neography/node_traverser.rb +24 -20
- data/lib/neography/property.rb +31 -28
- data/lib/neography/property_container.rb +1 -1
- data/lib/neography/relationship.rb +16 -19
- data/lib/neography/rest/auto_indexes.rb +64 -0
- data/lib/neography/rest/batch.rb +262 -0
- data/lib/neography/rest/clean.rb +19 -0
- data/lib/neography/rest/cypher.rb +24 -0
- data/lib/neography/rest/gremlin.rb +24 -0
- data/lib/neography/rest/helpers.rb +26 -0
- data/lib/neography/rest/indexes.rb +97 -0
- data/lib/neography/rest/node_auto_indexes.rb +14 -0
- data/lib/neography/rest/node_indexes.rb +35 -0
- data/lib/neography/rest/node_paths.rb +57 -0
- data/lib/neography/rest/node_properties.rb +11 -0
- data/lib/neography/rest/node_relationships.rb +53 -0
- data/lib/neography/rest/node_traversal.rb +81 -0
- data/lib/neography/rest/nodes.rb +102 -0
- data/lib/neography/rest/paths.rb +36 -0
- data/lib/neography/rest/properties.rb +56 -0
- data/lib/neography/rest/relationship_auto_indexes.rb +14 -0
- data/lib/neography/rest/relationship_indexes.rb +35 -0
- data/lib/neography/rest/relationship_properties.rb +11 -0
- data/lib/neography/rest/relationships.rb +23 -0
- data/lib/neography/rest.rb +285 -615
- data/lib/neography/tasks.rb +1 -1
- data/lib/neography/version.rb +1 -1
- data/lib/neography.rb +13 -2
- data/neography.gemspec +8 -8
- data/spec/integration/authorization_spec.rb +2 -2
- data/spec/integration/index_spec.rb +4 -4
- data/spec/integration/neography_spec.rb +2 -2
- data/spec/integration/node_path_spec.rb +2 -2
- data/spec/integration/node_relationship_spec.rb +5 -3
- data/spec/integration/node_spec.rb +20 -19
- data/spec/integration/parsing_spec.rb +2 -2
- data/spec/integration/relationship_spec.rb +2 -2
- data/spec/integration/rest_batch_spec.rb +28 -28
- data/spec/integration/rest_bulk_spec.rb +2 -2
- data/spec/integration/rest_experimental_spec.rb +2 -2
- data/spec/integration/rest_gremlin_fail_spec.rb +2 -2
- data/spec/integration/rest_header_spec.rb +4 -9
- data/spec/integration/rest_index_spec.rb +21 -1
- data/spec/integration/rest_node_spec.rb +58 -44
- data/spec/integration/rest_path_spec.rb +5 -5
- data/spec/integration/rest_plugin_spec.rb +8 -2
- data/spec/integration/rest_relationship_spec.rb +35 -30
- data/spec/integration/rest_traverse_spec.rb +2 -2
- data/spec/matchers.rb +33 -0
- data/spec/neography_spec.rb +23 -0
- data/spec/spec_helper.rb +19 -1
- data/spec/unit/config_spec.rb +46 -0
- data/spec/unit/connection_spec.rb +205 -0
- data/spec/unit/node_spec.rb +100 -0
- data/spec/unit/properties_spec.rb +136 -0
- data/spec/unit/relationship_spec.rb +118 -0
- data/spec/unit/rest/batch_spec.rb +243 -0
- data/spec/unit/rest/clean_spec.rb +17 -0
- data/spec/unit/rest/cypher_spec.rb +21 -0
- data/spec/unit/rest/gremlin_spec.rb +26 -0
- data/spec/unit/rest/node_auto_indexes_spec.rb +67 -0
- data/spec/unit/rest/node_indexes_spec.rb +126 -0
- data/spec/unit/rest/node_paths_spec.rb +80 -0
- data/spec/unit/rest/node_properties_spec.rb +80 -0
- data/spec/unit/rest/node_relationships_spec.rb +78 -0
- data/spec/unit/rest/node_traversal_spec.rb +128 -0
- data/spec/unit/rest/nodes_spec.rb +188 -0
- data/spec/unit/rest/paths_spec.rb +69 -0
- data/spec/unit/rest/relationship_auto_indexes_spec.rb +67 -0
- data/spec/unit/rest/relationship_indexes_spec.rb +128 -0
- data/spec/unit/rest/relationship_properties_spec.rb +80 -0
- data/spec/unit/rest/relationships_spec.rb +22 -0
- metadata +86 -19
- data/Gemfile.lock +0 -44
- data/README.rdoc +0 -420
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Neography
|
|
4
|
+
describe Connection do
|
|
5
|
+
|
|
6
|
+
subject(:connection)
|
|
7
|
+
|
|
8
|
+
context "defaults" do
|
|
9
|
+
|
|
10
|
+
it "intializes with defaults" do
|
|
11
|
+
connection.configuration.should == "http://localhost:7474/db/data"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
context "custom options" do
|
|
17
|
+
|
|
18
|
+
subject(:connection) { Connection.new(options) }
|
|
19
|
+
|
|
20
|
+
context "hash options" do
|
|
21
|
+
let(:options) do
|
|
22
|
+
{
|
|
23
|
+
:protocol => "https://",
|
|
24
|
+
:server => "foobar",
|
|
25
|
+
:port => 4242,
|
|
26
|
+
:directory => "/dir",
|
|
27
|
+
:cypher_path => "/cyph",
|
|
28
|
+
:gremlin_path => "/grem",
|
|
29
|
+
:log_file => "neo.log",
|
|
30
|
+
:log_enabled => false,
|
|
31
|
+
:max_threads => 10,
|
|
32
|
+
:parser => Foo,
|
|
33
|
+
:authentication => "foo",
|
|
34
|
+
:username => "bar",
|
|
35
|
+
:password => "baz"
|
|
36
|
+
}
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it "accepts all options in a hash" do
|
|
40
|
+
connection.configuration.should == "https://foobar:4242/dir/db/data"
|
|
41
|
+
|
|
42
|
+
connection.protocol.should == "https://"
|
|
43
|
+
connection.server.should == "foobar"
|
|
44
|
+
connection.port.should == 4242
|
|
45
|
+
connection.directory.should == "/dir"
|
|
46
|
+
connection.cypher_path.should == "/cyph"
|
|
47
|
+
connection.gremlin_path.should == "/grem"
|
|
48
|
+
connection.log_file.should == "neo.log"
|
|
49
|
+
connection.log_enabled.should == false
|
|
50
|
+
connection.max_threads.should == 10
|
|
51
|
+
connection.parser.should == Foo
|
|
52
|
+
|
|
53
|
+
connection.authentication.should == {
|
|
54
|
+
:foo_auth => {
|
|
55
|
+
:username => "bar",
|
|
56
|
+
:password => "baz"
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
context "string option" do
|
|
63
|
+
let(:options) { "https://user:pass@somehost:8585/path" }
|
|
64
|
+
|
|
65
|
+
it "accepts a string as configuration" do
|
|
66
|
+
connection.configuration.should == "https://somehost:8585/path/db/data"
|
|
67
|
+
connection.authentication.should == {
|
|
68
|
+
:basic_auth => {
|
|
69
|
+
:username => "user",
|
|
70
|
+
:password => "pass"
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
context "requests" do
|
|
79
|
+
|
|
80
|
+
it "does a GET request" do
|
|
81
|
+
HTTParty.should_receive(:get).with("http://localhost:7474/db/data/foo/bar", { :parser => MultiJsonParser }) { stub.as_null_object }
|
|
82
|
+
connection.get("/foo/bar")
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
it "does a POST request" do
|
|
86
|
+
HTTParty.should_receive(:post).with("http://localhost:7474/db/data/foo/bar", { :parser => MultiJsonParser }) { stub.as_null_object }
|
|
87
|
+
connection.post("/foo/bar")
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
it "does a PUT request" do
|
|
91
|
+
HTTParty.should_receive(:put).with("http://localhost:7474/db/data/foo/bar", { :parser => MultiJsonParser }) { stub.as_null_object }
|
|
92
|
+
connection.put("/foo/bar")
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
it "does a DELETE request" do
|
|
96
|
+
HTTParty.should_receive(:delete).with("http://localhost:7474/db/data/foo/bar", { :parser => MultiJsonParser }) { stub.as_null_object }
|
|
97
|
+
connection.delete("/foo/bar")
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
context "authentication" do
|
|
101
|
+
subject(:connection) do
|
|
102
|
+
Connection.new({
|
|
103
|
+
:authentication => "basic",
|
|
104
|
+
:username => "foo",
|
|
105
|
+
:password => "bar"
|
|
106
|
+
})
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
it "does requests with authentication" do
|
|
110
|
+
HTTParty.should_receive(:get).with(
|
|
111
|
+
"http://localhost:7474/db/data/foo/bar",
|
|
112
|
+
{ :parser => MultiJsonParser,
|
|
113
|
+
:basic_auth => {
|
|
114
|
+
:username => "foo",
|
|
115
|
+
:password => "bar"
|
|
116
|
+
}
|
|
117
|
+
}) { stub.as_null_object }
|
|
118
|
+
|
|
119
|
+
connection.get("/foo/bar")
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
it "adds the User-Agent to the headers" do
|
|
124
|
+
HTTParty.should_receive(:get).with(
|
|
125
|
+
"http://localhost:7474/db/data/foo/bar",
|
|
126
|
+
{ :parser => MultiJsonParser,
|
|
127
|
+
:headers => { "User-Agent" => "Neography/#{Neography::VERSION}" }
|
|
128
|
+
}) { stub.as_null_object }
|
|
129
|
+
|
|
130
|
+
connection.get("/foo/bar", :headers => {})
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
context "errors" do
|
|
134
|
+
|
|
135
|
+
it "raises NodeNotFoundException" do
|
|
136
|
+
response = error_response(code: 404, message: "a message", exception: "NodeNotFoundException")
|
|
137
|
+
HTTParty.stub(:get).and_return(response)
|
|
138
|
+
expect {
|
|
139
|
+
connection.get("/foo/bar")
|
|
140
|
+
}.to raise_error NodeNotFoundException
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
it "raises OperationFailureException" do
|
|
144
|
+
response = error_response(code: 409, message: "a message", exception: "OperationFailureException")
|
|
145
|
+
HTTParty.stub(:get).and_return(response)
|
|
146
|
+
expect {
|
|
147
|
+
connection.get("/foo/bar")
|
|
148
|
+
}.to raise_error OperationFailureException
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
it "raises PropertyValueException" do
|
|
152
|
+
response = error_response(code: 400, message: "a message", exception: "PropertyValueException")
|
|
153
|
+
HTTParty.stub(:get).and_return(response)
|
|
154
|
+
expect {
|
|
155
|
+
connection.get("/foo/bar")
|
|
156
|
+
}.to raise_error PropertyValueException
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
it "raises NoSuchPropertyException" do
|
|
160
|
+
response = error_response(code: 404, message: "a message", exception: "NoSuchPropertyException")
|
|
161
|
+
HTTParty.stub(:get).and_return(response)
|
|
162
|
+
expect {
|
|
163
|
+
connection.get("/foo/bar")
|
|
164
|
+
}.to raise_error NoSuchPropertyException
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
it "raises RelationshipNotFoundException" do
|
|
168
|
+
response = error_response(code: 404, message: "a message", exception: "RelationshipNotFoundException")
|
|
169
|
+
HTTParty.stub(:get).and_return(response)
|
|
170
|
+
expect {
|
|
171
|
+
connection.get("/foo/bar")
|
|
172
|
+
}.to raise_error RelationshipNotFoundException
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
it "raises BadInputException" do
|
|
176
|
+
response = error_response(code: 400, message: "a message", exception: "BadInputException")
|
|
177
|
+
HTTParty.stub(:get).and_return(response)
|
|
178
|
+
expect {
|
|
179
|
+
connection.get("/foo/bar")
|
|
180
|
+
}.to raise_error BadInputException
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
it "raises UnauthorizedError" do
|
|
184
|
+
response = error_response(code: 401)
|
|
185
|
+
HTTParty.stub(:get).and_return(response)
|
|
186
|
+
expect {
|
|
187
|
+
connection.get("/foo/bar")
|
|
188
|
+
}.to raise_error UnauthorizedError
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
it "raises NeographyError in all other cases" do
|
|
192
|
+
response = error_response(code: 418, message: "I'm a teapot.")
|
|
193
|
+
HTTParty.stub(:get).and_return(response)
|
|
194
|
+
expect {
|
|
195
|
+
connection.get("/foo/bar")
|
|
196
|
+
}.to raise_error NeographyError
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
class Foo; end
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Neography
|
|
4
|
+
describe Node do
|
|
5
|
+
|
|
6
|
+
describe "::create" do
|
|
7
|
+
context "no explicit server" do
|
|
8
|
+
|
|
9
|
+
before do
|
|
10
|
+
@db = mock(Neography::Rest, :is_a? => true).as_null_object
|
|
11
|
+
Rest.stub(:new) { @db }
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it "assigns a new Rest db by default" do
|
|
15
|
+
node = Node.create
|
|
16
|
+
node.neo_server.should == @db
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it "creates without arguments" do
|
|
20
|
+
@db.should_receive(:create_node).with(nil)
|
|
21
|
+
Node.create
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it "creates with only a hash argument" do
|
|
25
|
+
properties = { :foo => "bar" }
|
|
26
|
+
@db.should_receive(:create_node).with(properties)
|
|
27
|
+
Node.create(properties)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
context "explicit server" do
|
|
33
|
+
|
|
34
|
+
it "cannot pass a server as the first argument, properties as the second (deprecated)" do
|
|
35
|
+
@other_server = Neography::Rest.new
|
|
36
|
+
properties = { :foo => "bar" }
|
|
37
|
+
@other_server.should_not_receive(:create_node).with(properties)
|
|
38
|
+
expect {
|
|
39
|
+
Node.create(@other_server, properties)
|
|
40
|
+
}.to raise_error(ArgumentError)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it "can pass properties as the first argument, a server as the second" do
|
|
44
|
+
@other_server = Neography::Rest.new
|
|
45
|
+
properties = { :foo => "bar" }
|
|
46
|
+
@other_server.should_receive(:create_node).with(properties)
|
|
47
|
+
Node.create(properties, @other_server)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
describe "::load" do
|
|
54
|
+
context "no explicit server" do
|
|
55
|
+
|
|
56
|
+
before do
|
|
57
|
+
# stub out actual connections
|
|
58
|
+
@db = stub(Rest).as_null_object
|
|
59
|
+
Rest.stub(:new) { @db }
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it "load by id" do
|
|
63
|
+
@db.should_receive(:get_node).with(5)
|
|
64
|
+
Node.load(5)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
it "loads by node" do
|
|
68
|
+
node = Node.new
|
|
69
|
+
@db.should_receive(:get_node).with(node)
|
|
70
|
+
Node.load(node)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
it "loads by full server string" do
|
|
74
|
+
@db.should_receive(:get_node).with("http://localhost:7474/db/data/node/2")
|
|
75
|
+
Node.load("http://localhost:7474/db/data/node/2")
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
context "explicit server" do
|
|
81
|
+
|
|
82
|
+
it "cannot pass a server as the first argument, node as the second (depracted)" do
|
|
83
|
+
@other_server = Neography::Rest.new
|
|
84
|
+
@other_server.should_not_receive(:get_node).with(42)
|
|
85
|
+
expect {
|
|
86
|
+
node = Node.load(@other_server, 42)
|
|
87
|
+
}.to raise_error(ArgumentError)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
it "can pass a node as the first argument, server as the second" do
|
|
91
|
+
@other_server = Neography::Rest.new
|
|
92
|
+
@other_server.should_receive(:get_node).with(42)
|
|
93
|
+
node = Node.load(42, @other_server)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
end
|
|
100
|
+
end
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Neography
|
|
4
|
+
describe "Properties" do
|
|
5
|
+
|
|
6
|
+
before do
|
|
7
|
+
@db = mock(Neography::Rest, :is_a? => true).as_null_object
|
|
8
|
+
Rest.stub(:new) { @db }
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
context "Node" do
|
|
12
|
+
|
|
13
|
+
subject(:node) do
|
|
14
|
+
node = Node.create
|
|
15
|
+
node.stub(:neo_id => 42)
|
|
16
|
+
node
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it "sets properties as accessor" do
|
|
20
|
+
@db.should_receive(:"set_node_properties").with(42, { "key" => "value" })
|
|
21
|
+
node.key = "value"
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it "sets properties as array entry" do
|
|
25
|
+
@db.should_receive(:"set_node_properties").with(42, { "key" => "value" })
|
|
26
|
+
node["key"] = "value"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it "gets properties as accessor" do
|
|
30
|
+
@db.stub(:"set_node_properties")
|
|
31
|
+
node.key = "value"
|
|
32
|
+
node.key.should == "value"
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it "gets properties as array entry" do
|
|
36
|
+
@db.stub(:"set_node_properties")
|
|
37
|
+
node["key"] = "value"
|
|
38
|
+
node["key"].should == "value"
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it "resets properties as accessor" do
|
|
42
|
+
@db.should_receive(:"remove_node_properties").with(42, ["key"])
|
|
43
|
+
node.key = nil
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it "resets properties as array entry" do
|
|
47
|
+
@db.should_receive(:"remove_node_properties").with(42, ["key"])
|
|
48
|
+
node["key"] = nil
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it "gets unknown properties as nil" do
|
|
52
|
+
node.unknown.should == nil
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it "overwrites existing properties" do
|
|
56
|
+
@db.should_receive(:"set_node_properties").with(42, { "key" => "value1" })
|
|
57
|
+
node.key = "value1"
|
|
58
|
+
|
|
59
|
+
@db.should_receive(:"set_node_properties").with(42, { "key" => "value2" })
|
|
60
|
+
node.key = "value2"
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it "knows its attributes" do
|
|
64
|
+
@db.stub(:"set_node_properties")
|
|
65
|
+
node.key = "value"
|
|
66
|
+
node["key2"] = "value"
|
|
67
|
+
node.attributes.should =~ [ :key, :key2 ]
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
context "Relationship" do
|
|
73
|
+
|
|
74
|
+
subject(:relationship) do
|
|
75
|
+
from = Node.create
|
|
76
|
+
to = Node.create
|
|
77
|
+
|
|
78
|
+
rel = Relationship.create(:type, from, to)
|
|
79
|
+
rel.stub(:neo_id => 42)
|
|
80
|
+
rel
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
it "sets properties as accessor" do
|
|
84
|
+
@db.should_receive(:"set_relationship_properties").with(42, { "key" => "value" })
|
|
85
|
+
relationship.key = "value"
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
it "sets properties as array entry" do
|
|
89
|
+
@db.should_receive(:"set_relationship_properties").with(42, { "key" => "value" })
|
|
90
|
+
relationship["key"] = "value"
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
it "gets properties as accessor" do
|
|
94
|
+
@db.stub(:"set_relationship_properties")
|
|
95
|
+
relationship.key = "value"
|
|
96
|
+
relationship.key.should == "value"
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
it "gets properties as array entry" do
|
|
100
|
+
@db.stub(:"set_relationship_properties")
|
|
101
|
+
relationship["key"] = "value"
|
|
102
|
+
relationship["key"].should == "value"
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
it "resets properties as accessor" do
|
|
106
|
+
@db.should_receive(:"remove_relationship_properties").with(42, ["key"])
|
|
107
|
+
relationship.key = nil
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
it "resets properties as array entry" do
|
|
111
|
+
@db.should_receive(:"remove_relationship_properties").with(42, ["key"])
|
|
112
|
+
relationship["key"] = nil
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
it "gets unknown properties as nil" do
|
|
116
|
+
relationship.unknown.should == nil
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
it "overwrites existing properties" do
|
|
120
|
+
@db.should_receive(:"set_relationship_properties").with(42, { "key" => "value1" })
|
|
121
|
+
relationship.key = "value1"
|
|
122
|
+
|
|
123
|
+
@db.should_receive(:"set_relationship_properties").with(42, { "key" => "value2" })
|
|
124
|
+
relationship.key = "value2"
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
it "knows its attributes" do
|
|
128
|
+
@db.stub(:"set_relationship_properties")
|
|
129
|
+
relationship.key = "value"
|
|
130
|
+
relationship["key2"] = "value"
|
|
131
|
+
relationship.attributes.should =~ [ :key, :key2 ]
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Neography
|
|
4
|
+
describe Relationship do
|
|
5
|
+
|
|
6
|
+
let(:db) { stub(Rest).as_null_object }
|
|
7
|
+
let(:relationship_hash) do
|
|
8
|
+
{
|
|
9
|
+
"self" => "0",
|
|
10
|
+
"start" => "1",
|
|
11
|
+
"end" => "2",
|
|
12
|
+
"data" => {}
|
|
13
|
+
}
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
let(:from) { stub(:neo_server => db) }
|
|
17
|
+
let(:to) { stub(:neo_server => db) }
|
|
18
|
+
let(:props) { { :foo => "bar" } }
|
|
19
|
+
|
|
20
|
+
describe "::create" do
|
|
21
|
+
it "creates a new node through Rest" do
|
|
22
|
+
db.should_receive(:create_relationship).with("type", from, to, props)
|
|
23
|
+
|
|
24
|
+
Relationship.create("type", from, to, props)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it "assigns fields" do
|
|
28
|
+
db.stub(:create_relationship).and_return(relationship_hash)
|
|
29
|
+
|
|
30
|
+
rel = Relationship.create("type", from, to, props)
|
|
31
|
+
|
|
32
|
+
rel.start_node.should == from
|
|
33
|
+
rel.end_node.should == to
|
|
34
|
+
rel.rel_type.should == "type"
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
describe "::load" do
|
|
39
|
+
context "no explicit server" do
|
|
40
|
+
|
|
41
|
+
before do
|
|
42
|
+
# stub out actual connections
|
|
43
|
+
@db = stub(Rest).as_null_object
|
|
44
|
+
Rest.stub(:new) { @db }
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it "load by id" do
|
|
48
|
+
@db.should_receive(:get_relationship).with(5)
|
|
49
|
+
Relationship.load(5)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
it "loads by relationship" do
|
|
53
|
+
relationship = Relationship.new(relationship_hash)
|
|
54
|
+
@db.should_receive(:get_relationship).with(relationship)
|
|
55
|
+
Relationship.load(relationship)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it "loads by full server string" do
|
|
59
|
+
@db.should_receive(:get_relationship).with("http://localhost:7474/db/data/relationship/2")
|
|
60
|
+
Relationship.load("http://localhost:7474/db/data/relationship/2")
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
context "explicit server" do
|
|
66
|
+
|
|
67
|
+
it "cannot pass a server as the first argument, relationship as the second" do
|
|
68
|
+
@other_server = Neography::Rest.new
|
|
69
|
+
@other_server.should_not_receive(:get_relationship).with(42)
|
|
70
|
+
expect {
|
|
71
|
+
relationship = Relationship.load(@other_server, 42)
|
|
72
|
+
}.to raise_error(ArgumentError)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
it "can pass a relationship as the first argument, server as the second" do
|
|
76
|
+
@other_server = Neography::Rest.new
|
|
77
|
+
@other_server.should_receive(:get_relationship).with(42)
|
|
78
|
+
relationship = Relationship.load(42, @other_server)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
describe "#del" do
|
|
85
|
+
|
|
86
|
+
before do
|
|
87
|
+
db.stub(:create_relationship) { relationship_hash }
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
subject(:relationship) { Relationship.create("type", from, to, props) }
|
|
91
|
+
|
|
92
|
+
it "deletes a node" do
|
|
93
|
+
db.should_receive(:delete_relationship).with("0")
|
|
94
|
+
relationship.del
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
describe "#other_node" do
|
|
100
|
+
|
|
101
|
+
before do
|
|
102
|
+
db.stub(:create_relationship) { relationship_hash }
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
subject(:relationship) { Relationship.create("type", from, to, props) }
|
|
106
|
+
|
|
107
|
+
it "knows the other node based on from" do
|
|
108
|
+
relationship.other_node(from).should == to
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
it "knows the other node based on to" do
|
|
112
|
+
relationship.other_node(to).should == from
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
end
|
|
118
|
+
end
|