mongoid 1.2.14 → 1.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (200) hide show
  1. data/lib/mongoid.rb +10 -3
  2. data/lib/mongoid/associations.rb +133 -97
  3. data/lib/mongoid/associations/belongs_to_related.rb +2 -3
  4. data/lib/mongoid/associations/{belongs_to.rb → embedded_in.rb} +14 -6
  5. data/lib/mongoid/associations/{has_many.rb → embeds_many.rb} +89 -31
  6. data/lib/mongoid/associations/{has_one.rb → embeds_one.rb} +8 -7
  7. data/lib/mongoid/associations/has_many_related.rb +52 -7
  8. data/lib/mongoid/associations/has_one_related.rb +8 -4
  9. data/lib/mongoid/associations/meta_data.rb +2 -1
  10. data/lib/mongoid/associations/options.rb +6 -1
  11. data/lib/mongoid/associations/proxy.rb +14 -21
  12. data/lib/mongoid/attributes.rb +27 -12
  13. data/lib/mongoid/collection.rb +4 -3
  14. data/lib/mongoid/collections.rb +41 -0
  15. data/lib/mongoid/collections/master.rb +3 -2
  16. data/lib/mongoid/collections/slaves.rb +3 -2
  17. data/lib/mongoid/components.rb +21 -19
  18. data/lib/mongoid/concern.rb +31 -0
  19. data/lib/mongoid/config.rb +117 -12
  20. data/lib/mongoid/contexts.rb +1 -1
  21. data/lib/mongoid/contexts/enumerable.rb +1 -1
  22. data/lib/mongoid/contexts/mongo.rb +1 -1
  23. data/lib/mongoid/contexts/paging.rb +10 -2
  24. data/lib/mongoid/criterion/inclusion.rb +17 -0
  25. data/lib/mongoid/criterion/optional.rb +1 -1
  26. data/lib/mongoid/dirty.rb +253 -0
  27. data/lib/mongoid/document.rb +81 -52
  28. data/lib/mongoid/errors.rb +32 -1
  29. data/lib/mongoid/extensions.rb +11 -9
  30. data/lib/mongoid/extensions/big_decimal/conversions.rb +2 -2
  31. data/lib/mongoid/extensions/boolean/conversions.rb +8 -2
  32. data/lib/mongoid/extensions/date/conversions.rb +13 -4
  33. data/lib/mongoid/extensions/datetime/conversions.rb +1 -6
  34. data/lib/mongoid/extensions/float/conversions.rb +5 -1
  35. data/lib/mongoid/extensions/hash/assimilation.rb +12 -3
  36. data/lib/mongoid/extensions/hash/conversions.rb +34 -4
  37. data/lib/mongoid/extensions/integer/conversions.rb +5 -1
  38. data/lib/mongoid/extensions/nil/assimilation.rb +4 -0
  39. data/lib/mongoid/extensions/object/conversions.rb +1 -1
  40. data/lib/mongoid/extensions/string/conversions.rb +1 -1
  41. data/lib/mongoid/extensions/symbol/inflections.rb +1 -1
  42. data/lib/mongoid/extensions/time_conversions.rb +35 -0
  43. data/lib/mongoid/extras.rb +6 -9
  44. data/lib/mongoid/factory.rb +2 -1
  45. data/lib/mongoid/field.rb +9 -2
  46. data/lib/mongoid/fields.rb +1 -0
  47. data/lib/mongoid/identity.rb +3 -3
  48. data/lib/mongoid/indexes.rb +3 -3
  49. data/lib/mongoid/memoization.rb +8 -2
  50. data/lib/mongoid/named_scope.rb +0 -3
  51. data/lib/mongoid/observable.rb +30 -0
  52. data/lib/mongoid/paths.rb +62 -0
  53. data/lib/mongoid/persistence.rb +222 -0
  54. data/lib/mongoid/persistence/command.rb +39 -0
  55. data/lib/mongoid/persistence/insert.rb +50 -0
  56. data/lib/mongoid/persistence/insert_embedded.rb +38 -0
  57. data/lib/mongoid/persistence/remove.rb +39 -0
  58. data/lib/mongoid/persistence/remove_all.rb +37 -0
  59. data/lib/mongoid/persistence/remove_embedded.rb +50 -0
  60. data/lib/mongoid/persistence/update.rb +63 -0
  61. data/lib/mongoid/state.rb +28 -21
  62. data/lib/mongoid/timestamps.rb +5 -8
  63. data/lib/mongoid/version.rb +4 -0
  64. data/lib/mongoid/versioning.rb +6 -7
  65. metadata +81 -300
  66. data/.gitignore +0 -6
  67. data/.watchr +0 -29
  68. data/Rakefile +0 -53
  69. data/VERSION +0 -1
  70. data/caliper.yml +0 -4
  71. data/lib/mongoid/collections/mimic.rb +0 -46
  72. data/lib/mongoid/commands.rb +0 -174
  73. data/lib/mongoid/commands/create.rb +0 -21
  74. data/lib/mongoid/commands/delete.rb +0 -16
  75. data/lib/mongoid/commands/delete_all.rb +0 -23
  76. data/lib/mongoid/commands/deletion.rb +0 -18
  77. data/lib/mongoid/commands/destroy.rb +0 -19
  78. data/lib/mongoid/commands/destroy_all.rb +0 -23
  79. data/lib/mongoid/commands/save.rb +0 -27
  80. data/lib/mongoid/extensions/time/conversions.rb +0 -18
  81. data/mongoid.gemspec +0 -395
  82. data/perf/benchmark.rb +0 -77
  83. data/spec/integration/mongoid/associations_spec.rb +0 -340
  84. data/spec/integration/mongoid/attributes_spec.rb +0 -22
  85. data/spec/integration/mongoid/commands_spec.rb +0 -218
  86. data/spec/integration/mongoid/contexts/enumerable_spec.rb +0 -33
  87. data/spec/integration/mongoid/criteria_spec.rb +0 -272
  88. data/spec/integration/mongoid/document_spec.rb +0 -593
  89. data/spec/integration/mongoid/extensions_spec.rb +0 -26
  90. data/spec/integration/mongoid/finders_spec.rb +0 -119
  91. data/spec/integration/mongoid/inheritance_spec.rb +0 -137
  92. data/spec/integration/mongoid/named_scope_spec.rb +0 -46
  93. data/spec/models/address.rb +0 -39
  94. data/spec/models/animal.rb +0 -6
  95. data/spec/models/callbacks.rb +0 -18
  96. data/spec/models/comment.rb +0 -8
  97. data/spec/models/country_code.rb +0 -6
  98. data/spec/models/employer.rb +0 -5
  99. data/spec/models/game.rb +0 -7
  100. data/spec/models/inheritance.rb +0 -56
  101. data/spec/models/location.rb +0 -5
  102. data/spec/models/mixed_drink.rb +0 -4
  103. data/spec/models/name.rb +0 -13
  104. data/spec/models/namespacing.rb +0 -11
  105. data/spec/models/patient.rb +0 -4
  106. data/spec/models/person.rb +0 -99
  107. data/spec/models/pet.rb +0 -7
  108. data/spec/models/pet_owner.rb +0 -6
  109. data/spec/models/phone.rb +0 -7
  110. data/spec/models/post.rb +0 -15
  111. data/spec/models/translation.rb +0 -5
  112. data/spec/models/vet_visit.rb +0 -5
  113. data/spec/spec.opts +0 -3
  114. data/spec/spec_helper.rb +0 -31
  115. data/spec/unit/mongoid/associations/belongs_to_related_spec.rb +0 -145
  116. data/spec/unit/mongoid/associations/belongs_to_spec.rb +0 -193
  117. data/spec/unit/mongoid/associations/has_many_related_spec.rb +0 -420
  118. data/spec/unit/mongoid/associations/has_many_spec.rb +0 -519
  119. data/spec/unit/mongoid/associations/has_one_related_spec.rb +0 -179
  120. data/spec/unit/mongoid/associations/has_one_spec.rb +0 -282
  121. data/spec/unit/mongoid/associations/meta_data_spec.rb +0 -88
  122. data/spec/unit/mongoid/associations/options_spec.rb +0 -192
  123. data/spec/unit/mongoid/associations_spec.rb +0 -595
  124. data/spec/unit/mongoid/attributes_spec.rb +0 -507
  125. data/spec/unit/mongoid/callbacks_spec.rb +0 -55
  126. data/spec/unit/mongoid/collection_spec.rb +0 -187
  127. data/spec/unit/mongoid/collections/cyclic_iterator_spec.rb +0 -75
  128. data/spec/unit/mongoid/collections/master_spec.rb +0 -41
  129. data/spec/unit/mongoid/collections/mimic_spec.rb +0 -43
  130. data/spec/unit/mongoid/collections/slaves_spec.rb +0 -81
  131. data/spec/unit/mongoid/commands/create_spec.rb +0 -30
  132. data/spec/unit/mongoid/commands/delete_all_spec.rb +0 -58
  133. data/spec/unit/mongoid/commands/delete_spec.rb +0 -38
  134. data/spec/unit/mongoid/commands/destroy_all_spec.rb +0 -23
  135. data/spec/unit/mongoid/commands/destroy_spec.rb +0 -50
  136. data/spec/unit/mongoid/commands/save_spec.rb +0 -105
  137. data/spec/unit/mongoid/commands_spec.rb +0 -275
  138. data/spec/unit/mongoid/config_spec.rb +0 -172
  139. data/spec/unit/mongoid/contexts/enumerable_spec.rb +0 -421
  140. data/spec/unit/mongoid/contexts/mongo_spec.rb +0 -682
  141. data/spec/unit/mongoid/contexts_spec.rb +0 -25
  142. data/spec/unit/mongoid/criteria_spec.rb +0 -824
  143. data/spec/unit/mongoid/criterion/complex_spec.rb +0 -19
  144. data/spec/unit/mongoid/criterion/exclusion_spec.rb +0 -91
  145. data/spec/unit/mongoid/criterion/inclusion_spec.rb +0 -219
  146. data/spec/unit/mongoid/criterion/optional_spec.rb +0 -319
  147. data/spec/unit/mongoid/cursor_spec.rb +0 -74
  148. data/spec/unit/mongoid/deprecation_spec.rb +0 -24
  149. data/spec/unit/mongoid/document_spec.rb +0 -952
  150. data/spec/unit/mongoid/errors_spec.rb +0 -103
  151. data/spec/unit/mongoid/extensions/array/accessors_spec.rb +0 -50
  152. data/spec/unit/mongoid/extensions/array/assimilation_spec.rb +0 -24
  153. data/spec/unit/mongoid/extensions/array/conversions_spec.rb +0 -35
  154. data/spec/unit/mongoid/extensions/array/parentization_spec.rb +0 -20
  155. data/spec/unit/mongoid/extensions/big_decimal/conversions_spec.rb +0 -22
  156. data/spec/unit/mongoid/extensions/binary/conversions_spec.rb +0 -22
  157. data/spec/unit/mongoid/extensions/boolean/conversions_spec.rb +0 -49
  158. data/spec/unit/mongoid/extensions/date/conversions_spec.rb +0 -102
  159. data/spec/unit/mongoid/extensions/datetime/conversions_spec.rb +0 -70
  160. data/spec/unit/mongoid/extensions/float/conversions_spec.rb +0 -61
  161. data/spec/unit/mongoid/extensions/hash/accessors_spec.rb +0 -184
  162. data/spec/unit/mongoid/extensions/hash/assimilation_spec.rb +0 -46
  163. data/spec/unit/mongoid/extensions/hash/conversions_spec.rb +0 -21
  164. data/spec/unit/mongoid/extensions/hash/criteria_helpers_spec.rb +0 -17
  165. data/spec/unit/mongoid/extensions/hash/scoping_spec.rb +0 -14
  166. data/spec/unit/mongoid/extensions/integer/conversions_spec.rb +0 -61
  167. data/spec/unit/mongoid/extensions/nil/assimilation_spec.rb +0 -24
  168. data/spec/unit/mongoid/extensions/object/conversions_spec.rb +0 -57
  169. data/spec/unit/mongoid/extensions/proc/scoping_spec.rb +0 -34
  170. data/spec/unit/mongoid/extensions/string/conversions_spec.rb +0 -17
  171. data/spec/unit/mongoid/extensions/string/inflections_spec.rb +0 -208
  172. data/spec/unit/mongoid/extensions/symbol/inflections_spec.rb +0 -91
  173. data/spec/unit/mongoid/extensions/time/conversions_spec.rb +0 -70
  174. data/spec/unit/mongoid/extras_spec.rb +0 -102
  175. data/spec/unit/mongoid/factory_spec.rb +0 -31
  176. data/spec/unit/mongoid/field_spec.rb +0 -143
  177. data/spec/unit/mongoid/fields_spec.rb +0 -181
  178. data/spec/unit/mongoid/finders_spec.rb +0 -404
  179. data/spec/unit/mongoid/identity_spec.rb +0 -109
  180. data/spec/unit/mongoid/indexes_spec.rb +0 -93
  181. data/spec/unit/mongoid/javascript_spec.rb +0 -48
  182. data/spec/unit/mongoid/matchers/all_spec.rb +0 -27
  183. data/spec/unit/mongoid/matchers/default_spec.rb +0 -27
  184. data/spec/unit/mongoid/matchers/exists_spec.rb +0 -56
  185. data/spec/unit/mongoid/matchers/gt_spec.rb +0 -39
  186. data/spec/unit/mongoid/matchers/gte_spec.rb +0 -49
  187. data/spec/unit/mongoid/matchers/in_spec.rb +0 -27
  188. data/spec/unit/mongoid/matchers/lt_spec.rb +0 -39
  189. data/spec/unit/mongoid/matchers/lte_spec.rb +0 -49
  190. data/spec/unit/mongoid/matchers/ne_spec.rb +0 -27
  191. data/spec/unit/mongoid/matchers/nin_spec.rb +0 -27
  192. data/spec/unit/mongoid/matchers/size_spec.rb +0 -27
  193. data/spec/unit/mongoid/matchers_spec.rb +0 -329
  194. data/spec/unit/mongoid/memoization_spec.rb +0 -75
  195. data/spec/unit/mongoid/named_scope_spec.rb +0 -123
  196. data/spec/unit/mongoid/scope_spec.rb +0 -240
  197. data/spec/unit/mongoid/state_spec.rb +0 -83
  198. data/spec/unit/mongoid/timestamps_spec.rb +0 -25
  199. data/spec/unit/mongoid/versioning_spec.rb +0 -41
  200. data/spec/unit/mongoid_spec.rb +0 -46
