mongodoc 0.2.2 → 0.2.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. data/Rakefile +21 -0
  2. data/TODO +6 -1
  3. data/VERSION +1 -1
  4. data/features/finders.feature +1 -1
  5. data/features/mongodoc_base.feature +11 -2
  6. data/features/{named_scopes.feature → scopes.feature} +0 -0
  7. data/features/step_definitions/document_steps.rb +15 -4
  8. data/features/step_definitions/documents.rb +3 -3
  9. data/features/step_definitions/query_steps.rb +17 -14
  10. data/features/step_definitions/{named_scope_steps.rb → scope_steps.rb} +0 -0
  11. data/features/using_criteria.feature +22 -43
  12. data/lib/mongodoc.rb +1 -1
  13. data/lib/mongodoc/associations/collection_proxy.rb +3 -1
  14. data/lib/mongodoc/associations/document_proxy.rb +4 -1
  15. data/lib/mongodoc/associations/hash_proxy.rb +3 -1
  16. data/lib/mongodoc/associations/proxy_base.rb +6 -4
  17. data/lib/mongodoc/attributes.rb +6 -6
  18. data/lib/mongodoc/contexts.rb +24 -0
  19. data/lib/mongodoc/contexts/enumerable.rb +132 -0
  20. data/lib/mongodoc/contexts/mongo.rb +215 -0
  21. data/lib/mongodoc/criteria.rb +36 -479
  22. data/lib/mongodoc/document.rb +3 -2
  23. data/lib/mongodoc/finders.rb +31 -11
  24. data/lib/mongodoc/matchers.rb +35 -0
  25. data/lib/mongodoc/scope.rb +64 -0
  26. data/lib/mongoid/contexts/paging.rb +42 -0
  27. data/lib/mongoid/criteria.rb +264 -0
  28. data/lib/mongoid/criterion/complex.rb +21 -0
  29. data/lib/mongoid/criterion/exclusion.rb +65 -0
  30. data/lib/mongoid/criterion/inclusion.rb +92 -0
  31. data/lib/mongoid/criterion/optional.rb +136 -0
  32. data/lib/mongoid/extensions/hash/criteria_helpers.rb +20 -0
  33. data/lib/mongoid/extensions/symbol/inflections.rb +36 -0
  34. data/lib/mongoid/matchers/all.rb +11 -0
  35. data/lib/mongoid/matchers/default.rb +26 -0
  36. data/lib/mongoid/matchers/exists.rb +13 -0
  37. data/lib/mongoid/matchers/gt.rb +11 -0
  38. data/lib/mongoid/matchers/gte.rb +11 -0
  39. data/lib/mongoid/matchers/in.rb +11 -0
  40. data/lib/mongoid/matchers/lt.rb +11 -0
  41. data/lib/mongoid/matchers/lte.rb +11 -0
  42. data/lib/mongoid/matchers/ne.rb +11 -0
  43. data/lib/mongoid/matchers/nin.rb +11 -0
  44. data/lib/mongoid/matchers/size.rb +11 -0
  45. data/mongodoc.gemspec +39 -9
  46. data/spec/attributes_spec.rb +16 -2
  47. data/spec/contexts/enumerable_spec.rb +335 -0
  48. data/spec/contexts/mongo_spec.rb +148 -0
  49. data/spec/contexts_spec.rb +28 -0
  50. data/spec/criteria_spec.rb +15 -766
  51. data/spec/finders_spec.rb +28 -36
  52. data/spec/matchers_spec.rb +342 -0
  53. data/spec/scope_spec.rb +79 -0
  54. metadata +40 -10
  55. data/features/step_definitions/criteria_steps.rb +0 -42
  56. data/lib/mongodoc/named_scope.rb +0 -68
  57. data/spec/named_scope_spec.rb +0 -82
