mongomatic 0.6.2 → 0.6.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.
@@ -1,656 +0,0 @@
1
- require 'helper'
2
-
3
- class TestMongomatic < Test::Unit::TestCase
4
- should "treat all keys as strings" do
5
- Person.collection.drop
6
- p1 = Person.new(:name => "Jordan")
7
- p1[:address] = { :city => "San Francisco" }
8
- assert_equal "Jordan", p1["name"]
9
- assert_equal "Jordan", p1[:name]
10
- assert_equal "San Francisco", p1["address"]["city"]
11
- assert_equal "San Francisco", p1[:address][:city]
12
- p1.insert
13
-
14
- p1 = Person.find_one(:name => "Jordan")
15
- assert_equal "Jordan", p1["name"]
16
- assert_equal "Jordan", p1[:name]
17
- assert_equal "San Francisco", p1["address"]["city"]
18
- assert_equal "San Francisco", p1[:address][:city]
19
- end
20
-
21
- should "find one with a query" do
22
- Person.collection.drop
23
- p1 = Person.new(:name => "Jordan")
24
- p1.insert
25
-
26
- assert_equal p1, Person.find_one(:name => "Jordan")
27
- end
28
-
29
- should "find one with an instance of BSON::ObjectId" do
30
- Person.collection.drop
31
- p1 = Person.new(:name => "Jordan")
32
- p1.insert
33
-
34
- assert_equal p1, Person.find_one(p1['_id'])
35
- end
36
-
37
- should "accurately return whether the cursor is or is not empty" do
38
- Person.collection.drop
39
- assert Person.empty?
40
- assert Person.find.empty?
41
- p1 = Person.new(:name => "Jordan")
42
- p1.insert
43
- assert !Person.empty?
44
- assert !Person.find.empty?
45
- assert !Person.find({"name" => "Jordan"}).empty?
46
- assert Person.find({"name" => "Ben"}).empty?
47
- p1.remove!
48
- assert Person.empty?
49
- assert Person.find.empty?
50
- assert Person.find({"name" => "Jordan"}).empty?
51
- end
52
-
53
- should "find one with ObjectId or hash only" do
54
- Person.collection.drop
55
- Person.create_indexes
56
-
57
- p = Person.new(:name => "Ben1", :birth_year => 1984, :created_at => Time.now.utc, :admin => true)
58
- assert p.insert!.is_a?(BSON::ObjectId)
59
- assert_equal 1, Person.count
60
-
61
- found = Person.find({"_id" => BSON::ObjectId(p["_id"].to_s)}).next
62
- assert_equal found, p
63
-
64
- assert_raise(TypeError) { Person.find_one(p["_id"].to_s) }
65
-
66
- found = Person.find_one({"_id" => p["_id"].to_s})
67
- assert_equal found, nil
68
-
69
- found = Person.find_one({"_id" => BSON::ObjectId(p["_id"].to_s)})
70
- assert_equal found, p
71
- end
72
-
73
- should "return an instance of class when finding one" do
74
- Person.collection.drop
75
- p1 = Person.new(:name => "Jordan")
76
- p1.insert
77
-
78
- assert_equal Person, Person.find_one(:name => "Jordan").class
79
- end
80
- should "work with enumerable methods" do
81
- Person.collection.drop
82
- p1 = Person.new(:name => "Ben1", :birth_year => 1984, :created_at => Time.now.utc, :admin => true)
83
- p2 = Person.new(:name => "Ben2", :birth_year => 1986, :created_at => Time.now.utc, :admin => true)
84
- assert p1.insert.is_a?(BSON::ObjectId)
85
- assert p2.insert.is_a?(BSON::ObjectId)
86
- assert_equal 2, Person.collection.count
87
- assert_equal 2, Person.find.inject(0) { |sum, p| assert p.is_a?(Person); sum += 1 }
88
- assert_equal p2, Person.find.max { |p1,p2| p1["birth_year"] <=> p2["birth_year"] }
89
- end
90
-
91
- should "be able to insert, update, remove documents" do
92
- Person.collection.drop
93
-
94
- p = Person.new
95
-
96
- assert !p.valid?
97
- assert_equal(["name can't be empty"], p.errors.full_messages)
98
-
99
- p["name"] = "Ben Myles"
100
- p["birth_year"] = 1984
101
- p["created_at"] = Time.now.utc
102
- p["admin"] = true
103
-
104
- assert !p.update
105
-
106
- assert p.insert.is_a?(BSON::ObjectId)
107
-
108
- assert_equal 1, Person.collection.count
109
-
110
- cursor = Person.find({"_id" => p["_id"]})
111
- found = cursor.next
112
- assert_equal p, found
113
- assert_equal "Ben Myles", found["name"]
114
-
115
- p["name"] = "Benjamin"
116
- assert p.update
117
-
118
- cursor = Person.find({"_id" => p["_id"]})
119
- found = cursor.next
120
- assert_equal p, found
121
- assert_equal "Benjamin", found["name"]
122
-
123
- assert p.remove
124
- assert p.removed?
125
- cursor = Person.find({"_id" => p["_id"]})
126
- found = cursor.next
127
- assert_nil found
128
- end
129
-
130
- should "be able to limit and sort" do
131
- Person.collection.drop
132
- p = Person.new(:name => "Ben", :birth_year => 1984, :created_at => Time.now.utc, :admin => true)
133
- assert p.insert.is_a?(BSON::ObjectId)
134
- assert_equal 1, Person.collection.count
135
- p2 = Person.new(:name => "Ben2", :birth_year => 1984, :created_at => Time.now.utc, :admin => true)
136
- assert p2.insert.is_a?(BSON::ObjectId)
137
- assert_equal 2, Person.collection.count
138
-
139
- cursor = Person.find({"_id" => p["_id"]})
140
- found = cursor.next
141
- assert_equal p, found
142
-
143
- cursor = Person.find()
144
- assert_equal 0, cursor.current_limit
145
- assert_equal 2, cursor.to_a.size
146
- cursor = Person.find().limit(1)
147
- assert_equal 1, cursor.current_limit
148
- assert_equal 1, cursor.to_a.size
149
- cursor = Person.find().limit(1)
150
- assert_equal p, cursor.next
151
- assert_equal nil, cursor.next
152
- cursor = Person.find().limit(1).skip(1)
153
- assert_equal p2, cursor.next
154
-
155
- cursor = Person.find().sort("name", Mongo::ASCENDING)
156
- assert_equal p, cursor.next
157
-
158
- cursor = Person.find().sort("name", Mongo::DESCENDING)
159
- assert_equal p2, cursor.next
160
- end
161
-
162
- should "cursor implements enumerable" do
163
- Person.collection.drop
164
- 1000.upto(2000) do |i|
165
- p = Person.new(:name => "Ben#{i}", :birth_year => 1984, :created_at => Time.now.utc, :admin => true)
166
- assert p.insert.is_a?(BSON::ObjectId)
167
- end
168
- i = 1000
169
- Person.find().sort(["name", :asc]).each { |p| assert_equal "Ben#{i}", p["name"]; i += 1 }
170
- Person.find().sort(["name", :asc]).each_with_index { |p,i| assert_equal "Ben#{1000+i}", p["name"] }
171
-
172
- p = Person.find().limit(1).next
173
- assert Person.find().sort(["name", :asc]).include?(p)
174
-
175
- assert_equal 10, Person.find().limit(10).to_a.size
176
- end
177
-
178
- should "be able to merge hashes" do
179
- Person.collection.drop
180
- p = Person.new(:name => "Ben", :birth_year => 1984, :created_at => Time.now.utc, :admin => true)
181
- assert p.insert.is_a?(BSON::ObjectId)
182
- assert_equal 1, Person.collection.count
183
- p.merge(:birth_year => 1986)
184
- p.update
185
- p = Person.find({"_id" => p["_id"]}).next
186
- assert_equal 1986, p["birth_year"]
187
- end
188
-
189
- should "have callbacks" do
190
- p = Person.new(:name => "Ben1", :birth_year => 1984, :created_at => Time.now.utc, :admin => true)
191
- p.callback_tests = []
192
- assert p.callback_tests.empty?
193
- assert p.valid?
194
- assert_equal [:before_validate, :after_validate], p.callback_tests
195
- p.callback_tests = []
196
- assert p.insert.is_a?(BSON::ObjectId)
197
- assert_equal [:before_validate, :after_validate, :before_insert, :before_insert_or_update, :after_insert, :after_insert_or_update], p.callback_tests
198
- p.callback_tests = []
199
- p.update
200
- assert_equal [:before_validate, :after_validate, :before_update, :before_insert_or_update, :after_update, :after_insert_or_update], p.callback_tests
201
- p.callback_tests = []
202
- p.remove
203
- assert_equal [:before_remove, :after_remove], p.callback_tests
204
- Person.class_callbacks = []
205
- Person.drop
206
- assert_equal [:before_drop, :after_drop], Person.class_callbacks
207
- end
208
-
209
- should "raise an error on unique index dup insert" do
210
- Person.collection.drop
211
- Person.create_indexes
212
-
213
- p = Person.new(:name => "Ben1", :birth_year => 1984, :created_at => Time.now.utc, :admin => true)
214
- assert p.insert!.is_a?(BSON::ObjectId)
215
- assert_equal 1, Person.count
216
-
217
- p = Person.new(:name => "Ben1", :birth_year => 1984, :created_at => Time.now.utc, :admin => true)
218
- assert_raise(Mongo::OperationFailure) { p.insert! }
219
-
220
- assert_equal 1, Person.count
221
- end
222
-
223
- should "have the is_new flag set appropriately" do
224
- Person.collection.drop
225
- p = Person.new
226
- assert p.is_new?
227
- assert !p.insert
228
- assert p.is_new?
229
- p["name"] = "Ben"
230
- assert p.insert
231
- assert !p.is_new?
232
- p = Person.find_one(p["_id"])
233
- assert !p.is_new?
234
- end
235
-
236
- should "be able to set a custom id" do
237
- Person.collection.drop
238
- p = Person.new(:name => "Ben")
239
- assert p.is_new?
240
- p["_id"] = "mycustomid"
241
- assert p.insert
242
- found = Person.find_one({"_id" => "mycustomid"})
243
- assert_equal found, p
244
- assert !p.is_new?
245
- found["age"] = 26
246
- assert found.update
247
- found = Person.find_one({"_id" => "mycustomid"})
248
- assert_equal found["_id"], "mycustomid"
249
- assert_equal 26, found["age"]
250
- end
251
-
252
- should "be able to use array style error adding" do
253
- class Foobar < Mongomatic::Base
254
- def validate
255
- errors << ["color", "must not be blank"] if self["color"].blank?
256
- errors << "missing style" if self["style"].blank?
257
- end
258
- end
259
-
260
- f = Foobar.new
261
- assert !f.valid?
262
- assert_equal ["color must not be blank", "missing style"], f.errors.full_messages
263
- f["color"] = "pink"; f.valid?
264
- assert_equal ["missing style"], f.errors.full_messages
265
- f["style"] = "awesome"; f.valid?
266
- assert_equal [], f.errors.full_messages
267
- end
268
-
269
- should "be able to use the be_expect expectation" do
270
- p = Person.new
271
- class << p
272
- def validate
273
- expectations do
274
- be_expected self['alive'], "Alive must be true"
275
- not_be_expected self['dead'], "Dead must be false"
276
- end
277
- end
278
- end
279
-
280
- assert !p.valid?
281
- assert_equal ['Alive must be true'], p.errors.full_messages
282
-
283
- p['alive'] = true
284
- assert p.valid?
285
-
286
- p['dead'] = true
287
- assert !p.valid?
288
- assert_equal ['Dead must be false'], p.errors.full_messages
289
- end
290
-
291
- should "be able to use be_expected with a block" do
292
- p = Person.new
293
- class << p
294
- def validate
295
- expectations do
296
- be_expected lambda { self['name'].is_a? String }, "Name must be a string"
297
- not_be_expected lambda { self['alive'] && self['dead'] }, "Cannot be alive and dead"
298
- end
299
- end
300
- end
301
-
302
- p['name'] = 1
303
- assert !p.valid?
304
- assert_equal p.errors.full_messages, ["Name must be a string"]
305
-
306
- p['alive'] = true
307
- p['dead'] = true
308
- p['name'] = "Jordan"
309
-
310
- assert !p.valid?
311
- assert_equal p.errors.full_messages, ["Cannot be alive and dead"]
312
-
313
- p['dead'] = false
314
- assert p.valid?
315
- end
316
-
317
- should "be able to use be_expected with a method call" do
318
- p = Person.new
319
- class << p
320
- def validate
321
- expectations do
322
- be_expected :method_1, "Method 1 must return true"
323
- not_be_expected :method_2, "Method 2 must return false"
324
- end
325
- end
326
-
327
- def method_1
328
- (self['name'] == 'Jordan') ? true : false
329
- end
330
-
331
- def method_2
332
- (self['age'] == 21) ? false : true
333
- end
334
- end
335
-
336
- assert !p.valid?
337
- assert_equal ["Method 1 must return true", "Method 2 must return false"], p.errors.full_messages
338
-
339
- p['name'] = 'Jordan'
340
- p['age'] = 21
341
-
342
- assert p.valid?
343
- end
344
-
345
- should "be able to use the be_present expectation" do
346
- p = Person.new
347
- class << p
348
- def validate
349
- expectations do
350
- be_present self['name'], 'name cannot be blank'
351
- not_be_present self['age'], 'age must be blank'
352
- end
353
- end
354
- end
355
-
356
- assert !p.valid?
357
- assert_equal ['name cannot be blank'], p.errors.full_messages
358
-
359
- p['name'] = "Jordan"
360
- p['age'] = 21
361
-
362
-
363
- assert !p.valid?
364
- assert_equal ['age must be blank'], p.errors.full_messages
365
-
366
- p['age'] = nil
367
-
368
- assert p.valid?
369
-
370
- end
371
-
372
- should "be able to use be_a_number expectation" do
373
- p = Person.new
374
- class << p
375
- def validate
376
- expectations do
377
- be_a_number self['age'], 'Age is not a number'
378
- not_be_a_number self['name'], 'Name cannot be a number'
379
- be_a_number self['birth_year'], 'Birth year is not a number', :allow_nil => true
380
- end
381
- end
382
- end
383
-
384
- assert !p.valid?
385
- assert_equal ["Age is not a number"], p.errors.full_messages
386
-
387
- p['age'] = 21
388
- p['name'] = 65
389
-
390
- assert !p.valid?
391
- assert_equal ["Name cannot be a number"], p.errors.full_messages
392
-
393
- p['name'] = 'Jordan'
394
-
395
- assert p.valid?
396
- end
397
-
398
- should "be able to use be_match expectation" do
399
- p = Person.new
400
- class << p
401
- def validate
402
- expectations do
403
- be_match self['name'], "Name must start with uppercase letter", :with => /[A-Z][a-z]*/
404
- not_be_match self['nickname'], "Nickname cannot start with uppercase letter", :with => /[A-Z][a-z]*/
405
- be_match self['age'], "Age must only contain digits", :with => /\d+/, :allow_nil => true
406
- end
407
- end
408
- end
409
-
410
- assert !p.valid?
411
- assert_equal ["Name must start with uppercase letter"], p.errors.full_messages
412
-
413
- p['name'] = 'Jordan'
414
- p['nickname'] = 'Jordan'
415
-
416
- assert !p.valid?
417
- assert_equal ["Nickname cannot start with uppercase letter"], p.errors.full_messages
418
-
419
- p['nickname'] = 'jordan'
420
-
421
- assert p.valid?
422
-
423
- p['age'] = 'asd'
424
-
425
- assert !p.valid?
426
- assert_equal ["Age must only contain digits"], p.errors.full_messages
427
-
428
- p['age'] = '21'
429
-
430
- assert p.valid?
431
-
432
- end
433
-
434
- should "be able to use be_of_length expectation" do
435
- p = Person.new
436
- class << p
437
- def validate
438
- expectations do
439
- be_of_length self['name'], "Name must be 3 characters long", :minimum => 3
440
- be_of_length self['nickname'], "Nickname must not be longer than 5 characters", :maximum => 5
441
- be_of_length self['computers'], "Can only specify between 1 and 3 computers", :range => 1..3
442
- be_of_length self['status'], "Status must be a minimum of 1 character", :minumum => 1, :allow_nil => true
443
- end
444
- end
445
- end
446
-
447
- assert !p.valid?
448
- assert_equal ["Name must be 3 characters long",
449
- "Can only specify between 1 and 3 computers"], p.errors.full_messages
450
-
451
- p['name'] = 'Jordan'
452
- p['nickname'] = 'Jordan'
453
-
454
- assert !p.valid?
455
- assert_equal ["Nickname must not be longer than 5 characters",
456
- "Can only specify between 1 and 3 computers"], p.errors.full_messages
457
-
458
- p['nickname'] = 'abc'
459
- p['computers'] = ['comp_a']
460
-
461
- assert p.valid?
462
- end
463
-
464
- should "be able to use be_reference expectation" do
465
- id = Person.new('name' => 'jordan').insert
466
- p = Person.new
467
- class << p
468
- def validate
469
- expectations do
470
- be_reference self['friend'], 'friend must be an ObjectId'
471
- end
472
- end
473
- end
474
-
475
- assert !p.valid?
476
- assert_equal ["friend must be an ObjectId"], p.errors.full_messages
477
-
478
- p['friend'] = id
479
-
480
- assert p.valid?
481
- end
482
-
483
- should "raise an error if expectations are called outside of helper block" do
484
- p = Person.new
485
- class << p
486
- def validate
487
- be_present self['name'], ''
488
- end
489
- end
490
-
491
- assert_raise NoMethodError do
492
- p.valid?
493
- end
494
-
495
- class << p
496
- def validate
497
- expectations { }
498
- be_present
499
- end
500
- end
501
-
502
- assert_raise NameError do
503
- p.valid?
504
- end
505
- end
506
-
507
- should "be able to drop a collection" do
508
- p = Person.new
509
- p['name'] = "Jordan"
510
- p.insert
511
-
512
- assert !Person.empty?
513
-
514
- Person.drop
515
- assert Person.empty?
516
- end
517
-
518
- should "be able to use errors.on with two part error messages" do
519
- p = Person.new
520
- class << p
521
- def validate
522
- expectations do
523
- be_expected self['name'], ['name', 'cannot be empty']
524
- be_of_length self['name'], ['name', 'must be at least 3 characters long'], :minimum => 3
525
- be_a_number self['age'], ['age', 'must be a number']
526
- end
527
- end
528
- end
529
-
530
- p.valid?
531
- assert_equal ['cannot be empty', 'must be at least 3 characters long'], p.errors.on(:name)
532
- assert_equal ['must be a number'], p.errors.on('age')
533
-
534
- p['name'] = 'Jo'
535
- p['age'] = 21
536
-
537
- p.valid?
538
- assert_equal ['must be at least 3 characters long'], p.errors.on('name')
539
- assert_equal [], p.errors.on(:age)
540
-
541
- p['name'] = 'Jordan'
542
-
543
- p.valid?
544
- assert_equal [], p.errors.on(:name)
545
- end
546
-
547
- should "be able to use errors.on with one part error messages" do
548
- p = Person.new
549
- class << p
550
- def validate
551
- expectations do
552
- be_expected self['name'], ['name', 'cannot be empty' ]
553
- be_of_length self['name'], ['name', 'must be at least 3 characters long'], :minimum => 3
554
- be_a_number self['age'], ['age','must be a number']
555
- end
556
- end
557
- end
558
-
559
- p.valid?
560
- assert_equal ['cannot be empty', 'must be at least 3 characters long'], p.errors.on(:name)
561
- assert_equal ['must be a number'], p.errors.on('age')
562
-
563
- p['name'] = 'Jo'
564
- p['age'] = 21
565
-
566
- p.valid?
567
- assert_equal ['must be at least 3 characters long'], p.errors.on('name')
568
- assert_equal [], p.errors.on(:age)
569
-
570
- p['name'] = 'Jordan'
571
-
572
- p.valid?
573
- assert_equal [], p.errors.on(:name)
574
- end
575
-
576
- should "be able to use errors.on case insensitive" do
577
- p = Person.new
578
- class << p
579
- def validate
580
- expectations do
581
- be_expected self['name'], ['name', 'cannot be empty']
582
- be_expected self['age'], ['age','cannot be empty']
583
- end
584
- end
585
- end
586
-
587
- p.valid?
588
- assert_equal ['cannot be empty'], p.errors.on('name')
589
- assert_equal ['cannot be empty'], p.errors.on(:age)
590
- end
591
-
592
- should "be able to use errors.on with multi word fields" do
593
- p = Person.new
594
- class << p
595
- def validate
596
- expectations do
597
- be_expected self['hair_color'], ['hair_color', 'must exist']
598
- end
599
- end
600
- end
601
-
602
- p.valid?
603
- assert_equal ['must exist'], p.errors.on(:hair_color)
604
- end
605
-
606
- should "be able to use has_key?" do
607
- p = Person.new
608
-
609
- assert !p.has_key?(:name)
610
-
611
- p['name'] = 'Jordan'
612
-
613
- assert p.has_key?(:name)
614
- assert p.has_key?('name')
615
- end
616
-
617
- should "be able to reach into keys with has_key?" do
618
- p = Person.new(:employer => {:name => 'Meta+Level Games',
619
- :function => 'Makes things with code',
620
- :something_else => {
621
- :with_a_key => 'And Value'}
622
- })
623
-
624
- assert !p.has_key?('employer.started_at')
625
- assert p.has_key?('employer.name')
626
- assert !p.has_key?('non.existent')
627
- assert !p.has_key?('employer.something_else.not_here')
628
- assert p.has_key?('employer.something_else.with_a_key')
629
- end
630
-
631
- should "be able to get the value for a key in an embedded doc" do
632
- p = Person.new(:employer => {:name => 'Meta+Level Games',
633
- :function => 'Makes things with code',
634
- :something_else => {
635
- :with_a_key => 'And Value'}
636
- })
637
- assert_equal "And Value", p.value_for_key("employer.something_else.with_a_key")
638
- assert_equal "Meta+Level Games", p.value_for_key("employer.name")
639
- assert_nil p.value_for_key("some_key.that_does_not.exist")
640
- end
641
-
642
- should "not rescue a NoMethodError raised in a callback" do
643
- class Thing < Mongomatic::Base
644
- def before_insert
645
- raise NoMethodError
646
- end
647
-
648
- def self.before_drop
649
- raise NoMethodError
650
- end
651
- end
652
-
653
- assert_raise(NoMethodError) { Thing.new.insert }
654
- assert_raise(NoMethodError) { Thing.drop }
655
- end
656
- end