mongoid 1.1.3 → 1.1.4

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 (60) hide show
  1. data/.watchr +20 -2
  2. data/VERSION +1 -1
  3. data/caliper.yml +4 -0
  4. data/lib/mongoid.rb +0 -1
  5. data/lib/mongoid/associations.rb +25 -13
  6. data/lib/mongoid/associations/belongs_to.rb +15 -17
  7. data/lib/mongoid/associations/belongs_to_related.rb +12 -14
  8. data/lib/mongoid/associations/has_many.rb +53 -35
  9. data/lib/mongoid/associations/has_many_related.rb +10 -15
  10. data/lib/mongoid/associations/has_one.rb +31 -30
  11. data/lib/mongoid/associations/has_one_related.rb +18 -20
  12. data/lib/mongoid/associations/options.rb +10 -0
  13. data/lib/mongoid/associations/proxy.rb +18 -1
  14. data/lib/mongoid/criteria.rb +9 -233
  15. data/lib/mongoid/criterion/complex.rb +21 -0
  16. data/lib/mongoid/criterion/exclusion.rb +63 -0
  17. data/lib/mongoid/criterion/inclusion.rb +91 -0
  18. data/lib/mongoid/criterion/optional.rb +96 -0
  19. data/lib/mongoid/document.rb +2 -2
  20. data/lib/mongoid/extensions/hash/accessors.rb +6 -0
  21. data/lib/mongoid/extensions/hash/criteria_helpers.rb +2 -2
  22. data/lib/mongoid/extensions/symbol/inflections.rb +1 -1
  23. data/mongoid.gemspec +53 -3
  24. data/spec/integration/mongoid/associations_spec.rb +41 -0
  25. data/spec/models/address.rb +39 -0
  26. data/spec/models/animal.rb +6 -0
  27. data/spec/models/comment.rb +8 -0
  28. data/spec/models/country_code.rb +6 -0
  29. data/spec/models/employer.rb +5 -0
  30. data/spec/models/game.rb +6 -0
  31. data/spec/models/inheritance.rb +56 -0
  32. data/spec/models/location.rb +5 -0
  33. data/spec/models/mixed_drink.rb +4 -0
  34. data/spec/models/name.rb +13 -0
  35. data/spec/models/namespacing.rb +11 -0
  36. data/spec/models/patient.rb +4 -0
  37. data/spec/models/person.rb +97 -0
  38. data/spec/models/pet.rb +7 -0
  39. data/spec/models/pet_owner.rb +6 -0
  40. data/spec/models/phone.rb +7 -0
  41. data/spec/models/post.rb +15 -0
  42. data/spec/models/translation.rb +5 -0
  43. data/spec/models/vet_visit.rb +5 -0
  44. data/spec/spec_helper.rb +9 -326
  45. data/spec/unit/mongoid/associations/belongs_to_related_spec.rb +26 -5
  46. data/spec/unit/mongoid/associations/belongs_to_spec.rb +96 -30
  47. data/spec/unit/mongoid/associations/has_many_related_spec.rb +32 -12
  48. data/spec/unit/mongoid/associations/has_many_spec.rb +48 -12
  49. data/spec/unit/mongoid/associations/has_one_related_spec.rb +29 -4
  50. data/spec/unit/mongoid/associations/has_one_spec.rb +46 -1
  51. data/spec/unit/mongoid/associations/options_spec.rb +58 -0
  52. data/spec/unit/mongoid/associations_spec.rb +58 -1
  53. data/spec/unit/mongoid/criteria_spec.rb +71 -735
  54. data/spec/unit/mongoid/criterion/complex_spec.rb +19 -0
  55. data/spec/unit/mongoid/criterion/exclusion_spec.rb +75 -0
  56. data/spec/unit/mongoid/criterion/inclusion_spec.rb +213 -0
  57. data/spec/unit/mongoid/criterion/optional_spec.rb +244 -0
  58. data/spec/unit/mongoid/extensions/hash/accessors_spec.rb +20 -0
  59. metadata +53 -3
  60. data/lib/mongoid/complex_criterion.rb +0 -10
@@ -63,6 +63,31 @@ describe Mongoid::Associations::HasOne do
63
63
 
64
64
  end
65
65
 
66
+ describe "#initialize" do
67
+
68
+ before do
69
+ @parent = Person.new(:title => "Dr")
70
+ @name = Name.new(:first_name => "Richard", :last_name => "Dawkins")
71
+ @parent.name = @name
72
+ @block = Proc.new {
73
+ def extension
74
+ "Testing"
75
+ end
76
+ }
77
+ @options = Mongoid::Associations::Options.new(:name => :name, :extend => @block)
78
+ @association = Mongoid::Associations::HasOne.new(@parent, {}, @options)
79
+ end
80
+
81
+ context "when the options have an extension" do
82
+
83
+ it "adds the extension module" do
84
+ @association.extension.should == "Testing"
85
+ end
86
+
87
+ end
88
+
89
+ end
90
+
66
91
  describe ".instantiate" do
67
92
 
68
93
  context "when the attributes are nil" do
@@ -178,7 +203,7 @@ describe Mongoid::Associations::HasOne do
178
203
  before do
