mongoid 1.2.6 → 1.2.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. data/VERSION +1 -1
  2. data/lib/mongoid.rb +1 -0
  3. data/lib/mongoid/associations.rb +1 -1
  4. data/lib/mongoid/attributes.rb +1 -0
  5. data/lib/mongoid/collection.rb +1 -1
  6. data/lib/mongoid/commands.rb +1 -1
  7. data/lib/mongoid/commands/delete_all.rb +2 -1
  8. data/lib/mongoid/commands/destroy_all.rb +1 -1
  9. data/lib/mongoid/components.rb +1 -0
  10. data/lib/mongoid/config.rb +3 -1
  11. data/lib/mongoid/contexts.rb +21 -0
  12. data/lib/mongoid/contexts/enumerable.rb +15 -12
  13. data/lib/mongoid/contexts/ids.rb +25 -0
  14. data/lib/mongoid/contexts/mongo.rb +25 -23
  15. data/lib/mongoid/contexts/paging.rb +2 -2
  16. data/lib/mongoid/criteria.rb +5 -43
  17. data/lib/mongoid/document.rb +1 -0
  18. data/lib/mongoid/enslavement.rb +38 -0
  19. data/lib/mongoid/fields.rb +5 -2
  20. data/lib/mongoid/identity.rb +7 -1
  21. data/lib/mongoid/named_scope.rb +2 -0
  22. data/mongoid.gemspec +8 -2
  23. data/spec/integration/mongoid/commands_spec.rb +2 -2
  24. data/spec/integration/mongoid/contexts/enumerable_spec.rb +13 -0
  25. data/spec/integration/mongoid/criteria_spec.rb +2 -2
  26. data/spec/integration/mongoid/document_spec.rb +5 -1
  27. data/spec/integration/mongoid/finders_spec.rb +85 -28
  28. data/spec/models/person.rb +1 -0
  29. data/spec/unit/mongoid/associations_spec.rb +12 -0
  30. data/spec/unit/mongoid/attributes_spec.rb +60 -51
  31. data/spec/unit/mongoid/collection_spec.rb +30 -0
  32. data/spec/unit/mongoid/commands/delete_all_spec.rb +3 -3
  33. data/spec/unit/mongoid/commands_spec.rb +16 -0
  34. data/spec/unit/mongoid/config_spec.rb +7 -0
  35. data/spec/unit/mongoid/contexts/enumerable_spec.rb +151 -11
  36. data/spec/unit/mongoid/contexts/mongo_spec.rb +168 -42
  37. data/spec/unit/mongoid/contexts_spec.rb +25 -0
  38. data/spec/unit/mongoid/criteria_spec.rb +49 -75
  39. data/spec/unit/mongoid/criterion/exclusion_spec.rb +3 -13
  40. data/spec/unit/mongoid/criterion/inclusion_spec.rb +17 -19
  41. data/spec/unit/mongoid/criterion/optional_spec.rb +25 -8
  42. data/spec/unit/mongoid/document_spec.rb +4 -0
  43. data/spec/unit/mongoid/enslavement_spec.rb +63 -0
  44. data/spec/unit/mongoid/extensions/array/conversions_spec.rb +2 -2
  45. data/spec/unit/mongoid/extensions/object/conversions_spec.rb +2 -2
  46. data/spec/unit/mongoid/extensions/proc/scoping_spec.rb +1 -1
  47. data/spec/unit/mongoid/fields_spec.rb +10 -0
  48. data/spec/unit/mongoid/finders_spec.rb +1 -1
  49. data/spec/unit/mongoid/identity_spec.rb +23 -3
  50. data/spec/unit/mongoid/named_scope_spec.rb +15 -2
  51. data/spec/unit/mongoid/scope_spec.rb +1 -1
  52. metadata +8 -2
@@ -40,6 +40,36 @@ describe Mongoid::Collection do
40
40
  end
41
41
  end
42
42
 