@@ -0,0 +1,148 @@
1
+ require 'spec_helper'
2
+
3
+ describe "MongoDoc::Contexts::MongoDoc" do
4
+
5
+ class Address
6
+ include MongoDoc::Document
7
+ include MongoDoc::Matchers
8
+
9
+ key :number
10
+ key :street
11
+ end
12
+
13
+ let(:criteria) { Mongoid::Criteria.new(Address) }
14
+ let(:context) { criteria.context }
15
+
16
+ context "#initialize" do
17
+ it "sets the criteria" do
18
+ context.criteria.should == criteria
19
+ end
20
+ end
21
+
22
+ context "#collection" do
23
+ it "delegates to klass" do
24
+ klass = mock('klass', :collection => true)
25
+ context.should_receive(:klass).and_return(klass)
26
+ context.collection
27
+ end
28
+ end
29
+
30
+ context "querying" do
31
+ let(:collection) { stub('collection') }
32
+
33
+ before { context.stub(:collection).and_return(collection) }
34
+
35
+ context "#aggregate" do
36
+ it "uses group with the appropriate JS" do
37
+ collection.should_receive(:group).with(nil, {}, {:count=>0}, MongoDoc::Contexts::Mongo::AGGREGATE_REDUCE, true)
38
+ context.aggregate
39
+ end
40
+ end
41
+
42
+ context "#count" do
43
+ it "uses find and count" do
44
+ result = stub('result')
45
+ result.should_receive(:count)
46
+ collection.should_receive(:find).and_return(result)
47
+ context.count
48
+ end
49
+ end
50
+
51
+ context "#execute" do
52
+ it "uses find" do
53
+ collection.should_receive(:find)
54
+ context.execute
55
+ end
56
+
57
+ it "returns [] if nothing returned from find" do
58
+ collection.stub(:find => nil)
59
+ context.execute.should == []
60
+ end
61
+
62
+ it "returns the cursor if one is returned from find" do
63
+ cursor = stub('cursor')
64
+ collection.stub(:find => cursor)
65
+ context.execute.should == cursor
66
+ end
67
+
68
+ it "memoizes the count if paginating" do
69
+ count = 20
70
+ cursor = stub('cursor', :count => count)
71
+ collection.stub(:find => cursor)
72
+ context.execute
73
+ context.count.should == count
74
+ end
75
+ end
76
+
77
+ context "#group" do
78
+ it "uses group with the appropriate JS" do
79
+ collection.should_receive(:group).with(nil, {}, {:group=>[]}, MongoDoc::Contexts::Mongo::GROUP_REDUCE, true).and_return([])
80
+ context.group
81
+ end
82
+
83
+ it "decodes returned documents" do
84
+ doc = stub('doc')
85
+ collection.stub(:group).and_return([{:group => [doc]}])
86
+ MongoDoc::BSON.should_receive(:decode).and_return(doc)
87
+ context.group
88
+ end
89
+ end
90
+
91
+ context "#id_criteria" do
92
+ it "delegates to one if passed a string or ObjectID" do
93
+ context.should_receive(:one)
94
+ context.id_criteria('id')
95
+ end
96
+
97
+ it "delegates to entries if passed an array" do
98
+ criteria.should_receive(:entries)
99
+ context.id_criteria(['id'])
100
+ end
101
+ end
102
+
103
+ context "#last" do
104
+ it "delegates to find_one" do
105
+ collection.should_receive(:find_one).with({}, {:sort=>[[:_id, :desc]]})
106
+ context.last
107
+ end
108
+ end
109
+
110
+ context "#max" do
111
+ it "delegates to grouped" do
112
+ context.should_receive(:grouped).with(:max, "number", MongoDoc::Contexts::Mongo::MAX_REDUCE)
113
+ context.max(:number)
114
+ end
115
+ end
116
+
117
+ context "#min" do
118
+ it "delegates to grouped" do
119
+ context.should_receive(:grouped).with(:min, "number", MongoDoc::Contexts::Mongo::MIN_REDUCE)
120
+ context.min(:number)
121
+ end
122
+ end
123
+
124
+ context "#one" do
125
+ it "delegates to find_one" do
126
+ collection.should_receive(:find_one).with({}, {})
127
+ context.one
128
+ end
129
+ end
130
+
131
+ context "#sum" do
132
+ it "delegates to grouped" do
133
+ context.should_receive(:grouped).with(:sum, "number", MongoDoc::Contexts::Mongo::SUM_REDUCE)
134
+ context.sum(:number)
135
+ end
136
+ end
137
+
138
+ context "#grouped" do
139
+ it "delegates to group" do
140
+ op = 'op'
141
+ field = 'name'
142
+ reduce = '[field]'
143
+ collection.should_receive(:group).with(nil, {}, {op =>"start"}, field, true).and_return([])
144
+ context.send(:grouped, op, field, reduce)
145
+ end
146
+ end
147
+ end
148
+ end
@@ -0,0 +1,28 @@
1
+ require "spec_helper"
2
+
3
+ describe MongoDoc::Contexts do
4
+
5
+ context ".context_for" do
6
+ let(:criteria) { stub('criteria', :klass => klass) }
7
+
8
+ context "when criteria is for a top-level MongoDoc::Document" do
9
+ let(:klass) { stub('klass', :collection => stub('collection')) }
10
+
11
+ it "creates a MongoDoc context" do
12
+ MongoDoc::Contexts::Mongo.should_receive(:new).with(criteria)
13
+ Mongoid::Contexts.context_for(criteria)
14
+ end
15
+ end
16
+
17
+ context "when criteria is for an embedded MongoDoc::Document" do
18
+ let(:klass) { stub('klass') }
19
+
20
+ it "creates an Enumerable context" do
21
+ MongoDoc::Contexts::Enumerable.should_receive(:new).with(criteria)
22
+ Mongoid::Contexts.context_for(criteria)
23
+ end
24
+ end
25
+ end
26
+
27
+ end
28
+
@@ -1,784 +1,33 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper.rb"))
1
+ require 'spec_helper'
2
2
 
