mongomatic 0.6.2 → 0.6.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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