43
+ describe "#directed" do
44
+
45
+ before do
46
+ slaves.expects(:empty?).returns(false)
47
+ end
48
+
49
+ context "when an enslave option is not passed" do
50
+
51
+ before do
52
+ Person.enslave
53
+ end
54
+
55
+ after do
56
+ Person.enslaved = false
57
+ end
58
+
59
+ it "uses the default" do
60
+ collection.directed.should == slaves
61
+ end
62
+ end
63
+
64
+ context "when an enslave option is passed" do
65
+
66
+ it "overwrites the default" do
67
+ collection.directed(:enslave => true).should == slaves
68
+ end
69
+ end
70
+
71
+ end
72
+
43
73
  describe "#find" do
44
74
 
45
75
  before do
@@ -19,7 +19,7 @@ describe Mongoid::Commands::DeleteAll do
19
19
 
20
20
  it "deletes each document that the criteria finds" do
21
21
  @klass.expects(:collection).returns(@collection)
22
- @collection.expects(:remove).with(@conditions[:conditions].merge(:_type => "Person"))
22
+ @collection.expects(:remove).with(@conditions[:conditions].merge(:_type => "Person"), :safe => true)
23
23
  Mongoid::Commands::DeleteAll.execute(@klass, @conditions)
24
24
  end
25
25
 
@@ -33,7 +33,7 @@ describe Mongoid::Commands::DeleteAll do
33
33
 
34
34
  it "drops the collection" do
35
35
  @klass.expects(:collection).returns(@collection)
36
- @collection.expects(:remove).with(:_type => "Person")
36
+ @collection.expects(:remove).with({ :_type => "Person" }, { :safe => true })
37
37
  Mongoid::Commands::DeleteAll.execute(@klass)
38
38
  end
39
39
 
@@ -47,7 +47,7 @@ describe Mongoid::Commands::DeleteAll do
47
47
 
48
48
  it "drops the collection" do
49
49
  @klass.expects(:collection).returns(@collection)
50
- @collection.expects(:remove).with(:_type => "Person")
50
+ @collection.expects(:remove).with({ :_type => "Person" }, { :safe => true })
51
51
  Mongoid::Commands::DeleteAll.execute(@klass, {})
52
52
  end
53
53
 
@@ -37,6 +37,22 @@ describe Mongoid::Commands do
37
37
  @person = Person.new
38
38
  end
39
39
 
40
+ context "when validation fails" do
41
+
42
+ it "it raises an error" do
43
+ Mongoid::Commands::Save.expects(:execute).with(@person, true).returns(false)
44
+ @person.save.should be_false
45
+ end
46
+
47
+ it "should run callback before_create and no after_create" do
48
+ @person.expects(:run_callbacks).with(:before_create)
49
+ Mongoid::Commands::Save.expects(:execute).with(@person, true).returns(false)
50
+ @person.expects(:run_callbacks).with(:after_create).never
51
+ @person.save.should be_false
52
+ end
53
+
54
+ end
55
+
40
56
  it "delegates to the save command" do
41
57
  Mongoid::Commands::Save.expects(:execute).with(@person, true).returns(true)
42
58
  @person.save
@@ -155,4 +155,11 @@ describe Mongoid::Config do
155
155
 
156
156
  end
157
157
 
158
+ describe "#use_object_ids" do
159
+
160
+ it "defaults to false" do
161
+ config.use_object_ids.should == false
162
+ end
163
+ end
164
+
158
165
  end
@@ -8,9 +8,10 @@ describe Mongoid::Contexts::Enumerable do
8
8
  @melbourne = Address.new(:number => 20, :street => "Bourke Street")
9
9
  @new_york = Address.new(:number => 20, :street => "Broadway")
10
10
  @docs = [ @london, @shanghai, @melbourne, @new_york ]
11
- @selector = { :street => "Bourke Street" }
12
- @options = { :fields => [ :number ] }
13
- @context = Mongoid::Contexts::Enumerable.new(@selector, @options, @docs)
11
+ @criteria = Mongoid::Criteria.new(Address)
12
+ @criteria.documents = @docs
13
+ @criteria.where(:street => "Bourke Street").only(:number)
14
+ @context = Mongoid::Contexts::Enumerable.new(@criteria)
14
15
  end
15
16
 
16
17
  describe "#aggregate" do