3
3
  describe MongoDoc::Criteria do
4
- class CountryCode
5
- include MongoDoc::Document
6
4
 
7
- key :code
5
+ class CriteriaTest
6
+ extend MongoDoc::Criteria
8
7
  end
9
8
 
10
- class Phone
11
- include MongoDoc::Document
12
-
13
- key :number
14
- has_one :country_code
15
- end
16
-
17
- class Animal
18
- include MongoDoc::Document
19
-
20
- key :name
21
- end
22
-
23
- class Address
24
- include MongoDoc::Document
25
-
26
- key :street
27
- key :city
28
- key :state
29
- key :post_code
30
- end
31
-
32
- class Name
33
- include MongoDoc::Document
34
-
35
- key :first_name
36
- key :last_name
37
- end
38
-
39
- class Person
40
- include MongoDoc::Document
41
-
42
- key :title
43
- key :terms
44
- key :age
45
- key :dob
46
- key :mixed_drink
47
- key :employer_id
48
- key :lunch_time
49
-
50
- has_many :addresses
51
- has_many :phone_numbers, :class_name => "Phone"
52
-
53
- has_one :name
54
- has_one :pet
55
-
56
- def update_addresses
57
- addresses.each_with_index do |address, i|
58
- address.street = "Updated #{i}"
59
- end
60
- end
61
-
62
- def employer=(emp)
63
- self.employer_id = emp.id
64
- end
65
- end
66
-
67
- before do
68
- @criteria = MongoDoc::Criteria.new(Person)
69
- end
70
-
71
- describe "#all" do
72
- it "calls collect" do
73
- @criteria.should_receive(:collect).with(no_args)
74
- @criteria.all
75
- end
76
- end
77
-
78
- describe "#aggregate" do
79
- before do
80
- @reduce = "function(obj, prev) { prev.count++; }"
81
- @collection = mock
82
- Person.should_receive(:collection).and_return(@collection)
83
- end
84
-
85
- it "calls group on the collection with the aggregate js" do
86
- @collection.should_receive(:group).with([:field1], {}, {:count => 0}, @reduce, true)
87
- @criteria.only(:field1).aggregate
88
- end
89
- end
90
-
91
- describe "#every" do
92
-
93
- it "adds the $all query to the selector" do
94
- @criteria.every(:title => ["title1", "title2"])
95
- @criteria.selector.should == { :title => { "$all" => ["title1", "title2"] } }
96
- end
97
-
98
- it "returns self" do
99
- @criteria.every(:title => [ "title1" ]).should == @criteria
100
- end
101
-
102
- end
103
-
104
- describe "including Enumerable" do
105
-
106
- before do
107
- @cursor = stub('cursor').as_null_object
108
- @criteria.stub(:execute).and_return(@cursor)
109
- end
110
-
111
- it "calls each" do
112
- @criteria.should_receive(:each).and_return(@criteria)
113
- @criteria.collect
114
- end
115
-
116
- end
117
-
118
- describe "#count" do
119
-
120
- context "when criteria has not been executed" do
121
-
122
- before do
123
- @count = 27
124
- @collection = mock
125
- @cursor = stub('cursor', :count => @count)
126
- Person.stub(:collection).and_return(@collection)
127
- end
128
-
129
- it "calls through to the collection" do
130
- @collection.should_receive(:find).and_return(@cursor)
131
- @criteria.count
132
- end
133
-
134
- it "returns the count from the cursor" do
135
- @collection.stub(:find).and_return(@cursor)
136
- @criteria.count.should == @count
137
- end
138
-
139
- end
140
-
141
- context "when criteria has been executed" do
142
-
143
- before do
144
- @count = 28
145
- @criteria.instance_variable_set(:@count, @count)
146
- end
147
-
148
- it "returns the count from the cursor without creating the documents" do
149
- @criteria.count.should == @count
150
- end
151
-
152
- end
153
-
154
- end
155
-
156
- describe "#each" do
157
-
158
- before do
159
- @criteria.where(:title => "Sir")
160
- @person = Person.new(:title => "Sir")
161
- @cursor = [@person]
162
- end
163
-
164
- context "when no block given" do
165
- it "executes the criteria" do
166
- @criteria.should_receive(:execute).and_return(@cursor)
167
- @criteria.each
168
- end
169
-
170
- it "has memoized the result of execute" do
171
- @criteria.stub(:execute).and_return(@cursor)
172
- @criteria.each
173
- @criteria.collection.should == @cursor
174
- end
175
-
176
- it "returns self" do
177
- @criteria.stub(:execute).and_return(@cursor)
178
- @criteria.each.should == @criteria
179
- end
180
- end
181
-
182
- context "when a block is given" do
183
- class CursorStub
184
- include Enumerable
185
-
186
- attr_accessor :data
187
-
188
- def each(*args, &block)
189
- data.each(*args, &block)
190
- end
191
- end
192
-
193
- context "when the criteria has not been executed" do
194
- before do
195
- @cursor = CursorStub.new
196
- @cursor.data = [@person]
197
- end
198
-
199
- it "executes the criteria" do
200
- @criteria.should_receive(:execute).and_return(@cursor)
201
- @criteria.each do |person|
202
- person.should == @person
203
- end
204
- end
205
-
206
- it "yields into the block" do
207
- @criteria.stub(:execute).and_return(@cursor)
208
- @criteria.each do |person|
209
- @result = person
210
- end
211
- @result.should == @person
212
- end
213
-
214
- it "has memoized the cursor iteration" do
215
- @criteria.stub(:execute).and_return(@cursor)
216
- @criteria.each do |person|
217
- @result = person
218
- end
219
- @criteria.collection.should == [@person]
220
- end
221
-
222
-
223
- it "returns self" do
224
- @criteria.stub(:execute).and_return(@cursor)
225
- @criteria.each.should == @criteria
226
- end
227
- end
228
-
229
- context "when the criteria has been executed" do
230
- before do
231
- @criteria.stub(:execute).and_return(@cursor)
232
- @criteria.each
233
- end
234
-
235
- it "does not execute the criteria" do
236
- @criteria.should_not_receive(:execute)
237
- @criteria.each do |person|
238
- person.should == @person
239
- end
240
- end
241
-
242
- it "yields into the block" do
243
- @criteria.each do |person|
244
- @result = person
245
- end
246
- @result.should == @person
247
- end
248
-
249
- it "returns self" do
250
- @criteria.each.should == @criteria
251
- end
252
- end
253
- end
254
- end
255
-
256
- describe "#excludes" do
257
-
258
- it "adds the $ne query to the selector" do
259
- @criteria.excludes(:title => "Bad Title", :text => "Bad Text")
260
- @criteria.selector.should == { :title => { "$ne" => "Bad Title"}, :text => { "$ne" => "Bad Text" } }
261
- end
262
-
263
- it "returns self" do
264
- @criteria.excludes(:title => "Bad").should == @criteria
265
- end
266
-
267
- end
268
-
269
- describe "#extras" do
270
-
271
- context "filtering" do
272
-
273
- context "when page is provided" do
274
-
275
- it "sets the limit and skip options" do
276
- @criteria.extras({ :page => "2" })
277
- @criteria.page.should == 2
278
- @criteria.options.should == { :skip => 20, :limit => 20 }
279
- end
280
-
281
- end
282
-
283
- context "when per_page is provided" do
284
-
285
- it "sets the limit and skip options" do
286
- @criteria.extras({ :per_page => 45 })
287
- @criteria.options.should == { :skip => 0, :limit => 45 }
288
- end
289
-
290
- end
291
-
292
- context "when page and per_page both provided" do
293
-
294
- it "sets the limit and skip options" do
295
- @criteria.extras({ :per_page => 30, :page => "4" })
296
- @criteria.options.should == { :skip => 90, :limit => 30 }
297
- @criteria.page.should == 4
298
- end
299
-
300
- end
301
-
302
- end
303
-
304
- it "adds the extras to the options" do
305
- @criteria.extras({ :skip => 10 })
306
- @criteria.options.should == { :skip => 10 }
307
- end
308
-
309
- it "returns self" do
310
- @criteria.extras({}).should == @criteria
311
- end
312
-
313
- it "adds the extras without overwriting existing options" do
314
- @criteria.order_by([:field1])
315
- @criteria.extras({ :skip => 10 })
316
- @criteria.options.should have_key(:sort)
317
- end
318
-
319
- end
320
-
321
- describe "#group" do
322
- before do
323
- @grouping = [{ "title" => "Sir", "group" => [{ "title" => "Sir", "age" => 30 }] }]
324
- @reduce = "function(obj, prev) { prev.group.push(obj); }"
325
- @collection = mock
326
- Person.should_receive(:collection).and_return(@collection)
327
- end
328
-
329
- it "calls group on the collection with the aggregate js" do
330
- @collection.should_receive(:group).with([:field1], {}, {:group => []}, @reduce, true).and_return(@grouping)
331
- @criteria.only(:field1).group
332
- end
333
- end
334
-
335
- describe "#id" do
336
-
337
- it "adds the ObjectID as the _id query to the selector" do
338
- id = Mongo::ObjectID.new
339
- @criteria.id(id)
340
- @criteria.selector.should == { :_id => id }
341
- end
342
-
343
- it "when a string adds ObjectID as the _id query to the selector" do
344
- id = Mongo::ObjectID.new
345
- @criteria.id(id.to_s)
346
- @criteria.selector.should == { :_id => id }
347
- end
348
-
349
- it "returns self" do
350
- id = Mongo::ObjectID.new
351
- @criteria.id(id).should == @criteria
352
- end
353
-
354
- end
355
-
356
- describe "#in" do
357
-
358
- it "adds the $in clause to the selector" do
359
- @criteria.in(:title => ["title1", "title2"], :text => ["test"])
360
- @criteria.selector.should == { :title => { "$in" => ["title1", "title2"] }, :text => { "$in" => ["test"] } }
361
- end
362
-
363
- it "returns self" do
364
- @criteria.in(:title => ["title1"]).should == @criteria
365
- end
366
-
367
- end
368
-
369
- describe "#last" do
370
-
371
- context "when documents exist" do
372
-
373
- before do
374
- @collection = mock
375
- Person.should_receive(:collection).and_return(@collection)
376
- @collection.should_receive(:find_one).with(@criteria.selector, { :sort => [[:title, :desc]] }).and_return(Person.new(:title => "Sir"))
377
- end
378
-
379
- it "calls find on the collection with the selector and sort options reversed" do
380
- @criteria.order_by([[:title, :asc]])
381
- @criteria.last.should be_a_kind_of(Person)
382
- end
383
-
384
- end
385
-
386
- context "when no documents exist" do
387
-
388
- before do
389
- @collection = mock
390
- Person.should_receive(:collection).and_return(@collection)
391
- @collection.should_receive(:find_one).with(@criteria.selector, { :sort => [[:_id, :desc]] }).and_return(nil)
392
- end
393
-
394
- it "returns nil" do
395
- @criteria.last.should be_nil
396
- end
397
-
398
- end
399
-
400
- context "when no sorting options provided" do
401
-
402
- before do
403
- @collection = mock
404
- Person.should_receive(:collection).and_return(@collection)
405
- @collection.should_receive(:find_one).with(@criteria.selector, { :sort => [[:_id, :desc]] }).and_return({ :title => "Sir" })
406
- end
407
-
408
- it "defaults to sort by id" do
409
- @criteria.last
410
- end
411
-
412
- end
413
-
414
- end
415
-
416
- describe "#limit" do
417
-
418
- context "when value provided" do
419
-
420
- it "adds the limit to the options" do
421
- @criteria.limit(100)
422
- @criteria.options.should == { :limit => 100 }
423
- end
424
-
425
- end
426
-
427
- context "when value not provided" do
428
-
429
- it "defaults to 20" do
430
- @criteria.limit
431
- @criteria.options.should == { :limit => 20 }
432
- end
433
-
434
- end
435
-
436
- it "returns self" do
437
- @criteria.limit.should == @criteria
438
- end
439
-
440
- end
441
-
442
- describe "#not_in" do
443
-
444
- it "adds the exclusion to the selector" do
445
- @criteria.not_in(:title => ["title1", "title2"], :text => ["test"])
446
- @criteria.selector.should == { :title => { "$nin" => ["title1", "title2"] }, :text => { "$nin" => ["test"] } }
447
- end
448
-
449
- it "returns self" do
450
- @criteria.not_in(:title => ["title1"]).should == @criteria
451
- end
452
-
453
- end
454
-
455
- describe "#offset" do
456
-
457
- context "when the per_page option exists" do
458
-
459
- before do
460
- @criteria.extras({ :per_page => 20, :page => 3 })
461
- end
462
-
463
- it "returns the per_page option" do
464
- @criteria.offset.should == 40
465
- end
466
-
467
- end
468
-
469
- context "when the skip option exists" do
470
-
471
- before do
472
- @criteria.extras({ :skip => 20 })
473
- end
474
-
475
- it "returns the skip option" do
476
- @criteria.offset.should == 20
477
- end
478
-
479
- end
480
-
481
- context "when no option exists" do
482
-
483
- context "when page option exists" do
484
-
485
- before do
486
- @criteria.extras({ :page => 2 })
487
- end
488
-
489
- it "adds the skip option to the options and returns it" do
490
- @criteria.offset.should == 20
491
- @criteria.options[:skip].should == 20
492
- end
493
-
494
- end
495
-
496
- context "when page option does not exist" do
497
-
498
- it "returns nil" do
499
- @criteria.offset.should be_nil
500
- @criteria.options[:skip].should be_nil
501
- end
502
-
503
- end
504
-
505
- end
506
-
507
- end
508
-
509
- describe "#one" do
510
-
511
- context "when documents exist" do
512
-
513
- before do
514
- @collection = mock
515
- Person.should_receive(:collection).and_return(@collection)
516
- @collection.should_receive(:find_one).with(@criteria.selector, @criteria.options).and_return(Person.new(:title => "Sir"))
517
- end
518
-
519
- it "calls find on the collection with the selector and options" do
520
- @criteria.one.should be_a_kind_of(Person)
521
- end
522
-
523
- end
524
-
525
- context "when no documents exist" do
526
-
527
- before do
528
- @collection = mock
529
- Person.should_receive(:collection).and_return(@collection)
530
- @collection.should_receive(:find_one).with(@criteria.selector, @criteria.options).and_return(nil)
531
- end
532
-
533
- it "returns nil" do
534
- @criteria.one.should be_nil
535
- end
536
-
537
- end
538
-
539
- end
540
-
541
- describe "#order_by" do
542
-
543
- context "when field names and direction specified" do
544
-
545
- it "adds the sort to the options" do
546
- @criteria.order_by([[:title, :asc], [:text, :desc]])
547
- @criteria.options.should == { :sort => [[:title, :asc], [:text, :desc]] }
548
- end
549
-
550
- end
551
-
552
- it "returns self" do
553
- @criteria.order_by.should == @criteria
554
- end
555
-
556
- end
557
-
558
- describe "#page" do
559
-
560
- context "when the page option exists" do
561
-
562
- before do
563
- @criteria.extras({ :page => 5 })
564
- end
565
-
566
- it "returns the page option" do
567
- @criteria.page.should == 5
568
- end
569
-
9
+ context ".criteria" do
10
+ it "creates a new criteria for the document" do
11
+ CriteriaTest.criteria.should be_a_kind_of(Mongoid::Criteria)
570
12
  end
