mongoid 1.1.3 → 1.1.4

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