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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 33464acefa3d59d3071f27af3019a285073dc7d1
4
- data.tar.gz: a537c768adee7c8ca400d87607d0ad7ead7669ee
3
+ metadata.gz: 93b785d7d848372e3e0f88d79804905bcafe8b1d
4
+ data.tar.gz: 8d0ffc4195047662b2d3eaa7b4dfa8f9046f55bb
5
5
  SHA512:
6
- metadata.gz: fc049c900e092be9babe15d44e009424352f8bc6531a4dd419652f613334f45aa33082b4aeee3d1f11decf44b8da475c7f0fe9706cc47ad61a666db7bd404194
7
- data.tar.gz: 7c769583d16f698a924313263fa2fba815cba80fb40a82a55e1e4dec893e9de0f271378fcc8c77d33fcc481a5df2504a3c1511abd8cc2934e828749315228dbb
6
+ metadata.gz: fd5c4ea2ca8c748e67a5268493d6b7c08486788591e09cab08fb9f1fbe2d798563584012c0caf239ab94b8032982ec65d850d3330a84abec9abfb6f1161ad5cd
7
+ data.tar.gz: 83ba6f494982d0205f172653534ee614e46e054671a02ee12fcce99a7bd8f650f03c977e0363bfe5f99cb478077ebea5a8d898cf79e732a21b0868c574a745c3
data/Gemfile CHANGED
@@ -3,6 +3,7 @@ source 'https://rubygems.org'
3
3
  gemspec
4
4
 
5
5
  gem "bson_ext", "~> 1.10.2"
6
+ gem "muve", "~> 1.2.0"
6
7
 
7
8
  group :test do
8
9
  gem "ffaker", "~> 1.24.0"
@@ -0,0 +1,5 @@
1
+ module Muve
2
+ module Error
3
+ class MongoError < StandardError; end
4
+ end
5
+ end
@@ -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
@@ -1,7 +1,7 @@
1
1
  module Muve
2
2
  module Store
3
3
  module Mongo
4
- VERSION = "0.0.2"
4
+ VERSION = "0.0.3"
5
5
  end
6
6
  end
7
7
  end
@@ -1,30 +1,35 @@
1
- require "muve-store-mongo/version"
2
- require "muve"
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 MuveInvalidAttributes, "invalid update data" unless details.kind_of? Hash
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
- details = {} unless details.kind_of? Hash
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
- details = {} unless details.kind_of? Hash
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 MuveInvalidAttributes, "invalid update data" unless details.kind_of? Hash
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=nil)
47
- details = {} unless details.kind_of? Hash
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
@@ -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.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
- expect{
34
- Muve::Store::Mongo.update(Place, id, { name: new_name })
35
- }.to change{database['places'].find_one(_id: id)['name']}.to(new_name)
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
- id = database['places'].insert(name: Faker::Venue.name)
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(Muve::Store::Mongo.find(Place, {})).to be_a(Enumerable)
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
- Muve::Store::Mongo.find(Place, {}).take(3).each do |result|
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', 'city', 'street', 'building')
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.2
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-07-30 00:00:00.000000000 Z
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.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.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