ashikawa-core 0.12.0 → 0.13.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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.hound.yml +1 -1
- data/.travis.yml +1 -5
- data/CHANGELOG.md +13 -0
- data/README.md +2 -3
- data/config/reek.yml +1 -0
- data/lib/ashikawa-core/collection.rb +14 -1
- data/lib/ashikawa-core/connection.rb +1 -0
- data/lib/ashikawa-core/database.rb +46 -3
- data/lib/ashikawa-core/document.rb +14 -1
- data/lib/ashikawa-core/edge.rb +6 -1
- data/lib/ashikawa-core/edge_collection.rb +92 -0
- data/lib/ashikawa-core/error_response.rb +16 -0
- data/lib/ashikawa-core/exceptions/client_error/resource_not_found/collection_not_in_graph.rb +18 -0
- data/lib/ashikawa-core/exceptions/client_error/resource_not_found/graph_not_found.rb +18 -0
- data/lib/ashikawa-core/faraday_factory.rb +1 -1
- data/lib/ashikawa-core/graph.rb +222 -0
- data/lib/ashikawa-core/version.rb +11 -1
- data/lib/ashikawa-core/vertex_collection.rb +35 -0
- data/lib/ashikawa-core/x_arango_version.rb +26 -0
- data/spec/acceptance/graph_spec.rb +89 -0
- data/spec/acceptance/spec_helper.rb +15 -2
- data/spec/unit/collection_spec.rb +23 -8
- data/spec/unit/connection_spec.rb +47 -0
- data/spec/unit/database_spec.rb +111 -0
- data/spec/unit/document_spec.rb +16 -0
- data/spec/unit/edge_collection_spec.rb +105 -0
- data/spec/unit/edge_spec.rb +23 -0
- data/spec/unit/exception_spec.rb +12 -0
- data/spec/unit/faraday_factory_spec.rb +1 -0
- data/spec/unit/graph_spec.rb +270 -0
- data/spec/unit/vertex_collection_spec.rb +48 -0
- metadata +17 -3
@@ -21,6 +21,19 @@ describe Ashikawa::Core::Connection do
|
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
+
it 'should include include the x-arango-version header in each request' do
|
25
|
+
[:get, :post, :put, :delete].each do |http_verb|
|
26
|
+
request_stub.send(http_verb, '/_db/_system/_api/my/path') do |request|
|
27
|
+
expect(request[:request_headers][:'X-Arango-Version']).to eq '20200'
|
28
|
+
[200, response_headers, JSON.generate({ 'name' => 'dude' })]
|
29
|
+
end
|
30
|
+
|
31
|
+
subject.send_request 'my/path', http_verb => {}
|
32
|
+
|
33
|
+
request_stub.verify_stubbed_calls
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
24
37
|
it 'should send a get request' do
|
25
38
|
request_stub.get('/_db/_system/_api/my/path') do
|
26
39
|
[200, response_headers, JSON.generate({ 'name' => 'dude' })]
|
@@ -205,6 +218,40 @@ describe Ashikawa::Core::Connection do
|
|
205
218
|
request_stub.verify_stubbed_calls
|
206
219
|
end
|
207
220
|
|
221
|
+
context 'handle 404 in the gharial module' do
|
222
|
+
let(:request_url) { '/_db/_system/_api/gharial/vertex/42' }
|
223
|
+
|
224
|
+
it 'should raise GraphNotFoundException if the graph could not be found' do
|
225
|
+
request_stub.get(request_url) do
|
226
|
+
[404, response_headers, { 'errorMessage' => 'graph not found' }]
|
227
|
+
end
|
228
|
+
|
229
|
+
expect { subject.send_request 'gharial/vertex/42' }.to raise_error(Ashikawa::Core::GraphNotFoundException)
|
230
|
+
|
231
|
+
request_stub.verify_stubbed_calls
|
232
|
+
end
|
233
|
+
|
234
|
+
it 'should raise CollectionNotFoundException the collection could not be found' do
|
235
|
+
request_stub.get(request_url) do
|
236
|
+
[404, response_headers, { 'errorMessage' => 'collection not found' }]
|
237
|
+
end
|
238
|
+
|
239
|
+
expect { subject.send_request 'gharial/vertex/42' }.to raise_error(Ashikawa::Core::CollectionNotFoundException)
|
240
|
+
|
241
|
+
request_stub.verify_stubbed_calls
|
242
|
+
end
|
243
|
+
|
244
|
+
it 'should raise DocumentNotFoundException the document could not be found' do
|
245
|
+
request_stub.get(request_url) do
|
246
|
+
[404, response_headers, { 'errorMessage' => 'document not found' }]
|
247
|
+
end
|
248
|
+
|
249
|
+
expect { subject.send_request 'gharial/vertex/42' }.to raise_error(Ashikawa::Core::DocumentNotFoundException)
|
250
|
+
|
251
|
+
request_stub.verify_stubbed_calls
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
208
255
|
it 'should raise an exception for unknown pathes' do
|
209
256
|
request_stub.get('/_db/_system/_api/unknown_path/4590/333') do
|
210
257
|
[404, response_headers, '']
|
data/spec/unit/database_spec.rb
CHANGED
@@ -208,5 +208,116 @@ describe Ashikawa::Core::Database do
|
|
208
208
|
|
209
209
|
expect(subject.create_transaction(js_function, collections)).to be(transaction)
|
210
210
|
end
|
211
|
+
|
212
|
+
context 'managing graphs' do
|
213
|
+
let(:raw_graph) { double('RawGraph') }
|
214
|
+
let(:gharial_response) { double('GharialResponse') }
|
215
|
+
let(:graph) { instance_double(Ashikawa::Core::Graph) }
|
216
|
+
|
217
|
+
before do
|
218
|
+
allow(gharial_response).to receive(:[]).with('graph').and_return(raw_graph)
|
219
|
+
end
|
220
|
+
|
221
|
+
it 'should fetch a single graph if it exists' do
|
222
|
+
expect(connection).to receive(:send_request)
|
223
|
+
.with('gharial/my_awesome_graph')
|
224
|
+
.and_return(gharial_response)
|
225
|
+
|
226
|
+
expect(Ashikawa::Core::Graph).to receive(:new)
|
227
|
+
.with(subject, raw_graph)
|
228
|
+
.and_return(graph)
|
229
|
+
|
230
|
+
expect(subject.graph('my_awesome_graph')).to eq graph
|
231
|
+
end
|
232
|
+
|
233
|
+
it "should create a single graph if it doesn't exist" do
|
234
|
+
expect(connection).to receive(:send_request).with('gharial/my_awesome_graph') do
|
235
|
+
raise Ashikawa::Core::GraphNotFoundException
|
236
|
+
end
|
237
|
+
|
238
|
+
expect(subject).to receive(:create_graph).with('my_awesome_graph').and_return(graph)
|
239
|
+
|
240
|
+
expect(subject.graph('my_awesome_graph')).to eq graph
|
241
|
+
end
|
242
|
+
|
243
|
+
it 'should create a graph' do
|
244
|
+
expect(connection).to receive(:send_request)
|
245
|
+
.with('gharial', post: { name: 'my_awesome_graph' })
|
246
|
+
.and_return(gharial_response)
|
247
|
+
|
248
|
+
expect(Ashikawa::Core::Graph).to receive(:new)
|
249
|
+
.with(subject, raw_graph)
|
250
|
+
.and_return(graph)
|
251
|
+
|
252
|
+
expect(subject.create_graph('my_awesome_graph')).to eq graph
|
253
|
+
end
|
254
|
+
|
255
|
+
it 'should create a single graph with list of edge_definitions' do
|
256
|
+
create_params = {
|
257
|
+
name: 'my_awesome_graph',
|
258
|
+
edgeDefinitions: [
|
259
|
+
{ collection: 'visited', from: ['ponies'], to: ['places'] }
|
260
|
+
]
|
261
|
+
}
|
262
|
+
expect(connection).to receive(:send_request)
|
263
|
+
.with('gharial', post: create_params)
|
264
|
+
.and_return(gharial_response)
|
265
|
+
|
266
|
+
expect(Ashikawa::Core::Graph).to receive(:new)
|
267
|
+
.with(subject, raw_graph)
|
268
|
+
.and_return(graph)
|
269
|
+
|
270
|
+
options = {
|
271
|
+
edge_definitions: [
|
272
|
+
{
|
273
|
+
collection: 'visited',
|
274
|
+
from: ['ponies'],
|
275
|
+
to: ['places']
|
276
|
+
}
|
277
|
+
]
|
278
|
+
}
|
279
|
+
|
280
|
+
expect(subject.create_graph('my_awesome_graph', options)).to eq graph
|
281
|
+
end
|
282
|
+
|
283
|
+
it 'should create a single graph with list of orphan_collections' do
|
284
|
+
create_params = {
|
285
|
+
name: 'my_awesome_graph',
|
286
|
+
orphanCollections: ['i_am_alone']
|
287
|
+
}
|
288
|
+
expect(connection).to receive(:send_request)
|
289
|
+
.with('gharial', post: create_params)
|
290
|
+
.and_return(gharial_response)
|
291
|
+
|
292
|
+
expect(Ashikawa::Core::Graph).to receive(:new)
|
293
|
+
.with(subject, raw_graph)
|
294
|
+
.and_return(graph)
|
295
|
+
|
296
|
+
options = {
|
297
|
+
orphan_collections: ['i_am_alone']
|
298
|
+
}
|
299
|
+
|
300
|
+
expect(subject.create_graph('my_awesome_graph', options)).to eq graph
|
301
|
+
|
302
|
+
end
|
303
|
+
|
304
|
+
it 'should fetch a list of all graphs in the database' do
|
305
|
+
raw_list_of_graphs = double('ListOfGraphs')
|
306
|
+
allow(raw_list_of_graphs).to receive(:[])
|
307
|
+
.with('graphs')
|
308
|
+
.and_return([raw_graph])
|
309
|
+
|
310
|
+
expect(connection).to receive(:send_request)
|
311
|
+
.with('gharial')
|
312
|
+
.and_return(raw_list_of_graphs)
|
313
|
+
|
314
|
+
expect(Ashikawa::Core::Graph).to receive(:new)
|
315
|
+
.with(subject, raw_graph)
|
316
|
+
.and_return(graph)
|
317
|
+
|
318
|
+
expect(subject.graphs).to eq [graph]
|
319
|
+
end
|
320
|
+
end
|
321
|
+
|
211
322
|
end
|
212
323
|
end
|
data/spec/unit/document_spec.rb
CHANGED
@@ -57,6 +57,22 @@ describe Ashikawa::Core::Document do
|
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
60
|
+
describe 'initialized with a garaph' do
|
61
|
+
let(:graph) { double('Ashikawa::Core::Graph', name: 'my-graph') }
|
62
|
+
let(:additional_data_with_graph) { { graph: graph, more_info: more_info } }
|
63
|
+
subject { Ashikawa::Core::Document.new(database, raw_data, additional_data_with_graph) }
|
64
|
+
|
65
|
+
its(['more_info']) { should eq(more_info) }
|
66
|
+
its(:graph) { should eq(graph) }
|
67
|
+
|
68
|
+
it 'should send requests through the graph module' do
|
69
|
+
expect(database).to receive(:send_request)
|
70
|
+
.with("gharial/my-graph/vertex/#{id}", {})
|
71
|
+
|
72
|
+
subject.send(:send_request_for_document, {})
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
60
76
|
describe 'initialized document with ID' do
|
61
77
|
subject { Ashikawa::Core::Document.new(database, raw_data) }
|
62
78
|
|
@@ -0,0 +1,105 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
require 'unit/spec_helper'
|
3
|
+
require 'ashikawa-core/edge_collection'
|
4
|
+
require 'ashikawa-core/document'
|
5
|
+
require 'ashikawa-core/graph'
|
6
|
+
require 'ashikawa-core/database'
|
7
|
+
|
8
|
+
describe Ashikawa::Core::EdgeCollection do
|
9
|
+
let(:database) { instance_double('Ashikawa::Core::Database') }
|
10
|
+
let(:raw_collection) do
|
11
|
+
{
|
12
|
+
'id' => '60768679',
|
13
|
+
'name' => 'relation',
|
14
|
+
'status' => 3,
|
15
|
+
'type' => 3,
|
16
|
+
'error' => false,
|
17
|
+
'code' => 200
|
18
|
+
}
|
19
|
+
end
|
20
|
+
let(:graph) { instance_double('Ashikawa::Core::Graph', name: 'my_graph') }
|
21
|
+
let(:new_edge) { instance_double('Ashikawa::Core::Edge') }
|
22
|
+
let(:raw_edge) { double('RawEdge') }
|
23
|
+
let(:post_response) { { 'edge' => { '_key' => '123' } } }
|
24
|
+
|
25
|
+
context 'an initialized edge collection' do
|
26
|
+
subject { Ashikawa::Core::EdgeCollection.new(database, raw_collection, graph) }
|
27
|
+
|
28
|
+
it 'should be a subclass of Collection' do
|
29
|
+
expect(subject).to be_kind_of Ashikawa::Core::Collection
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should have a reference to its graph' do
|
33
|
+
expect(subject.graph).to eq graph
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'adding edges' do
|
37
|
+
let(:this_document) { instance_double('Ashikawa::Core::Document', id: 'this_document_id') }
|
38
|
+
let(:that_document) { instance_double('Ashikawa::Core::Document', id: 'that_document_id') }
|
39
|
+
|
40
|
+
before do
|
41
|
+
allow(subject).to receive(:send_request)
|
42
|
+
.with('gharial/my_graph/edge/relation/', post: { _from: 'this_document_id', _to: 'that_document_id' })
|
43
|
+
.and_return(post_response)
|
44
|
+
|
45
|
+
allow(subject).to receive(:fetch)
|
46
|
+
.with('123')
|
47
|
+
.and_return(new_edge)
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'should add a directed relation between to vertices' do
|
51
|
+
expect(subject).to receive(:send_request)
|
52
|
+
.with('gharial/my_graph/edge/relation/', post: { _from: 'this_document_id', _to: 'that_document_id' })
|
53
|
+
.and_return(post_response)
|
54
|
+
|
55
|
+
subject.add(from: this_document, to: that_document)
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'should return the edge documents' do
|
59
|
+
created_edges = subject.add(from: this_document, to: that_document)
|
60
|
+
|
61
|
+
expect(created_edges).to eq new_edge
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context 'removing edges by example' do
|
66
|
+
let(:this_document) { instance_double('Ashikawa::Core::Document', id: 'this_document_id') }
|
67
|
+
let(:that_document) { instance_double('Ashikawa::Core::Document', id: 'that_document_id') }
|
68
|
+
let(:query) { double('Query') }
|
69
|
+
let(:aql_string) do
|
70
|
+
<<-AQL.gsub(/^[ \t]*/, '')
|
71
|
+
FOR e IN @@edge_collection
|
72
|
+
FILTER e._from == @from && e._to == @to
|
73
|
+
REMOVE e._key IN @@edge_collection
|
74
|
+
AQL
|
75
|
+
end
|
76
|
+
let(:bind_vars) { { :'@edge_collection' => 'relation', :from => 'this_document_id', :to => 'that_document_id' } }
|
77
|
+
|
78
|
+
before do
|
79
|
+
allow(database).to receive(:query).and_return(query)
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'should remove the edges' do
|
83
|
+
expect(query).to receive(:execute)
|
84
|
+
.with(aql_string, bind_vars: bind_vars)
|
85
|
+
|
86
|
+
subject.remove(from: this_document, to: that_document)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'should overwrite #send_request_for_this_collection to use gharial' do
|
91
|
+
expect(subject).to receive(:send_request)
|
92
|
+
.with('gharial/my_graph/edge/relation/edge_key', {})
|
93
|
+
|
94
|
+
subject.send(:send_request_for_this_collection, 'edge_key')
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'should overwrite the #build_content_class to create edges with the graph attached' do
|
98
|
+
expect(Ashikawa::Core::Edge).to receive(:new)
|
99
|
+
.with(database, raw_edge, graph: graph)
|
100
|
+
.and_return(new_edge)
|
101
|
+
|
102
|
+
subject.build_content_class(raw_edge)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
data/spec/unit/edge_spec.rb
CHANGED
@@ -55,6 +55,13 @@ describe Ashikawa::Core::Edge do
|
|
55
55
|
subject['last_name'] = new_last_name
|
56
56
|
subject.save
|
57
57
|
end
|
58
|
+
|
59
|
+
it 'should send requests to the edge endpoint' do
|
60
|
+
expect(database).to receive(:send_request)
|
61
|
+
.with("edge/#{id}", {})
|
62
|
+
|
63
|
+
subject.send(:send_request_for_document, {})
|
64
|
+
end
|
58
65
|
end
|
59
66
|
|
60
67
|
describe 'initializing edge with additional data' do
|
@@ -63,5 +70,21 @@ describe Ashikawa::Core::Edge do
|
|
63
70
|
subject { Ashikawa::Core::Edge.new(database, raw_data, additional_data) }
|
64
71
|
|
65
72
|
its(['more_info']) { should eq(more_info) }
|
73
|
+
|
74
|
+
context 'initializing with a graph' do
|
75
|
+
let(:graph) { double('Ashikawa::Core::Graph', name: 'my-graph') }
|
76
|
+
let(:additional_data_with_graph) { { graph: graph, more_info: more_info } }
|
77
|
+
subject { Ashikawa::Core::Edge.new(database, raw_data, additional_data_with_graph) }
|
78
|
+
|
79
|
+
its(['more_info']) { should eq(more_info) }
|
80
|
+
its(:graph) { should eq(graph) }
|
81
|
+
|
82
|
+
it 'should send requests through the graph module' do
|
83
|
+
expect(database).to receive(:send_request)
|
84
|
+
.with("gharial/my-graph/edge/#{id}", {})
|
85
|
+
|
86
|
+
subject.send(:send_request_for_document, {})
|
87
|
+
end
|
88
|
+
end
|
66
89
|
end
|
67
90
|
end
|
data/spec/unit/exception_spec.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
|
+
require 'unit/spec_helper'
|
3
|
+
|
2
4
|
require 'ashikawa-core/exceptions/no_collection_provided'
|
3
5
|
require 'ashikawa-core/exceptions/client_error'
|
4
6
|
require 'ashikawa-core/exceptions/client_error/authentication_failed'
|
@@ -6,7 +8,9 @@ require 'ashikawa-core/exceptions/client_error/bad_syntax'
|
|
6
8
|
require 'ashikawa-core/exceptions/client_error/resource_not_found'
|
7
9
|
require 'ashikawa-core/exceptions/client_error/resource_not_found/document_not_found'
|
8
10
|
require 'ashikawa-core/exceptions/client_error/resource_not_found/collection_not_found'
|
11
|
+
require 'ashikawa-core/exceptions/client_error/resource_not_found/collection_not_in_graph'
|
9
12
|
require 'ashikawa-core/exceptions/client_error/resource_not_found/index_not_found'
|
13
|
+
require 'ashikawa-core/exceptions/client_error/resource_not_found/graph_not_found'
|
10
14
|
require 'ashikawa-core/exceptions/server_error'
|
11
15
|
require 'ashikawa-core/exceptions/server_error/json_error'
|
12
16
|
|
@@ -48,6 +52,14 @@ describe Ashikawa::Core::IndexNotFoundException do
|
|
48
52
|
its(:to_s) { should include 'does not exist' }
|
49
53
|
end
|
50
54
|
|
55
|
+
describe Ashikawa::Core::GraphNotFoundException do
|
56
|
+
its(:to_s) { should include 'does not exist' }
|
57
|
+
end
|
58
|
+
|
59
|
+
describe Ashikawa::Core::CollectionNotInGraphException do
|
60
|
+
its(:to_s) { should include 'not been added to the graph yet' }
|
61
|
+
end
|
62
|
+
|
51
63
|
describe Ashikawa::Core::ServerError do
|
52
64
|
let(:error_message) { 'The server is misbehaving' }
|
53
65
|
subject { Ashikawa::Core::ServerError.new(error_message) }
|
@@ -11,6 +11,7 @@ describe Ashikawa::Core::FaradayFactory do
|
|
11
11
|
before do
|
12
12
|
allow(Faraday).to receive(:new).with(api_string).and_yield(config_block)
|
13
13
|
allow(config_block).to receive(:request).with(:json)
|
14
|
+
allow(config_block).to receive(:request).with(:x_arango_version)
|
14
15
|
allow(config_block).to receive(:response).with(:error_response)
|
15
16
|
allow(config_block).to receive(:response).with(:json)
|
16
17
|
allow(config_block).to receive(:adapter).with(Faraday.default_adapter)
|
@@ -0,0 +1,270 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
require 'unit/spec_helper'
|
3
|
+
require 'ashikawa-core/graph'
|
4
|
+
require 'ashikawa-core/document'
|
5
|
+
require 'ashikawa-core/database'
|
6
|
+
|
7
|
+
describe Ashikawa::Core::Graph do
|
8
|
+
let(:database) { instance_double('Ashikawa::Core::Database') }
|
9
|
+
let(:raw_graph) { double('RawGraph').as_null_object }
|
10
|
+
let(:edge_definition) do
|
11
|
+
{
|
12
|
+
'collection' => 'friends',
|
13
|
+
'from' => %w(ponies),
|
14
|
+
'to' => %w(dragons ponies)
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
def collection_double(name)
|
19
|
+
instance_double('Ashikawa::Core::VertexCollection', name: name.to_s)
|
20
|
+
end
|
21
|
+
|
22
|
+
def edge_collection_double(name)
|
23
|
+
instance_double('Ashikawa::Core::EdgeCollection', name: name.to_s)
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'an initialized graph' do
|
27
|
+
subject { Ashikawa::Core::Graph.new(database, raw_graph) }
|
28
|
+
|
29
|
+
before do
|
30
|
+
allow(raw_graph).to receive(:[]).with('name').and_return('my_graph')
|
31
|
+
allow(raw_graph).to receive(:[]).with('_rev').and_return('A113')
|
32
|
+
allow(raw_graph).to receive(:fetch).with('orphanCollections').and_return(['orphan'])
|
33
|
+
allow(raw_graph).to receive(:fetch).with('edgeDefinitions').and_return([edge_definition])
|
34
|
+
end
|
35
|
+
|
36
|
+
its(:database) { should eq database }
|
37
|
+
its(:name) { should eq 'my_graph' }
|
38
|
+
its(:revision) { should eq 'A113' }
|
39
|
+
its(:edge_definitions) { should eq [edge_definition] }
|
40
|
+
|
41
|
+
it 'should delegate send_request to the database' do
|
42
|
+
expect(database).to receive(:send_request).with('gharial/my_graph')
|
43
|
+
|
44
|
+
subject.send_request 'gharial/my_graph'
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'should extract the name from the _key if no name was provided' do
|
48
|
+
allow(raw_graph).to receive(:[]).with('name').and_return(nil)
|
49
|
+
allow(raw_graph).to receive(:[]).with('_key').and_return('my_graph')
|
50
|
+
expect(subject.name).to eq 'my_graph'
|
51
|
+
end
|
52
|
+
|
53
|
+
context 'finding neighbors' do
|
54
|
+
let(:some_document) { instance_double('Ashikawa::Core::Document', key: 'somekey') }
|
55
|
+
let(:query) { double('Query') }
|
56
|
+
let(:cursor) { double('Cursor') }
|
57
|
+
|
58
|
+
before do
|
59
|
+
allow(database).to receive(:query).and_return(query)
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'should return the cursor for the query' do
|
63
|
+
allow(query).to receive(:execute)
|
64
|
+
.and_return(cursor)
|
65
|
+
|
66
|
+
expect(subject.neighbors(some_document)).to eq cursor
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'should run a neighbors AQL for all edge collections' do
|
70
|
+
aql_string = <<-AQL.gsub(/^[ \t]*/, '')
|
71
|
+
FOR n IN GRAPH_NEIGHBORS(@graph, { _key:@vertex_key }, {})
|
72
|
+
RETURN n.vertex
|
73
|
+
AQL
|
74
|
+
bind_vars = { graph: 'my_graph', vertex_key: 'somekey' }
|
75
|
+
|
76
|
+
expect(query).to receive(:execute)
|
77
|
+
.with(aql_string, bind_vars: bind_vars)
|
78
|
+
|
79
|
+
subject.neighbors(some_document)
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'should run a neighbors AQL for a specific edge collection' do
|
83
|
+
aql_string = <<-AQL.gsub(/^[ \t]*/, '')
|
84
|
+
FOR n IN GRAPH_NEIGHBORS(@graph, { _key:@vertex_key }, {edgeCollectionRestriction: @edge_collection})
|
85
|
+
RETURN n.vertex
|
86
|
+
AQL
|
87
|
+
bind_vars = { edge_collection: ['my-edges'], graph: 'my_graph', vertex_key: 'somekey' }
|
88
|
+
|
89
|
+
expect(query).to receive(:execute)
|
90
|
+
.with(aql_string, bind_vars: bind_vars)
|
91
|
+
|
92
|
+
subject.neighbors(some_document, edges: ['my-edges'])
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
context 'delete the graph' do
|
97
|
+
it 'should delete just the graph' do
|
98
|
+
expect(database).to receive(:send_request).with('gharial/my_graph', delete: { dropCollections: false })
|
99
|
+
|
100
|
+
subject.delete
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'should delete the graph including all collections' do
|
104
|
+
expect(database).to receive(:send_request).with('gharial/my_graph', delete: { dropCollections: true })
|
105
|
+
|
106
|
+
subject.delete(drop_collections: true)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
context 'vertex collections' do
|
111
|
+
let(:raw_vertex_collection) { double('RawVertexCollection') }
|
112
|
+
|
113
|
+
its(:vertex_collection_names) { should match_array %w(ponies dragons orphan) }
|
114
|
+
|
115
|
+
it 'should have a list of vertex collections' do
|
116
|
+
expected_vertex_collection = [
|
117
|
+
collection_double(:ponies),
|
118
|
+
collection_double(:orphan),
|
119
|
+
collection_double(:dragons)
|
120
|
+
]
|
121
|
+
allow(subject).to receive(:vertex_collection).and_return(*expected_vertex_collection)
|
122
|
+
|
123
|
+
expect(subject.vertex_collections).to match_array expected_vertex_collection
|
124
|
+
end
|
125
|
+
|
126
|
+
it 'should know if a collection has already been added to the list of vertices' do
|
127
|
+
allow(subject).to receive(:vertex_collection_names).and_return(['ponies'])
|
128
|
+
|
129
|
+
expect(subject.has_vertex_collection?('dragons')).to be_falsy
|
130
|
+
expect(subject.has_vertex_collection?('ponies')).to be_truthy
|
131
|
+
end
|
132
|
+
|
133
|
+
context 'fetching a single collection' do
|
134
|
+
let(:existing_vertex_collection) { instance_double('Ashikawa::Core::VertexCollection') }
|
135
|
+
|
136
|
+
before do
|
137
|
+
allow(database).to receive(:send_request)
|
138
|
+
.with('collection/places')
|
139
|
+
.and_return(raw_vertex_collection)
|
140
|
+
|
141
|
+
allow(Ashikawa::Core::VertexCollection).to receive(:new)
|
142
|
+
.with(database, raw_vertex_collection, subject)
|
143
|
+
.and_return(existing_vertex_collection)
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'should get a single vertex collection' do
|
147
|
+
places_collection = subject.vertex_collection 'places'
|
148
|
+
expect(places_collection).to eq existing_vertex_collection
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
context 'adding a collection' do
|
153
|
+
let(:updated_raw_graph) { double('UpdatedRawGraph') }
|
154
|
+
let(:new_vertex_collection) { instance_double('Ashikawa::Core::VertexCollection') }
|
155
|
+
|
156
|
+
before do
|
157
|
+
allow(updated_raw_graph).to receive(:[]).with('name').and_return('my_graph')
|
158
|
+
allow(updated_raw_graph).to receive(:[]).with('_rev')
|
159
|
+
allow(updated_raw_graph).to receive(:fetch).with('orphanCollections').and_return(['books'])
|
160
|
+
allow(updated_raw_graph).to receive(:fetch).with('edgeDefinitions').and_return([edge_definition])
|
161
|
+
|
162
|
+
allow(database).to receive(:send_request)
|
163
|
+
.with('gharial/my_graph/vertex', post: { collection: 'books' })
|
164
|
+
.and_return({ 'graph' => updated_raw_graph })
|
165
|
+
|
166
|
+
allow(database).to receive(:send_request)
|
167
|
+
.with('collection/books')
|
168
|
+
.and_return(raw_vertex_collection)
|
169
|
+
|
170
|
+
allow(Ashikawa::Core::VertexCollection).to receive(:new)
|
171
|
+
.with(database, raw_vertex_collection, subject)
|
172
|
+
.and_return(new_vertex_collection)
|
173
|
+
end
|
174
|
+
|
175
|
+
it 'should add the new collection to the vertex collections of the graph' do
|
176
|
+
books_collection = collection_double(:books)
|
177
|
+
allow(subject).to receive(:vertex_collection).and_return(books_collection)
|
178
|
+
|
179
|
+
subject.add_vertex_collection 'books'
|
180
|
+
|
181
|
+
expect(subject.vertex_collections).to include books_collection
|
182
|
+
end
|
183
|
+
|
184
|
+
it 'should return the newly created collection' do
|
185
|
+
expect(subject.add_vertex_collection('books')).to eq new_vertex_collection
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
context 'edge collections' do
|
191
|
+
let(:raw_edge_collection) { double('RawEdgeCollection') }
|
192
|
+
|
193
|
+
its(:edge_collection_names) { should match_array %w(friends) }
|
194
|
+
|
195
|
+
it 'should have a list of edge collections' do
|
196
|
+
expected_edge_collections = [edge_collection_double(:friends)]
|
197
|
+
allow(subject).to receive(:edge_collection).and_return(*expected_edge_collections)
|
198
|
+
|
199
|
+
expect(subject.edge_collections).to match_array expected_edge_collections
|
200
|
+
end
|
201
|
+
|
202
|
+
context 'fetching a single edge collections' do
|
203
|
+
let(:existing_edge_collection) { instance_double('Ashikawa::Core::EdgeCollection') }
|
204
|
+
|
205
|
+
before do
|
206
|
+
allow(database).to receive(:send_request)
|
207
|
+
.with('collection/friends')
|
208
|
+
.and_return(raw_edge_collection)
|
209
|
+
|
210
|
+
allow(Ashikawa::Core::EdgeCollection).to receive(:new)
|
211
|
+
.with(database, raw_edge_collection, subject)
|
212
|
+
.and_return(existing_edge_collection)
|
213
|
+
end
|
214
|
+
|
215
|
+
it 'should return a single edge collection' do
|
216
|
+
friends_colection = subject.edge_collection :friends
|
217
|
+
expect(friends_colection).to eq existing_edge_collection
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
context 'adding a definition' do
|
222
|
+
let(:updated_raw_graph) { double('UpdatedRawGraph') }
|
223
|
+
let(:new_edge_collection) { instance_double('Ashikawa::Core::EdgeCollection') }
|
224
|
+
let(:new_edge_definition) do
|
225
|
+
{
|
226
|
+
'collection' => 'authorship',
|
227
|
+
'from' => ['author'],
|
228
|
+
'to' => ['books']
|
229
|
+
}
|
230
|
+
end
|
231
|
+
|
232
|
+
before do
|
233
|
+
allow(updated_raw_graph).to receive(:[]).with('name').and_return('my_graph')
|
234
|
+
allow(updated_raw_graph).to receive(:[]).with('_rev')
|
235
|
+
allow(updated_raw_graph).to receive(:fetch).with('orphanCollections').and_return(['orphans'])
|
236
|
+
allow(updated_raw_graph).to receive(:fetch).with('edgeDefinitions').and_return([edge_definition])
|
237
|
+
|
238
|
+
allow(database).to receive(:send_request)
|
239
|
+
.with('gharial/my_graph/edge', post: { collection: :authorship, from: [:author], to: [:books] })
|
240
|
+
.and_return({ 'graph' => updated_raw_graph })
|
241
|
+
|
242
|
+
allow(subject).to receive(:edge_collection).and_return(new_edge_collection)
|
243
|
+
end
|
244
|
+
|
245
|
+
it 'should define the name and direction' do
|
246
|
+
expect(database).to receive(:send_request)
|
247
|
+
.with('gharial/my_graph/edge', post: { collection: :authorship, from: [:author], to: [:books] })
|
248
|
+
.and_return({ 'graph' => updated_raw_graph })
|
249
|
+
|
250
|
+
subject.add_edge_definition(:authorship, from: [:author], to: [:books])
|
251
|
+
end
|
252
|
+
|
253
|
+
it 'should add the definition to the collection edge collections' do
|
254
|
+
allow(updated_raw_graph).to receive(:fetch).with('edgeDefinitions').and_return([
|
255
|
+
edge_definition,
|
256
|
+
new_edge_definition
|
257
|
+
])
|
258
|
+
|
259
|
+
subject.add_edge_definition(:authorship, from: [:author], to: [:books])
|
260
|
+
|
261
|
+
expect(subject.edge_collections).to include new_edge_collection
|
262
|
+
end
|
263
|
+
|
264
|
+
it 'should return the edge collection' do
|
265
|
+
expect(subject.add_edge_definition(:authorship, from: [:author], to: [:books])).to eq new_edge_collection
|
266
|
+
end
|
267
|
+
end
|
268
|
+
end
|
269
|
+
end
|
270
|
+
end
|