mongoid 1.2.6 → 1.2.7

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 (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