mongoo 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,91 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{mongoo}
8
+ s.version = "0.1.2"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Ben Myles"]
12
+ s.date = %q{2011-02-15}
13
+ s.description = %q{Simple object mapper for MongoDB}
14
+ s.email = %q{ben.myles@gmail.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE.txt",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".rvmrc",
22
+ "Gemfile",
23
+ "LICENSE.txt",
24
+ "README.rdoc",
25
+ "Rakefile",
26
+ "VERSION",
27
+ "lib/mongoo.rb",
28
+ "lib/mongoo/attribute_proxy.rb",
29
+ "lib/mongoo/attribute_sanitizer.rb",
30
+ "lib/mongoo/base.rb",
31
+ "lib/mongoo/changelog.rb",
32
+ "lib/mongoo/cursor.rb",
33
+ "lib/mongoo/hash_ext.rb",
34
+ "lib/mongoo/modifiers.rb",
35
+ "lib/mongoo/mongohash.rb",
36
+ "lib/mongoo/persistence.rb",
37
+ "test/helper.rb",
38
+ "test/test_activemodel.rb",
39
+ "test/test_mongohash.rb",
40
+ "test/test_mongoo.rb"
41
+ ]
42
+ s.homepage = %q{http://github.com/benmyles/mongoo}
43
+ s.licenses = ["MIT"]
44
+ s.require_paths = ["lib"]
45
+ s.rubygems_version = %q{1.3.7}
46
+ s.summary = %q{Object mapper for MongoDB}
47
+ s.test_files = [
48
+ "test/helper.rb",
49
+ "test/test_activemodel.rb",
50
+ "test/test_mongohash.rb",
51
+ "test/test_mongoo.rb"
52
+ ]
53
+
54
+ if s.respond_to? :specification_version then
55
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
56
+ s.specification_version = 3
57
+
58
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
59
+ s.add_runtime_dependency(%q<i18n>, [">= 0.4.1"])
60
+ s.add_runtime_dependency(%q<activesupport>, [">= 3.0.3"])
61
+ s.add_runtime_dependency(%q<activemodel>, [">= 3.0.3"])
62
+ s.add_runtime_dependency(%q<mongo-em>, [">= 1.2.1"])
63
+ s.add_runtime_dependency(%q<bson_ext>, [">= 1.2.2"])
64
+ s.add_development_dependency(%q<shoulda>, [">= 0"])
65
+ s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
66
+ s.add_development_dependency(%q<jeweler>, ["~> 1.5.1"])
67
+ s.add_development_dependency(%q<rcov>, [">= 0"])
68
+ else
69
+ s.add_dependency(%q<i18n>, [">= 0.4.1"])
70
+ s.add_dependency(%q<activesupport>, [">= 3.0.3"])
71
+ s.add_dependency(%q<activemodel>, [">= 3.0.3"])
72
+ s.add_dependency(%q<mongo-em>, [">= 1.2.1"])
73
+ s.add_dependency(%q<bson_ext>, [">= 1.2.2"])
74
+ s.add_dependency(%q<shoulda>, [">= 0"])
75
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
76
+ s.add_dependency(%q<jeweler>, ["~> 1.5.1"])
77
+ s.add_dependency(%q<rcov>, [">= 0"])
78
+ end
79
+ else
80
+ s.add_dependency(%q<i18n>, [">= 0.4.1"])
81
+ s.add_dependency(%q<activesupport>, [">= 3.0.3"])
82
+ s.add_dependency(%q<activemodel>, [">= 3.0.3"])
83
+ s.add_dependency(%q<mongo-em>, [">= 1.2.1"])
84
+ s.add_dependency(%q<bson_ext>, [">= 1.2.2"])
85
+ s.add_dependency(%q<shoulda>, [">= 0"])
86
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
87
+ s.add_dependency(%q<jeweler>, ["~> 1.5.1"])
88
+ s.add_dependency(%q<rcov>, [">= 0"])
89
+ end
90
+ end
91
+
@@ -0,0 +1,62 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ groups = [:default, :development]
5
+ if defined?(EM) && EM.reactor_running?
6
+ groups << :async
7
+ else
8
+ groups << :sync
9
+ end
10
+ Bundler.setup(groups)
11
+ rescue Bundler::BundlerError => e
12
+ $stderr.puts e.message
13
+ $stderr.puts "Run `bundle install` to install missing gems"
14
+ exit e.status_code
15
+ end
16
+ require 'test/unit'
17
+ require 'shoulda'
18
+
19
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
20
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
21
+ require 'mongoo'
22
+
23
+ Mongoo.config = {host: "127.0.0.1", port: 27017, db: 'mongoo-test'}
24
+
25
+ class SearchIndex < Mongoo::Base
26
+ attribute "terms", :type => :array
27
+ index "terms"
28
+ end
29
+
30
+ class Person < Mongoo::Base
31
+ attribute "name", :type => :string
32
+ attribute "visits", :type => :integer
33
+ attribute "interests", :type => :array
34
+ attribute "jobs.total", :type => :integer
35
+ attribute "jobs.professional", :type => :array
36
+ attribute "jobs.volunteer", :type => :array
37
+ attribute "jobs.internships.high_school", :type => :array
38
+ attribute "location.city", :type => :string
39
+ attribute "location.demographics.crime_rate", :type => :symbol
40
+ attribute "location.demographics.education_quality", :type => :symbol
41
+ attribute "misc", :type => :hash
42
+
43
+ index "name"
44
+ index "location.city"
45
+ end
46
+
47
+ class TvShow < Mongoo::Base
48
+ attribute "name", :type => :string
49
+ attribute "cast.director", :type => :string
50
+ attribute "cast.lead", :type => :string
51
+ attribute "rating", :type => :float
52
+ attribute "comments", :type => :array
53
+
54
+ index "name"
55
+
56
+ validates_presence_of "name"
57
+ validates_presence_of "cast.director"
58
+ validates_presence_of "rating"
59
+ end
60
+
61
+ class Test::Unit::TestCase
62
+ end
@@ -0,0 +1,14 @@
1
+ require 'helper'
2
+
3
+ class TestActivemodel < Test::Unit::TestCase
4
+ include ActiveModel::Lint::Tests
5
+
6
+ def setup
7
+ [TvShow].each do |obj|
8
+ obj.drop
9
+ obj.create_indexes
10
+ end
11
+ @model = TvShow.new
12
+ end
13
+ end
14
+
@@ -0,0 +1,36 @@
1
+ require 'helper'
2
+
3
+ class TestMongohash < Test::Unit::TestCase
4
+ should "work with dot_get, dot_set, dot_delete" do
5
+ h = Mongoo::Mongohash.new({
6
+ "name" => "Ben",
7
+ "travel" => {},
8
+ "location" => { "city" => "SF", "zip" => 94107, "demographics" => { "pop" => 120000 } }})
9
+ assert_equal "Ben", h.dot_get("name")
10
+ assert_equal "SF", h.dot_get("location.city")
11
+ assert_equal 94107, h.dot_get("location.zip")
12
+ assert_equal 120000, h.dot_get("location.demographics.pop")
13
+ assert_equal nil, h.dot_get("foobar")
14
+ assert_equal nil, h.dot_get("location.idontexist.andneitherdoi")
15
+ h.dot_set("location.demographics.pop", 10000)
16
+ assert_equal 10000, h.dot_get("location.demographics.pop")
17
+ h.dot_set("interests", ["skydiving"])
18
+ assert_equal ["skydiving"], h.dot_get("interests")
19
+ h.dot_set("languages.fluent", ["english"])
20
+ h.dot_set("languages.nonfluent", ["german"])
21
+ assert_equal ["english"], h.dot_get("languages.fluent")
22
+ assert_equal ["german"], h.dot_get("languages.nonfluent")
23
+ h.dot_delete("languages.fluent")
24
+ assert_equal nil, h.dot_get("languages.fluent")
25
+ h.dot_delete("languages")
26
+ assert_equal nil, h.dot_get("languages")
27
+ assert_equal "Ben", h.dot_get("name")
28
+ h.dot_delete("name")
29
+ assert_equal nil, h.dot_get("name")
30
+ end
31
+
32
+ # should "not be able to initialize an object with undefined attributes" do
33
+ # assert_raise(Mongoo::UnknownAttributeError) { Person.new(:idontexist => "bah") }
34
+ # end
35
+ end
36
+
@@ -0,0 +1,276 @@
1
+ require 'helper'
2
+
3
+ class TestMongoo < Test::Unit::TestCase
4
+
5
+ def setup
6
+ [Person, TvShow, SearchIndex].each do |obj|
7
+ obj.drop
8
+ obj.create_indexes
9
+ end
10
+ end
11
+
12
+ should "set and get attributes" do
13
+ p = Person.new("name" => "Ben")
14
+ assert_equal "Ben", p.g(:name)
15
+ assert_equal "Ben", p.get(:name)
16
+ assert_equal "Ben", p.get_attribute(:name)
17
+ p.set("location.city", "San Francisco")
18
+ assert_equal "San Francisco", p.get("location.city")
19
+ p.sets({"location.demographics.crime_rate" => :high, "location.demographics.education_quality" => :low})
20
+ assert_equal({"name"=>"Ben",
21
+ "location.demographics.crime_rate"=>:high}, p.gets(%w(name location.demographics.crime_rate)))
22
+ assert_raise(Mongoo::UnknownAttributeError) { p.set("idontexist", "foo") }
23
+ assert_raise(Mongoo::UnknownAttributeError) { p.get("idontexist") }
24
+ assert_raise(NoMethodError) { p.idontexist }
25
+ assert_raise(NoMethodError) { p.idontexist = "val" }
26
+ end
27
+
28
+ should "have attribute methods" do
29
+ p = Person.new("name" => "Ben", "jobs" => { "professional" => "iList" })
30
+ p.jobs.internships.high_school = ["Sun Microsystems"]
31
+ assert_equal ["Sun Microsystems"], p.jobs.internships.high_school
32
+ assert_equal ["Sun Microsystems"], p.get("jobs.internships.high_school")
33
+ p.name = "Ben Myles"
34
+ assert_equal "Ben Myles", p.name
35
+ assert_equal "Ben Myles", p.get("name")
36
+ end
37
+
38
+ should "never has the same object for persisted_mongohash and mongohash" do
39
+ p = Person.new("name" => "Ben")
40
+ p.insert
41
+ p.name = "Ben Myles"
42
+ assert_not_equal p.persisted_mongohash.raw_hash, p.mongohash.raw_hash
43
+ p.update
44
+ assert_equal p.persisted_mongohash.raw_hash, p.mongohash.raw_hash
45
+ p.name = "Ben 2"
46
+ assert_not_equal p.persisted_mongohash.raw_hash, p.mongohash.raw_hash
47
+ end
48
+
49
+ should "be able to do crud" do
50
+ p = Person.new("name" => "Ben")
51
+ p.jobs.internships.high_school = ["Sun Microsystems"]
52
+ p.insert
53
+
54
+ p = Person.find_one(p.id)
55
+ p.update
56
+ p.location.city = "San Francisco"
57
+ p.update
58
+ p.name = "Ben Myles"
59
+ p.location.city = "San Diego"
60
+ assert_not_equal p.persisted_mongohash.raw_hash, p.mongohash.raw_hash
61
+ p.update
62
+
63
+ p2 = Person.find_one(p.id)
64
+ assert_equal "Ben Myles", p2.name
65
+ assert_equal "San Diego", p2.location.city
66
+
67
+ p.location.city = "Los Angeles"
68
+ p.update!
69
+
70
+ p2.location.city = "San Jose"
71
+ assert_raise(Mongoo::StaleUpdateError) { p2.update! }
72
+ p2.location.city = "San Diego"
73
+ p2.name = "Benjamin"
74
+ p2.update!
75
+
76
+ assert p2.reload
77
+
78
+ assert_equal "Los Angeles", p2.location.city
79
+ assert_equal "Benjamin", p2.name
80
+
81
+ assert p2.persisted_mongohash.raw_hash["location"].has_key?("city")
82
+ p2.unset "location.city"
83
+ p2.update
84
+ assert !p2.persisted_mongohash.raw_hash["location"].has_key?("city")
85
+
86
+ p2.location.demographics.crime_rate = :high
87
+ p2.location.city = "San Bruno"
88
+ p2.update
89
+ assert_raise(NoMethodError) { p2.location.demographics = 123 }
90
+
91
+ p2.unset "location"
92
+ p2.update
93
+ p2 = Person.find_one(p2.id)
94
+ assert !p2.persisted_mongohash.raw_hash.has_key?("location")
95
+
96
+ p2.location.city = "Brisbane"
97
+ p2.location.demographics.crime_rate = :low
98
+ p2.update
99
+ assert_equal ["Brisbane", :low], [p2.location.city, p2.location.demographics.crime_rate]
100
+ p2 = Person.find_one(p2.id)
101
+ assert_equal ["Brisbane", :low], [p2.location.city, p2.location.demographics.crime_rate]
102
+ p2.location.unset
103
+ p2.update
104
+ assert !p2.persisted_mongohash.raw_hash.has_key?("location")
105
+ p2 = Person.find_one(p2.id)
106
+ assert !p2.persisted_mongohash.raw_hash.has_key?("location")
107
+
108
+ p2.location.city = "Brisbane"
109
+ p2.location.demographics.crime_rate = :low
110
+ p2.update
111
+ assert_equal ["Brisbane", :low], [p2.location.city, p2.location.demographics.crime_rate]
112
+ assert p2.persisted_mongohash.raw_hash["location"].has_key?("demographics")
113
+ p2.location.demographics.unset
114
+ p2.update
115
+ assert !p2.persisted_mongohash.raw_hash["location"].has_key?("demographics")
116
+ p2 = Person.find_one(p2.id)
117
+ assert !p2.persisted_mongohash.raw_hash["location"].has_key?("demographics")
118
+ assert_equal "Brisbane", p2.location.city
119
+ end
120
+
121
+ should "be able to modify fields" do
122
+ p = Person.new("name" => "Ben", "visits" => 0)
123
+ p.insert!
124
+ assert_equal 0, p.visits
125
+
126
+ p.mod! do |mod|
127
+ mod.inc "visits", 2
128
+ mod.set "jobs.total", 10
129
+ end
130
+ assert_equal 2, p.visits
131
+ assert_equal 10, p.jobs.total
132
+ assert_equal [], p.changelog
133
+ p = Person.find_one(p.id)
134
+ assert_equal 2, p.visits
135
+ assert_equal 10, p.jobs.total
136
+
137
+ p.jobs.mod! do |mod|
138
+ mod.inc "total", 5
139
+ end
140
+ assert_equal 15, p.jobs.total
141
+ p = Person.find_one(p.id)
142
+ assert_equal 15, p.jobs.total
143
+
144
+ assert_equal nil, p.interests
145
+ p.mod! { |mod| mod.push("interests", "skydiving") }
146
+ assert_equal ["skydiving"], p.interests
147
+ p = Person.find_one(p.id)
148
+ assert_equal ["skydiving"], p.interests
149
+ p.mod! { |mod| mod.push("interests", "snowboarding") }
150
+ assert_equal ["skydiving", "snowboarding"], p.interests
151
+ p = Person.find_one(p.id)
152
+ assert_equal ["skydiving", "snowboarding"], p.interests
153
+
154
+ p.mod! { |mod| mod.push_all("interests", ["reading","travelling"]) }
155
+ assert_equal ["skydiving", "snowboarding", "reading", "travelling"], p.interests
156
+ p = Person.find_one(p.id)
157
+ assert_equal ["skydiving", "snowboarding", "reading", "travelling"], p.interests
158
+
159
+ p.mod! { |mod| mod.add_to_set("interests", "skydiving") }
160
+ assert_equal ["skydiving", "snowboarding", "reading", "travelling"], p.interests
161
+ p.mod! { |mod| mod.add_to_set("interests", "swimming") }
162
+ assert_equal ["skydiving", "snowboarding", "reading", "travelling", "swimming"], p.interests
163
+ p.mod! { |mod| mod.add_to_set("interests", "swimming") }
164
+ assert_equal ["skydiving", "snowboarding", "reading", "travelling", "swimming"], p.interests
165
+
166
+ p.mod! { |mod| mod.pop("interests") }
167
+ assert_equal ["skydiving", "snowboarding", "reading", "travelling"], p.interests
168
+
169
+ p.mod! { |mod| mod.pop("interests") }
170
+ assert_equal ["skydiving", "snowboarding", "reading"], p.interests
171
+
172
+ p.mod! { |mod| mod.push("interests", "reading") }
173
+ assert_equal ["skydiving", "snowboarding", "reading", "reading"], p.interests
174
+ p = Person.find_one(p.id)
175
+ assert_equal ["skydiving", "snowboarding", "reading", "reading"], p.interests
176
+ p.mod! { |mod| mod.pull("interests", "reading") }
177
+ assert_equal ["skydiving", "snowboarding"], p.interests
178
+ p = Person.find_one(p.id)
179
+ assert_equal ["skydiving", "snowboarding"], p.interests
180
+
181
+ p.mod! { |mod| mod.push_all("interests", ["reading","travelling"]) }
182
+ assert_equal ["skydiving", "snowboarding", "reading", "travelling"], p.interests
183
+ p = Person.find_one(p.id)
184
+ assert_equal ["skydiving", "snowboarding", "reading", "travelling"], p.interests
185
+
186
+ p.mod! { |mod| mod.pull_all("interests", ["reading", "skydiving"]) }
187
+ assert_equal ["snowboarding", "travelling"], p.interests
188
+ p = Person.find_one(p.id)
189
+ assert_equal ["snowboarding", "travelling"], p.interests
190
+ end
191
+
192
+ should "not be able to modify fields that don't exist" do
193
+ p = Person.new("name" => "Ben", "visits" => 0)
194
+ p.insert!
195
+ assert_raise(Mongoo::UnknownAttributeError) do
196
+ p.mod! { |mod| mod.push("idontexist", "foobar") }
197
+ end
198
+ end
199
+
200
+ should "be able to access a hash type directly" do
201
+ p = Person.new("name" => "Ben")
202
+ p.insert!
203
+ assert_equal nil, p.misc
204
+ p.misc = { "height" => 5.5, "weight" => 160 }
205
+ p.update!
206
+ assert_equal({ "height" => 5.5, "weight" => 160 }, p.misc)
207
+ p.update!
208
+ p = Person.find_one(p.id)
209
+ assert_equal({ "height" => 5.5, "weight" => 160 }, p.misc)
210
+ p.misc["height"] = 5.6
211
+ p.misc["eyes"] = :blue
212
+ assert_equal({ "height" => 5.6, "weight" => 160, "eyes" => :blue }, p.misc)
213
+ p.update!
214
+ assert_equal({ "height" => 5.6, "weight" => 160, "eyes" => :blue }, p.misc)
215
+ p = Person.find_one(p.id)
216
+ assert_equal({ "height" => 5.6, "weight" => 160, "eyes" => :blue }, p.misc)
217
+ end
218
+
219
+ should "cast to type automatically" do
220
+ p = Person.new("name" => "ben")
221
+ p.insert!
222
+ p.visits = "5"
223
+ assert_equal 5, p.visits
224
+ p.update!
225
+ p = Person.find_one(p.id)
226
+ assert_equal 5, p.visits
227
+ p.mod! { |mod| mod.inc("visits", 3) }
228
+ assert_equal 8, p.visits
229
+ p = Person.find_one(p.id)
230
+ assert_equal 8, p.visits
231
+ end
232
+
233
+ should "validate documents" do
234
+ show = TvShow.new
235
+ assert !show.valid?
236
+ assert !show.insert
237
+ assert_equal({:name=>["can't be blank"],
238
+ :"cast.director"=>["can't be blank"],
239
+ :rating=>["can't be blank"]}, show.errors)
240
+ show.cast.director = "Some Guy"
241
+ show.name = "Some Show"
242
+ assert !show.valid?
243
+ assert !show.insert
244
+ assert_raise(Mongoo::NotValidError) { show.insert! }
245
+ assert_equal({:rating=>["can't be blank"]}, show.errors)
246
+ show.rating = 3.0
247
+ assert show.valid?
248
+ show.insert!
249
+ end
250
+
251
+ should "not care if keys are symbols or hashes" do
252
+ p = Person.new(:name => "Ben")
253
+ assert_equal "Ben", p.name
254
+ end
255
+
256
+ should "be able to merge properties into the mongohash" do
257
+ p = Person.new("name" => "Ben", "visits" => 10, "location" => { "city" => "SF" })
258
+ p.insert!
259
+ p = Person.find_one(p.id)
260
+ assert_equal "Ben", p.name
261
+ assert_equal 10, p.visits
262
+ assert_equal "SF", p.location.city
263
+ p.merge!({"visits" => 12, "location" => { "demographics" => {"crime_rate" => :high} } })
264
+ assert_equal "Ben", p.name
265
+ assert_equal 12, p.visits
266
+ assert_equal "SF", p.location.city
267
+ end
268
+
269
+ should "not fail on an empty array" do
270
+ i = SearchIndex.new(:terms => [])
271
+ i.insert!
272
+ i.terms << "foo"
273
+ i.update!
274
+ end
275
+ end
276
+