@@ -40,6 +41,11 @@ describe Mongoid::Contexts::Enumerable do
40
41
 
41
42
  describe "#execute" do
42
43
 
44
+ before do
45
+ @criteria = Mongoid::Criteria.new(Address)
46
+ @criteria.documents = @docs
47
+ end
48
+
43
49
  it "returns the matching documents from the array" do
44
50
  @context.execute.should == [ @melbourne ]
45
51
  end
@@ -47,7 +53,8 @@ describe Mongoid::Contexts::Enumerable do
47
53
  context "when selector is empty" do
48
54
 
49
55
  before do
50
- @context = Mongoid::Contexts::Enumerable.new({}, @options, @docs)
56
+ @criteria.only(:number)
57
+ @context = Mongoid::Contexts::Enumerable.new(@criteria)
51
58
  end
52
59
 
53
60
  it "returns all the documents" do
@@ -58,8 +65,8 @@ describe Mongoid::Contexts::Enumerable do
58
65
  context "when skip and limit are in the options" do
59
66
 
60
67
  before do
61
- @options = { :skip => 2, :limit => 2 }
62
- @context = Mongoid::Contexts::Enumerable.new({}, @options, @docs)
68
+ @criteria.skip(2).limit(2)
69
+ @context = Mongoid::Contexts::Enumerable.new(@criteria)
63
70
  end
64
71
 
65
72
  it "properly narrows down the matching results" do
@@ -67,6 +74,19 @@ describe Mongoid::Contexts::Enumerable do
67
74
  end
68
75
  end
69
76
 
77
+ context "when limit is set without skip in the options" do
78
+
79
+ before do
80
+ @criteria.limit(2)
81
+ @context = Mongoid::Contexts::Enumerable.new(@criteria)
82
+ end
83
+
84
+ it "properly narrows down the matching results" do
85
+ @context.execute.size.should == 2
86
+ end
87
+
88
+ end
89
+
70
90
  end
71
91
 
72
92
  describe "#first" do
@@ -105,7 +125,10 @@ describe Mongoid::Contexts::Enumerable do
105
125
  let(:documents) { [stub] }
106
126
 
107
127
  before do
108
- @context = Mongoid::Contexts::Enumerable.new(selector, options, documents)
128
+ @criteria = Mongoid::Criteria.new(Address)
129
+ @criteria.documents = documents
130
+ @criteria.where(selector).skip(20)
131
+ @context = Mongoid::Contexts::Enumerable.new(@criteria)
109
132
  end
110
133
 
111
134
  it "sets the selector" do
@@ -160,7 +183,8 @@ describe Mongoid::Contexts::Enumerable do
160
183
 
161
184
  before do
162
185
  @criteria = Mongoid::Criteria.new(Person).extras({ :page => 5 })
163
- @context = Mongoid::Contexts::Enumerable.new({}, @criteria.options, [])
186
+ @criteria.documents = []
187
+ @context = Mongoid::Contexts::Enumerable.new(@criteria)
164
188
  end
165
189
 
166
190
  it "returns the page option" do
@@ -173,7 +197,8 @@ describe Mongoid::Contexts::Enumerable do
173
197
 
174
198
  before do
175
199
  @criteria = Mongoid::Criteria.new(Person)
176
- @context = Mongoid::Contexts::Enumerable.new({}, @criteria.options, [])
200
+ @criteria.documents = []
201
+ @context = Mongoid::Contexts::Enumerable.new(@criteria)
177
202
  end
178
203
 
179
204
  it "returns 1" do
@@ -188,7 +213,7 @@ describe Mongoid::Contexts::Enumerable do
188
213
 
189
214
  before do
190
215
  @criteria = Person.criteria.skip(2).limit(2)
191
- @context = Mongoid::Contexts::Enumerable.new({}, @criteria.options, @docs)
216
+ @context = Mongoid::Contexts::Enumerable.new(@criteria)
192
217
  @results = @context.paginate
193
218
  end
194
219
 
@@ -212,7 +237,9 @@ describe Mongoid::Contexts::Enumerable do
212
237
  context "when a limit option does not exist" do
213
238
 
214
239
  before do
