ashikawa-core 0.8.0 → 0.9.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/.ruby-version +1 -1
- data/.travis.yml +3 -3
- data/CHANGELOG.md +49 -0
- data/Gemfile +3 -2
- data/Gemfile.devtools +14 -22
- data/Guardfile +3 -2
- data/README.md +37 -6
- data/Rakefile +2 -1
- data/ashikawa-core.gemspec +2 -2
- data/cache/Mac_applications +1 -0
- data/config/devtools.yml +5 -0
- data/config/flay.yml +1 -1
- data/config/flog.yml +1 -2
- data/config/reek.yml +1 -1
- data/config/rubocop.yml +23 -25
- data/lib/ashikawa-core.rb +6 -5
- data/lib/ashikawa-core/collection.rb +142 -165
- data/lib/ashikawa-core/configuration.rb +41 -2
- data/lib/ashikawa-core/connection.rb +17 -16
- data/lib/ashikawa-core/cursor.rb +18 -12
- data/lib/ashikawa-core/database.rb +69 -59
- data/lib/ashikawa-core/document.rb +22 -20
- data/lib/ashikawa-core/edge.rb +8 -6
- data/lib/ashikawa-core/exceptions/client_error.rb +1 -0
- data/lib/ashikawa-core/exceptions/client_error/authentication_failed.rb +25 -0
- data/lib/ashikawa-core/exceptions/client_error/bad_syntax.rb +3 -2
- data/lib/ashikawa-core/exceptions/client_error/resource_not_found.rb +3 -2
- data/lib/ashikawa-core/exceptions/client_error/resource_not_found/collection_not_found.rb +3 -2
- data/lib/ashikawa-core/exceptions/client_error/resource_not_found/document_not_found.rb +3 -2
- data/lib/ashikawa-core/exceptions/client_error/resource_not_found/index_not_found.rb +3 -2
- data/lib/ashikawa-core/exceptions/no_collection_provided.rb +1 -0
- data/lib/ashikawa-core/exceptions/server_error.rb +1 -0
- data/lib/ashikawa-core/exceptions/server_error/json_error.rb +3 -2
- data/lib/ashikawa-core/figure.rb +18 -17
- data/lib/ashikawa-core/index.rb +15 -5
- data/lib/ashikawa-core/key_options.rb +5 -4
- data/lib/ashikawa-core/query.rb +38 -27
- data/lib/ashikawa-core/request_preprocessor.rb +4 -3
- data/lib/ashikawa-core/response_preprocessor.rb +64 -24
- data/lib/ashikawa-core/status.rb +1 -0
- data/lib/ashikawa-core/transaction.rb +12 -11
- data/lib/ashikawa-core/version.rb +2 -1
- data/spec/acceptance/basic_spec.rb +117 -116
- data/spec/acceptance/index_spec.rb +18 -15
- data/spec/acceptance/query_spec.rb +61 -64
- data/spec/acceptance/spec_helper.rb +26 -3
- data/spec/acceptance/transactions_spec.rb +12 -16
- data/spec/setup/arangodb.sh +2 -2
- data/spec/unit/collection_spec.rb +224 -242
- data/spec/unit/configuration_spec.rb +64 -0
- data/spec/unit/connection_spec.rb +121 -111
- data/spec/unit/cursor_spec.rb +78 -65
- data/spec/unit/database_spec.rb +112 -163
- data/spec/unit/document_spec.rb +74 -70
- data/spec/unit/edge_spec.rb +45 -33
- data/spec/unit/exception_spec.rb +28 -38
- data/spec/unit/figure_spec.rb +44 -47
- data/spec/unit/index_spec.rb +27 -24
- data/spec/unit/key_options_spec.rb +19 -17
- data/spec/unit/query_spec.rb +186 -135
- data/spec/unit/spec_helper.rb +14 -3
- data/spec/unit/status_spec.rb +37 -37
- data/spec/unit/transaction_spec.rb +71 -74
- data/tasks/adjustments.rake +10 -34
- metadata +11 -13
- data/spec/acceptance/arango_helper.rb +0 -27
- data/spec/acceptance_auth/arango_helper.rb +0 -30
- data/spec/acceptance_auth/auth_spec.rb +0 -40
- data/spec/acceptance_auth/spec_helper.rb +0 -6
@@ -1,32 +1,35 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
1
2
|
require 'acceptance/spec_helper'
|
2
3
|
|
3
|
-
describe
|
4
|
-
let(:database) {
|
5
|
-
|
6
|
-
|
7
|
-
end
|
8
|
-
}
|
9
|
-
subject { database["documenttest"] }
|
10
|
-
let(:index) { subject.add_index(:skiplist, :on => [:identifier]) }
|
4
|
+
describe 'Indices' do
|
5
|
+
let(:database) { DATABASE }
|
6
|
+
subject { database['documenttest'] }
|
7
|
+
let(:index) { subject.add_index(:skiplist, on: [:identifier]) }
|
11
8
|
|
12
|
-
it
|
9
|
+
it 'should be possible to set indices' do
|
13
10
|
index.delete
|
14
11
|
|
15
12
|
expect {
|
16
|
-
subject.add_index :skiplist, :
|
13
|
+
subject.add_index :skiplist, on: [:identifier]
|
17
14
|
}.to change { subject.indices.length }.by(1)
|
18
15
|
end
|
19
16
|
|
20
|
-
it
|
17
|
+
it 'should be possible to get an index by ID' do
|
21
18
|
# This is temporary until Index has a key
|
22
19
|
index_key = index.id.split('/')[1]
|
23
20
|
|
24
|
-
subject.index(index_key).id.
|
25
|
-
subject.indices[0].class.
|
21
|
+
expect(subject.index(index_key).id).to eq(index.id)
|
22
|
+
expect(subject.indices[0].class).to eq(Ashikawa::Core::Index)
|
26
23
|
end
|
27
24
|
|
28
|
-
it
|
29
|
-
|
25
|
+
it 'should be possible to create an unique index' do
|
26
|
+
index = subject.add_index :skiplist, on: [:identifier], unique: true
|
27
|
+
|
28
|
+
expect(index.unique).to be_true
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'should be possible to remove indices' do
|
32
|
+
pending 'See Bug #34'
|
30
33
|
|
31
34
|
expect {
|
32
35
|
index.delete
|
@@ -1,98 +1,95 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
1
2
|
require 'acceptance/spec_helper'
|
2
3
|
|
3
|
-
describe
|
4
|
-
let(:database) {
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
names = database.query.execute(query, options).map { |person| person["name"] }
|
22
|
-
names.should include "Jeff Lebowski"
|
23
|
-
names.should_not include "Jeffrey Lebowski"
|
4
|
+
describe 'Queries' do
|
5
|
+
let(:database) { DATABASE }
|
6
|
+
let(:collection) { database['my_collection'] }
|
7
|
+
|
8
|
+
describe 'AQL query via the database' do
|
9
|
+
it 'should return the documents' do
|
10
|
+
query = 'FOR u IN my_collection FILTER u.bowling == true RETURN u'
|
11
|
+
options = { batch_size: 2, count: true }
|
12
|
+
|
13
|
+
collection.create_document({ 'name' => 'Jeff Lebowski', 'bowling' => true })
|
14
|
+
collection.create_document({ 'name' => 'Walter Sobchak', 'bowling' => true })
|
15
|
+
collection.create_document({ 'name' => 'Donny Kerabatsos', 'bowling' => true })
|
16
|
+
collection.create_document({ 'name' => 'Jeffrey Lebowski', 'bowling' => false })
|
17
|
+
|
18
|
+
names = database.query.execute(query, options).map { |person| person['name'] }
|
19
|
+
expect(names).to include 'Jeff Lebowski'
|
20
|
+
expect(names).not_to include 'Jeffrey Lebowski'
|
24
21
|
end
|
25
22
|
|
26
|
-
it
|
27
|
-
valid_query =
|
28
|
-
database.query.valid?(valid_query).
|
23
|
+
it 'should be possible to validate' do
|
24
|
+
valid_query = 'FOR u IN my_collection FILTER u.bowling == true RETURN u'
|
25
|
+
expect(database.query.valid?(valid_query)).to be_true
|
29
26
|
|
30
|
-
invalid_query =
|
31
|
-
database.query.valid?(invalid_query).
|
27
|
+
invalid_query = 'FOR u IN my_collection FILTER u.bowling == true'
|
28
|
+
expect(database.query.valid?(invalid_query)).to be_false
|
32
29
|
end
|
33
30
|
end
|
34
31
|
|
35
|
-
describe
|
32
|
+
describe 'simple query via collection object' do
|
36
33
|
subject { collection }
|
37
34
|
before(:each) { subject.truncate! }
|
38
35
|
|
39
|
-
it
|
40
|
-
subject.create_document({ :
|
41
|
-
subject.query.all.first[
|
36
|
+
it 'should return all documents of a collection' do
|
37
|
+
subject.create_document({ name: 'testname', age: 27 })
|
38
|
+
expect(subject.query.all.first['name']).to eq('testname')
|
42
39
|
end
|
43
40
|
|
44
|
-
it
|
45
|
-
subject.create_document({ :
|
46
|
-
subject.create_document({ :
|
47
|
-
subject.create_document({ :
|
41
|
+
it 'should be possible to limit and skip results' do
|
42
|
+
subject.create_document({ name: 'test1' })
|
43
|
+
subject.create_document({ name: 'test2' })
|
44
|
+
subject.create_document({ name: 'test3' })
|
48
45
|
|
49
|
-
subject.query.all(:
|
50
|
-
subject.query.all(:
|
46
|
+
expect(subject.query.all(limit: 2).length).to eq(2)
|
47
|
+
expect(subject.query.all(skip: 2).length).to eq(1)
|
51
48
|
end
|
52
49
|
|
53
|
-
it
|
54
|
-
subject.create_document({
|
55
|
-
result = subject.query.by_example :
|
56
|
-
result.length.
|
50
|
+
it 'should be possible to query documents by example' do
|
51
|
+
subject.create_document({ 'name' => 'Random Document' })
|
52
|
+
result = subject.query.by_example name: 'Random Document'
|
53
|
+
expect(result.length).to eq(1)
|
57
54
|
end
|
58
55
|
|
59
|
-
it
|
60
|
-
subject.create_document({
|
61
|
-
result = subject.query.first_example :
|
62
|
-
result[
|
56
|
+
it 'should be possible to query first document by example' do
|
57
|
+
subject.create_document({ 'name' => 'Single Document' })
|
58
|
+
result = subject.query.first_example name: 'Single Document'
|
59
|
+
expect(result['name']).to eq('Single Document')
|
63
60
|
end
|
64
61
|
|
65
|
-
describe
|
62
|
+
describe 'query by geo coordinates' do
|
66
63
|
before :each do
|
67
|
-
subject.add_index :geo, :
|
68
|
-
subject.create_document({
|
69
|
-
subject.create_document({
|
64
|
+
subject.add_index :geo, on: [:latitude, :longitude]
|
65
|
+
subject.create_document({ 'name' => 'cologne', 'latitude' => 50.948045, 'longitude' => 6.961212 })
|
66
|
+
subject.create_document({ 'name' => 'san francisco', 'latitude' => -122.395899, 'longitude' => 37.793621 })
|
70
67
|
end
|
71
68
|
|
72
|
-
it
|
73
|
-
found_places = subject.query.near :
|
74
|
-
found_places.first[
|
69
|
+
it 'should be possible to query documents near a certain location' do
|
70
|
+
found_places = subject.query.near latitude: 50, longitude: 6
|
71
|
+
expect(found_places.first['name']).to eq('cologne')
|
75
72
|
end
|
76
73
|
|
77
|
-
it
|
78
|
-
found_places = subject.query.within :
|
79
|
-
found_places.length.
|
80
|
-
found_places.first[
|
74
|
+
it 'should be possible to query documents within a certain range' do
|
75
|
+
found_places = subject.query.within latitude: 50.948040, longitude: 6.961210, radius: 2
|
76
|
+
expect(found_places.length).to eq(1)
|
77
|
+
expect(found_places.first['name']).to eq('cologne')
|
81
78
|
end
|
82
79
|
end
|
83
80
|
|
84
|
-
describe
|
81
|
+
describe 'queries by integer ranges' do
|
85
82
|
before :each do
|
86
|
-
subject.add_index :skiplist, :
|
87
|
-
subject.create_document({
|
88
|
-
subject.create_document({
|
89
|
-
subject.create_document({
|
83
|
+
subject.add_index :skiplist, on: [:age]
|
84
|
+
subject.create_document({ 'name' => 'Georg', 'age' => 12 })
|
85
|
+
subject.create_document({ 'name' => 'Anne', 'age' => 21 })
|
86
|
+
subject.create_document({ 'name' => 'Jens', 'age' => 49 })
|
90
87
|
end
|
91
88
|
|
92
|
-
it
|
93
|
-
found_people = subject.query.in_range :
|
94
|
-
found_people.length.
|
95
|
-
found_people.first[
|
89
|
+
it 'should be possible to query documents for numbers in a certain range' do
|
90
|
+
found_people = subject.query.in_range attribute: 'age', left: 20, right: 30, closed: true
|
91
|
+
expect(found_people.length).to eq(1)
|
92
|
+
expect(found_people.first['name']).to eq('Anne')
|
96
93
|
end
|
97
94
|
end
|
98
95
|
end
|
@@ -1,6 +1,29 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
1
2
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
|
-
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__),
|
3
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
4
|
|
4
|
-
|
5
|
+
RSpec.configure do |config|
|
6
|
+
config.expect_with :rspec do |c|
|
7
|
+
c.syntax = :expect
|
8
|
+
end
|
5
9
|
|
6
|
-
|
10
|
+
config.mock_with :rspec do |c|
|
11
|
+
c.syntax = :expect
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
require 'ashikawa-core'
|
16
|
+
|
17
|
+
port = ENV['ARANGODB_PORT'] || 8529
|
18
|
+
username = ENV['ARANGODB_USERNAME'] || 'root'
|
19
|
+
password = ENV['ARANGODB_PASSWORD'] || ''
|
20
|
+
|
21
|
+
# The database instance to use for all specs
|
22
|
+
DATABASE = Ashikawa::Core::Database.new do |config|
|
23
|
+
config.url = "http://localhost:#{port}"
|
24
|
+
|
25
|
+
unless ENV['ARANGODB_DISABLE_AUTHENTIFICATION']
|
26
|
+
config.username = username
|
27
|
+
config.password = password
|
28
|
+
end
|
29
|
+
end
|
@@ -1,30 +1,26 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
1
2
|
require 'acceptance/spec_helper'
|
2
3
|
|
3
|
-
describe
|
4
|
-
subject {
|
5
|
-
Ashikawa::Core::Database.new do |config|
|
6
|
-
config.url = ARANGO_HOST
|
7
|
-
end
|
8
|
-
}
|
4
|
+
describe 'Transactions' do
|
5
|
+
subject { DATABASE }
|
9
6
|
|
10
7
|
before :each do
|
11
8
|
subject.collections.each { |collection| collection.delete }
|
12
|
-
subject[
|
13
|
-
subject[
|
14
|
-
subject[
|
9
|
+
subject['collection_1']
|
10
|
+
subject['collection_2']
|
11
|
+
subject['collection_3']
|
15
12
|
end
|
16
13
|
|
17
|
-
let(:js_function) {
|
14
|
+
let(:js_function) { 'function (x) { return x.a; }' }
|
15
|
+
let(:write_collections) { %w{collection_1 collection_2} }
|
16
|
+
let(:read_collections) { %w{collection_2} }
|
18
17
|
|
19
|
-
it
|
20
|
-
transaction = subject.create_transaction
|
21
|
-
:write => ["collection_1", "collection_2"],
|
22
|
-
:read => ["collection_3"]
|
23
|
-
)
|
18
|
+
it 'should create and execute a transaction' do
|
19
|
+
transaction = subject.create_transaction js_function, write: write_collections, read: read_collections
|
24
20
|
|
25
21
|
transaction.wait_for_sync = true
|
26
22
|
transaction.lock_timeout = 14
|
27
23
|
|
28
|
-
transaction.execute({ :
|
24
|
+
expect(transaction.execute({ a: 5 })).to eq(5)
|
29
25
|
end
|
30
26
|
end
|
data/spec/setup/arangodb.sh
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
4
4
|
cd $DIR
|
5
5
|
|
6
|
-
VERSION=1.
|
6
|
+
# VERSION=1.4.devel
|
7
7
|
NAME=ArangoDB-$VERSION
|
8
8
|
|
9
9
|
if [ ! -d "$DIR/$NAME" ]; then
|
@@ -40,7 +40,7 @@ ${ARANGOD} \
|
|
40
40
|
--javascript.package-path ${ARANGODB_DIR}/js/npm:${ARANGODB_DIR}/js/common/test-data/modules \
|
41
41
|
--javascript.action-directory ${ARANGODB_DIR}/js/actions \
|
42
42
|
--database.maximal-journal-size 1048576 \
|
43
|
-
--server.disable-admin-interface
|
43
|
+
--server.disable-admin-interface ${ARANGODB_DISABLE_AUTHENTIFICATION} \
|
44
44
|
--server.disable-authentication true \
|
45
45
|
--javascript.gc-interval 1 &
|
46
46
|
|
@@ -1,338 +1,320 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
1
2
|
require 'unit/spec_helper'
|
2
3
|
require 'ashikawa-core/collection'
|
3
4
|
|
4
5
|
describe Ashikawa::Core::Collection do
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
let(:database) { double }
|
7
|
+
let(:raw_document_collection) { server_response('collections/60768679') }
|
8
|
+
let(:raw_edge_collection) do
|
9
|
+
{
|
10
|
+
'id' => '60768679',
|
11
|
+
'name' => 'example_1',
|
12
|
+
'type' => 3
|
13
|
+
}
|
9
14
|
end
|
10
15
|
|
11
|
-
|
12
|
-
|
13
|
-
my_collection.name.should == "example_1"
|
14
|
-
end
|
16
|
+
describe 'an initialized collection' do
|
17
|
+
subject { Ashikawa::Core::Collection.new(database, raw_document_collection) }
|
15
18
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
19
|
+
let(:raw_key_options) { double }
|
20
|
+
let(:key_options) { double }
|
21
|
+
let(:response) { double }
|
22
|
+
let(:value) { double }
|
23
|
+
let(:figure) { double }
|
20
24
|
|
21
|
-
|
22
|
-
|
25
|
+
its(:name) { should eq('example_1') }
|
26
|
+
its(:id) { should eq('60768679') }
|
23
27
|
|
24
|
-
|
25
|
-
|
26
|
-
|
28
|
+
it 'should know how many documents the collection has' do
|
29
|
+
allow(response).to receive(:[])
|
30
|
+
.with('count')
|
31
|
+
.and_return(value)
|
32
|
+
expect(database).to receive(:send_request)
|
33
|
+
.with('collection/60768679/count', {})
|
34
|
+
.and_return(response)
|
27
35
|
|
28
|
-
|
29
|
-
end
|
30
|
-
|
31
|
-
describe "attributes of a collection" do
|
32
|
-
it "should check if the collection waits for sync" do
|
33
|
-
@database.stub(:send_request).with("collection/60768679/properties", {}).and_return { server_response("collections/60768679-properties") }
|
34
|
-
@database.should_receive(:send_request).with("collection/60768679/properties", {})
|
35
|
-
|
36
|
-
my_collection = subject.new @database, { "id" => "60768679" }
|
37
|
-
my_collection.wait_for_sync?.should be_true
|
36
|
+
expect(subject.length).to be(value)
|
38
37
|
end
|
39
38
|
|
40
|
-
it
|
41
|
-
|
42
|
-
|
39
|
+
it 'should check for the figures' do
|
40
|
+
allow(response).to receive(:[])
|
41
|
+
.with('figures')
|
42
|
+
.and_return(value)
|
43
|
+
expect(database).to receive(:send_request)
|
44
|
+
.with('collection/60768679/figures', {})
|
45
|
+
.and_return(response)
|
43
46
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
+
expect(Ashikawa::Core::Figure).to receive(:new)
|
48
|
+
.exactly(1).times
|
49
|
+
.with(value)
|
50
|
+
.and_return(figure)
|
47
51
|
|
48
|
-
|
49
|
-
@database.stub(:send_request).with("collection/60768679/properties", {}).and_return { server_response("collections/60768679-properties-volatile") }
|
50
|
-
@database.should_receive(:send_request).with("collection/60768679/properties", {})
|
51
|
-
|
52
|
-
my_collection = subject.new(@database, { "id" => "60768679" })
|
53
|
-
my_collection.volatile?.should == true
|
54
|
-
end
|
55
|
-
|
56
|
-
it "should know if the collection is not volatile" do
|
57
|
-
@database.stub(:send_request).with("collection/60768679/properties", {}).and_return { server_response("collections/60768679-properties") }
|
58
|
-
@database.should_receive(:send_request).with("collection/60768679/properties", {})
|
59
|
-
|
60
|
-
my_collection = subject.new(@database, { "id" => "60768679" })
|
61
|
-
my_collection.volatile?.should == false
|
52
|
+
expect(subject.figure).to be(figure)
|
62
53
|
end
|
63
54
|
|
64
|
-
it
|
65
|
-
|
66
|
-
|
67
|
-
|
55
|
+
it 'should create a query' do
|
56
|
+
expect(Ashikawa::Core::Query).to receive(:new)
|
57
|
+
.exactly(1).times
|
58
|
+
.with(subject)
|
68
59
|
|
69
|
-
|
70
|
-
my_collection = subject.new(@database, { "id" => "60768679", "type" => 3 })
|
71
|
-
my_collection.content_type.should == :edge
|
60
|
+
subject.query
|
72
61
|
end
|
73
62
|
|
74
|
-
it
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
double Ashikawa::Core::Figure
|
79
|
-
Ashikawa::Core::Figure.stub(:new)
|
80
|
-
Ashikawa::Core::Figure.should_receive(:new).exactly(1).times.with(server_response("collections/60768679-figures")["figures"])
|
81
|
-
|
82
|
-
my_collection = subject.new @database, { "id" => "60768679" }
|
83
|
-
my_collection.figure
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
describe "an initialized collection" do
|
88
|
-
subject { Ashikawa::Core::Collection.new @database, { "id" => "60768679", "name" => "example_1" } }
|
89
|
-
|
90
|
-
it "should get deleted" do
|
91
|
-
@database.stub(:send_request).with("collection/60768679/", :delete => {})
|
92
|
-
@database.should_receive(:send_request).with("collection/60768679/", :delete => {})
|
63
|
+
it 'should get deleted' do
|
64
|
+
expect(database).to receive(:send_request)
|
65
|
+
.with('collection/60768679/', delete: {})
|
93
66
|
|
94
67
|
subject.delete
|
95
68
|
end
|
96
69
|
|
97
|
-
it
|
98
|
-
|
99
|
-
|
70
|
+
it 'should get loaded' do
|
71
|
+
expect(database).to receive(:send_request)
|
72
|
+
.with('collection/60768679/load', put: {})
|
100
73
|
|
101
74
|
subject.load
|
102
75
|
end
|
103
76
|
|
104
|
-
it
|
105
|
-
|
106
|
-
|
77
|
+
it 'should get unloaded' do
|
78
|
+
expect(database).to receive(:send_request)
|
79
|
+
.with('collection/60768679/unload', put: {})
|
107
80
|
|
108
81
|
subject.unload
|
109
82
|
end
|
110
83
|
|
111
|
-
it
|
112
|
-
|
113
|
-
|
84
|
+
it 'should get truncated' do
|
85
|
+
expect(database).to receive(:send_request)
|
86
|
+
.with('collection/60768679/truncate', put: {})
|
114
87
|
|
115
88
|
subject.truncate!
|
116
89
|
end
|
117
90
|
|
118
|
-
it
|
119
|
-
|
120
|
-
|
91
|
+
it 'should change its name' do
|
92
|
+
expect(database).to receive(:send_request)
|
93
|
+
.with('collection/60768679/rename', put: { 'name' => value })
|
121
94
|
|
122
|
-
subject.
|
95
|
+
subject.name = value
|
123
96
|
end
|
124
97
|
|
125
|
-
it
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
key_options = double
|
130
|
-
Ashikawa::Core::KeyOptions.stub(:new).with(raw_key_options).and_return { key_options }
|
98
|
+
it 'should change if it waits for sync' do
|
99
|
+
expect(database).to receive(:send_request)
|
100
|
+
.with('collection/60768679/properties', put: { 'waitForSync' => value })
|
131
101
|
|
132
|
-
subject.
|
102
|
+
subject.wait_for_sync = value
|
133
103
|
end
|
134
104
|
|
135
|
-
|
136
|
-
|
137
|
-
|
105
|
+
describe 'properties' do
|
106
|
+
before do
|
107
|
+
expect(database).to receive(:send_request)
|
108
|
+
.with('collection/60768679/properties', {})
|
109
|
+
.and_return(response)
|
110
|
+
end
|
138
111
|
|
139
|
-
|
140
|
-
|
112
|
+
it 'should check if the collection waits for sync' do
|
113
|
+
allow(response).to receive(:[])
|
114
|
+
.with('waitForSync')
|
115
|
+
.and_return(value)
|
141
116
|
|
142
|
-
|
143
|
-
|
144
|
-
@database.stub(:send_request).with("document/60768679/333", {}).and_return { server_response('documents/example_1-137249191') }
|
145
|
-
@database.should_receive(:send_request).with("document/60768679/333", {})
|
117
|
+
expect(subject.wait_for_sync?).to be(value)
|
118
|
+
end
|
146
119
|
|
147
|
-
|
148
|
-
|
120
|
+
it 'should know if the collection is volatile' do
|
121
|
+
allow(response).to receive(:[])
|
122
|
+
.with('isVolatile')
|
123
|
+
.and_return(value)
|
149
124
|
|
150
|
-
subject.
|
125
|
+
expect(subject.volatile?).to be(value)
|
151
126
|
end
|
152
127
|
|
153
|
-
it
|
154
|
-
|
155
|
-
|
128
|
+
it 'should check for the key options' do
|
129
|
+
allow(response).to receive(:[])
|
130
|
+
.with('keyOptions')
|
131
|
+
.and_return(value)
|
132
|
+
expect(Ashikawa::Core::KeyOptions).to receive(:new)
|
133
|
+
.with(value)
|
134
|
+
.and_return(key_options)
|
156
135
|
|
157
|
-
|
158
|
-
Ashikawa::Core::Document.should_receive(:new)
|
159
|
-
|
160
|
-
subject[333]
|
136
|
+
expect(subject.key_options).to eq(key_options)
|
161
137
|
end
|
138
|
+
end
|
162
139
|
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
140
|
+
describe 'non-existing documents' do
|
141
|
+
before do
|
142
|
+
allow(database).to receive(:send_request)
|
143
|
+
.and_raise(Ashikawa::Core::DocumentNotFoundException)
|
144
|
+
end
|
167
145
|
|
168
|
-
|
146
|
+
it 'should throw an exception when using fetch' do
|
147
|
+
expect do
|
169
148
|
subject.fetch(123)
|
170
|
-
|
149
|
+
end.to raise_exception Ashikawa::Core::DocumentNotFoundException
|
171
150
|
end
|
172
151
|
|
173
|
-
it
|
174
|
-
|
175
|
-
|
176
|
-
|
152
|
+
it 'should return nil when using []' do
|
153
|
+
expect(subject[123]).to be_nil
|
154
|
+
end
|
155
|
+
end
|
177
156
|
|
178
|
-
|
157
|
+
describe 'indexes' do
|
158
|
+
let(:index_response) { double }
|
159
|
+
|
160
|
+
it 'should add a new index' do
|
161
|
+
expect(database).to receive(:send_request)
|
162
|
+
.with('index?collection=60768679', post: {
|
163
|
+
'type' => 'hash', 'fields' => %w{a b}, 'unique' => false
|
164
|
+
})
|
165
|
+
.and_return(index_response)
|
166
|
+
expect(Ashikawa::Core::Index).to receive(:new)
|
167
|
+
.with(subject, index_response)
|
168
|
+
|
169
|
+
subject.add_index(:hash, on: [:a, :b])
|
179
170
|
end
|
180
171
|
|
181
|
-
it
|
182
|
-
|
183
|
-
|
172
|
+
it 'should add a new unique index' do
|
173
|
+
expect(database).to receive(:send_request)
|
174
|
+
.with('index?collection=60768679', post: {
|
175
|
+
'type' => 'hash', 'fields' => %w{a b}, 'unique' => true
|
176
|
+
})
|
177
|
+
.and_return(index_response)
|
178
|
+
expect(Ashikawa::Core::Index).to receive(:new)
|
179
|
+
.with(subject, index_response)
|
184
180
|
|
185
|
-
subject.
|
181
|
+
subject.add_index(:hash, on: [:a, :b], unique: true)
|
186
182
|
end
|
187
183
|
|
188
|
-
it
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
"_id" => "example_1/137249191",
|
197
|
-
"_rev" => "137249191",
|
198
|
-
"_key" => "137249191"
|
199
|
-
}
|
200
|
-
}
|
201
|
-
@database.stub(:send_request).with("document/60768679/333", {}).and_return { server_response('documents/example_1-137249191') }
|
202
|
-
|
203
|
-
# Documents need to get initialized:
|
204
|
-
Ashikawa::Core::Document.should_receive(:new).and_return {
|
205
|
-
document = double
|
206
|
-
document.should_receive(:refresh!)
|
207
|
-
document
|
208
|
-
}
|
209
|
-
|
210
|
-
subject.create_document({"name" => "The Dude"})
|
184
|
+
it 'should get an index by ID' do
|
185
|
+
allow(database).to receive(:send_request)
|
186
|
+
.with('index/example_1/168054969')
|
187
|
+
.and_return(index_response)
|
188
|
+
expect(Ashikawa::Core::Index).to receive(:new)
|
189
|
+
.with(subject, index_response)
|
190
|
+
|
191
|
+
subject.index(168_054_969)
|
211
192
|
end
|
212
193
|
|
213
|
-
it
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
@database.stub(:send_request).with("document/60768679/333").and_return { server_response('documents/example_1-137249191') }
|
194
|
+
it 'should get all indexes' do
|
195
|
+
multi_index_response = double
|
196
|
+
allow(multi_index_response).to receive(:map)
|
197
|
+
.and_yield(index_response)
|
218
198
|
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
document
|
224
|
-
}
|
199
|
+
cursor = double
|
200
|
+
allow(cursor).to receive(:[])
|
201
|
+
.with('indexes')
|
202
|
+
.and_return(multi_index_response)
|
225
203
|
|
226
|
-
|
227
|
-
|
204
|
+
allow(database).to receive(:send_request)
|
205
|
+
.with('index?collection=60768679')
|
206
|
+
.and_return(cursor)
|
207
|
+
|
208
|
+
expect(Ashikawa::Core::Index).to receive(:new)
|
209
|
+
.with(subject, index_response)
|
228
210
|
|
229
|
-
|
230
|
-
expect {
|
231
|
-
subject.create_edge(nil, nil, {"quote" => "D'ya have to use s'many cuss words?"})
|
232
|
-
}.to raise_exception(RuntimeError, "Can't create an edge in a document collection")
|
211
|
+
subject.indices
|
233
212
|
end
|
213
|
+
end
|
214
|
+
end
|
234
215
|
|
235
|
-
|
236
|
-
|
237
|
-
@database.stub(:send_request).with("index?collection=60768679", :post => {
|
238
|
-
"type" => "hash", "fields" => [ "a", "b" ]
|
239
|
-
}).and_return { server_response('indices/new-hash-index') }
|
240
|
-
@database.should_receive(:send_request).with("index?collection=60768679", :post => {
|
241
|
-
"type" => "hash", "fields" => [ "a", "b" ]
|
242
|
-
})
|
216
|
+
describe 'an initialized document collection' do
|
217
|
+
subject { Ashikawa::Core::Collection.new database, raw_document_collection }
|
243
218
|
|
244
|
-
|
245
|
-
|
219
|
+
let(:document) { double }
|
220
|
+
let(:response) { double }
|
221
|
+
let(:raw_document) { double }
|
222
|
+
let(:value) { double }
|
246
223
|
|
247
|
-
|
248
|
-
end
|
224
|
+
its(:content_type) { should be(:document) }
|
249
225
|
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
226
|
+
it 'should receive a document by ID via fetch' do
|
227
|
+
expect(database).to receive(:send_request)
|
228
|
+
.with('document/60768679/333', {})
|
229
|
+
.and_return(double)
|
230
|
+
expect(Ashikawa::Core::Document).to receive(:new)
|
254
231
|
|
255
|
-
|
256
|
-
|
232
|
+
subject.fetch(333)
|
233
|
+
end
|
257
234
|
|
258
|
-
|
259
|
-
|
235
|
+
it 'should receive a document by ID via []' do
|
236
|
+
expect(database).to receive(:send_request)
|
237
|
+
.with('document/60768679/333', {})
|
238
|
+
.and_return(double)
|
239
|
+
expect(Ashikawa::Core::Document).to receive(:new)
|
260
240
|
|
261
|
-
|
262
|
-
|
263
|
-
"index?collection=60768679"
|
264
|
-
).and_return { server_response('indices/all') }
|
241
|
+
subject[333]
|
242
|
+
end
|
265
243
|
|
266
|
-
|
244
|
+
it 'should replace a document by ID' do
|
245
|
+
expect(database).to receive(:send_request)
|
246
|
+
.with('document/60768679/333', put: { 'name' => value })
|
267
247
|
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
248
|
+
subject.replace(333, { 'name' => value })
|
249
|
+
end
|
250
|
+
|
251
|
+
it 'should create a new document' do
|
252
|
+
allow(database).to receive(:send_request)
|
253
|
+
.with('document?collection=60768679', post: raw_document)
|
254
|
+
.and_return(response)
|
255
|
+
expect(Ashikawa::Core::Document).to receive(:new)
|
256
|
+
.with(database, response, raw_document)
|
257
|
+
.and_return(document)
|
258
|
+
|
259
|
+
subject.create_document(raw_document)
|
260
|
+
end
|
261
|
+
|
262
|
+
it 'should not create a new edge' do
|
263
|
+
expect do
|
264
|
+
subject.create_edge(double, double, { 'quote' => "D'ya have to use s'many cuss words?" })
|
265
|
+
end.to raise_exception(RuntimeError, "Can't create an edge in a document collection")
|
272
266
|
end
|
273
267
|
end
|
274
268
|
|
275
|
-
describe
|
276
|
-
subject { Ashikawa::Core::Collection.new
|
269
|
+
describe 'an initialized edge collection' do
|
270
|
+
subject { Ashikawa::Core::Collection.new database, raw_edge_collection }
|
271
|
+
|
272
|
+
let(:document) { double }
|
273
|
+
let(:response) { double }
|
274
|
+
let(:raw_document) { double }
|
277
275
|
|
278
|
-
|
279
|
-
@database.stub(:send_request).with("edge/60768679/333", {}).and_return { server_response('documents/example_1-137249191') }
|
280
|
-
@database.should_receive(:send_request).with("edge/60768679/333", {})
|
276
|
+
its(:content_type) { should be(:edge) }
|
281
277
|
|
282
|
-
|
283
|
-
|
278
|
+
it 'should receive an edge by ID via fetch' do
|
279
|
+
expect(database).to receive(:send_request)
|
280
|
+
.with('edge/60768679/333', {})
|
281
|
+
.and_return(double)
|
282
|
+
expect(Ashikawa::Core::Edge).to receive(:new)
|
284
283
|
|
285
284
|
subject.fetch(333)
|
286
285
|
end
|
287
286
|
|
288
|
-
it
|
289
|
-
|
290
|
-
|
287
|
+
it 'should receive an edge by ID via []' do
|
288
|
+
expect(database).to receive(:send_request)
|
289
|
+
.with('edge/60768679/333', {})
|
290
|
+
.and_return(double)
|
291
|
+
expect(Ashikawa::Core::Edge).to receive(:new)
|
291
292
|
|
292
|
-
subject
|
293
|
+
subject[333]
|
293
294
|
end
|
294
295
|
|
295
|
-
it
|
296
|
-
|
297
|
-
|
298
|
-
end
|
299
|
-
@database.stub(:send_request).with("edge?collection=60768679&from=1&to=2", :post => { "name" => "The Dude" }).and_return { server_response('documents/example_1-137249191') }
|
300
|
-
from_double = double
|
301
|
-
from_double.stub(:id => "1")
|
302
|
-
to_double = double
|
303
|
-
to_double.stub(:id => "2")
|
304
|
-
|
305
|
-
# Documents need to get initialized:
|
306
|
-
Ashikawa::Core::Edge.should_receive(:new).and_return {
|
307
|
-
document = double
|
308
|
-
document.should_receive(:refresh!)
|
309
|
-
document
|
310
|
-
}
|
311
|
-
|
312
|
-
subject.create_edge(from_double, to_double, {"name" => "The Dude"})
|
313
|
-
end
|
296
|
+
it 'should replace an edge by ID' do
|
297
|
+
expect(database).to receive(:send_request)
|
298
|
+
.with('edge/60768679/333', put: { 'name' => 'The Dude' })
|
314
299
|
|
315
|
-
|
316
|
-
expect {
|
317
|
-
subject.create_document({"quote" => "D'ya have to use s'many cuss words?"})
|
318
|
-
}.to raise_exception(RuntimeError, "Can't create a document in an edge collection")
|
300
|
+
subject.replace(333, { 'name' => 'The Dude' })
|
319
301
|
end
|
320
|
-
end
|
321
302
|
|
322
|
-
|
323
|
-
|
324
|
-
|
303
|
+
it 'should create a new edge' do
|
304
|
+
allow(database).to receive(:send_request)
|
305
|
+
.with('edge?collection=60768679&from=1&to=2', post: raw_document)
|
306
|
+
.and_return(response)
|
307
|
+
expect(Ashikawa::Core::Edge).to receive(:new)
|
308
|
+
.with(database, response, raw_document)
|
309
|
+
.and_return(document)
|
325
310
|
|
326
|
-
|
327
|
-
subject.should_receive(:create_document).with(attributes).and_return nil
|
328
|
-
subject.should_receive(:warn).with("`<<` is deprecated, please use `create_document`")
|
329
|
-
subject << attributes
|
311
|
+
subject.create_edge(double(id: '1'), double(id: '2'), raw_document)
|
330
312
|
end
|
331
313
|
|
332
|
-
it
|
333
|
-
|
334
|
-
|
335
|
-
|
314
|
+
it 'should not create a new document' do
|
315
|
+
expect do
|
316
|
+
subject.create_document({ 'quote' => "D'ya have to use s'many cuss words?" })
|
317
|
+
end.to raise_exception(RuntimeError, "Can't create a document in an edge collection")
|
336
318
|
end
|
337
319
|
end
|
338
320
|
end
|