mrkurt-mongo_mapper 0.6.8

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.
Files changed (77) hide show
  1. data/.gitignore +10 -0
  2. data/LICENSE +20 -0
  3. data/README.rdoc +38 -0
  4. data/Rakefile +55 -0
  5. data/VERSION +1 -0
  6. data/bin/mmconsole +60 -0
  7. data/lib/mongo_mapper.rb +139 -0
  8. data/lib/mongo_mapper/associations.rb +72 -0
  9. data/lib/mongo_mapper/associations/base.rb +113 -0
  10. data/lib/mongo_mapper/associations/belongs_to_polymorphic_proxy.rb +26 -0
  11. data/lib/mongo_mapper/associations/belongs_to_proxy.rb +21 -0
  12. data/lib/mongo_mapper/associations/collection.rb +19 -0
  13. data/lib/mongo_mapper/associations/many_documents_as_proxy.rb +26 -0
  14. data/lib/mongo_mapper/associations/many_documents_proxy.rb +115 -0
  15. data/lib/mongo_mapper/associations/many_embedded_polymorphic_proxy.rb +31 -0
  16. data/lib/mongo_mapper/associations/many_embedded_proxy.rb +54 -0
  17. data/lib/mongo_mapper/associations/many_polymorphic_proxy.rb +11 -0
  18. data/lib/mongo_mapper/associations/one_proxy.rb +61 -0
  19. data/lib/mongo_mapper/associations/proxy.rb +111 -0
  20. data/lib/mongo_mapper/callbacks.rb +61 -0
  21. data/lib/mongo_mapper/dirty.rb +117 -0
  22. data/lib/mongo_mapper/document.rb +496 -0
  23. data/lib/mongo_mapper/dynamic_finder.rb +74 -0
  24. data/lib/mongo_mapper/embedded_document.rb +380 -0
  25. data/lib/mongo_mapper/finder_options.rb +145 -0
  26. data/lib/mongo_mapper/key.rb +36 -0
  27. data/lib/mongo_mapper/mongo_mapper.rb +125 -0
  28. data/lib/mongo_mapper/pagination.rb +66 -0
  29. data/lib/mongo_mapper/rails_compatibility/document.rb +15 -0
  30. data/lib/mongo_mapper/rails_compatibility/embedded_document.rb +28 -0
  31. data/lib/mongo_mapper/serialization.rb +54 -0
  32. data/lib/mongo_mapper/serializers/json_serializer.rb +48 -0
  33. data/lib/mongo_mapper/support.rb +192 -0
  34. data/lib/mongo_mapper/validations.rb +39 -0
  35. data/mongo_mapper.gemspec +173 -0
  36. data/specs.watchr +30 -0
  37. data/test/NOTE_ON_TESTING +1 -0
  38. data/test/functional/associations/test_belongs_to_polymorphic_proxy.rb +55 -0
  39. data/test/functional/associations/test_belongs_to_proxy.rb +91 -0
  40. data/test/functional/associations/test_many_documents_as_proxy.rb +246 -0
  41. data/test/functional/associations/test_many_documents_proxy.rb +477 -0
  42. data/test/functional/associations/test_many_embedded_polymorphic_proxy.rb +156 -0
  43. data/test/functional/associations/test_many_embedded_proxy.rb +192 -0
  44. data/test/functional/associations/test_many_polymorphic_proxy.rb +339 -0
  45. data/test/functional/associations/test_one_proxy.rb +131 -0
  46. data/test/functional/test_associations.rb +44 -0
  47. data/test/functional/test_binary.rb +33 -0
  48. data/test/functional/test_callbacks.rb +85 -0
  49. data/test/functional/test_dirty.rb +159 -0
  50. data/test/functional/test_document.rb +1198 -0
  51. data/test/functional/test_embedded_document.rb +135 -0
  52. data/test/functional/test_logger.rb +20 -0
  53. data/test/functional/test_modifiers.rb +242 -0
  54. data/test/functional/test_pagination.rb +95 -0
  55. data/test/functional/test_rails_compatibility.rb +25 -0
  56. data/test/functional/test_string_id_compatibility.rb +72 -0
  57. data/test/functional/test_validations.rb +361 -0
  58. data/test/models.rb +271 -0
  59. data/test/support/custom_matchers.rb +55 -0
  60. data/test/support/timing.rb +16 -0
  61. data/test/test_helper.rb +27 -0
  62. data/test/unit/associations/test_base.rb +182 -0
  63. data/test/unit/associations/test_proxy.rb +91 -0
  64. data/test/unit/serializers/test_json_serializer.rb +189 -0
  65. data/test/unit/test_document.rb +236 -0
  66. data/test/unit/test_dynamic_finder.rb +125 -0
  67. data/test/unit/test_embedded_document.rb +709 -0
  68. data/test/unit/test_finder_options.rb +325 -0
  69. data/test/unit/test_key.rb +172 -0
  70. data/test/unit/test_mongo_mapper.rb +65 -0
  71. data/test/unit/test_pagination.rb +119 -0
  72. data/test/unit/test_rails_compatibility.rb +52 -0
  73. data/test/unit/test_serializations.rb +52 -0
  74. data/test/unit/test_support.rb +346 -0
  75. data/test/unit/test_time_zones.rb +40 -0
  76. data/test/unit/test_validations.rb +503 -0
  77. metadata +239 -0