179
204
  @name = Name.new(:first_name => "Donald")
180
205
  @person = Person.new(:title => "Sir")
181
- Mongoid::Associations::HasOne.update(
206
+ @association = Mongoid::Associations::HasOne.update(
182
207
  @name,
183
208
  @person,
184
209
  Mongoid::Associations::Options.new(:name => :name)
@@ -194,6 +219,10 @@ describe Mongoid::Associations::HasOne do
194
219
  { "_id" => "donald", "first_name" => "Donald", "_type" => "Name" }
195
220
  end
196
221
 
222
+ it "returns the proxy" do
223
+ @association.target.should == @name
224
+ end
225
+
197
226
  end
198
227
 
199
228
  context "when setting the object to nil" do
@@ -216,6 +245,22 @@ describe Mongoid::Associations::HasOne do
216
245
 
217
246
  end
218
247
 
248
+ describe "#to_a" do
249
+
250
+ before do
251
+ @association = Mongoid::Associations::HasOne.new(
252
+ @document,
253
+ @attributes["mixed_drink"],
254
+ Mongoid::Associations::Options.new(:name => :mixed_drink)
255
+ )
256
+ end
257
+
258
+ it "returns the target in a new array" do
259
+ @association.to_a.first.should be_a_kind_of(MixedDrink)
260
+ end
261
+
262
+ end
263
+
219
264
  describe "#valid?" do
220
265
 
221
266
  context "when the document is not nil" do
@@ -15,6 +15,64 @@ describe Mongoid::Associations::Options do
15
15
 
16
16
  end
17
17
 
18
+ describe "#extend" do
19
+
20
+ context "when extension exists" do
21
+
22
+ before do
23
+ @attributes = { :extend => lambda { "Test" } }
24
+ @options = Mongoid::Associations::Options.new(@attributes)
25
+ end
26
+
27
+ it "returns the proc" do
28
+ @options.extension.should == @attributes[:extend]
29
+ end
30
+
31
+ end
32
+
33
+ context "when extension doesnt exist" do
34
+
35
+ before do
36
+ @options = Mongoid::Associations::Options.new({})
37
+ end
38
+
39
+ it "returns nil" do
40
+ @options.extension.should be_nil
41
+ end
42
+
43
+ end
44
+
45
+ end
46
+
47
+ describe "extension?" do
48
+
49
+ context "when extension exists" do
50
+
51
+ before do
52
+ @attributes = { :extend => lambda { "Test" } }
53
+ @options = Mongoid::Associations::Options.new(@attributes)
54
+ end
55
+
56
+ it "returns true" do
57
+ @options.extension?.should be_true
58
+ end
59
+
60
+ end
61
+
62
+ context "when extension doesnt exist" do
63
+
64
+ before do
65
+ @options = Mongoid::Associations::Options.new({})
66
+ end
67
+
68
+ it "returns false" do
69
+ @options.extension?.should be_false
70
+ end
71
+
72
+ end
73
+
74
+ end
75
+
18
76
  describe "#foreign_key" do
19
77
 
20
78
  before do
@@ -113,6 +113,20 @@ describe Mongoid::Associations do
113
113
  code.phone_number.should == phone_number
114
114
  end
115
115
 
116
+ context "when adding an anonymous extension" do
117
+
118
+ before do
119
+ @person = Person.new(:title => "Dr")
120
+ @address = Address.new(:street => "Clarkenwell Road")
121
+ @person.addresses << @address
122
+ end
123
+
124
+ it "defines the method on the association" do
125
+ @address.addressable.extension.should == "Testing"
126
+ end
127
+
128
+ end
129
+
116
130
  context "when inverse_of not supplied" do
117
131
 
118
132
  it "raises an error" do
@@ -254,6 +268,15 @@ describe Mongoid::Associations do
254
268
  person.should respond_to(:addresses=)
255
269
  end
256
270
 
271
+ context "when adding an anonymous extension" do
272
+
273
+ it "defines the method on the association" do
274
+ person = Person.new
275
+ person.addresses.extension.should == "Testing"
276
+ end
277
+
278
+ end
279
+
257
280
  context "when setting the association directly" do
258
281
 
259
282
  before do
@@ -330,6 +353,15 @@ describe Mongoid::Associations do
330
353
  @person.should respond_to(:create_name)
331
354
  end
332
355
 
356
+ context "when adding an anonymous extension" do
357
+
358
+ it "defines the method on the association" do
359
+ @person.name = Name.new(:first_name => "Richard")
360
+ @person.name.extension.should == "Testing"
361
+ end
362
+
363
+ end
364
+
333
365
  context "when setting the association directly" do
334
366
 
335
367
  before do
@@ -391,6 +423,8 @@ describe Mongoid::Associations do
391
423
 
392
424
  before do
393
425
  @person = Person.new
426
+ @game = Game.new
427
+ @person.game = @game
394
428
  end
395
429
 
396
430
  it "creates a getter for the relationship" do
@@ -401,15 +435,38 @@ describe Mongoid::Associations do
401
435
  @person.should respond_to(:game=)
402
436
  end
403
437
 
438
+ context "when adding an anonymous extension" do
439
+
440
+ it "defines the method on the association" do
441
+ @person.game.extension.should == "Testing"
442
+ end
443
+
444
+ end
445
+
404
446
  end
405
447
 
406
448
  describe ".has_many_related" do
407
449
 
408
- it "creates a getter and setter for the relationship" do
450
+ it "creates a getter for the association" do
409
451
  Person.new.should respond_to(:posts)
452
+ end
453
+
454
+ it "creates a setter for the association" do
410
455
  Person.new.should respond_to(:posts=)
411
456
  end
412
457
 
458
+ context "when adding an anonymous extension" do
459
+
460
+ before do
461
+ @person = Person.new
462
+ end
463
+
464
+ it "defines the method on the association" do
465
+ @person.posts.extension.should == "Testing"
466
+ end
467
+
468
+ end
469
+
413
470
  end
414
471
 
415
472
  describe "#update_associations" do
@@ -138,58 +138,14 @@ describe Mongoid::Criteria do
138
138
 
139
139
  describe "#aggregate" do
140
140
 
141
- context "when klass not provided" do
142
-
143
- before do
144
- @reduce = "function(obj, prev) { prev.count++; }"
145
- @collection = mock
146
- Person.expects(:collection).returns(@collection)
147
- end
148
-
149
- it "calls group on the collection with the aggregate js" do
150
- @collection.expects(:group).with([:field1], {:_type => { "$in" => ["Doctor", "Person"] }}, {:count => 0}, @reduce, true)
151
- @criteria.only(:field1).aggregate
152
- end
153
-
154
- end
155
-
156
- end
157
-
158
- describe "#all" do
159
-
160
- it "adds the $all query to the selector" do
161
- @criteria.all(:title => ["title1", "title2"])
162
- @criteria.selector.should == { :_type => { "$in" => ["Doctor", "Person"] }, :title => { "$all" => ["title1", "title2"] } }
163
- end
164
-
165
- it "returns self" do
166
- @criteria.all(:title => [ "title1" ]).should == @criteria
167
- end
168
-
169
- end
170
-
171
- describe "#and" do
172
-
173
- context "when provided a hash" do
174
-
175
- it "adds the clause to the selector" do
176
- @criteria.and(:title => "Title", :text => "Text")
177
- @criteria.selector.should == { :_type => { "$in" => ["Doctor", "Person"] }, :title => "Title", :text => "Text" }
178
- end
179
-
180
- end
181
-
182
- context "when provided a string" do
183
-
184
- it "adds the $where clause to the selector" do
185
- @criteria.and("this.date < new Date()")
186
- @criteria.selector.should == { :_type => { "$in" => ["Doctor", "Person"] }, "$where" => "this.date < new Date()" }
187
- end
188
-
141
+ before do
142
+ @context = stub.quacks_like(Mongoid::Contexts::Mongo.allocate)
143
+ @criteria.instance_variable_set(:@context, @context)
189
144
  end
190
145
 
191
- it "returns self" do
192
- @criteria.and.should == @criteria
146
+ it "delegates to the context" do
147
+ @context.expects(:aggregate)
148
+ @criteria.aggregate
193
149
  end
194
150
 
195
151
  end
@@ -298,23 +254,14 @@ describe Mongoid::Criteria do
298
254
 
299
255
  describe "#count" do
300
256
 
301
- context "when criteria has been executed" do
302
-
303
- before do
304
- @criteria = Mongoid::Criteria.new(Person)
305
- @selector = { :_type => { "$in" => ["Doctor", "Person"] }, :test => "Testing" }
306
- @criteria.where(@selector)
307
- @collection = mock
308
- @cursor = mock
309
- Person.expects(:collection).returns(@collection)
310
- end
311
-
312
- it "returns the count from the cursor without creating the documents" do
313
- @collection.expects(:find).with(@selector, {}).returns(@cursor)
314
- @cursor.expects(:count).returns(10)
315
- @criteria.count.should == 10
316
- end
257
+ before do
258
+ @context = stub.quacks_like(Mongoid::Contexts::Mongo.allocate)
259
+ @criteria.instance_variable_set(:@context, @context)
260
+ end
317
261
 
262
+ it "delegates to the context" do
263
+ @context.expects(:count).returns(10)
264
+ @criteria.count.should == 10
318
265
  end
319
266
 
320
267
  end
@@ -371,112 +318,14 @@ describe Mongoid::Criteria do
371
318
 
372
319
  describe "#first" do
373
320
 
374
- context "when documents exist" do
375
-
376
- before do
377
- @collection = mock
378
- Person.expects(:collection).returns(@collection)
379
- @collection.expects(:find_one).with(@criteria.selector, @criteria.options).returns(
380
- { "title" => "Sir", "_type" => "Person" }
381
- )
382
- end
383
-
384
- it "calls find on the collection with the selector and options" do
385
- criteria = Mongoid::Criteria.new(Person)
386
- criteria.first.should be_a_kind_of(Person)
387
- end
388
-
389
- end
390
-
391
- context "when no documents exist" do
392
-
393
- before do
394
- @collection = mock
395
- Person.expects(:collection).returns(@collection)
396
- @collection.expects(:find_one).with(@criteria.selector, @criteria.options).returns(nil)
397
- end
398
-
399
- it "returns nil" do
400
- criteria = Mongoid::Criteria.new(Person)
401
- criteria.first.should be_nil
402
- end
403
-
404
- end
405
-
406
- context "when document is a subclass of the class queried from" do
407
-
408
- before do
409
- @collection = mock
410
- Canvas.expects(:collection).returns(@collection)
411
- @collection.expects(:find_one).with(@canvas_criteria.selector, @canvas_criteria.options).returns(
412
- { "name" => "Firefox", "_type" => "Firefox" }
413
- )
414
- end
415
-
416
- it "instantiates the subclass" do
417
- criteria = Mongoid::Criteria.new(Canvas)
418
- criteria.first.should be_a_kind_of(Firefox)
419
- end
420
-
421
- end
422
-
423
- end
424
-
425
- describe "#excludes" do
426
-
427
- it "adds the $ne query to the selector" do
428
- @criteria.excludes(:title => "Bad Title", :text => "Bad Text")
429
- @criteria.selector.should == { :_type => { "$in" => ["Doctor", "Person"] }, :title => { "$ne" => "Bad Title"}, :text => { "$ne" => "Bad Text" } }
430
- end
431
-
432
- it "returns self" do
433
- @criteria.excludes(:title => "Bad").should == @criteria
434
- end
435
-
436
- end
437
-
438
- describe "#extras" do
439
-
440
- context "filtering" do
441
-
442
- context "when page is provided" do
443
-
444
- it "sets the limit and skip options" do
445
- @criteria.extras({ :page => "2" })
446
- @criteria.page.should == 2
447
- @criteria.options.should == { :skip => 20, :limit => 20 }
448
- end
449
-
450
- end
451
-
452
- context "when per_page is provided" do
453
-
454
- it "sets the limit and skip options" do
455
- @criteria.extras({ :per_page => 45 })
456
- @criteria.options.should == { :skip => 0, :limit => 45 }
457
- end
458
-
459
- end
460
-
461
- context "when page and per_page both provided" do
462
-
463
- it "sets the limit and skip options" do
464
- @criteria.extras({ :per_page => 30, :page => "4" })
465
- @criteria.options.should == { :skip => 90, :limit => 30 }
466
- @criteria.page.should == 4
467
- end
468
-
469
- end
470
-
471
- end
472
-
473
- it "adds the extras to the options" do
474
- @criteria.extras({ :skip => 10 })
475
- @criteria.options.should == { :skip => 10 }
321
+ before do
322
+ @context = stub.quacks_like(Mongoid::Contexts::Mongo.allocate)
323
+ @criteria.instance_variable_set(:@context, @context)
476
324
  end
477
325
 
478
- it "returns self" do
479
- @criteria.extras({}).should == @criteria
326
+ it "delegates to the context" do
327
+ @context.expects(:first).returns([])
328
+ @criteria.first.should == []
480
329
  end
481
330
 
482
331
  end
@@ -484,99 +333,13 @@ describe Mongoid::Criteria do
484
333
  describe "#group" do
485
334
 
486
335
  before do
487
- @grouping = [{ "title" => "Sir", "group" => [{ "title" => "Sir", "age" => 30, "_type" => "Person" }] }]
488
- end
489
-
490
- context "when klass provided" do
491
-
492
- before do
493
- @reduce = "function(obj, prev) { prev.group.push(obj); }"
494
- @criteria = Mongoid::Criteria.new(Person)
495
- @collection = mock
496
- Person.expects(:collection).returns(@collection)
497
- end
498
-
499
- it "calls group on the collection with the aggregate js" do
500
- @collection.expects(:group).with(
501
- [ :field1 ],
502
- { :_type =>
503
- { "$in" => ["Doctor", "Person"] }},
504
- {:group => []}, @reduce, true
505
- ).returns(@grouping)
506
- @criteria.only(:field1).group
507
- end
508
-
336
+ @context = stub.quacks_like(Mongoid::Contexts::Mongo.allocate)
337
+ @criteria.instance_variable_set(:@context, @context)
509
338
  end
510
339
 
511
- context "when klass not provided" do
512
-
513
- before do
514
- @reduce = "function(obj, prev) { prev.group.push(obj); }"
515
- @collection = mock
516
- Person.expects(:collection).returns(@collection)
517
- end
518
-
519
- it "calls group on the collection with the aggregate js" do
520
- @collection.expects(:group).with(
521
- [ :field1 ],
522
- { :_type =>
523
- { "$in" => ["Doctor", "Person"] }
524
- }, { :group => []}, @reduce, true).returns(@grouping)
525
- @criteria.only(:field1).group
526
- end
527
-
528
- end
529
-
530
- end
531
-
532
- describe "#id" do
533
-
534
- context "when passing a single id" do
535
-
536
- it "adds the _id query to the selector" do
537
- id = Mongo::ObjectID.new.to_s
538
- @criteria.id(id)
539
- @criteria.selector.should == { :_type => { "$in" => ["Doctor", "Person"] }, :_id => id }
540
- end
541
-
542
- it "returns self" do
543
- id = Mongo::ObjectID.new.to_s
544
- @criteria.id(id.to_s).should == @criteria
545
- end
546
-
547
- end
548
-
549
- context "when passing in an array of ids" do
550
-
551
- before do
552
- @ids = []
553
- 3.times { @ids << Mongo::ObjectID.new.to_s }
554
- end
555
-
556
- it "adds the _id query to the selector" do
557
- @criteria.id(@ids)
558
- @criteria.selector.should ==
559
- { :_type => { "$in" => ["Doctor", "Person"] }, :_id => { "$in" => @ids } }
560
- end
561
-
562
- end
563
-
564
- end
565
-
566
- describe "#in" do
567
-
568
- it "adds the $in clause to the selector" do
569
- @criteria.in(:title => ["title1", "title2"], :text => ["test"])
570
- @criteria.selector.should ==
571
- { :_type =>
572
- { "$in" =>
573
- ["Doctor", "Person"]
574
- }, :title => { "$in" => ["title1", "title2"] }, :text => { "$in" => ["test"] }
575
- }
576
- end
577
-
578
- it "returns self" do
579
- @criteria.in(:title => ["title1"]).should == @criteria
340
+ it "delegates to the context" do
341
+ @context.expects(:group).returns({})
342
+ @criteria.group.should == {}
580
343
  end
581
344
 
582
345
  end
@@ -605,80 +368,14 @@ describe Mongoid::Criteria do
605
368
 
606
369
  describe "#last" do
607
370
 
608
- context "when documents exist" do
609
-
610
- before do
611
- @collection = mock
612
- Person.expects(:collection).returns(@collection)
613
- @collection.expects(:find_one).with(@criteria.selector, { :sort => [[:title, :desc]] }).returns(
614
- { "title" => "Sir", "_type" => "Person" }
615
- )
616
- end
617
-
618
- it "calls find on the collection with the selector and sort options reversed" do
619
- criteria = Mongoid::Criteria.new(Person)
620
- criteria.order_by([[:title, :asc]])
621
- criteria.last.should be_a_kind_of(Person)
622
- end
623
-
624
- end
625
-
626
- context "when no documents exist" do
627
-
628
- before do
629
- @collection = mock
630
- Person.expects(:collection).returns(@collection)
631
- @collection.expects(:find_one).with(@criteria.selector, { :sort => [[:_id, :desc]] }).returns(nil)
632
- end
633
-
634
- it "returns nil" do
635
- criteria = Mongoid::Criteria.new(Person)
636
- criteria.last.should be_nil
637
- end
638
-
639
- end
640
-
641
- context "when no sorting options provided" do
642
-
643
- before do
644
- @collection = mock
645
- Person.expects(:collection).returns(@collection)
646
- @collection.expects(:find_one).with(@criteria.selector, { :sort => [[:_id, :desc]] }).returns(
647
- { "title" => "Sir", "_type" => "Person" }
648
- )
649
- end
650
-
651
- it "defaults to sort by id" do
652
- criteria = Mongoid::Criteria.new(Person)
653
- criteria.last
654
- end
655
-
656
- end
657
-
658
- end
659
-
660
- describe "#limit" do
661
-
662
- context "when value provided" do
663
-
664
- it "adds the limit to the options" do
665
- @criteria.limit(100)
666
- @criteria.options.should == { :limit => 100 }
667
- end
668
-
669
- end
670
-
671
- context "when value not provided" do
672
-
673
- it "defaults to 20" do
674
- @criteria.limit
675
- @criteria.options.should == { :limit => 20 }
676
- end
677
-
371
+ before do
372
+ @context = stub.quacks_like(Mongoid::Contexts::Mongo.allocate)
373
+ @criteria.instance_variable_set(:@context, @context)
678
374
  end
679
375
 
680
- it "returns self" do
681
- @criteria.limit.should == @criteria
376
+ it "delegates to the context" do
377
+ @context.expects(:last).returns([])
378
+ @criteria.last.should == []
682
379
  end
683
380
 
684
381
  end
@@ -686,20 +383,13 @@ describe Mongoid::Criteria do
686
383
  describe "#max" do
687
384
 
688
385
  before do
689
- @reduce = Mongoid::Contexts::Mongo::MAX_REDUCE.gsub("[field]", "age")
690
- @collection = mock
691
- Person.expects(:collection).returns(@collection)
386
+ @context = stub.quacks_like(Mongoid::Contexts::Mongo.allocate)
387
+ @criteria.instance_variable_set(:@context, @context)
692
388
  end
693
389
 
694
- it "calls group on the collection with the aggregate js" do
695
- @collection.expects(:group).with(
696
- nil,
697
- {:_type => { "$in" => ["Doctor", "Person"] } },
698
- {:max => "start"},
699
- @reduce,
700
- true
701
- ).returns([{"max" => 200.0}])
702
- @criteria.max(:age).should == 200.0
390
+ it "delegates to the context" do
391
+ @context.expects(:max).with(:field).returns(100)
392
+ @criteria.max(:field).should == 100
703
393
  end
704
394
 
705
395
  end
@@ -822,176 +512,41 @@ describe Mongoid::Criteria do
822
512
  describe "#min" do
823
513
 
824
514
  before do
825
- @reduce = Mongoid::Contexts::Mongo::MIN_REDUCE.gsub("[field]", "age")
826
- @collection = mock
827
- Person.expects(:collection).returns(@collection)
828
- end
829
-
830
- it "calls group on the collection with the aggregate js" do
831
- @collection.expects(:group).with(
832
- nil,
833
- {:_type => { "$in" => ["Doctor", "Person"] } },
834
- {:min => "start"},
835
- @reduce,
836
- true
837
- ).returns([{"min" => 4.0}])
838
- @criteria.min(:age).should == 4.0
839
- end
840
-
841
- end
842
-
843
- describe "#not_in" do
844
-
845
- it "adds the exclusion to the selector" do
846
- @criteria.not_in(:title => ["title1", "title2"], :text => ["test"])
847
- @criteria.selector.should == {
848
- :_type => { "$in" => ["Doctor", "Person"] },
849
- :title => { "$nin" => ["title1", "title2"] },
850
- :text => { "$nin" => ["test"] }
851
- }
852
- end
853
-
854
- it "returns self" do
855
- @criteria.not_in(:title => ["title1"]).should == @criteria
856
- end
857
-
858
- end
859
-
860
- describe "#offset" do
861
-
862
- context "when the per_page option exists" do
863
-
864
- before do
865
- @criteria = Mongoid::Criteria.new(Person).extras({ :per_page => 20, :page => 3 })
866
- end
867
-
868
- it "returns the per_page option" do
869
- @criteria.offset.should == 40
870
- end
871
-
515
+ @context = stub.quacks_like(Mongoid::Contexts::Mongo.allocate)
516
+ @criteria.instance_variable_set(:@context, @context)
872
517
  end
873
518
 
874
- context "when the skip option exists" do
875
-
876
- before do
877
- @criteria = Mongoid::Criteria.new(Person).extras({ :skip => 20 })
878
- end
879
-
880
- it "returns the skip option" do
881
- @criteria.offset.should == 20
882
- end
883
-
884
- end
885
-
886
- context "when no option exists" do
887
-
888
- context "when page option exists" do
889
-
890
- before do
891
- @criteria = Mongoid::Criteria.new(Person).extras({ :page => 2 })
892
- end
893
-
894
- it "adds the skip option to the options and returns it" do
895
- @criteria.offset.should == 20
896
- @criteria.options[:skip].should == 20
897
- end
898
-
899
- end
900
-
901
- context "when page option does not exist" do
902
-
903
- before do
904
- @criteria = Mongoid::Criteria.new(Person)
905
- end
906
-
907
- it "returns nil" do
908
- @criteria.offset.should be_nil
909
- @criteria.options[:skip].should be_nil
910
- end
911
-
912
- end
913
-
519
+ it "delegates to the context" do
520
+ @context.expects(:min).with(:field).returns(100)
521
+ @criteria.min(:field).should == 100
914
522
  end
915
523
 
916
524
  end
917
525
 
918
526
  describe "#one" do
919
527
 
920
- context "when documents exist" do
921
-
922
- before do
923
- @collection = mock
924
- Person.expects(:collection).returns(@collection)
925
- @collection.expects(:find_one).with(@criteria.selector, @criteria.options).returns(
926
- { "title"=> "Sir", "_type" => "Person" }
927
- )
928
- end
929
-
930
- it "calls find on the collection with the selector and options" do
931
- criteria = Mongoid::Criteria.new(Person)
932
- criteria.one.should be_a_kind_of(Person)
933
- end
934
-
935
- end
936
-
937
- context "when no documents exist" do
938
-
939
- before do
940
- @collection = mock
941
- Person.expects(:collection).returns(@collection)
942
- @collection.expects(:find_one).with(@criteria.selector, @criteria.options).returns(nil)
943
- end
944
-
945
- it "returns nil" do
946
- criteria = Mongoid::Criteria.new(Person)
947
- criteria.one.should be_nil
948
- end
949
-
950
- end
951
-
952
- end
953
-
954
- describe "#order_by" do
955
-
956
- context "when field names and direction specified" do
957
-
958
- it "adds the sort to the options" do
959
- @criteria.order_by([[:title, :asc], [:text, :desc]])
960
- @criteria.options.should == { :sort => [[:title, :asc], [:text, :desc]] }
961
- end
962
-
528
+ before do
529
+ @context = stub.quacks_like(Mongoid::Contexts::Mongo.allocate)
530
+ @criteria.instance_variable_set(:@context, @context)
963
531
  end
964
532
 
965
- it "returns self" do
966
- @criteria.order_by.should == @criteria
533
+ it "delegates to the context" do
534
+ @context.expects(:one)
535
+ @criteria.one
967
536
  end
968
537
 
969
538
  end
970
539
 
971
540
  describe "#page" do
972
541
 
973
- context "when the page option exists" do
974
-
975
- before do
976
- @criteria = Mongoid::Criteria.new(Person).extras({ :page => 5 })
977
- end
978
-
979
- it "returns the page option" do
980
- @criteria.page.should == 5
981
- end
982
-
542
+ before do
543
+ @context = stub.quacks_like(Mongoid::Contexts::Mongo.allocate)
544
+ @criteria.instance_variable_set(:@context, @context)
983
545
  end
984
546
 
985
- context "when the page option does not exist" do
986
-
987
- before do
988
- @criteria = Mongoid::Criteria.new(Person)
989
- end
990
-
991
- it "returns 1" do
992
- @criteria.page.should == 1
993
- end
994
-
547
+ it "delegates to the context" do
548
+ @context.expects(:page).returns(1)
549
+ @criteria.page.should == 1
995
550
  end
996
551
 
997
552
  end
@@ -999,74 +554,27 @@ describe Mongoid::Criteria do
999
554
  describe "#paginate" do
1000
555
 
1001
556
  before do
1002
- @collection = mock
1003
- Person.expects(:collection).returns(@collection)
1004
- @criteria = Person.where(:_id => "1").skip(60).limit(20)
1005
- @collection.expects(:find).with(
1006
- { :_type =>
1007
- { "$in" => ["Doctor", "Person"] },
1008
- :_id => "1"
1009
- }, :skip => 60, :limit => 20).returns([])
1010
- @results = @criteria.paginate
557
+ @context = stub.quacks_like(Mongoid::Contexts::Mongo.allocate)
558
+ @criteria.instance_variable_set(:@context, @context)
1011
559
  end
1012
560
 
1013
- it "executes and paginates the results" do
1014
- @results.current_page.should == 4
1015
- @results.per_page.should == 20
561
+ it "delegates to the context" do
562
+ @context.expects(:paginate).returns([])
563
+ @criteria.paginate.should == []
1016
564
  end
1017
565
 
1018
566
  end
1019
567
 
1020
568
  describe "#per_page" do
1021
569
 
1022
- context "when the per_page option exists" do
1023
-
1024
- before do
1025
- @criteria = Mongoid::Criteria.new(Person).extras({ :per_page => 10 })
1026
- end
1027
-
1028
- it "returns the per_page option" do
1029
- @criteria.per_page.should == 10
1030
- end
1031
-
1032
- end
1033
-
1034
- context "when the per_page option does not exist" do
1035
-
1036
- before do
1037
- @criteria = Mongoid::Criteria.new(Person)
1038
- end
1039
-
1040
- it "returns 1" do
1041
- @criteria.per_page.should == 20
1042
- end
1043
-
1044
- end
1045
-
1046
- end
1047
-
1048
- describe "#only" do
1049
-
1050
- context "when args are provided" do
1051
-
1052
- it "adds the options for limiting by fields" do
1053
- @criteria.only(:title, :text)
1054
- @criteria.options.should == { :fields => [ :title, :text ] }
1055
- end
1056
-
1057
- it "returns self" do
1058
- @criteria.only.should == @criteria
1059
- end
1060
-
570
+ before do
571
+ @context = stub.quacks_like(Mongoid::Contexts::Mongo.allocate)
572
+ @criteria.instance_variable_set(:@context, @context)
1061
573
  end
1062
574
 
1063
- context "when no args provided" do
1064
-
1065
- it "does not add the field option" do
1066
- @criteria.only
1067
- @criteria.options[:fields].should be_nil
1068
- end
1069
-
575
+ it "delegates to the context" do
576
+ @context.expects(:per_page).returns(20)
577
+ @criteria.per_page.should == 20
1070
578
  end
1071
579
 
1072
580
  end
@@ -1084,53 +592,16 @@ describe Mongoid::Criteria do
1084
592
 
1085
593
  end
1086
594
 
1087
- describe "#skip" do
1088
-
1089
- context "when value provided" do
1090
-
1091
- it "adds the skip value to the options" do
1092
- @criteria.skip(20)
1093
- @criteria.options.should == { :skip => 20 }
1094
- end
1095
-
1096
- end
1097
-
1098
- context "when value not provided" do
1099
-
1100
- it "defaults to zero" do
1101
- @criteria.skip
1102
- @criteria.options.should == { :skip => 0 }
1103
- end
1104
-
1105
- end
1106
-
1107
- it "returns self" do
1108
- @criteria.skip.should == @criteria
1109
- end
1110
-
1111
- end
1112
-
1113
595
  describe "#sum" do
1114
596
 
1115
- context "when klass not provided" do
1116
-
1117
- before do
1118
- @reduce = Mongoid::Contexts::Mongo::SUM_REDUCE.gsub("[field]", "age")
1119
- @collection = mock
1120
- Person.expects(:collection).returns(@collection)
1121
- end
1122
-
1123
- it "calls group on the collection with the aggregate js" do
1124
- @collection.expects(:group).with(
1125
- nil,
1126
- {:_type => { "$in" => ["Doctor", "Person"] } },
1127
- {:sum => "start"},
1128
- @reduce,
1129
- true
1130
- ).returns([{"sum" => 50.0}])
1131
- @criteria.sum(:age).should == 50.0
1132
- end
597
+ before do
598
+ @context = stub.quacks_like(Mongoid::Contexts::Mongo.allocate)
599
+ @criteria.instance_variable_set(:@context, @context)
600
+ end
1133
601
 
602
+ it "delegates to the context" do
603
+ @context.expects(:sum).with(:field).returns(20)
604
+ @criteria.sum(:field).should == 20
1134
605
  end
1135
606
 
1136
607
  end
@@ -1277,142 +748,6 @@ describe Mongoid::Criteria do
1277
748
 
1278
749
  end
1279
750
 
1280
- describe "#where" do
1281
-
1282
- context "when provided a hash" do
1283
-
1284
- context "with simple hash keys" do
1285
-
1286
- it "adds the clause to the selector" do
1287
- @criteria.where(:title => "Title", :text => "Text")
1288
- @criteria.selector.should ==
1289
- { :_type => { "$in" => ["Doctor", "Person"] }, :title => "Title", :text => "Text" }
1290
- end
1291
-
1292
- end
1293
-
1294
- context "with complex criterion" do
1295
-
1296
- context "#all" do
1297
-
1298
- it "returns those matching an all clause" do
1299
- @criteria.where(:title.all => ["Sir"])
1300
- @criteria.selector.should ==
1301
- { :_type => { "$in" => ["Doctor", "Person"] }, :title => { "$all" => ["Sir"] } }
1302
- end
1303
-
1304
- end
1305
-
1306
- context "#exists" do
1307
-
1308
- it "returns those matching an exists clause" do
1309
- @criteria.where(:title.exists => true)
1310
- @criteria.selector.should ==
1311
- { :_type => { "$in" => ["Doctor", "Person"] }, :title => { "$exists" => true } }
1312
- end
1313
-
1314
- end
1315
-
1316
- context "#gt" do
1317
-
1318
- it "returns those matching a gt clause" do
1319
- @criteria.where(:age.gt => 30)
1320
- @criteria.selector.should ==
1321
- { :_type => { "$in" => ["Doctor", "Person"] }, :age => { "$gt" => 30 } }
1322
- end
1323
-
1324
- end
1325
-
1326
- context "#gte" do
1327
-
1328
- it "returns those matching a gte clause" do
1329
- @criteria.where(:age.gte => 33)
1330
- @criteria.selector.should ==
1331
- { :_type => { "$in" => ["Doctor", "Person"] }, :age => { "$gte" => 33 } }
1332
- end
1333
-
1334
- end
1335
-
1336
- context "#in" do
1337
-
1338
- it "returns those matching an in clause" do
1339
- @criteria.where(:title.in => ["Sir", "Madam"])
1340
- @criteria.selector.should ==
1341
- { :_type => { "$in" => ["Doctor", "Person"] }, :title => { "$in" => ["Sir", "Madam"] } }
1342
- end
1343
-
1344
- end
1345
-
1346
- context "#lt" do
1347
-
1348
- it "returns those matching a lt clause" do
1349
- @criteria.where(:age.lt => 34)
1350
- @criteria.selector.should ==
1351
- { :_type => { "$in" => ["Doctor", "Person"] }, :age => { "$lt" => 34 } }
1352
- end
1353
-
1354
- end
1355
-
1356
- context "#lte" do
1357
-
1358
- it "returns those matching a lte clause" do
1359
- @criteria.where(:age.lte => 33)
1360
- @criteria.selector.should ==
1361
- { :_type => { "$in" => ["Doctor", "Person"] }, :age => { "$lte" => 33 } }
1362
- end
1363
-
1364
- end
1365
-
1366
- context "#ne" do
1367
-
1368
- it "returns those matching a ne clause" do
1369
- @criteria.where(:age.ne => 50)
1370
- @criteria.selector.should ==
1371
- { :_type => { "$in" => ["Doctor", "Person"] }, :age => { "$ne" => 50 } }
1372
- end
1373
-
1374
- end
1375
-
1376
- context "#nin" do
1377
-
1378
- it "returns those matching a nin clause" do
1379
- @criteria.where(:title.nin => ["Esquire", "Congressman"])
1380
- @criteria.selector.should ==
1381
- { :_type => { "$in" => ["Doctor", "Person"] }, :title => { "$nin" => ["Esquire", "Congressman"] } }
1382
- end
1383
-
1384
- end
1385
-
1386
- context "#size" do
1387
-
1388
- it "returns those matching a size clause" do
1389
- @criteria.where(:aliases.size => 2)
1390
- @criteria.selector.should ==
1391
- { :_type => { "$in" => ["Doctor", "Person"] }, :aliases => { "$size" => 2 } }
1392
- end
1393
-
1394
- end
1395
-
1396
- end
1397
-
1398
- end
1399
-
1400
- context "when provided a string" do
1401
-
1402
- it "adds the $where clause to the selector" do
1403
- @criteria.where("this.date < new Date()")
1404
- @criteria.selector.should ==
1405
- { :_type => { "$in" => ["Doctor", "Person"] }, "$where" => "this.date < new Date()" }
1406
- end
1407
-
1408
- end
1409
-
1410
- it "returns self" do
1411
- @criteria.where.should == @criteria
1412
- end
1413
-
1414
- end
1415
-
1416
751
  context "#fuse" do
1417
752
 
1418
753
  it ":where => {:title => 'Test'} returns a criteria with the correct selector" do
@@ -1426,4 +761,5 @@ describe Mongoid::Criteria do
1426
761
  @result.options.should == { :skip => 10 }
1427
762
  end
1428
763
  end
764
+
1429
765
  end