215
- @context = Mongoid::Contexts::Enumerable.new({}, { :limit => 50 }, [])
240
+ @criteria = Person.criteria.limit(50)
241
+ @criteria.documents = []
242
+ @context = Mongoid::Contexts::Enumerable.new(@criteria)
216
243
  end
217
244
 
218
245
  it "returns the limit" do
@@ -231,4 +258,117 @@ describe Mongoid::Contexts::Enumerable do
231
258
 
232
259
  end
233
260
 
261
+ context "#id_criteria" do
262
+
263
+ let(:criteria) do
264
+ criteria = Mongoid::Criteria.new(Address)
265
+ criteria.documents = []
266
+ criteria
267
+ end
268
+ let(:context) { criteria.context }
269
+
270
+ context "with a single argument" do
271
+
272
+ let(:id) { Mongo::ObjectID.new.to_s }
273
+
274
+ before do
275
+ criteria.expects(:id).with(id).returns(criteria)
276
+ end
277
+
278
+ context "when the document is found" do
279
+
280
+ let(:document) { stub }
281
+
282
+ it "returns a matching document" do
283
+ context.expects(:one).returns(document)
284
+ document.expects(:blank? => false)
285
+ context.id_criteria(id).should == document
286
+ end
287
+
288
+ end
289
+
290
+ context "when the document is not found" do
291
+
292
+ it "raises an error" do
293
+ context.expects(:one).returns(nil)
294
+ lambda { context.id_criteria(id) }.should raise_error
295
+ end
296
+
297
+ end
298
+
299
+ end
300
+
301
+ context "multiple arguments" do
302
+
303
+ context "when an array of ids" do
304
+
305
+ let(:ids) do
306
+ (0..2).inject([]) { |ary, i| ary << Mongo::ObjectID.new.to_s }
307
+ end
308
+
309
+ context "when documents are found" do
310
+
311
+ let(:docs) do
312
+ (0..2).inject([]) { |ary, i| ary << stub }
313
+ end
314
+
315
+ before do
316
+ criteria.expects(:id).with(ids).returns(criteria)
317
+ end
318
+
319
+ it "returns matching documents" do
320
+ context.expects(:execute).returns(docs)
321
+ context.id_criteria(ids).should == docs
322
+ end
323
+
324
+ end
325
+
326
+ context "when documents are not found" do
327
+
328
+ it "raises an error" do
329
+ context.expects(:execute).returns([])
330
+ lambda { context.id_criteria(ids) }.should raise_error
331
+ end
332
+
333
+ end
334
+
335
+ end
336
+
337
+ context "when an array of object ids" do
338
+
339
+ let(:ids) do
340
+ (0..2).inject([]) { |ary, i| ary << Mongo::ObjectID.new }
341
+ end
342
+
343
+ context "when documents are found" do
344
+
345
+ let(:docs) do
346
+ (0..2).inject([]) { |ary, i| ary << stub }
347
+ end
348
+
349
+ before do
350
+ criteria.expects(:id).with(ids).returns(criteria)
351
+ end
352
+
353
+ it "returns matching documents" do
354
+ context.expects(:execute).returns(docs)
355
+ context.id_criteria(ids).should == docs
356
+ end
357
+
358
+ end
359
+
360
+ context "when documents are not found" do
361
+
362
+ it "raises an error" do
363
+ context.expects(:execute).returns([])
364
+ lambda { context.id_criteria(ids) }.should raise_error
365
+ end
366
+
367
+ end
368
+
369
+ end
370
+ end
371
+
372
+ end
373
+
234
374
  end
@@ -5,9 +5,9 @@ describe Mongoid::Contexts::Mongo do
5
5
  describe "#aggregate" do
6
6
 
7
7
  before do
8
- @selector = {}
9
- @options = { :fields => [:field1] }
10
- @context = Mongoid::Contexts::Mongo.new(@selector, @options, Person)
8
+ @criteria = Mongoid::Criteria.new(Person)
9
+ @criteria.only(:field1)
10
+ @context = Mongoid::Contexts::Mongo.new(@criteria)
11
11
  end
12
12
 
13
13
  context "when klass not provided" do