@@ -0,0 +1,25 @@
1
+ require 'test_helper'
2
+
3
+ class TestRailsCompatibility < Test::Unit::TestCase
4
+ class Item
5
+ include MongoMapper::EmbeddedDocument
6
+ key :for_all, String
7
+ end
8
+
9
+ class Order
10
+ include MongoMapper::Document
11
+ many :items, :class_name => 'TestRailsCompatibility::Item'
12
+ key :order_only, String
13
+ end
14
+
15
+ context "Document" do
16
+ setup do
17
+ Order.collection.remove
18
+ end
19
+
20
+ should "alias new to new_record?" do
21
+ instance = Order.new
22
+ instance.new_record?.should == instance.new?
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,72 @@
1
+ require 'test_helper'
2
+
3
+ class StringIdCompatibilityTest < Test::Unit::TestCase
4
+ def setup
5
+ @note_class = Class.new do
6
+ include MongoMapper::EmbeddedDocument
7
+ key :_id, String
8
+ end
9
+
10
+ @task_class = Class.new do
11
+ include MongoMapper::Document
12
+ key :_id, String
13
+ key :project_id, String
14
+ belongs_to :project
15
+ end
16
+
17
+ @project_class = Class.new do
18
+ include MongoMapper::Document
19
+ key :_id, String
20
+ end
21
+
22
+ @task_class.belongs_to :project, :class => @project_class
23
+ @project_class.many :notes, :class => @note_class
24
+ @project_class.many :tasks, :class => @task_class, :foreign_key => 'project_id'
25
+
26
+ @project_class.collection.remove
27
+ @task_class.collection.remove
28
+ end
29
+
30
+ should "assign correct _id for documents" do
31
+ project = @project_class.create
32
+ project._id.should == project.id
33
+ project._id.should be_instance_of(String)
34
+ project.id.size.should == 24
35
+ lambda {
36
+ Mongo::ObjectID.from_string(project.id)
37
+ }.should_not raise_error
38
+ end
39
+
40
+ should "assign correct _id for embedded documents" do
41
+ note = @note_class.new
42
+ note.id.should == note._id
43
+ note.id.size.should == 24
44
+ end
45
+
46
+ should "find records" do
47
+ project = @project_class.create
48
+ @project_class.find(project.id).should == project
49
+ end
50
+
51
+ should "save embedded docs" do
52
+ n1 = @note_class.new
53
+ n2 = @note_class.new
54
+ n3 = @note_class.new
55
+ project = @project_class.create(:notes => [n1, n2, n3])
56
+
57
+ project = project.reload
58
+ project.notes.size.should == 3
59
+ project.notes.should == [n1, n2, n3]
60
+ end
61
+
62
+ should "be able to associate records" do
63
+ t1 = @task_class.new(:body => 'First task')
64
+ t2 = @task_class.new(:body => 'Second task')
65
+ t3 = @task_class.new(:body => 'Third task')
66
+ project = @project_class.create(:name => 'MM', :tasks => [t1, t2, t3])
67
+
68
+ project = project.reload
69
+ project.tasks.count.should == 3
70
+ project.tasks.should == [t1, t2, t3]
71
+ end
72
+ end
@@ -0,0 +1,361 @@
1
+ require 'test_helper'
2
+
3
+ class ValidationsTest < Test::Unit::TestCase
4
+ context "Saving a new document that is invalid" do
5
+ setup do
6
+ @document = Class.new do
7
+ include MongoMapper::Document
8
+ set_collection_name 'test'
9
+ key :name, String, :required => true
10
+ end
11
+ @document.collection.remove
12
+ end
13
+
14
+ should "not insert document" do
15
+ doc = @document.new
16
+ doc.save
17
+ @document.count.should == 0
18
+ end
19
+
20
+ should "populate document's errors" do
21
+ doc = @document.new
22
+ doc.errors.size.should == 0
23
+ doc.save
24
+ doc.errors.full_messages.should == ["Name can't be empty"]
25
+ end
26
+ end
27
+
28
+ context "Saving a document that is invalid (destructive)" do
29
+ setup do
30
+ @document = Class.new do
31
+ include MongoMapper::Document
32
+ set_collection_name 'test'
33
+ key :name, String, :required => true
34
+ end
35
+ @document.collection.remove
36
+ end
37
+
38
+ should "raise error" do
39
+ doc = @document.new
40
+ lambda { doc.save! }.should raise_error(MongoMapper::DocumentNotValid)
41
+ end
42
+ end
43
+
44
+ context "Creating a document that is invalid (destructive)" do
45
+ setup do
46
+ @document = Class.new do
47
+ include MongoMapper::Document
48
+ set_collection_name 'test'
49
+ key :name, String, :required => true
50
+ end
51
+ @document.collection.remove
52
+ end
53
+
54
+ should "raise error" do
55
+ lambda { @document.create! }.should raise_error(MongoMapper::DocumentNotValid)
56
+ end
57
+
58
+ should "create a new document" do
59
+ instance = @document.create!(:name => "James")
60
+ instance.new_record?.should be_false
61
+ end
62
+ end
63
+
64
+ context "Saving an existing document that is invalid" do
65
+ setup do
66
+ @document = Class.new do
67
+ include MongoMapper::Document
68
+ set_collection_name 'test'
69
+ key :name, String, :required => true
70
+ end
71
+ @document.collection.remove
72
+
73
+ @doc = @document.create(:name => 'John Nunemaker')
74
+ end
75
+
76
+ should "not update document" do
77
+ @doc.name = nil
78
+ @doc.save
79
+ @doc.reload.name.should == 'John Nunemaker'
80
+ end
81
+
82
+ should "populate document's errors" do
83
+ @doc.name = nil
84
+ @doc.save
85
+ @doc.errors.full_messages.should == ["Name can't be empty"]
86
+ end
87
+ end
88
+
89
+ context "Adding validation errors" do
90
+ setup do
91
+ @document = Class.new do
92
+ include MongoMapper::Document
93
+ set_collection_name 'test'
94
+
95
+ key :action, String
96
+ def action_present
97
+ errors.add(:action, 'is invalid') if action.blank?
98
+ end
99
+ end
100
+ @document.collection.remove
101
+ end
102
+
103
+ should "work with validate_on_create callback" do
104
+ @document.validate_on_create :action_present
105
+
106
+ doc = @document.new
107
+ doc.action = nil
108
+ doc.should have_error_on(:action)
109
+
110
+ doc.action = 'kick'
111
+ doc.should_not have_error_on(:action)
112
+ doc.save
113
+
114
+ doc.action = nil
115
+ doc.should_not have_error_on(:action)
116
+ end
117
+
118
+ should "work with validate_on_update callback" do
119
+ @document.validate_on_update :action_present
120
+
121
+ doc = @document.new
122
+ doc.action = nil
123
+ doc.should_not have_error_on(:action)
124
+ doc.save
125
+
126
+ doc.action = nil
127
+ doc.should have_error_on(:action)
128
+
129
+ doc.action = 'kick'
130
+ doc.should_not have_error_on(:action)
131
+ end
132
+ end
133
+
134
+ context "validating uniqueness of" do
135
+ setup do
136
+ @document = Class.new do
137
+ include MongoMapper::Document
138
+ set_collection_name 'test'
139
+
140
+ key :name, String
141
+ validates_uniqueness_of :name
142
+ end
143
+ @document.collection.remove
144
+ end
145
+
146
+ should "not fail if object is new" do
147
+ doc = @document.new
148
+ doc.should_not have_error_on(:name)
149
+ end
150
+
151
+ should "not fail when new object is out of scope" do
152
+ document = Class.new do
153
+ include MongoMapper::Document
154
+ set_collection_name 'test'
155
+
156
+ key :name
157
+ key :adult
158
+ validates_uniqueness_of :name, :scope => :adult
159
+ end
160
+ doc = document.new("name" => "joe", :adult => true)
161
+ doc.save.should be_true
162
+
163
+ doc2 = document.new("name" => "joe", :adult => false)
164
+ doc2.should be_valid
165
+
166
+ end
167
+
168
+ should "allow to update an object" do
169
+ doc = @document.new("name" => "joe")
170
+ doc.save.should be_true
171
+
172
+ @document \
173
+ .stubs(:first) \
174
+ .with(:name => 'joe') \
175
+ .returns(doc)
176
+
177
+ doc.name = "joe"
178
+ doc.valid?.should be_true
179
+ doc.should_not have_error_on(:name)
180
+ end
181
+
182
+ should "fail if object name is not unique" do
183
+ doc = @document.new("name" => "joe")
184
+ doc.save.should be_true
185
+
186
+ @document \
187
+ .stubs(:first) \
188
+ .with(:name => 'joe') \
189
+ .returns(doc)
190
+
191
+ doc2 = @document.new("name" => "joe")
192
+ doc2.should have_error_on(:name)
193
+ end
194
+
195
+ should "allow multiple blank entries if :allow_blank => true" do
196
+ document = Class.new do
197
+ include MongoMapper::Document
198
+ set_collection_name 'test'
199
+
200
+ key :name
201
+ validates_uniqueness_of :name, :allow_blank => :true
202
+ end
203
+
204
+ doc = document.new("name" => "")
205
+ doc.save.should be_true
206
+
207
+ document \
208
+ .stubs(:first) \
209
+ .with(:name => '') \
210
+ .returns(doc)
211
+
212
+ doc2 = document.new("name" => "")
213
+ doc2.should_not have_error_on(:name)
214
+ end
215
+
216
+ should "allow entries that differ only in case by default" do
217
+ document = Class.new do
218
+ include MongoMapper::Document
219
+ set_collection_name 'test'
220
+
221
+ key :name
222
+ validates_uniqueness_of :name
223
+ end
224
+
225
+ doc = document.new("name" => "BLAMMO")
226
+ doc.save.should be_true
227
+
228
+ doc2 = document.new("name" => "blammo")
229
+ doc2.should_not have_error_on(:name)
230
+ end
231
+
232
+ context "with :case_sensitive => false" do
233
+ setup do
234
+ @document = Class.new do
235
+ include MongoMapper::Document
236
+ set_collection_name 'test'
237
+
238
+ key :name
239
+ validates_uniqueness_of :name, :case_sensitive => false
240
+ end
241
+ end
242
+
243
+ should "fail on entries that differ only in case" do
244
+ doc = @document.new("name" => "BLAMMO")
245
+ doc.save.should be_true
246
+
247
+ doc2 = @document.new("name" => "blammo")
248
+ doc2.should have_error_on(:name)
249
+ end
250
+
251
+ should "not raise an error if value is nil" do
252
+ doc = @document.new("name" => nil)
253
+ lambda { doc.valid? }.should_not raise_error
254
+ end
255
+ end
256
+
257
+ context "scoped by a single attribute" do
258
+ setup do
259
+ @document = Class.new do
260
+ include MongoMapper::Document
261
+ set_collection_name 'test'
262
+
263
+ key :name, String
264
+ key :scope, String
265
+ validates_uniqueness_of :name, :scope => :scope
266
+ end
267
+ @document.collection.remove
268
+ end
269
+
270
+ should "fail if the same name exists in the scope" do
271
+ doc = @document.new("name" => "joe", "scope" => "one")
272
+ doc.save.should be_true
273
+
274
+ @document \
275
+ .stubs(:first) \
276
+ .with(:name => 'joe', :scope => "one") \
277
+ .returns(doc)
278
+
279
+ doc2 = @document.new("name" => "joe", "scope" => "one")
280
+ doc2.should have_error_on(:name)
281
+ end
282
+
283
+ should "pass if the same name exists in a different scope" do
284
+ doc = @document.new("name" => "joe", "scope" => "one")
285
+ doc.save.should be_true
286
+
287
+ @document \
288
+ .stubs(:first) \
289
+ .with(:name => 'joe', :scope => 'two') \
290
+ .returns(nil)
291
+
292
+ doc2 = @document.new("name" => "joe", "scope" => "two")
293
+ doc2.should_not have_error_on(:name)
294
+ end
295
+ end
296
+
297
+ context "scoped by a multiple attributes" do
298
+ setup do
299
+ @document = Class.new do
300
+ include MongoMapper::Document
301
+ set_collection_name 'test'
302
+
303
+ key :name, String
304
+ key :first_scope, String
305
+ key :second_scope, String
306
+ validates_uniqueness_of :name, :scope => [:first_scope, :second_scope]
307
+ end
308
+ @document.collection.remove
309
+ end
310
+
311
+ should "fail if the same name exists in the scope" do
312
+ doc = @document.new("name" => "joe", "first_scope" => "one", "second_scope" => "two")
313
+ doc.save.should be_true
314
+
315
+ @document \
316
+ .stubs(:first) \
317
+ .with(:name => 'joe', :first_scope => 'one', :second_scope => 'two') \
318
+ .returns(doc)
319
+
320
+ doc2 = @document.new("name" => "joe", "first_scope" => "one", "second_scope" => "two")
321
+ doc2.should have_error_on(:name)
322
+ end
323
+
324
+ should "pass if the same name exists in a different scope" do
325
+ doc = @document.new("name" => "joe", "first_scope" => "one", "second_scope" => "two")
326
+ doc.save.should be_true
327
+
328
+ @document \
329
+ .stubs(:first) \
330
+ .with(:name => 'joe', :first_scope => 'one', :second_scope => 'one') \
331
+ .returns(nil)
332
+
333
+ doc2 = @document.new("name" => "joe", "first_scope" => "one", "second_scope" => "one")
334
+ doc2.should_not have_error_on(:name)
335
+ end
336
+ end
337
+ end
338
+
339
+ context "validates uniqueness of with :unique shortcut" do
340
+ should "work" do
341
+ @document = Class.new do
342
+ include MongoMapper::Document
343
+ set_collection_name 'test'
344
+
345
+ key :name, String, :unique => true
346
+ end
347
+ @document.collection.remove
348
+
349
+ doc = @document.create(:name => 'John')
350
+ doc.should_not have_error_on(:name)
351
+
352
+ @document \
353
+ .stubs(:first) \
354
+ .with(:name => 'John') \
355
+ .returns(doc)
356
+
357
+ second_john = @document.create(:name => 'John')
358
+ second_john.should have_error_on(:name, 'has already been taken')
359
+ end
360
+ end
361
+ end