mongoid 0.8.10 → 0.9.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.
@@ -21,6 +21,7 @@ end
21
21
 
22
22
  class Person < Mongoid::Document
23
23
  include Mongoid::Timestamps
24
+
24
25
  field :title
25
26
  field :terms, :type => Boolean
26
27
  field :age, :type => Integer, :default => 100
@@ -28,8 +29,10 @@ class Person < Mongoid::Document
28
29
  field :mixed_drink, :type => MixedDrink
29
30
  field :employer_id
30
31
  field :lunch_time, :type => Time
32
+
31
33
  has_many :addresses
32
34
  has_many :phone_numbers, :class_name => "Phone"
35
+
33
36
  has_one :name
34
37
  has_one :pet, :class_name => "Animal"
35
38
 
@@ -42,6 +45,19 @@ class Person < Mongoid::Document
42
45
  def employer=(emp)
43
46
  self.employer_id = emp.id
44
47
  end
48
+
49
+ class << self
50
+ def accepted
51
+ criteria.where(:terms => true)
52
+ end
53
+ def knight
54
+ criteria.where(:title => "Sir")
55
+ end
56
+ def old
57
+ criteria.where(:age => { "$gt" => 50 })
58
+ end
59
+ end
60
+
45
61
  end
46
62
 
47
63
  class Employer