571
13
 
572
- context "when the page option does not exist" do
573
-
574
- it "returns 1" do
575
- @criteria.page.should == 1
576
- end
577
-
14
+ it "sets the criteria klass" do
15
+ CriteriaTest.criteria.klass.should == CriteriaTest
578
16
  end
579
-
580
17
  end
581
18
 
582
- describe "#paginate" do
19
+ context "criteria delegates" do
20
+ let(:criteria) { stub('criteria').as_null_object }
583
21
 
584
22
  before do
585
- @collection = mock
586
- Person.should_receive(:collection).and_return(@collection)
587
- @criteria.where(:_id => "1").skip(60).limit(20)
588
- @cursor = mock('cursor', :count => 20, :to_a => [])
589
- @collection.should_receive(:find).with({:_id => "1"}, :skip => 60, :limit => 20).and_return(@cursor)
590
- @results = @criteria.paginate
591
- end
592
-
593
- it "executes and paginates the results" do
594
- @results.current_page.should == 4
595
- @results.per_page.should == 20
23
+ CriteriaTest.stub(:criteria).and_return(criteria)
596
24
  end
597
25
 
598
- end
599
-
600
- describe "#per_page" do
601
-
602
- context "when the per_page option exists" do
603
-
604
- before do
605
- @criteria.extras({ :per_page => 10 })
606
- end
607
-
608
- it "returns the per_page option" do
609
- @criteria.per_page.should == 10
610
- end
611
-
612
- end
613
-
614
- context "when the per_page option does not exist" do
615
-
616
- it "returns 1" do
617
- @criteria.per_page.should == 20
618
- end
619
-
620
- end
621
-
622
- end
623
-
624
- describe "#only" do
625
-
626
- context "when args are provided" do
627
-
628
- it "adds the options for limiting by fields" do
629
- @criteria.only(:title, :text)
630
- @criteria.options.should == { :fields => [ :title, :text ] }
631
- end
632
-
633
- it "returns self" do
634
- @criteria.only.should == @criteria
635
- end
636
-
637
- end
638
-
639
- context "when no args provided" do
640
-
641
- it "does not add the field option" do
642
- @criteria.only
643
- @criteria.options[:fields].should be_nil
644
- end
645
-
646
- end
647
-
648
- end
649
-
650
- describe "#skip" do
651
-
652
- context "when value provided" do
653
-
654
- it "adds the skip value to the options" do
655
- @criteria.skip(20)
656
- @criteria.options.should == { :skip => 20 }
657
- end
658
-
659
- end
660
-
661
- context "when value not provided" do
662
-
663
- it "defaults to zero" do
664
- @criteria.skip
665
- @criteria.options.should == { :skip => 0 }
26
+ %w(and cache enslave excludes extras id in limit not_in offset only order_by page per_page skip where).each do |criteria_op|
27
+ it "#{criteria_op} delegates to the criteria" do
28
+ criteria.should_receive(criteria_op)
29
+ CriteriaTest.send(criteria_op)
666
30
  end