@@ -1,682 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe Mongoid::Contexts::Mongo do
4
-
5
- describe "#aggregate" do
6
-
7
- before do
8
- @criteria = Mongoid::Criteria.new(Person)
9
- @criteria.only(:field1)
10
- @context = Mongoid::Contexts::Mongo.new(@criteria)
11
- end
12
-
13
- context "when klass not provided" do
14
-
15
- before do
16
- @reduce = "function(obj, prev) { prev.count++; }"
17
- @collection = mock
18
- Person.expects(:collection).returns(@collection)
19
- end
20
-
21
- it "calls group on the collection with the aggregate js" do
22
- @collection.expects(:group).with([:field1], {:_type => {'$in' => ['Doctor', 'Person']}}, {:count => 0}, @reduce, true)
23
- @context.aggregate
24
- end
25
- end
26
- end
27
-
28
- describe "#avg" do
29
-
30
- before do
31
- @reduce = Mongoid::Javascript.sum.gsub("[field]", "age")
32
- @collection = mock
33
- Person.expects(:collection).twice.returns(@collection)
34
- @criteria = Mongoid::Criteria.new(Person)
35
- @context = Mongoid::Contexts::Mongo.new(@criteria)
36
- end
37
-
38
- it "calls group on the collection with the aggregate js" do
39
- @collection.expects(:group).with(
40
- nil,
41
- {:_type => {'$in' => ['Doctor', 'Person']}},
42
- {:sum => "start"},
43
- @reduce
44
- ).returns([{"sum" => 100.0}])
45
- @cursor = mock(:count => 10)
46
- @collection.expects(:find).returns(@cursor)
47
- @context.avg(:age).should == 10
48
- end
49
- end
50
-
51
- describe "blank?" do
52
-
53
- before do
54
- @criteria = Mongoid::Criteria.new(Game)
55
- @criteria.where(:test => 'Testing')
56
- @context = Mongoid::Contexts::Mongo.new(@criteria)
57
- end
58
-
59
- context "when a document exists" do
60
-
61
- before do
62
- @doc = mock
63
- @collection = mock
64
- Game.expects(:collection).returns(@collection)
65
- @collection.expects(:find_one).with({ :test => "Testing" }, { :fields => [ :_id ] }).returns(@doc)
66
- end
67
-
68
- it "returns false" do
69
- @context.blank?.should be_false
70
- end
71
- end
72
-
73
- context "when a document does not exist" do
74
-
75
- before do
76
- @doc = mock
77
- @collection = mock
78
- Game.expects(:collection).returns(@collection)
79
- @collection.expects(:find_one).with({ :test => "Testing" }, { :fields => [ :_id ] }).returns(nil)
80
- end
81
-
82
- it "returns true" do
83
- @context.blank?.should be_true
84
- end
85
- end
86
- end
87
-
88
- describe "#count" do
89
-
90
- before do
91
- @criteria = Mongoid::Criteria.new(Person)
92
- @criteria.where(:test => 'Testing')
93
- @context = Mongoid::Contexts::Mongo.new(@criteria)
94
- end
95
-
96
- context "when criteria has not been executed" do
97
-
98
- before do
99
- @context.instance_variable_set(:@count, 34)
100
- end
101
-
102
- it "returns a count from the cursor" do
103
- @context.count.should == 34
104
- end
105
-
106
- end
107
-
108
- context "when criteria has been executed" do
109
-
110
- before do
111
- @collection = mock
112
- @cursor = mock
113
- Person.expects(:collection).returns(@collection)
114
- end
115
-
116
- it "returns the count from the cursor without creating the documents" do
117
- @collection.expects(:find).with(@criteria.selector, {}).returns(@cursor)
118
- @cursor.expects(:count).returns(10)
119
- @context.count.should == 10
120
- end
121
-
122
- end
123
-
124
- end
125
-
126
- describe "#distinct" do
127
-
128
- before do
129
- @criteria = Mongoid::Criteria.new(Person)
130
- @criteria.where(:test => 'Testing')
131
- @context = Mongoid::Contexts::Mongo.new(@criteria)
132
- @collection = mock
133
- Person.expects(:collection).returns(@collection)
134
- end
135
-
136
- it "returns delegates to distinct on the collection" do
137
- @collection.expects(:distinct).with(:title, @criteria.selector).returns(["Sir"])
138
- @context.distinct(:title).should == ["Sir"]
139
- end
140
- end
141
-
142
- describe "#execute" do
143
-
144
- let(:selector) { { :field => "value" } }
145
- let(:options) { { :skip => 20 } }
146
-
147
- before do
148
- @cursor = stub(:count => 500)
149
- @collection = mock
150
- @klass = stub(
151
- :collection => @collection,
152
- :hereditary => false,
153
- :instantiate => @person,
154
- :enslaved? => false,
155
- :cached? => false
156
- )
157
- @criteria = Mongoid::Criteria.new(@klass)
158
- @criteria.where(selector).skip(20)
159
- @context = Mongoid::Contexts::Mongo.new(@criteria)
160
- end
161
-
162
- it "calls find on the collection" do
163
- @collection.expects(:find).with(selector, options).returns(@cursor)
164
- @context.execute.should == @cursor
165
- end
166
-
167
- context "when paginating" do
168
-
169
- it "should find the count from the cursor" do
170
- @collection.expects(:find).with(selector, options).returns(@cursor)
171
- @context.execute(true).should == @cursor
172
- @context.count.should == 500
173
- end
174
-
175
- end
176
-
177
- context "when field options are supplied" do
178
-
179
- context "when _type not in the field list" do
180
-
181
- before do
182
- @criteria.only(:title)
183
- @expected_options = { :skip => 20, :fields => [ :title, :_type ] }
184
- end
185
-
186
- it "adds _type to the fields" do
187
- @collection.expects(:find).with(selector, @expected_options).returns(@cursor)
188
- @context.execute.should == @cursor
189
- end
190
-
191
- end
192
-
193
- end
194
-
195
- end
196
-
197
- describe "#group" do
198
-
199
- before do
200
- @criteria = Mongoid::Criteria.new(Person)
201
- @criteria.only(:field1)
202
- @grouping = [{ "title" => "Sir", "group" => [{ "title" => "Sir", "age" => 30, "_type" => "Person" }] }]
203
- @context = Mongoid::Contexts::Mongo.new(@criteria)
204
- end
205
-
206
- context "when klass provided" do
207
-
208
- before do
209
- @reduce = "function(obj, prev) { prev.group.push(obj); }"
210
- @collection = mock
211
- Person.expects(:collection).returns(@collection)
212
- end
213
-
214
- it "calls group on the collection with the aggregate js" do
215
- @collection.expects(:group).with(
216
- [:field1],
217
- {:_type => { "$in" => ["Doctor", "Person"] }},
218
- {:group => []},
219
- @reduce
220
- ).returns(@grouping)
221
- @context.group
222
- end
223
-
224
- end
225
-
226
- end
227
-
228
- describe ".initialize" do
229
-
230
- let(:selector) { { :field => "value" } }
231
- let(:options) { { :skip => 20 } }
232
- let(:klass) { Person }
233
- let(:criteria) { Mongoid::Criteria.new(klass) }
234
- let(:context) { Mongoid::Contexts::Mongo.new(criteria) }
235
-
236
- before do
237
- criteria.where(selector).skip(20)
238
- end
239
-
240
- it "sets the selector" do
241
- context.selector.should == criteria.selector
242
- end
243
-
244
- it "sets the options" do
245
- context.options.should == options
246
- end
247
-
248
- it "sets the klass" do
249
- context.klass.should == klass
250
- end
251
-
252
- context "when persisting type" do
253
-
254
- it "set the selector to query across the _type when it is hereditary" do
255
- context.selector[:_type].should == {'$in' => Person._types}
256
- end
257
-
258
- end
259
-
260
- context "when not persisting type" do
261
-
262
- before do
263
- Mongoid.persist_types = false
264
- end
265
-
266
- after do
267
- Mongoid.persist_types = true
268
- end
269
-
270
- it "does not add the type to the selector" do
271
- context.selector[:_type].should be_nil
272
- end
273
-
274
- end
275
-
276
- context "enslaved and cached classes" do
277
-
278
- let(:klass) { Game }
279
-
280
- it "enslaves the criteria" do
281
- context.criteria.should be_enslaved
282
- end
283
-
284
- it "caches the criteria" do
285
- context.criteria.should be_cached
286
- end
287
- end
288
- end
289
-
290
- describe "#iterate" do
291
- before do
292
- @criteria = Mongoid::Criteria.new(Person)
293
- @context = Mongoid::Contexts::Mongo.new(@criteria)
294
- @person = Person.new(:title => "Sir")
295
- @cursor = stub('cursor')
296
- @cursor.stubs(:each).yields(@person)
297
- end
298
-
299
- context "when not caching" do
300
-
301
- it "executes the criteria" do
302
- @context.expects(:execute).returns(@cursor)
303
- @context.iterate do |person|
304
- person.should == @person
305
- end
306
-
307
- end
308
-
309
- end
310
-
311
- context "when caching" do
312
- before do
313
- @criteria.cache
314
- end
315
-
316
- it "executes the criteria" do
317
- @context.expects(:execute).returns(@cursor)
318
- @context.iterate do |person|
319
- person.should == @person
320
- end
321
- end
322
-
323
- it "executes only once and it caches the result" do
324
- @context.expects(:execute).once.returns(@cursor)
325
- @context.iterate do |person|
326
- person.should == @person
327
- end
328
- @context.iterate do |person|
329
- person.should == @person
330
- end
331
- end
332
-
333
- it "executes even if there is no block" do
334
- @context.expects(:execute).once.returns(@cursor)
335
- @context.iterate
336
- end
337
-
338
- it "caches even if there is no block" do
339
- @context.expects(:execute).once.returns(@cursor)
340
- @context.iterate
341
- @context.iterate do |person|
342
- person.should == @person
343
- end
344
- end
345
- end
346
-
347
- end
348
-
349
- describe "#last" do
350
-
351
- before do
352
- @collection = mock
353
- Person.expects(:collection).returns(@collection)
354
- end
355
-
356
- context "when documents exist" do
357
-
358
- before do
359
- @criteria = Mongoid::Criteria.new(Person)
360
- @criteria.order_by([[:title, :asc]])
361
- @context = Mongoid::Contexts::Mongo.new(@criteria)
362
- @collection.expects(:find_one).with(
363
- {:_type => {'$in' => ['Doctor', 'Person']}},
364
- { :sort => [[:title, :desc]] }
365
- ).returns(
366
- { "title" => "Sir", "_type" => "Person" }
367
- )
368
- end
369
-
370
- it "calls find on the collection with the selector and sort options reversed" do
371
- @context.last.should be_a_kind_of(Person)
372
- end
373
-
374
- end
375
-
376
- context "when no documents exist" do
377
-
378
- before do
379
- @criteria = Mongoid::Criteria.new(Person)
380
- @criteria.order_by([[:_id, :asc]])
381
- @context = Mongoid::Contexts::Mongo.new(@criteria)
382
- @collection.expects(:find_one).with(
383
- {:_type => {'$in' => ['Doctor', 'Person']}},
384
- { :sort => [[:_id, :desc]] }
385
- ).returns(nil)
386
- end
387
-
388
- it "returns nil" do
389
- @context.last.should be_nil
390
- end
391
-
392
- end
393
-
394
- context "when no sorting options provided" do
395
-
396
- before do
397
- @criteria = Mongoid::Criteria.new(Person)
398
- @criteria.order_by([[:_id, :asc]])
399
- @context = Mongoid::Contexts::Mongo.new(@criteria)
400
- @collection.expects(:find_one).with(
401
- {:_type => {'$in' => ['Doctor', 'Person']}},
402
- { :sort => [[:_id, :desc]] }
403
- ).returns(
404
- { "title" => "Sir", "_type" => "Person" }
405
- )
406
- end
407
-
408
- it "defaults to sort by id" do
409
- @context.last
410
- end
411
-
412
- end
413
-
414
- end
415
-
416
- describe "#max" do
417
-
418
- before do
419
- @reduce = Mongoid::Javascript.max.gsub("[field]", "age")
420
- @collection = mock
421
- Person.expects(:collection).returns(@collection)
422
- @criteria = Mongoid::Criteria.new(Person)
423
- @context = Mongoid::Contexts::Mongo.new(@criteria)
424
- end
425
-
426
- it "calls group on the collection with the aggregate js" do
427
- @collection.expects(:group).with(
428
- nil,
429
- {:_type => {'$in' => ['Doctor', 'Person']}},
430
- {:max => "start"},
431
- @reduce
432
- ).returns([{"max" => 200.0}])
433
- @context.max(:age).should == 200.0
434
- end
435
-
436
- end
437
-
438
- describe "#min" do
439
-
440
- before do
441
- @reduce = Mongoid::Javascript.min.gsub("[field]", "age")
442
- @collection = mock
443
- Person.expects(:collection).returns(@collection)
444
- @criteria = Mongoid::Criteria.new(Person)
445
- @context = Mongoid::Contexts::Mongo.new(@criteria)
446
- end
447
-
448
- it "calls group on the collection with the aggregate js" do
449
- @collection.expects(:group).with(
450
- nil,
451
- {:_type => {'$in' => ['Doctor', 'Person']}},
452
- {:min => "start"},
453
- @reduce
454
- ).returns([{"min" => 4.0}])
455
- @context.min(:age).should == 4.0
456
- end
457
-
458
- end
459
-
460
- describe "#one" do
461
-
462
- context "when documents exist" do
463
-
464
- before do
465
- Person.expects(:collection).returns(@collection)
466
- @criteria = Mongoid::Criteria.new(Person)
467
- @context = Mongoid::Contexts::Mongo.new(@criteria)
468
- @collection.expects(:find_one).with({:_type => {'$in' => ['Doctor', 'Person']}}, {}).returns(
469
- { "title"=> "Sir", "_type" => "Person" }
470
- )
471
- end
472
-
473
- it "calls find on the collection with the selector and options" do
474
- @context.one.should be_a_kind_of(Person)
475
- end
476
-
477
- end
478
-
479
- context "when no documents exist" do
480
-
481
- before do
482
- @collection = mock
483
- Person.expects(:collection).returns(@collection)
484
- @criteria = Mongoid::Criteria.new(Person)
485
- @context = Mongoid::Contexts::Mongo.new(@criteria)
486
- @collection.expects(:find_one).with({:_type => {'$in' => ['Doctor', 'Person']}}, {}).returns(nil)
487
- end
488
-
489
- it "returns nil" do
490
- @context.one.should be_nil
491
- end
492
-
493
- end
494
-
495
- end
496
-
497
- describe "#page" do
498
-
499
- context "when the page option exists" do
500
-
501
- before do
502
- @criteria = Mongoid::Criteria.new(Person).extras({ :page => 5 })
503
- @context = Mongoid::Contexts::Mongo.new(@criteria)
504
- end
505
-
506
- it "returns the page option" do
507
- @context.page.should == 5
508
- end
509
-
510
- end
511
-
512
- context "when the page option does not exist" do
513
-
514
- before do
515
- @criteria = Mongoid::Criteria.new(Person)
516
- @context = Mongoid::Contexts::Mongo.new(@criteria)
517
- end
518
-
519
- it "returns 1" do
520
- @context.page.should == 1
521
- end
522
-
523
- end
524
-
525
- end
526
-
527
- describe "#paginate" do
528
-
529
- before do
530
- @collection = mock
531
- Person.expects(:collection).returns(@collection)
532
- @criteria = Person.where(:_id => "1").skip(60).limit(20)
533
- @context = Mongoid::Contexts::Mongo.new(@criteria)
534
- @collection.expects(:find).with(
535
- {:_type => { "$in" => ["Doctor", "Person"] }, :_id => "1"}, :skip => 60, :limit => 20
536
- ).returns([])
537
- @results = @context.paginate
538
- end
539
-
540
- it "executes and paginates the results" do
541
- @results.current_page.should == 4
542
- @results.per_page.should == 20
543
- end
544
-
545
- end
546
-
547
- describe "#sum" do
548
-
549
- context "when klass not provided" do
550
-
551
- before do
552
- @reduce = Mongoid::Javascript.sum.gsub("[field]", "age")
553
- @collection = mock
554
- @criteria = Mongoid::Criteria.new(Person)
555
- @context = Mongoid::Contexts::Mongo.new(@criteria)
556
- Person.expects(:collection).returns(@collection)
557
- end
558
-
559
- it "calls group on the collection with the aggregate js" do
560
- @collection.expects(:group).with(
561
- nil,
562
- {:_type => {'$in' => ['Doctor', 'Person']}},
563
- {:sum => "start"},
564
- @reduce
565
- ).returns([{"sum" => 50.0}])
566
- @context.sum(:age).should == 50.0
567
- end
568
-
569
- end
570
-
571
- end
572
-
573
- context "#id_criteria" do
574
-
575
- let(:criteria) { Mongoid::Criteria.new(Person) }
576
- let(:context) { criteria.context }
577
-
578
- context "with a single argument" do
579
-
580
- let(:id) { Mongo::ObjectID.new.to_s }
581
-
582
- before do
583
- criteria.expects(:id).with(id).returns(criteria)
584
- end
585
-
586
- context "when the document is found" do
587
-
588
- let(:document) { stub }
589
-
590
- it "returns a matching document" do
591
- context.expects(:one).returns(document)
592
- document.expects(:blank? => false)
593
- context.id_criteria(id).should == document
594
- end
595
-
596
- end
597
-
598
- context "when the document is not found" do
599
-
600
- it "raises an error" do
601
- context.expects(:one).returns(nil)
602
- lambda { context.id_criteria(id) }.should raise_error
603
- end
604
-
605
- end
606
-
607
- end
608
-
609
- context "multiple arguments" do
610
-
611
- context "when an array of ids" do
612
-
613
- let(:ids) do
614
- (0..2).inject([]) { |ary, i| ary << Mongo::ObjectID.new.to_s }
615
- end
616
-
617
- context "when documents are found" do
618
-
619
- let(:docs) do
620
- (0..2).inject([]) { |ary, i| ary << stub }
621
- end
622
-
623
- before do
624
- criteria.expects(:id).with(ids).returns(criteria)
625
- end
626
-
627
- it "returns matching documents" do
628
- context.expects(:execute).returns(docs)
629
- context.id_criteria(ids).should == docs
630
- end
631
-
632
- end
633
-
634
- context "when documents are not found" do
635
-
636
- it "raises an error" do
637
- context.expects(:execute).returns([])
638
- lambda { context.id_criteria(ids) }.should raise_error
639
- end
640
-
641
- end
642
-
643
- end
644
-
645
- context "when an array of object ids" do
646
-
647
- let(:ids) do
648
- (0..2).inject([]) { |ary, i| ary << Mongo::ObjectID.new }
649
- end
650
-
651
- context "when documents are found" do
652
-
653
- let(:docs) do
654
- (0..2).inject([]) { |ary, i| ary << stub }
655
- end
656
-
657
- before do
658
- criteria.expects(:id).with(ids).returns(criteria)
659
- end
660
-
661
- it "returns matching documents" do
662
- context.expects(:execute).returns(docs)
663
- context.id_criteria(ids).should == docs
664
- end
665
-
666
- end
667
-
668
- context "when documents are not found" do
669
-
670
- it "raises an error" do
671
- context.expects(:execute).returns([])
672
- lambda { context.id_criteria(ids) }.should raise_error
673
- end
674
-
675
- end
676
-
677
- end
678
- end
679
-
680
- end
681
-
682
- end