muve-store-mongo 0.0.2 → 0.0.3
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/Gemfile +1 -0
- data/lib/muve-store-mongo/errors.rb +5 -0
- data/lib/muve-store-mongo/formatter.rb +25 -0
- data/lib/muve-store-mongo/version.rb +1 -1
- data/lib/muve-store-mongo.rb +27 -10
- data/muve-store-mongo.gemspec +1 -1
- data/spec/formatter_spec.rb +23 -0
- data/spec/mongo_spec.rb +119 -10
- metadata +8 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 93b785d7d848372e3e0f88d79804905bcafe8b1d
|
4
|
+
data.tar.gz: 8d0ffc4195047662b2d3eaa7b4dfa8f9046f55bb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fd5c4ea2ca8c748e67a5268493d6b7c08486788591e09cab08fb9f1fbe2d798563584012c0caf239ab94b8032982ec65d850d3330a84abec9abfb6f1161ad5cd
|
7
|
+
data.tar.gz: 83ba6f494982d0205f172653534ee614e46e054671a02ee12fcce99a7bd8f650f03c977e0363bfe5f99cb478077ebea5a8d898cf79e732a21b0868c574a745c3
|
data/Gemfile
CHANGED
@@ -0,0 +1,25 @@
|
|
1
|
+
module Muve
|
2
|
+
module Store
|
3
|
+
module Mongo
|
4
|
+
module Formatter
|
5
|
+
extend Muve::Store::Formatter
|
6
|
+
|
7
|
+
def self.convert_to_storeable_object(resource)
|
8
|
+
return {
|
9
|
+
type: 'Place',
|
10
|
+
coordinates: [resource.longitude, resource.latitude]
|
11
|
+
} if resource.kind_of? Muve::Location
|
12
|
+
resource
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.convert_from_storeable_object(storeable)
|
16
|
+
if storeable.kind_of? Hash
|
17
|
+
if Helper.symbolize_keys(storeable).to_a.include? [:type, 'Place']
|
18
|
+
Location.new(latitude: storeable[:coordinates][1], longitude: storeable[:coordinates][0]) if storeable[:coordinates]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/muve-store-mongo.rb
CHANGED
@@ -1,30 +1,35 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require 'muve-store-mongo/version'
|
2
|
+
require 'muve'
|
3
|
+
require 'mongo'
|
3
4
|
|
4
5
|
module Muve
|
5
6
|
module Store
|
6
7
|
module Mongo
|
7
|
-
require 'mongo'
|
8
|
+
require 'muve-store-mongo/errors'
|
9
|
+
require 'muve-store-mongo/formatter'
|
8
10
|
|
9
11
|
extend Muve::Store
|
10
12
|
|
11
13
|
def self.create(resource, details)
|
12
|
-
raise
|
14
|
+
raise Muve::Error::InvalidAttribute, "Invalid create details" unless details.kind_of? Hash
|
13
15
|
resource.database[resource.container].insert(details)
|
14
16
|
end
|
15
17
|
|
16
18
|
def self.fetch(resource, id, details={})
|
17
19
|
# TODO: discover a solution that works for situations where database
|
18
20
|
# driver returns string keys as well as symbol keys
|
19
|
-
|
21
|
+
raise Muve::Error::InvalidAttribute, "Invalid details" unless details.kind_of? Hash
|
22
|
+
raise Muve::Error::InvalidQuery, "The id or details need to be set" if (id.nil? && details.empty?)
|
23
|
+
id = ((BSON::ObjectId.from_string(id) if id.kind_of? String) or id)
|
20
24
|
result = resource.database[resource.container].find_one(details.merge(_id: id))
|
25
|
+
raise Muve::Error::NotFound, "#{resource} #{id} is not found" unless result
|
21
26
|
result = Helper.symbolize_keys(result)
|
22
27
|
result[:id] = result.delete(:_id)
|
23
28
|
result
|
24
29
|
end
|
25
30
|
|
26
|
-
def self.find(resource, details)
|
27
|
-
|
31
|
+
def self.find(resource, details={})
|
32
|
+
raise Muve::Error::InvalidAttribute, "Invalid details" unless details.kind_of? Hash
|
28
33
|
Enumerator.new do |result|
|
29
34
|
resource.database[resource.container].find(details).each do |item|
|
30
35
|
item = Helper.symbolize_keys(item)
|
@@ -35,19 +40,31 @@ module Muve
|
|
35
40
|
end
|
36
41
|
|
37
42
|
def self.update(resource, id, details)
|
38
|
-
raise
|
43
|
+
raise Muve::Error::InvalidAttribute, "Invalid details" unless details.kind_of? Hash
|
39
44
|
# TODO: raise error if details is not valid
|
45
|
+
id = ((BSON::ObjectId.from_string(id) if id.kind_of? String) or id)
|
40
46
|
resource.database[resource.container].find_and_modify(
|
41
47
|
query: { _id: id },
|
42
48
|
update: details
|
43
49
|
)
|
44
50
|
end
|
45
51
|
|
46
|
-
def self.delete(resource, id, details=
|
47
|
-
|
52
|
+
def self.delete(resource, id, details={})
|
53
|
+
raise Muve::Error::InvalidAttribute, "Invalid details" unless details.kind_of? Hash
|
54
|
+
id = ((BSON::ObjectId.from_string(id) if id.kind_of? String) or id)
|
48
55
|
details = details.merge(_id: id) if id
|
49
56
|
resource.database[resource.container].remove(details)
|
50
57
|
end
|
58
|
+
|
59
|
+
# TODO: raise error if details is not a hash
|
60
|
+
def self.count(resource, details={})
|
61
|
+
raise Muve::Error::InvalidAttribute, "Invalid details" unless details.kind_of? Hash
|
62
|
+
resource.database[resource.container].count(details)
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.formatter
|
66
|
+
Muve::Store::Mongo::Formatter
|
67
|
+
end
|
51
68
|
end
|
52
69
|
end
|
53
70
|
end
|
data/muve-store-mongo.gemspec
CHANGED
@@ -17,7 +17,7 @@ Gem::Specification.new do |gem|
|
|
17
17
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
18
|
gem.require_paths = ["lib"]
|
19
19
|
|
20
|
-
gem.add_runtime_dependency "muve", "~> 1.0.
|
20
|
+
gem.add_runtime_dependency "muve", "~> 1.2.0-alpha.1"
|
21
21
|
gem.add_runtime_dependency "mongo", "~> 1.10.2"
|
22
22
|
|
23
23
|
gem.required_ruby_version = '>= 1.9.2'
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'mongo'
|
3
|
+
|
4
|
+
describe 'Mongo Formatter' do
|
5
|
+
let(:latitude) { Faker::Geolocation.lat }
|
6
|
+
let(:longitude) { Faker::Geolocation.lng }
|
7
|
+
let(:location) { Muve::Location.new(latitude: latitude, longitude: longitude) }
|
8
|
+
let(:place) { Muve::Place.new(location: location, name: 'Somewhere') }
|
9
|
+
let(:storeable) { { type: 'Place', coordinates: [ longitude, latitude ] } }
|
10
|
+
|
11
|
+
before do
|
12
|
+
# Muve.init(connection, database)
|
13
|
+
end
|
14
|
+
|
15
|
+
it { expect(Muve::Store::Mongo::Formatter.convert_to_storeable_object(location)).to eq({
|
16
|
+
type: 'Place',
|
17
|
+
coordinates: [longitude, latitude]
|
18
|
+
}) }
|
19
|
+
|
20
|
+
it { expect(
|
21
|
+
Muve::Store::Mongo::Formatter.convert_from_storeable_object(storeable)
|
22
|
+
).to eq(Muve::Location.new(latitude: latitude, longitude: longitude)) }
|
23
|
+
end
|
data/spec/mongo_spec.rb
CHANGED
@@ -4,8 +4,15 @@ require 'mongo'
|
|
4
4
|
describe 'Mongo Adaptor' do
|
5
5
|
let(:connection) { Mongo::MongoClient.new }
|
6
6
|
let(:database) { connection.db('muve_test') }
|
7
|
+
let(:adaptor) { Muve::Store::Mongo }
|
8
|
+
let(:id_of_stored_resource) { database['places'].insert(
|
9
|
+
name: Faker::Venue.name
|
10
|
+
) }
|
11
|
+
|
7
12
|
before do
|
8
13
|
class Place
|
14
|
+
attr_accessor :city, :street, :building, :name
|
15
|
+
|
9
16
|
include Muve::Model
|
10
17
|
|
11
18
|
def self.container
|
@@ -13,12 +20,42 @@ describe 'Mongo Adaptor' do
|
|
13
20
|
end
|
14
21
|
end
|
15
22
|
|
23
|
+
class MockCollection
|
24
|
+
def self.insert(arg)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class MockResource
|
29
|
+
def self.database
|
30
|
+
[ MockCollection ]
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.container
|
34
|
+
0
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.collection
|
38
|
+
'collection'
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
16
42
|
Muve.init(connection, database)
|
17
43
|
end
|
18
44
|
|
45
|
+
it { expect { Muve::Store::Mongo.create(Place, 12) }.to raise_error(Muve::Error::InvalidAttribute) }
|
46
|
+
it { expect { Muve::Store::Mongo.update(Place, 12, nil) }.to raise_error(Muve::Error::InvalidAttribute) }
|
47
|
+
it { expect { Muve::Store::Mongo.delete(Place, 12, nil) }.to raise_error(Muve::Error::InvalidAttribute) }
|
48
|
+
it { expect { Muve::Store::Mongo.count(Place, 12) }.to raise_error(Muve::Error::InvalidAttribute) }
|
49
|
+
it { expect { Muve::Store::Mongo.count(Place, 12) }.to raise_error(Muve::Error::InvalidAttribute) }
|
50
|
+
it { expect { Muve::Store::Mongo.find(Place, 12) }.to raise_error(Muve::Error::InvalidAttribute) }
|
51
|
+
it { expect { Muve::Store::Mongo.fetch(Place, 12, nil) }.to raise_error(Muve::Error::InvalidAttribute) }
|
52
|
+
|
53
|
+
it { expect(Muve::Store::Mongo.formatter).to eq(Muve::Store::Mongo::Formatter) }
|
54
|
+
|
19
55
|
it 'writes model data to the store' do
|
20
56
|
expect{
|
21
57
|
Muve::Store::Mongo.create(Place, {
|
58
|
+
name: Faker::Venue.name,
|
22
59
|
city: Faker::Address.city,
|
23
60
|
street: Faker::Address.street_name,
|
24
61
|
building: Faker::Address.building_number
|
@@ -26,28 +63,100 @@ describe 'Mongo Adaptor' do
|
|
26
63
|
}.to change{database['places'].count}.by(1)
|
27
64
|
end
|
28
65
|
|
66
|
+
it 'counts the records in the datastore' do
|
67
|
+
expect{
|
68
|
+
database['places'].insert(
|
69
|
+
name: "Willy Wonka's Chocolate Factory",
|
70
|
+
street: "Chocolane 12",
|
71
|
+
building: "8",
|
72
|
+
city: "Confectionopolis"
|
73
|
+
)
|
74
|
+
}.to change{Muve::Store::Mongo.count(Place, {})}.by(1)
|
75
|
+
end
|
76
|
+
|
29
77
|
it 'writes modifications to the store' do
|
30
|
-
id = database['places'].insert(name: Faker::Venue.name)
|
31
78
|
new_name = Faker::Venue.name
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
79
|
+
expect {
|
80
|
+
adaptor.update(Place, id_of_stored_resource, { name: new_name })
|
81
|
+
}.to change {
|
82
|
+
database['places'].find_one(_id: id_of_stored_resource)['name']
|
83
|
+
}.to(new_name)
|
36
84
|
end
|
37
85
|
|
38
86
|
it 'finds a resource from store' do
|
39
|
-
|
40
|
-
expect(Muve::Store::Mongo.get(Place, id)[:id]).to eq(id)
|
87
|
+
expect(adaptor.get(Place, id_of_stored_resource)[:id]).to eq(id_of_stored_resource)
|
41
88
|
end
|
42
89
|
|
43
90
|
it 'finds multiple resources from store' do
|
44
|
-
expect(
|
91
|
+
expect(adaptor.find(Place, {})).to be_a(Enumerable)
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'removes a resource from the store' do
|
95
|
+
id_of_resource_to_be_removed = id_of_stored_resource
|
96
|
+
expect {
|
97
|
+
adaptor.delete(Place, id_of_resource_to_be_removed)
|
98
|
+
}.to change { database['places'].count }.by(-1)
|
45
99
|
end
|
46
100
|
|
47
101
|
it 'extracts a resource from every result in a multiple resource set' do
|
48
|
-
|
102
|
+
adaptor.find(Place, {}).take(3).each do |result|
|
49
103
|
attributes = result.keys.map{ |i| i.to_s }
|
50
|
-
expect(attributes).to include('id', '
|
104
|
+
expect(attributes).to include('id', 'name')
|
51
105
|
end
|
52
106
|
end
|
107
|
+
|
108
|
+
context "wired to handle model I/O" do
|
109
|
+
before do
|
110
|
+
Place.adaptor = adaptor
|
111
|
+
end
|
112
|
+
|
113
|
+
it {
|
114
|
+
expect(adaptor).to receive(:find).with(Place, {})
|
115
|
+
Place.where({}).count
|
116
|
+
}
|
117
|
+
|
118
|
+
it {
|
119
|
+
expect_any_instance_of(Place).to receive(:populate).with(anything).once
|
120
|
+
Place.where({}).take(1).each do |item|
|
121
|
+
expect(item).to be_a_kind_of(Place)
|
122
|
+
end
|
123
|
+
}
|
124
|
+
|
125
|
+
it {
|
126
|
+
Muve::Place.adaptor = adaptor
|
127
|
+
expect(adaptor).to receive(:create).with(Muve::Place, {
|
128
|
+
name: 'Hell',
|
129
|
+
location: { type: 'Place', coordinates: [6, 66] }
|
130
|
+
})
|
131
|
+
|
132
|
+
Muve::Place.new(
|
133
|
+
name: 'Hell',
|
134
|
+
location: Muve::Location.new(latitude: 66, longitude: 6)
|
135
|
+
).save
|
136
|
+
}
|
137
|
+
|
138
|
+
it {
|
139
|
+
Place.adaptor = adaptor
|
140
|
+
expect(adaptor).to receive(:create).with(Muve::Place, {
|
141
|
+
name: 'Hell',
|
142
|
+
location: { type: 'Place', coordinates: [6, 66] }
|
143
|
+
})
|
144
|
+
|
145
|
+
Muve::Place.new(
|
146
|
+
name: 'Hell',
|
147
|
+
location: Muve::Location.new(latitude: 66, longitude: 6)
|
148
|
+
).save
|
149
|
+
}
|
150
|
+
|
151
|
+
it {
|
152
|
+
storeable_object = {
|
153
|
+
name: 'Hell',
|
154
|
+
location: Muve::Location.new(latitude: 66, longitude: 6)
|
155
|
+
}
|
156
|
+
|
157
|
+
expect(MockCollection).to receive(:insert).with(storeable_object)
|
158
|
+
|
159
|
+
Muve::Store::Mongo.create(MockResource, storeable_object)
|
160
|
+
}
|
161
|
+
end
|
53
162
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: muve-store-mongo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Asabina
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-09-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: muve
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 1.0.
|
19
|
+
version: 1.2.0.pre.alpha.1
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 1.0.
|
26
|
+
version: 1.2.0.pre.alpha.1
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: mongo
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -52,8 +52,11 @@ files:
|
|
52
52
|
- README.md
|
53
53
|
- Rakefile
|
54
54
|
- lib/muve-store-mongo.rb
|
55
|
+
- lib/muve-store-mongo/errors.rb
|
56
|
+
- lib/muve-store-mongo/formatter.rb
|
55
57
|
- lib/muve-store-mongo/version.rb
|
56
58
|
- muve-store-mongo.gemspec
|
59
|
+
- spec/formatter_spec.rb
|
57
60
|
- spec/mongo_spec.rb
|
58
61
|
- spec/spec_helper.rb
|
59
62
|
homepage: https://github.com/vidbina/muve-store-mongo
|
@@ -80,5 +83,6 @@ signing_key:
|
|
80
83
|
specification_version: 4
|
81
84
|
summary: Mongo adaptor for the Muve engine
|
82
85
|
test_files:
|
86
|
+
- spec/formatter_spec.rb
|
83
87
|
- spec/mongo_spec.rb
|
84
88
|
- spec/spec_helper.rb
|