mongo_mapper 0.5.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.
Files changed (69) hide show
  1. data/.gitignore +7 -0
  2. data/LICENSE +20 -0
  3. data/README.rdoc +39 -0
  4. data/Rakefile +87 -0
  5. data/VERSION +1 -0
  6. data/bin/mmconsole +55 -0
  7. data/lib/mongo_mapper.rb +92 -0
  8. data/lib/mongo_mapper/associations.rb +86 -0
  9. data/lib/mongo_mapper/associations/base.rb +83 -0
  10. data/lib/mongo_mapper/associations/belongs_to_polymorphic_proxy.rb +34 -0
  11. data/lib/mongo_mapper/associations/belongs_to_proxy.rb +22 -0
  12. data/lib/mongo_mapper/associations/many_documents_as_proxy.rb +27 -0
  13. data/lib/mongo_mapper/associations/many_documents_proxy.rb +116 -0
  14. data/lib/mongo_mapper/associations/many_embedded_polymorphic_proxy.rb +33 -0
  15. data/lib/mongo_mapper/associations/many_embedded_proxy.rb +67 -0
  16. data/lib/mongo_mapper/associations/many_polymorphic_proxy.rb +11 -0
  17. data/lib/mongo_mapper/associations/many_proxy.rb +6 -0
  18. data/lib/mongo_mapper/associations/proxy.rb +64 -0
  19. data/lib/mongo_mapper/callbacks.rb +106 -0
  20. data/lib/mongo_mapper/document.rb +317 -0
  21. data/lib/mongo_mapper/dynamic_finder.rb +35 -0
  22. data/lib/mongo_mapper/embedded_document.rb +354 -0
  23. data/lib/mongo_mapper/finder_options.rb +94 -0
  24. data/lib/mongo_mapper/key.rb +32 -0
  25. data/lib/mongo_mapper/observing.rb +50 -0
  26. data/lib/mongo_mapper/pagination.rb +51 -0
  27. data/lib/mongo_mapper/rails_compatibility/document.rb +15 -0
  28. data/lib/mongo_mapper/rails_compatibility/embedded_document.rb +27 -0
  29. data/lib/mongo_mapper/save_with_validation.rb +19 -0
  30. data/lib/mongo_mapper/serialization.rb +55 -0
  31. data/lib/mongo_mapper/serializers/json_serializer.rb +92 -0
  32. data/lib/mongo_mapper/support.rb +157 -0
  33. data/lib/mongo_mapper/validations.rb +69 -0
  34. data/mongo_mapper.gemspec +156 -0
  35. data/test/NOTE_ON_TESTING +1 -0
  36. data/test/custom_matchers.rb +48 -0
  37. data/test/functional/associations/test_belongs_to_polymorphic_proxy.rb +54 -0
  38. data/test/functional/associations/test_belongs_to_proxy.rb +46 -0
  39. data/test/functional/associations/test_many_documents_as_proxy.rb +244 -0
  40. data/test/functional/associations/test_many_embedded_polymorphic_proxy.rb +132 -0
  41. data/test/functional/associations/test_many_embedded_proxy.rb +174 -0
  42. data/test/functional/associations/test_many_polymorphic_proxy.rb +297 -0
  43. data/test/functional/associations/test_many_proxy.rb +331 -0
  44. data/test/functional/test_associations.rb +48 -0
  45. data/test/functional/test_binary.rb +18 -0
  46. data/test/functional/test_callbacks.rb +85 -0
  47. data/test/functional/test_document.rb +951 -0
  48. data/test/functional/test_embedded_document.rb +97 -0
  49. data/test/functional/test_pagination.rb +87 -0
  50. data/test/functional/test_rails_compatibility.rb +30 -0
  51. data/test/functional/test_validations.rb +279 -0
  52. data/test/models.rb +169 -0
  53. data/test/test_helper.rb +29 -0
  54. data/test/unit/serializers/test_json_serializer.rb +189 -0
  55. data/test/unit/test_association_base.rb +144 -0
  56. data/test/unit/test_document.rb +165 -0
  57. data/test/unit/test_dynamic_finder.rb +125 -0
  58. data/test/unit/test_embedded_document.rb +645 -0
  59. data/test/unit/test_finder_options.rb +193 -0
  60. data/test/unit/test_key.rb +163 -0
  61. data/test/unit/test_mongomapper.rb +28 -0
  62. data/test/unit/test_observing.rb +101 -0
  63. data/test/unit/test_pagination.rb +109 -0
  64. data/test/unit/test_rails_compatibility.rb +39 -0
  65. data/test/unit/test_serializations.rb +52 -0
  66. data/test/unit/test_support.rb +272 -0
  67. data/test/unit/test_time_zones.rb +40 -0
  68. data/test/unit/test_validations.rb +503 -0
  69. metadata +204 -0