@@ -19,7 +19,7 @@ describe Mongoid::Contexts::Mongo do
19
19
  end
20
20
 
21
21
  it "calls group on the collection with the aggregate js" do
22
- @collection.expects(:group).with([:field1], {}, {:count => 0}, @reduce, true)
22
+ @collection.expects(:group).with([:field1], {:_type => {'$in' => ['Doctor', 'Person']}}, {:count => 0}, @reduce, true)
23
23
  @context.aggregate
24
24
  end
25
25
 
@@ -30,9 +30,9 @@ describe Mongoid::Contexts::Mongo do
30
30
  describe "#count" do
31
31
 
32
32
  before do
33
- @selector = { :_type => { "$in" => ["Doctor", "Person"] }, :test => "Testing" }
34
- @options = {}
35
- @context = Mongoid::Contexts::Mongo.new(@selector, @options, Person)
33
+ @criteria = Mongoid::Criteria.new(Person)
34
+ @criteria.where(:test => 'Testing')
35
+ @context = Mongoid::Contexts::Mongo.new(@criteria)
36
36
  end
37
37
 
38
38
  context "when criteria has not been executed" do
@@ -56,7 +56,7 @@ describe Mongoid::Contexts::Mongo do
56
56
  end
57
57
 
58
58
  it "returns the count from the cursor without creating the documents" do
59
- @collection.expects(:find).with(@selector, {}).returns(@cursor)
59
+ @collection.expects(:find).with(@criteria.selector, {}).returns(@cursor)
60
60
  @cursor.expects(:count).returns(10)
61
61
  @context.count.should == 10
62
62
  end
@@ -74,7 +74,9 @@ describe Mongoid::Contexts::Mongo do
74
74
  @cursor = stub(:count => 500)
75
75
  @collection = mock
76
76
  @klass = stub(:collection => @collection, :hereditary => false, :instantiate => @person)
77
- @context = Mongoid::Contexts::Mongo.new(selector, options, @klass)
77
+ @criteria = Mongoid::Criteria.new(@klass)
78
+ @criteria.where(selector).skip(20)
79
+ @context = Mongoid::Contexts::Mongo.new(@criteria)
78
80
  end
79
81
 
80
82
  it "calls find on the collection" do
@@ -97,7 +99,7 @@ describe Mongoid::Contexts::Mongo do
97
99
  context "when _type not in the field list" do
98
100
 
99
101
  before do
100
- options[:fields] = [ :title ]
102
+ @criteria.only(:title)
101
103
  @expected_options = { :skip => 20, :fields => [ :title, :_type ] }
102
104
  end
103
105
 
@@ -115,10 +117,10 @@ describe Mongoid::Contexts::Mongo do
115
117
  describe "#group" do
116
118
 
117
119
  before do
118
- @selector = { :_type => { "$in" => ["Doctor", "Person"] } }
119
- @options = { :fields => [ :field1 ] }
120
+ @criteria = Mongoid::Criteria.new(Person)
121
+ @criteria.only(:field1)
120
122
  @grouping = [{ "title" => "Sir", "group" => [{ "title" => "Sir", "age" => 30, "_type" => "Person" }] }]
121
- @context = Mongoid::Contexts::Mongo.new(@selector, @options, Person)
123
+ @context = Mongoid::Contexts::Mongo.new(@criteria)
122
124
  end
123
125
 
124
126
  context "when klass provided" do
@@ -130,7 +132,13 @@ describe Mongoid::Contexts::Mongo do
130
132
  end
131
133
 
132
134
  it "calls group on the collection with the aggregate js" do
133
- @collection.expects(:group).with([:field1], {:_type => { "$in" => ["Doctor", "Person"] }}, {:group => []}, @reduce, true).returns(@grouping)
135
+ @collection.expects(:group).with(
136
+ [:field1],
137
+ {:_type => { "$in" => ["Doctor", "Person"] }},
138
+ {:group => []},
139
+ @reduce,
140
+ true
141
+ ).returns(@grouping)
134
142
  @context.group
135
143
  end
136
144
 
@@ -145,11 +153,13 @@ describe Mongoid::Contexts::Mongo do
145
153
  let(:klass) { Person }