667
-
668
- end
669
-
670
- it "returns self" do
671
- @criteria.skip.should == @criteria
672
- end
673
-
674
- end
675
-
676
- describe ".translate" do
677
-
678
- context "with a single argument" do
679
-
680
- before do
681
- @id = Mongo::ObjectID.new.to_s
682
- @document = stub
683
- @criteria = mock
684
- end
685
-
686
- it "creates a criteria for a string" do
687
- MongoDoc::Criteria.should_receive(:new).and_return(@criteria)
688
- @criteria.should_receive(:id).with(@id).and_return(@criteria)
689
- @criteria.should_receive(:one).and_return(@document)
690
- MongoDoc::Criteria.translate(Person, @id)
691
- end
692
-
693
- end
694
-
695
- context "multiple arguments" do
696
-
697
- context "when Person, :conditions => {}" do
698
-
699
- before do
700
- @criteria = MongoDoc::Criteria.translate(Person, :conditions => { :title => "Test" })
701
- end
702
-
703
- it "returns a criteria with a selector from the conditions" do
704
- @criteria.selector.should == { :title => "Test" }
705
- end
706
-
707
- it "returns a criteria with klass Person" do
708
- @criteria.klass.should == Person
709
- end
710
-
711
- end
712
-
713
- context "when :all, :conditions => {}" do
714
-
715
- before do
716
- @criteria = MongoDoc::Criteria.translate(Person, :conditions => { :title => "Test" })
717
- end
718
-
719
- it "returns a criteria with a selector from the conditions" do
720
- @criteria.selector.should == { :title => "Test" }
721
- end
722
-
723
- it "returns a criteria with klass Person" do
724
- @criteria.klass.should == Person
725
- end
726
-
727
- end
728
-
729
- context "when :last, :conditions => {}" do
730
-
731
- before do
732
- @criteria = MongoDoc::Criteria.translate(Person, :conditions => { :title => "Test" })
733
- end
734
-
735
- it "returns a criteria with a selector from the conditions" do
736
- @criteria.selector.should == { :title => "Test" }
737
- end
738
-
739
- it "returns a criteria with klass Person" do
740
- @criteria.klass.should == Person
741
- end
742
- end
743
-
744
- context "when options are provided" do
745
-
746
- before do
747
- @criteria = MongoDoc::Criteria.translate(Person, :conditions => { :title => "Test" }, :skip => 10)
748
- end
749
-
750
- it "adds the criteria and the options" do
751
- @criteria.selector.should == { :title => "Test" }
752
- @criteria.options.should == { :skip => 10 }
753
- end
754
- end
755
- end
756
- end
757
-
758
- describe "#where" do
759
-
760
- it "adds the clause to the selector" do
761
- @criteria.where(:title => "Title", :text => "Text")
762
- @criteria.selector.should == { :title => "Title", :text => "Text" }
763
- end
764
-
765
- it "accepts a js where clause" do
766
- @criteria.where("this.a > 3")
767
- @criteria.selector.should == { '$where' => "this.a > 3" }
768
- end
769
-
770
- it "and return self" do
771
- @criteria.where.should == @criteria
772
- end
773
-
774
- it "#and is an alias for where" do
775
- @criteria.and(:title => "Title", :text => "Text")
776
- @criteria.selector.should == { :title => "Title", :text => "Text" }
777
- end
778
-
779
- it "#conditions is an alias for where" do
780
- @criteria.conditions(:title => "Title", :text => "Text")
781
- @criteria.selector.should == { :title => "Title", :text => "Text" }
782
31
  end
783
32
  end
784
33
  end