@@ -3,7 +3,7 @@ require File.expand_path(File.join(File.dirname(__FILE__), "/../../spec_helper.r
3
3
  describe Mongoid::Criteria do
4
4
 
5
5
  before do
6
- @criteria = Mongoid::Criteria.new(:all)
6
+ @criteria = Mongoid::Criteria.new(Person)
7
7
  end
8
8
 
9
9
  describe "#aggregate" do
@@ -12,7 +12,7 @@ describe Mongoid::Criteria do
12
12
 
13
13
  before do
14
14
  @reduce = "function(obj, prev) { prev.count++; }"
15
- @criteria = Mongoid::Criteria.new(:all, Person)
15
+ @criteria = Mongoid::Criteria.new(Person)
16
16
  @collection = mock
17
17
  Person.expects(:collection).returns(@collection)
18
18
  end
@@ -54,134 +54,147 @@ describe Mongoid::Criteria do
54
54
 
55
55
  end
56
56
 
57
- describe "#count" do
57
+ describe "#collect" do
58
58
 
59
- context "when criteria has not been executed" do
59
+ context "filtering" do
60
60
 
61
61
  before do
62
- @criteria.instance_variable_set(:@count, 34)
62
+ @collection = mock
63
+ Person.expects(:collection).returns(@collection)
64
+ @criteria = Mongoid::Criteria.new(Person).extras(:page => 1, :per_page => 20)
65
+ @collection.expects(:find).with(@criteria.selector, @criteria.options).returns([])
63
66
  end
64
67
 
65
- it "returns a count from the cursor" do
66
- @criteria.count.should == 34
68
+ it "filters out unused params" do
69
+ @criteria.collect
70
+ @criteria.options[:page].should be_nil
71
+ @criteria.options[:per_page].should be_nil
67
72
  end
68
73
 
69
74
  end
70
75
 
71
- context "when criteria has been executed" do
76
+ context "when type is :all" do
72
77
 
73
78
  before do
74
- @criteria = Mongoid::Criteria.new(:all, Person)
75
- @selector = { :test => "Testing" }
76
- @criteria.where(@selector)
77
79
  @collection = mock
78
- @cursor = mock
79
80
  Person.expects(:collection).returns(@collection)
81
+ @criteria = Mongoid::Criteria.new(Person).extras(:page => 1, :per_page => 20)
82
+ @cursor = stub(:count => 44, :collect => [])
83
+ @collection.expects(:find).with(@criteria.selector, @criteria.options).returns(@cursor)
80
84
  end
81
85
 
82
- it "returns the count from the cursor without creating the documents" do
83
- @collection.expects(:find).with(@selector, {}).returns(@cursor)
84
- @cursor.expects(:count).returns(10)
85
- @criteria.count.should == 10
86
+ it "adds the count instance variable" do
87
+ @criteria.collect.should == []
88
+ @criteria.count.should == 44
86
89
  end
87
90
 
88
91
  end
89
92
 
90
- end
93
+ context "when type is :first" do
91
94
 
92
- describe "#excludes" do
93
95
 
94
- it "adds the $ne query to the selector" do
95
- @criteria.excludes(:title => "Bad Title", :text => "Bad Text")
96
- @criteria.selector.should == { :title => { "$ne" => "Bad Title"}, :text => { "$ne" => "Bad Text" } }
97
96
  end
98
97
 
99
- it "returns self" do
100
- @criteria.excludes(:title => "Bad").should == @criteria
98
+ context "when type is not :first" do
99
+
100
+ it "calls find on the collection with the selector and options" do
101
+ criteria = Mongoid::Criteria.new(Person)
102
+ collection = mock
103
+ Person.expects(:collection).returns(collection)
104
+ collection.expects(:find).with(@criteria.selector, @criteria.options).returns([])
105
+ criteria.collect.should == []
106
+ end
107
+
101
108
  end
102
109
 
103
110
  end
104
111
 
105
- describe "#execute" do
112
+ describe "#count" do
106
113
 
107
- context "filtering" do
114
+ context "when criteria has not been executed" do
108
115
 
109
116
  before do
110
- @collection = mock
111
- Person.expects(:collection).returns(@collection)
112
- @criteria = Mongoid::Criteria.new(:all).extras(:page => 1, :per_page => 20)
113
- @collection.expects(:find).with(@criteria.selector, @criteria.options).returns([])
117
+ @criteria.instance_variable_set(:@count, 34)
114
118
  end
115
119
 
116
- it "filters out unused params" do
117
- @criteria.execute(Person)
118
- @criteria.options[:page].should be_nil
119
- @criteria.options[:per_page].should be_nil
120
+ it "returns a count from the cursor" do
121
+ @criteria.count.should == 34
120
122
  end
121
123
 
122
124
  end
123
125
 
124
- context "when type is :all" do
126
+ context "when criteria has been executed" do
125
127
 
126
128
  before do
129
+ @criteria = Mongoid::Criteria.new(Person)
130
+ @selector = { :test => "Testing" }
131
+ @criteria.where(@selector)
127
132
  @collection = mock
133
+ @cursor = mock
128
134
  Person.expects(:collection).returns(@collection)
129
- @criteria = Mongoid::Criteria.new(:all).extras(:page => 1, :per_page => 20)
130
- @cursor = stub(:count => 44, :collect => [])
131
- @collection.expects(:find).with(@criteria.selector, @criteria.options).returns(@cursor)
132
135
  end
133
136
 
134
- it "adds the count instance variable" do
135
- @criteria.execute(Person).should == []
136
- @criteria.count.should == 44
137
+ it "returns the count from the cursor without creating the documents" do
138
+ @collection.expects(:find).with(@selector, {}).returns(@cursor)
139
+ @cursor.expects(:count).returns(10)
140
+ @criteria.count.should == 10
137
141
  end
138
142
 
139
143
  end
140
144
 
141
- context "when type is :first" do
145
+ end
142
146
 
143
- context "when documents exist" do
147
+ describe "#each" do
144
148
 
145
- before do
146
- @collection = mock
147
- Person.expects(:collection).returns(@collection)
148
- @collection.expects(:find_one).with(@criteria.selector, @criteria.options).returns({ :title => "Sir" })
149
- end
149
+ before do
150
+ @criteria.where(:title => "Sir")
151
+ @collection = stub
152
+ @person = Person.new(:title => "Sir")
153
+ @cursor = stub(:count => 10, :collect => [@person])
154
+ end
150
155
 
151
- it "calls find on the collection with the selector and options" do
152
- criteria = Mongoid::Criteria.new(:first)
153
- criteria.execute(Person).should be_a_kind_of(Person)
154
- end
156
+ context "when the criteria has not been executed" do
155
157
 
158
+ before do
159
+ Person.expects(:collection).returns(@collection)
160
+ @collection.expects(:find).with({ :title => "Sir" }, {}).returns(@cursor)
156
161
  end
157
162
 
158
- context "when no documents exist" do
159
-
160
- before do
161
- @collection = mock
162
- Person.expects(:collection).returns(@collection)
163
- @collection.expects(:find_one).with(@criteria.selector, @criteria.options).returns(nil)
163
+ it "executes the criteria" do
164
+ @criteria.each do |person|
165
+ person.should == @person
164
166
  end
167
+ end
165
168
 
166
- it "returns nil" do
167
- criteria = Mongoid::Criteria.new(:first)
168
- criteria.execute(Person).should be_nil
169
- end
169
+ end
170
170
 
171
+ context "when the criteria has been executed" do
172
+
173
+ before do
174
+ Person.expects(:collection).returns(@collection)
175
+ @collection.expects(:find).with({ :title => "Sir" }, {}).returns(@cursor)
176
+ end
177
+
178
+ it "calls each on the existing results" do
179
+ @criteria.each
180
+ @criteria.each do |person|
181
+ person.should == @person
182
+ end
171
183
  end
172
184
 
173
185
  end
174
186
 
175
- context "when type is not :first" do
187
+ end
176
188
 
177
- it "calls find on the collection with the selector and options" do
178
- criteria = Mongoid::Criteria.new(:all)
179
- collection = mock
180
- Person.expects(:collection).returns(collection)
181
- collection.expects(:find).with(@criteria.selector, @criteria.options).returns([])
182
- criteria.execute(Person).should == []
183
- end
189
+ describe "#excludes" do
184
190
 
191
+ it "adds the $ne query to the selector" do
192
+ @criteria.excludes(:title => "Bad Title", :text => "Bad Text")
193
+ @criteria.selector.should == { :title => { "$ne" => "Bad Title"}, :text => { "$ne" => "Bad Text" } }
194
+ end
195
+
196
+ it "returns self" do
197
+ @criteria.excludes(:title => "Bad").should == @criteria
185
198
  end
186
199
 
187
200
  end
@@ -242,7 +255,7 @@ describe Mongoid::Criteria do
242
255
 
243
256
  before do
244
257
  @reduce = "function(obj, prev) { prev.group.push(obj); }"
245
- @criteria = Mongoid::Criteria.new(:all, Person)
258
+ @criteria = Mongoid::Criteria.new(Person)
246
259
  @collection = mock
247
260
  Person.expects(:collection).returns(@collection)
248
261
  end
@@ -299,6 +312,56 @@ describe Mongoid::Criteria do
299
312
 
300
313
  end
301
314
 
315
+ describe "#last" do
316
+
317
+ context "when documents exist" do
318
+
319
+ before do
320
+ @collection = mock
321
+ Person.expects(:collection).returns(@collection)
322
+ @collection.expects(:find_one).with(@criteria.selector, { :sort => [[:title, :desc]] }).returns({ :title => "Sir" })
323
+ end
324
+
325
+ it "calls find on the collection with the selector and sort options reversed" do
326
+ criteria = Mongoid::Criteria.new(Person)
327
+ criteria.order_by([[:title, :asc]])
328
+ criteria.last.should be_a_kind_of(Person)
329
+ end
330
+
331
+ end
332
+
333
+ context "when no documents exist" do
334
+
335
+ before do
336
+ @collection = mock
337
+ Person.expects(:collection).returns(@collection)
338
+ @collection.expects(:find_one).with(@criteria.selector, { :sort => [[:_id, :desc]] }).returns(nil)
339
+ end
340
+
341
+ it "returns nil" do
342
+ criteria = Mongoid::Criteria.new(Person)
343
+ criteria.last.should be_nil
344
+ end
345
+
346
+ end
347
+
348
+ context "when no sorting options provided" do
349
+
350
+ before do
351
+ @collection = mock
352
+ Person.expects(:collection).returns(@collection)
353
+ @collection.expects(:find_one).with(@criteria.selector, { :sort => [[:_id, :desc]] }).returns({ :title => "Sir" })
354
+ end
355
+
356
+ it "defaults to sort by id" do
357
+ criteria = Mongoid::Criteria.new(Person)
358
+ criteria.last
359
+ end
360
+
361
+ end
362
+
363
+ end
364
+
302
365
  describe "#limit" do
303
366
 
304
367
  context "when value provided" do
@@ -325,6 +388,116 @@ describe Mongoid::Criteria do
325
388
 
326
389
  end
327
390
 
391
+ describe "#merge" do
392
+
393
+ before do
394
+ @criteria.where(:title => "Sir", :age => 30).skip(40).limit(20)
395
+ end
396
+
397
+ context "with another criteria" do
398
+
399
+ context "when the other has a selector and options" do
400
+
401
+ before do
402
+ @other = Mongoid::Criteria.new(Person)
403
+ @other.where(:name => "Chloe").order_by([[:name, :asc]])
404
+ @selector = { :title => "Sir", :age => 30, :name => "Chloe" }
405
+ @options = { :skip => 40, :limit => 20, :sort => [[:name, :asc]] }
406
+ end
407
+
408
+ it "merges the selector and options hashes together" do
409
+ @criteria.merge(@other)
410
+ @criteria.selector.should == @selector
411
+ @criteria.options.should == @options
412
+ end
413
+
414
+ end
415
+
416
+ context "when the other has no selector or options" do
417
+
418
+ before do
419
+ @other = Mongoid::Criteria.new(Person)
420
+ @selector = { :title => "Sir", :age => 30 }
421
+ @options = { :skip => 40, :limit => 20 }
422
+ end
423
+
424
+ it "merges the selector and options hashes together" do
425
+ @criteria.merge(@other)
426
+ @criteria.selector.should == @selector
427
+ @criteria.options.should == @options
428
+ end
429
+ end
430
+
431
+ end
432
+
433
+ context "with a hash" do
434
+
435
+ context "when hash has values" do
436
+
437
+ before do
438
+ @hash = { :conditions => { :name => "Rebecca" }, :sort => [[:name, :desc]] }
439
+ @selector = { :title => "Sir", :age => 30, :name => "Rebecca" }
440
+ @options = { :skip => 40, :limit => 20, :sort => [[:name, :desc]] }
441
+ @criteria.merge(@hash)
442
+ end
443
+
444
+ it "merges the conditions with the selector" do
445
+ @criteria.selector.should == @selector
446
+ end
447
+
448
+ it "merges all valid other values into the options" do
449
+ @criteria.options.should == @options
450
+ end
451
+
452
+ end
453
+
454
+ context "when hash is empty" do
455
+
456
+ before do
457
+ @hash = {}
458
+ @selector = { :title => "Sir", :age => 30 }
459
+ @options = { :skip => 40, :limit => 20 }
460
+ end
461
+
462
+ it "merges nothing" do
463
+ @criteria.merge(@hash)
464
+ @criteria.selector.should == @selector
465
+ @criteria.options.should == @options
466
+ end
467
+
468
+ end
469
+
470
+ end
471
+
472
+ end
473
+
474
+ describe "#method_missing" do
475
+
476
+ before do
477
+ @criteria = Mongoid::Criteria.new(Person)
478
+ @criteria.where(:title => "Sir")
479
+ end
480
+
481
+ it "merges the criteria with the next one" do
482
+ @new_criteria = @criteria.accepted
483
+ @new_criteria.selector.should == { :title => "Sir", :terms => true }
484
+ end
485
+
486
+ context "chaining more than one scope" do
487
+
488
+ before do
489
+ @criteria = Person.accepted.old.knight
490
+ end
491
+
492
+ it "returns the final merged criteria" do
493
+ @criteria.selector.should ==
494
+ { :title => "Sir", :terms => true, :age => { "$gt" => 50 } }
495
+ end
496
+
497
+ end
498
+
499
+ end
500
+
328
501
  describe "#not_in" do
329
502
 
330
503
  it "adds the exclusion to the selector" do
@@ -343,7 +516,7 @@ describe Mongoid::Criteria do
343
516
  context "when the per_page option exists" do
344
517
 
345
518
  before do
346
- @criteria = Mongoid::Criteria.new(:all).extras({ :per_page => 20, :page => 3 })
519
+ @criteria = Mongoid::Criteria.new(Person).extras({ :per_page => 20, :page => 3 })
347
520
  end
348
521
 
349
522
  it "returns the per_page option" do
@@ -355,7 +528,7 @@ describe Mongoid::Criteria do
355
528
  context "when the skip option exists" do
356
529
 
357
530
  before do
358
- @criteria = Mongoid::Criteria.new(:all).extras({ :skip => 20 })
531
+ @criteria = Mongoid::Criteria.new(Person).extras({ :skip => 20 })
359
532
  end
360
533
 
361
534
  it "returns the skip option" do
@@ -369,7 +542,7 @@ describe Mongoid::Criteria do
369
542
  context "when page option exists" do
370
543
 
371
544
  before do
372
- @criteria = Mongoid::Criteria.new(:all).extras({ :page => 2 })
545
+ @criteria = Mongoid::Criteria.new(Person).extras({ :page => 2 })
373
546
  end
374
547
 
375
548
  it "adds the skip option to the options and returns it" do
@@ -382,7 +555,7 @@ describe Mongoid::Criteria do
382
555
  context "when page option does not exist" do
383
556
 
384
557
  before do
385
- @criteria = Mongoid::Criteria.new(:all)
558
+ @criteria = Mongoid::Criteria.new(Person)
386
559
  end
387
560
 
388
561
  it "returns nil" do
@@ -396,6 +569,40 @@ describe Mongoid::Criteria do
396
569
 
397
570
  end
398
571
 
572
+ describe "#one" do
573
+
574
+ context "when documents exist" do
575
+
576
+ before do
577
+ @collection = mock
578
+ Person.expects(:collection).returns(@collection)
579
+ @collection.expects(:find_one).with(@criteria.selector, @criteria.options).returns({ :title => "Sir" })
580
+ end
581
+
582
+ it "calls find on the collection with the selector and options" do
583
+ criteria = Mongoid::Criteria.new(Person)
584
+ criteria.one.should be_a_kind_of(Person)
585
+ end
586
+
587
+ end
588
+
589
+ context "when no documents exist" do
590
+
591
+ before do
592
+ @collection = mock
593
+ Person.expects(:collection).returns(@collection)
594
+ @collection.expects(:find_one).with(@criteria.selector, @criteria.options).returns(nil)
595
+ end
596
+
597
+ it "returns nil" do
598
+ criteria = Mongoid::Criteria.new(Person)
599
+ criteria.one.should be_nil
600
+ end
601
+
602
+ end
603
+
604
+ end
605
+
399
606
  describe "#order_by" do
400
607
 
401
608
  context "when field names and direction specified" do
@@ -418,7 +625,7 @@ describe Mongoid::Criteria do
418
625
  context "when the page option exists" do
419
626
 
420
627
  before do
421
- @criteria = Mongoid::Criteria.new(:all).extras({ :page => 5 })
628
+ @criteria = Mongoid::Criteria.new(Person).extras({ :page => 5 })
422
629
  end
423
630
 
424
631
  it "returns the page option" do
@@ -430,7 +637,7 @@ describe Mongoid::Criteria do
430
637
  context "when the page option does not exist" do
431
638
 
432
639
  before do
433
- @criteria = Mongoid::Criteria.new(:all)
640
+ @criteria = Mongoid::Criteria.new(Person)
434
641
  end
435
642
 
436
643
  it "returns 1" do
@@ -463,7 +670,7 @@ describe Mongoid::Criteria do
463
670
  context "when the per_page option exists" do
464
671
 
465
672
  before do
466
- @criteria = Mongoid::Criteria.new(:all).extras({ :per_page => 10 })
673
+ @criteria = Mongoid::Criteria.new(Person).extras({ :per_page => 10 })
467
674
  end
468
675
 
469
676
  it "returns the per_page option" do
@@ -475,7 +682,7 @@ describe Mongoid::Criteria do
475
682
  context "when the per_page option does not exist" do
476
683
 
477
684
  before do
478
- @criteria = Mongoid::Criteria.new(:all)
685
+ @criteria = Mongoid::Criteria.new(Person)
479
686
  end
480
687
 
481
688
  it "returns 1" do
@@ -542,34 +749,35 @@ describe Mongoid::Criteria do
542
749
 
543
750
  context "with a single argument" do
544
751
 
545
- it "creates a criteria for an object id" do
546
- id = Mongo::ObjectID.new.to_s
547
- criteria = Mongoid::Criteria.translate(id)
548
- criteria.selector.should == { :_id => id }
752
+ before do
753
+ @id = Mongo::ObjectID.new.to_s
754
+ @document = stub
755
+ @criteria = mock
756
+ Mongoid::Criteria.expects(:new).returns(@criteria)
757
+ @criteria.expects(:id).with(@id).returns(@criteria)
758
+ @criteria.expects(:one).returns(@document)
549
759
  end
550
760
 
551
761
  it "creates a criteria for a string" do
552
- id = Mongo::ObjectID.new.to_s
553
- criteria = Mongoid::Criteria.translate(id)
554
- criteria.selector.should == { :_id => id }
762
+ Mongoid::Criteria.translate(Person, @id)
555
763
  end
556
764
 
557
765
  end
558
766
 
559
767
  context "multiple arguments" do
560
768
 
561
- context "when :first, :conditions => {}" do
769
+ context "when Person, :conditions => {}" do
562
770
 
563
771
  before do
564
- @criteria = Mongoid::Criteria.translate(:first, :conditions => { :title => "Test" })
772
+ @criteria = Mongoid::Criteria.translate(Person, :conditions => { :title => "Test" })
565
773
  end
566
774
 
567
775
  it "returns a criteria with a selector from the conditions" do
568
776
  @criteria.selector.should == { :title => "Test" }
569
777
  end
570
778
 
571
- it "returns a criteria with type :first" do
572
- @criteria.type.should == :first
779
+ it "returns a criteria with klass Person" do
780
+ @criteria.klass.should == Person
573
781
  end
574
782
 
575
783
  end
@@ -577,15 +785,15 @@ describe Mongoid::Criteria do
577
785
  context "when :all, :conditions => {}" do
578
786
 
579
787
  before do
580
- @criteria = Mongoid::Criteria.translate(:all, :conditions => { :title => "Test" })
788
+ @criteria = Mongoid::Criteria.translate(Person, :conditions => { :title => "Test" })
581
789
  end
582
790
 
583
791
  it "returns a criteria with a selector from the conditions" do
584
792
  @criteria.selector.should == { :title => "Test" }
585
793
  end
586
794
 
587
- it "returns a criteria with type :all" do
588
- @criteria.type.should == :all
795
+ it "returns a criteria with klass Person" do
796
+ @criteria.klass.should == Person
589
797
  end
590
798
 
591
799
  end
@@ -593,23 +801,22 @@ describe Mongoid::Criteria do
593
801
  context "when :last, :conditions => {}" do
594
802
 
595
803
  before do
596
- @criteria = Mongoid::Criteria.translate(:last, :conditions => { :title => "Test" })
804
+ @criteria = Mongoid::Criteria.translate(Person, :conditions => { :title => "Test" })
597
805
  end
598
806
 
599
807
  it "returns a criteria with a selector from the conditions" do
600
808
  @criteria.selector.should == { :title => "Test" }
601
809
  end
602
810
 
603
- it "returns a criteria with type :last" do
604
- @criteria.type.should == :last
811
+ it "returns a criteria with klass Person" do
812
+ @criteria.klass.should == Person
605
813
  end
606
-
607
814
  end
608
815
 
609
816
  context "when options are provided" do
610
817
 
611
818
  before do
612
- @criteria = Mongoid::Criteria.translate(:last, :conditions => { :title => "Test" }, :skip => 10)
819
+ @criteria = Mongoid::Criteria.translate(Person, :conditions => { :title => "Test" }, :skip => 10)
613
820
  end
614
821
 
615
822
  it "adds the criteria and the options" do