146
154
 
147
155
  before do
148
- @context = Mongoid::Contexts::Mongo.new(selector, options, klass)
156
+ @criteria = Mongoid::Criteria.new(klass)
157
+ @criteria.where(selector).skip(20)
158
+ @context = Mongoid::Contexts::Mongo.new(@criteria)
149
159
  end
150
160
 
151
161
  it "sets the selector" do
152
- @context.selector.should == selector
162
+ @context.selector.should == @criteria.selector
153
163
  end
154
164
 
155
165
  it "sets the options" do
@@ -160,6 +170,9 @@ describe Mongoid::Contexts::Mongo do
160
170
  @context.klass.should == klass
161
171
  end
162
172
 
173
+ it "set the selector to query across the _type of the Criteria's klass when it is hereditary" do
174
+ @context.selector[:_type].should == {'$in' => Person._types}
175
+ end
163
176
  end
164
177
 
165
178
  describe "#last" do
@@ -172,10 +185,10 @@ describe Mongoid::Contexts::Mongo do
172
185
  context "when documents exist" do
173
186
 
174
187
  before do
175
- @selector = {}
176
- @options = { :sort => [[:title, :asc]] }
177
- @context = Mongoid::Contexts::Mongo.new(@selector, @options, Person)
178
- @collection.expects(:find_one).with(@selector, { :sort => [[:title, :desc]] }).returns(
188
+ @criteria = Mongoid::Criteria.new(Person)
189
+ @criteria.order_by([[:title, :asc]])
190
+ @context = Mongoid::Contexts::Mongo.new(@criteria)
191
+ @collection.expects(:find_one).with({:_type => {'$in' => ['Doctor', 'Person']}}, { :sort => [[:title, :desc]] }).returns(
179
192
  { "title" => "Sir", "_type" => "Person" }
180
193
  )
181
194
  end
@@ -189,10 +202,10 @@ describe Mongoid::Contexts::Mongo do
189
202
  context "when no documents exist" do
190
203
 
191
204
  before do
192
- @selector = {}
193
- @options = { :sort => [[:_id, :asc]] }
194
- @context = Mongoid::Contexts::Mongo.new(@selector, @options, Person)
195
- @collection.expects(:find_one).with(@selector, { :sort => [[:_id, :desc]] }).returns(nil)
205
+ @criteria = Mongoid::Criteria.new(Person)
206
+ @criteria.order_by([[:_id, :asc]])
207
+ @context = Mongoid::Contexts::Mongo.new(@criteria)
208
+ @collection.expects(:find_one).with({:_type => {'$in' => ['Doctor', 'Person']}}, { :sort => [[:_id, :desc]] }).returns(nil)
196
209
  end
197
210
 
198
211
  it "returns nil" do
@@ -204,10 +217,10 @@ describe Mongoid::Contexts::Mongo do
204
217
  context "when no sorting options provided" do
205
218
 
206
219
  before do
207
- @selector = {}
208
- @options = { :sort => [[:_id, :asc]] }
209
- @context = Mongoid::Contexts::Mongo.new(@selector, @options, Person)
210
- @collection.expects(:find_one).with(@selector, { :sort => [[:_id, :desc]] }).returns(
220
+ @criteria = Mongoid::Criteria.new(Person)
221
+ @criteria.order_by([[:_id, :asc]])
222
+ @context = Mongoid::Contexts::Mongo.new(@criteria)
223
+ @collection.expects(:find_one).with({:_type => {'$in' => ['Doctor', 'Person']}}, { :sort => [[:_id, :desc]] }).returns(
211
224
  { "title" => "Sir", "_type" => "Person" }
212
225
  )
213
226
  end
@@ -226,13 +239,14 @@ describe Mongoid::Contexts::Mongo do
226
239
  @reduce = Mongoid::Contexts::Mongo::MAX_REDUCE.gsub("[field]", "age")
227
240
  @collection = mock
228
241
  Person.expects(:collection).returns(@collection)
229
- @context = Mongoid::Contexts::Mongo.new({}, {}, Person)
242
+ @criteria = Mongoid::Criteria.new(Person)
243
+ @context = Mongoid::Contexts::Mongo.new(@criteria)
230
244
  end
231
245
 
232
246
  it "calls group on the collection with the aggregate js" do
233
247
  @collection.expects(:group).with(
234
248
  nil,
235
- {},
249
+ {:_type => {'$in' => ['Doctor', 'Person']}},
236
250
  {:max => "start"},
237
251
  @reduce,
238
252
  true
@@ -248,13 +262,14 @@ describe Mongoid::Contexts::Mongo do
248
262
  @reduce = Mongoid::Contexts::Mongo::MIN_REDUCE.gsub("[field]", "age")
249
263
  @collection = mock
250
264
  Person.expects(:collection).returns(@collection)
251
- @context = Mongoid::Contexts::Mongo.new({}, {}, Person)
265
+ @criteria = Mongoid::Criteria.new(Person)
266
+ @context = Mongoid::Contexts::Mongo.new(@criteria)
252
267
  end
253
268
 
254
269
  it "calls group on the collection with the aggregate js" do
255
270
  @collection.expects(:group).with(
256
271
  nil,
257
- {},
272
+ {:_type => {'$in' => ['Doctor', 'Person']}},
258
273
  {:min => "start"},
259
274
  @reduce,
260
275
  true
@@ -269,10 +284,10 @@ describe Mongoid::Contexts::Mongo do
269
284
  context "when documents exist" do
270
285
 
271
286
  before do
272
- @collection = mock
273
287
  Person.expects(:collection).returns(@collection)
274
- @context = Mongoid::Contexts::Mongo.new({}, {}, Person)
275
- @collection.expects(:find_one).with({}, {}).returns(
288
+ @criteria = Mongoid::Criteria.new(Person)
289
+ @context = Mongoid::Contexts::Mongo.new(@criteria)
290
+ @collection.expects(:find_one).with({:_type => {'$in' => ['Doctor', 'Person']}}, {}).returns(
276
291
  { "title"=> "Sir", "_type" => "Person" }
277
292
  )
278
293
  end
@@ -288,8 +303,9 @@ describe Mongoid::Contexts::Mongo do
288
303
  before do
289
304
  @collection = mock
290
305
  Person.expects(:collection).returns(@collection)
291
- @context = Mongoid::Contexts::Mongo.new({}, {}, Person)
292
- @collection.expects(:find_one).with({}, {}).returns(nil)
306
+ @criteria = Mongoid::Criteria.new(Person)
307
+ @context = Mongoid::Contexts::Mongo.new(@criteria)
308
+ @collection.expects(:find_one).with({:_type => {'$in' => ['Doctor', 'Person']}}, {}).returns(nil)
293
309
  end
294
310
 
295
311
  it "returns nil" do
@@ -306,7 +322,7 @@ describe Mongoid::Contexts::Mongo do
306
322
 
307
323
  before do
308
324
  @criteria = Mongoid::Criteria.new(Person).extras({ :page => 5 })
309
- @context = Mongoid::Contexts::Mongo.new({}, @criteria.options, Person)
325
+ @context = Mongoid::Contexts::Mongo.new(@criteria)
310
326
  end
311
327
 
312
328
  it "returns the page option" do
@@ -319,7 +335,7 @@ describe Mongoid::Contexts::Mongo do
319
335
 
320
336
  before do
321
337
  @criteria = Mongoid::Criteria.new(Person)
322
- @context = Mongoid::Contexts::Mongo.new({}, @criteria.options, Person)
338
+ @context = Mongoid::Contexts::Mongo.new(@criteria)
323
339
  end
324
340
 
325
341
  it "returns 1" do
@@ -336,7 +352,7 @@ describe Mongoid::Contexts::Mongo do
336
352
  @collection = mock
337
353
  Person.expects(:collection).returns(@collection)
338
354
  @criteria = Person.where(:_id => "1").skip(60).limit(20)
339
- @context = Mongoid::Contexts::Mongo.new(@criteria.selector, @criteria.options, Person)
355
+ @context = Mongoid::Contexts::Mongo.new(@criteria)
340
356
  @collection.expects(:find).with(
341
357
  {:_type => { "$in" => ["Doctor", "Person"] }, :_id => "1"}, :skip => 60, :limit => 20
342
358
  ).returns([])
@@ -357,14 +373,15 @@ describe Mongoid::Contexts::Mongo do
357
373
  before do
358
374
  @reduce = Mongoid::Contexts::Mongo::SUM_REDUCE.gsub("[field]", "age")
359
375
  @collection = mock
360
- @context = Mongoid::Contexts::Mongo.new({}, {}, Person)
376
+ @criteria = Mongoid::Criteria.new(Person)
377
+ @context = Mongoid::Contexts::Mongo.new(@criteria)
361
378
  Person.expects(:collection).returns(@collection)
362
379
  end
363
380
 
364
381
  it "calls group on the collection with the aggregate js" do
365
382
  @collection.expects(:group).with(
366
383
  nil,
367
- {},
384
+ {:_type => {'$in' => ['Doctor', 'Person']}},
368
385
  {:sum => "start"},
369
386
  @reduce,
370
387
  true
@@ -376,4 +393,113 @@ describe Mongoid::Contexts::Mongo do
376
393
 
377
394
  end
378
395
 
396
+ context "#id_criteria" do
397
+
398
+ let(:criteria) { Mongoid::Criteria.new(Person) }
399
+ let(:context) { criteria.context }
400
+
401
+ context "with a single argument" do
402
+
403
+ let(:id) { Mongo::ObjectID.new.to_s }
404
+
405
+ before do
406
+ criteria.expects(:id).with(id).returns(criteria)
407
+ end
408
+
409
+ context "when the document is found" do
410
+
411
+ let(:document) { stub }
412
+
413
+ it "returns a matching document" do
414
+ context.expects(:one).returns(document)
415
+ document.expects(:blank? => false)
416
+ context.id_criteria(id).should == document
417
+ end
418
+
419
+ end
420
+
421
+ context "when the document is not found" do
422
+
423
+ it "raises an error" do
424
+ context.expects(:one).returns(nil)
425
+ lambda { context.id_criteria(id) }.should raise_error
426
+ end
427
+
428
+ end
429
+
430
+ end
431
+
432
+ context "multiple arguments" do
433
+
434
+ context "when an array of ids" do
435
+
436
+ let(:ids) do
437
+ (0..2).inject([]) { |ary, i| ary << Mongo::ObjectID.new.to_s }
438
+ end
439
+
440
+ context "when documents are found" do
441
+
442
+ let(:docs) do
443
+ (0..2).inject([]) { |ary, i| ary << stub }
444
+ end
445
+
446
+ before do
447
+ criteria.expects(:id).with(ids).returns(criteria)
448
+ end
449
+
450
+ it "returns matching documents" do
451
+ context.expects(:execute).returns(docs)
452
+ context.id_criteria(ids).should == docs
453
+ end
454
+
455
+ end
456
+
457
+ context "when documents are not found" do
458
+
459
+ it "raises an error" do
460
+ context.expects(:execute).returns([])
461
+ lambda { context.id_criteria(ids) }.should raise_error
462
+ end
463
+
464
+ end
465
+
466
+ end
467
+
468
+ context "when an array of object ids" do
469
+
470
+ let(:ids) do
471
+ (0..2).inject([]) { |ary, i| ary << Mongo::ObjectID.new }
472
+ end
473
+
474
+ context "when documents are found" do
475
+
476
+ let(:docs) do
477
+ (0..2).inject([]) { |ary, i| ary << stub }
478
+ end
479
+
480
+ before do
481
+ criteria.expects(:id).with(ids).returns(criteria)
482
+ end
483
+
484
+ it "returns matching documents" do
485
+ context.expects(:execute).returns(docs)
486
+ context.id_criteria(ids).should == docs
487
+ end
488
+
489
+ end
490
+
491
+ context "when documents are not found" do
492
+
493
+ it "raises an error" do
494
+ context.expects(:execute).returns([])
495
+ lambda { context.id_criteria(ids) }.should raise_error
496
+ end
497
+
498
+ end
499
+
500
+ end
501
+ end
502
+
503
+ end
504
+
379
505
  end