@@ -0,0 +1,40 @@
1
+ require 'test_helper'
2
+
3
+ class TimeZonesTest < Test::Unit::TestCase
4
+ context "An instance of an embedded document" do
5
+ setup do
6
+ @document = Class.new do
7
+ include MongoMapper::EmbeddedDocument
8
+ key :name, String
9
+ key :created_at, Time
10
+ end
11
+ end
12
+
13
+ should "work without Time.zone" do
14
+ Time.zone = nil
15
+
16
+ doc = @document.new(:created_at => "2009-08-15 14:00:00")
17
+ doc.created_at.should == Time.local(2009, 8, 15, 14, 0, 0).utc
18
+ end
19
+
20
+ should "work with Time.zone set to the (default) UTC" do
21
+ Time.zone = 'UTC'
22
+
23
+ doc = @document.new(:created_at => "2009-08-15 14:00:00")
24
+ doc.created_at.is_a?(ActiveSupport::TimeWithZone).should be_true
25
+ doc.created_at.should == Time.utc(2009, 8, 15, 14)
26
+
27
+ Time.zone = nil
28
+ end
29
+
30
+ should_eventually "work with timezones that are not UTC" do
31
+ Time.zone = 'Hawaii'
32
+
33
+ doc = @document.new(:created_at => @original_time)
34
+ doc.created_at.is_a?(ActiveSupport::TimeWithZone).should be_true
35
+ doc.created_at.should == Time.utc(2009, 8, 16)
36
+
37
+ Time.zone = nil
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,503 @@
1
+ require 'test_helper'
2
+
3
+ class ValidationsTest < Test::Unit::TestCase
4
+ context "Validations" do
5
+
6
+ context "on a Document" do
7
+
8
+ setup do
9
+ @document = Class.new do
10
+ include MongoMapper::Document
11
+ set_collection_name 'test'
12
+ end
13
+ end
14
+
15
+ context "Validating acceptance of" do
16
+ should "work with validates_acceptance_of macro" do
17
+ @document.key :terms, String
18
+ @document.validates_acceptance_of :terms
19
+ doc = @document.new(:terms => '')
20
+ doc.should have_error_on(:terms)
21
+ doc.terms = '1'
22
+ doc.should_not have_error_on(:terms)
23
+ end
24
+ end
25
+
26
+ context "validating confirmation of" do
27
+ should "work with validates_confirmation_of macro" do
28
+ @document.key :password, String
29
+ @document.validates_confirmation_of :password
30
+ doc = @document.new
31
+ doc.password = 'foobar'
32
+ doc.should have_error_on(:password)
33
+ doc.password_confirmation = 'foobar'
34
+ doc.should_not have_error_on(:password)
35
+ end
36
+ end
37
+
38
+ context "validating format of" do
39
+ should "work with validates_format_of macro" do
40
+ @document.key :name, String
41
+ @document.validates_format_of :name, :with => /.+/
42
+ doc = @document.new
43
+ doc.should have_error_on(:name)
44
+ doc.name = 'John'
45
+ doc.should_not have_error_on(:name)
46
+ end
47
+
48
+ should "work with :format shorcut key" do
49
+ @document.key :name, String, :format => /.+/
50
+ doc = @document.new
51
+ doc.should have_error_on(:name)
52
+ doc.name = 'John'
53
+ doc.should_not have_error_on(:name)
54
+ end
55
+ end
56
+
57
+ context "validating length of" do
58
+ should "work with validates_length_of macro" do
59
+ @document.key :name, String
60
+ @document.validates_length_of :name, :minimum => 5
61
+ doc = @document.new
62
+ doc.should have_error_on(:name)
63
+ end
64
+
65
+ context "with :length => integer shortcut" do
66
+ should "set maximum of integer provided" do
67
+ @document.key :name, String, :length => 5
68
+ doc = @document.new
69
+ doc.name = '123456'
70
+ doc.should have_error_on(:name)
71
+ doc.name = '12345'
72
+ doc.should_not have_error_on(:name)
73
+ end
74
+ end
75
+
76
+ context "with :length => range shortcut" do
77
+ setup do
78
+ @document.key :name, String, :length => 5..7
79
+ end
80
+
81
+ should "set minimum of range min" do
82
+ doc = @document.new
83
+ doc.should have_error_on(:name)
84
+ doc.name = '123456'
85
+ doc.should_not have_error_on(:name)
86
+ end
87
+
88
+ should "set maximum of range max" do
89
+ doc = @document.new
90
+ doc.should have_error_on(:name)
91
+ doc.name = '12345678'
92
+ doc.should have_error_on(:name)
93
+ doc.name = '123456'
94
+ doc.should_not have_error_on(:name)
95
+ end
96
+ end
97
+
98
+ context "with :length => hash shortcut" do
99
+ should "pass options through" do
100
+ @document.key :name, String, :length => {:minimum => 2}
101
+ doc = @document.new
102
+ doc.should have_error_on(:name)
103
+ doc.name = '12'
104
+ doc.should_not have_error_on(:name)
105
+ end
106
+ end
107
+ end # validates_length_of
108
+
109
+ context "Validating numericality of" do
110
+ should "work with validates_numericality_of macro" do
111
+ @document.key :age, Integer
112
+ @document.validates_numericality_of :age
113
+ doc = @document.new
114
+ doc.age = 'String'
115
+ doc.should have_error_on(:age)
116
+ doc.age = 23
117
+ doc.should_not have_error_on(:age)
118
+ end
119
+
120
+ context "with :numeric shortcut" do
121
+ should "work with integer or float" do
122
+ @document.key :weight, Float, :numeric => true
123
+ doc = @document.new
124
+ doc.weight = 'String'
125
+ doc.should have_error_on(:weight)
126
+ doc.weight = 23.0
127
+ doc.should_not have_error_on(:weight)
128
+ doc.weight = 23
129
+ doc.should_not have_error_on(:weight)
130
+ end
131
+ end
132
+
133
+ context "with :numeric shortcut on Integer key" do
134
+ should "only work with integers" do
135
+ @document.key :age, Integer, :numeric => true
136
+ doc = @document.new
137
+ doc.age = 'String'
138
+ doc.should have_error_on(:age)
139
+ doc.age = 23.1
140
+ doc.should have_error_on(:age)
141
+ doc.age = 23
142
+ doc.should_not have_error_on(:age)
143
+ end
144
+ end
145
+ end # numericality of
146
+
147
+ context "validating presence of" do
148
+ should "work with validates_presence_of macro" do
149
+ @document.key :name, String
150
+ @document.validates_presence_of :name
151
+ doc = @document.new
152
+ doc.should have_error_on(:name)
153
+ end
154
+
155
+ should "work with :required shortcut on key definition" do
156
+ @document.key :name, String, :required => true
157
+ doc = @document.new
158
+ doc.should have_error_on(:name)
159
+ end
160
+ end
161
+
162
+ context "validating exclusion of" do
163
+ should "throw error if enumerator not provided" do
164
+ @document.key :action, String
165
+ lambda {
166
+ @document.validates_exclusion_of :action
167
+ }.should raise_error(ArgumentError)
168
+ end
169
+
170
+ should "work with validates_exclusion_of macro" do
171
+ @document.key :action, String
172
+ @document.validates_exclusion_of :action, :within => %w(kick run)
173
+
174
+ doc = @document.new
175
+ doc.should_not have_error_on(:action)
176
+
177
+ doc.action = 'fart'
178
+ doc.should_not have_error_on(:action)
179
+
180
+ doc.action = 'kick'
181
+ doc.should have_error_on(:action, 'is reserved')
182
+ end
183
+
184
+ should "not have error if allow nil is true and value is nil" do
185
+ @document.key :action, String
186
+ @document.validates_exclusion_of :action, :within => %w(kick run), :allow_nil => true
187
+
188
+ doc = @document.new
189
+ doc.should_not have_error_on(:action)
190
+ end
191
+
192
+ should "not have error if allow blank is true and value is blank" do
193
+ @document.key :action, String
194
+ @document.validates_exclusion_of :action, :within => %w(kick run), :allow_nil => true
195
+
196
+ doc = @document.new(:action => '')
197
+ doc.should_not have_error_on(:action)
198
+ end
199
+ end
200
+
201
+ context "validating inclusion of" do
202
+ should "throw error if enumerator not provided" do
203
+ @document.key :action, String
204
+ lambda {
205
+ @document.validates_inclusion_of :action
206
+ }.should raise_error(ArgumentError)
207
+ end
208
+
209
+ should "work with validates_inclusion_of macro" do
210
+ @document.key :action, String
211
+ @document.validates_inclusion_of :action, :within => %w(kick run)
212
+
213
+ doc = @document.new
214
+ doc.should have_error_on(:action, 'is not in the list')
215
+
216
+ doc.action = 'fart'
217
+ doc.should have_error_on(:action, 'is not in the list')
218
+
219
+ doc.action = 'kick'
220
+ doc.should_not have_error_on(:action)
221
+ end
222
+
223
+ should "not have error if allow nil is true and value is nil" do
224
+ @document.key :action, String
225
+ @document.validates_inclusion_of :action, :within => %w(kick run), :allow_nil => true
226
+
227
+ doc = @document.new
228
+ doc.should_not have_error_on(:action)
229
+ end
230
+
231
+ should "not have error if allow blank is true and value is blank" do
232
+ @document.key :action, String
233
+ @document.validates_inclusion_of :action, :within => %w(kick run), :allow_blank => true
234
+
235
+ doc = @document.new(:action => '')
236
+ doc.should_not have_error_on(:action)
237
+ end
238
+ end
239
+
240
+ end # End on a Document
241
+
242
+ context "On an EmbeddedDocument" do
243
+
244
+ setup do
245
+ @embedded_doc = Class.new do
246
+ include MongoMapper::EmbeddedDocument
247
+ end
248
+ end
249
+
250
+ context "Validating acceptance of" do
251
+ should "work with validates_acceptance_of macro" do
252
+ @embedded_doc.key :terms, String
253
+ @embedded_doc.validates_acceptance_of :terms
254
+ doc = @embedded_doc.new(:terms => '')
255
+ doc.should have_error_on(:terms)
256
+ doc.terms = '1'
257
+ doc.should_not have_error_on(:terms)
258
+ end
259
+ end
260
+
261
+ context "validating confirmation of" do
262
+ should "work with validates_confirmation_of macro" do
263
+ @embedded_doc.key :password, String
264
+ @embedded_doc.validates_confirmation_of :password
265
+ doc = @embedded_doc.new
266
+ doc.password = 'foobar'
267
+ doc.should have_error_on(:password)
268
+ doc.password_confirmation = 'foobar'
269
+ doc.should_not have_error_on(:password)
270
+ end
271
+ end
272
+
273
+ context "validating format of" do
274
+ should "work with validates_format_of macro" do
275
+ @embedded_doc.key :name, String
276
+ @embedded_doc.validates_format_of :name, :with => /.+/
277
+ doc = @embedded_doc.new
278
+ doc.should have_error_on(:name)
279
+ doc.name = 'John'
280
+ doc.should_not have_error_on(:name)
281
+ end
282
+
283
+ should "work with :format shorcut key" do
284
+ @embedded_doc.key :name, String, :format => /.+/
285
+ doc = @embedded_doc.new
286
+ doc.should have_error_on(:name)
287
+ doc.name = 'John'
288
+ doc.should_not have_error_on(:name)
289
+ end
290
+ end
291
+
292
+ context "validating length of" do
293
+ should "work with validates_length_of macro" do
294
+ @embedded_doc.key :name, String
295
+ @embedded_doc.validates_length_of :name, :minimum => 5
296
+ doc = @embedded_doc.new
297
+ doc.should have_error_on(:name)
298
+ end
299
+
300
+ context "with :length => integer shortcut" do
301
+ should "set maximum of integer provided" do
302
+ @embedded_doc.key :name, String, :length => 5
303
+ doc = @embedded_doc.new
304
+ doc.name = '123456'
305
+ doc.should have_error_on(:name)
306
+ doc.name = '12345'
307
+ doc.should_not have_error_on(:name)
308
+ end
309
+ end
310
+
311
+ context "with :length => range shortcut" do
312
+ setup do
313
+ @embedded_doc.key :name, String, :length => 5..7
314
+ end
315
+
316
+ should "set minimum of range min" do
317
+ doc = @embedded_doc.new
318
+ doc.should have_error_on(:name)
319
+ doc.name = '123456'
320
+ doc.should_not have_error_on(:name)
321
+ end
322
+
323
+ should "set maximum of range max" do
324
+ doc = @embedded_doc.new
325
+ doc.should have_error_on(:name)
326
+ doc.name = '12345678'
327
+ doc.should have_error_on(:name)
328
+ doc.name = '123456'
329
+ doc.should_not have_error_on(:name)
330
+ end
331
+ end
332
+
333
+ context "with :length => hash shortcut" do
334
+ should "pass options through" do
335
+ @embedded_doc.key :name, String, :length => {:minimum => 2}
336
+ doc = @embedded_doc.new
337
+ doc.should have_error_on(:name)
338
+ doc.name = '12'
339
+ doc.should_not have_error_on(:name)
340
+ end
341
+ end
342
+ end # validates_length_of
343
+
344
+ context "Validating numericality of" do
345
+ should "work with validates_numericality_of macro" do
346
+ @embedded_doc.key :age, Integer
347
+ @embedded_doc.validates_numericality_of :age
348
+ doc = @embedded_doc.new
349
+ doc.age = 'String'
350
+ doc.should have_error_on(:age)
351
+ doc.age = 23
352
+ doc.should_not have_error_on(:age)
353
+ end
354
+
355
+ context "with :numeric shortcut" do
356
+ should "work with integer or float" do
357
+ @embedded_doc.key :weight, Float, :numeric => true
358
+ doc = @embedded_doc.new
359
+ doc.weight = 'String'
360
+ doc.should have_error_on(:weight)
361
+ doc.weight = 23.0
362
+ doc.should_not have_error_on(:weight)
363
+ doc.weight = 23
364
+ doc.should_not have_error_on(:weight)
365
+ end
366
+ end
367
+
368
+ context "with :numeric shortcut on Integer key" do
369
+ should "only work with integers" do
370
+ @embedded_doc.key :age, Integer, :numeric => true
371
+ doc = @embedded_doc.new
372
+ doc.age = 'String'
373
+ doc.should have_error_on(:age)
374
+ doc.age = 23.1
375
+ doc.should have_error_on(:age)
376
+ doc.age = 23
377
+ doc.should_not have_error_on(:age)
378
+ end
379
+ end
380
+ end # numericality of
381
+
382
+ context "validating presence of" do
383
+ should "work with validates_presence_of macro" do
384
+ @embedded_doc.key :name, String
385
+ @embedded_doc.validates_presence_of :name
386
+ doc = @embedded_doc.new
387
+ doc.should have_error_on(:name)
388
+ end
389
+
390
+ should "work with :required shortcut on key definition" do
391
+ @embedded_doc.key :name, String, :required => true
392
+ doc = @embedded_doc.new
393
+ doc.should have_error_on(:name)
394
+ end
395
+ end
396
+
397
+ context "validating exclusion of" do
398
+ should "throw error if enumerator not provided" do
399
+ @embedded_doc.key :action, String
400
+ lambda {
401
+ @embedded_doc.validates_exclusion_of :action
402
+ }.should raise_error(ArgumentError)
403
+ end
404
+
405
+ should "work with validates_exclusion_of macro" do
406
+ @embedded_doc.key :action, String
407
+ @embedded_doc.validates_exclusion_of :action, :within => %w(kick run)
408
+
409
+ doc = @embedded_doc.new
410
+ doc.should_not have_error_on(:action)
411
+
412
+ doc.action = 'fart'
413
+ doc.should_not have_error_on(:action)
414
+
415
+ doc.action = 'kick'
416
+ doc.should have_error_on(:action, 'is reserved')
417
+ end
418
+
419
+ should "not have error if allow nil is true and value is nil" do
420
+ @embedded_doc.key :action, String
421
+ @embedded_doc.validates_exclusion_of :action, :within => %w(kick run), :allow_nil => true
422
+
423
+ doc = @embedded_doc.new
424
+ doc.should_not have_error_on(:action)
425
+ end
426
+
427
+ should "not have error if allow blank is true and value is blank" do
428
+ @embedded_doc.key :action, String
429
+ @embedded_doc.validates_exclusion_of :action, :within => %w(kick run), :allow_nil => true
430
+
431
+ doc = @embedded_doc.new(:action => '')
432
+ doc.should_not have_error_on(:action)
433
+ end
434
+ end
435
+
436
+ context "validating inclusion of" do
437
+ should "throw error if enumerator not provided" do
438
+ @embedded_doc.key :action, String
439
+ lambda {
440
+ @embedded_doc.validates_inclusion_of :action
441
+ }.should raise_error(ArgumentError)
442
+ end
443
+
444
+ should "work with validates_inclusion_of macro" do
445
+ @embedded_doc.key :action, String
446
+ @embedded_doc.validates_inclusion_of :action, :within => %w(kick run)
447
+
448
+ doc = @embedded_doc.new
449
+ doc.should have_error_on(:action, 'is not in the list')
450
+
451
+ doc.action = 'fart'
452
+ doc.should have_error_on(:action, 'is not in the list')
453
+
454
+ doc.action = 'kick'
455
+ doc.should_not have_error_on(:action)
456
+ end
457
+
458
+ should "not have error if allow nil is true and value is nil" do
459
+ @embedded_doc.key :action, String
460
+ @embedded_doc.validates_inclusion_of :action, :within => %w(kick run), :allow_nil => true
461
+
462
+ doc = @embedded_doc.new
463
+ doc.should_not have_error_on(:action)
464
+ end
465
+
466
+ should "not have error if allow blank is true and value is blank" do
467
+ @embedded_doc.key :action, String
468
+ @embedded_doc.validates_inclusion_of :action, :within => %w(kick run), :allow_blank => true
469
+
470
+ doc = @embedded_doc.new(:action => '')
471
+ doc.should_not have_error_on(:action)
472
+ end
473
+ end
474
+
475
+ end # End on an EmbeddedDocument
476
+
477
+ end # Validations
478
+
479
+ context "Adding validation errors" do
480
+ setup do
481
+ @document = Class.new do
482
+ include MongoMapper::Document
483
+ set_collection_name 'test'
484
+
485
+ key :action, String
486
+ def action_present
487
+ errors.add(:action, 'is invalid') if action.blank?
488
+ end
489
+ end
490
+ end
491
+
492
+ should "work with validate callback" do
493
+ @document.validate :action_present
494
+
495
+ doc = @document.new
496
+ doc.action = nil
497
+ doc.should have_error_on(:action)
498
+
499
+ doc.action = 'kick'
500
+ doc.should_not have_error_on(:action)
501
+ end
502
+ end
503
+ end