lookout-mongo_mapper 0.11.3

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 (176) hide show
  1. data/LICENSE +20 -0
  2. data/README.rdoc +33 -0
  3. data/UPGRADES +26 -0
  4. data/bin/mmconsole +59 -0
  5. data/examples/attr_accessible.rb +22 -0
  6. data/examples/attr_protected.rb +22 -0
  7. data/examples/cache_key.rb +24 -0
  8. data/examples/custom_types.rb +24 -0
  9. data/examples/identity_map.rb +33 -0
  10. data/examples/identity_map/automatic.rb +2 -0
  11. data/examples/keys.rb +40 -0
  12. data/examples/modifiers/set.rb +25 -0
  13. data/examples/plugins.rb +38 -0
  14. data/examples/querying.rb +35 -0
  15. data/examples/safe.rb +43 -0
  16. data/examples/scopes.rb +52 -0
  17. data/examples/validating/embedded_docs.rb +29 -0
  18. data/lib/mongo_mapper.rb +94 -0
  19. data/lib/mongo_mapper/connection.rb +96 -0
  20. data/lib/mongo_mapper/document.rb +42 -0
  21. data/lib/mongo_mapper/embedded_document.rb +32 -0
  22. data/lib/mongo_mapper/exceptions.rb +30 -0
  23. data/lib/mongo_mapper/extensions/array.rb +19 -0
  24. data/lib/mongo_mapper/extensions/binary.rb +22 -0
  25. data/lib/mongo_mapper/extensions/boolean.rb +44 -0
  26. data/lib/mongo_mapper/extensions/date.rb +25 -0
  27. data/lib/mongo_mapper/extensions/float.rb +14 -0
  28. data/lib/mongo_mapper/extensions/hash.rb +14 -0
  29. data/lib/mongo_mapper/extensions/integer.rb +19 -0
  30. data/lib/mongo_mapper/extensions/kernel.rb +9 -0
  31. data/lib/mongo_mapper/extensions/nil_class.rb +18 -0
  32. data/lib/mongo_mapper/extensions/object.rb +26 -0
  33. data/lib/mongo_mapper/extensions/object_id.rb +32 -0
  34. data/lib/mongo_mapper/extensions/set.rb +20 -0
  35. data/lib/mongo_mapper/extensions/string.rb +18 -0
  36. data/lib/mongo_mapper/extensions/time.rb +28 -0
  37. data/lib/mongo_mapper/locale/en.yml +5 -0
  38. data/lib/mongo_mapper/middleware/identity_map.rb +16 -0
  39. data/lib/mongo_mapper/plugins.rb +22 -0
  40. data/lib/mongo_mapper/plugins/accessible.rb +52 -0
  41. data/lib/mongo_mapper/plugins/active_model.rb +18 -0
  42. data/lib/mongo_mapper/plugins/associations.rb +90 -0
  43. data/lib/mongo_mapper/plugins/associations/base.rb +92 -0
  44. data/lib/mongo_mapper/plugins/associations/belongs_to_association.rb +54 -0
  45. data/lib/mongo_mapper/plugins/associations/belongs_to_polymorphic_proxy.rb +34 -0
  46. data/lib/mongo_mapper/plugins/associations/belongs_to_proxy.rb +52 -0
  47. data/lib/mongo_mapper/plugins/associations/collection.rb +27 -0
  48. data/lib/mongo_mapper/plugins/associations/embedded_collection.rb +44 -0
  49. data/lib/mongo_mapper/plugins/associations/in_array_proxy.rb +133 -0
  50. data/lib/mongo_mapper/plugins/associations/many_association.rb +63 -0
  51. data/lib/mongo_mapper/plugins/associations/many_documents_as_proxy.rb +28 -0
  52. data/lib/mongo_mapper/plugins/associations/many_documents_proxy.rb +118 -0
  53. data/lib/mongo_mapper/plugins/associations/many_embedded_polymorphic_proxy.rb +32 -0
  54. data/lib/mongo_mapper/plugins/associations/many_embedded_proxy.rb +24 -0
  55. data/lib/mongo_mapper/plugins/associations/many_polymorphic_proxy.rb +14 -0
  56. data/lib/mongo_mapper/plugins/associations/one_as_proxy.rb +22 -0
  57. data/lib/mongo_mapper/plugins/associations/one_association.rb +48 -0
  58. data/lib/mongo_mapper/plugins/associations/one_embedded_polymorphic_proxy.rb +30 -0
  59. data/lib/mongo_mapper/plugins/associations/one_embedded_proxy.rb +44 -0
  60. data/lib/mongo_mapper/plugins/associations/one_proxy.rb +95 -0
  61. data/lib/mongo_mapper/plugins/associations/proxy.rb +134 -0
  62. data/lib/mongo_mapper/plugins/associations/single_association.rb +46 -0
  63. data/lib/mongo_mapper/plugins/caching.rb +21 -0
  64. data/lib/mongo_mapper/plugins/callbacks.rb +29 -0
  65. data/lib/mongo_mapper/plugins/clone.rb +22 -0
  66. data/lib/mongo_mapper/plugins/dirty.rb +60 -0
  67. data/lib/mongo_mapper/plugins/document.rb +41 -0
  68. data/lib/mongo_mapper/plugins/dynamic_querying.rb +45 -0
  69. data/lib/mongo_mapper/plugins/dynamic_querying/dynamic_finder.rb +44 -0
  70. data/lib/mongo_mapper/plugins/embedded_callbacks.rb +56 -0
  71. data/lib/mongo_mapper/plugins/embedded_document.rb +53 -0
  72. data/lib/mongo_mapper/plugins/equality.rb +23 -0
  73. data/lib/mongo_mapper/plugins/identity_map.rb +128 -0
  74. data/lib/mongo_mapper/plugins/indexes.rb +13 -0
  75. data/lib/mongo_mapper/plugins/inspect.rb +16 -0
  76. data/lib/mongo_mapper/plugins/keys.rb +313 -0
  77. data/lib/mongo_mapper/plugins/keys/key.rb +61 -0
  78. data/lib/mongo_mapper/plugins/logger.rb +18 -0
  79. data/lib/mongo_mapper/plugins/modifiers.rb +134 -0
  80. data/lib/mongo_mapper/plugins/pagination.rb +16 -0
  81. data/lib/mongo_mapper/plugins/persistence.rb +69 -0
  82. data/lib/mongo_mapper/plugins/protected.rb +45 -0
  83. data/lib/mongo_mapper/plugins/querying.rb +165 -0
  84. data/lib/mongo_mapper/plugins/querying/decorator.rb +36 -0
  85. data/lib/mongo_mapper/plugins/rails.rb +58 -0
  86. data/lib/mongo_mapper/plugins/rails/active_record_association_adapter.rb +33 -0
  87. data/lib/mongo_mapper/plugins/safe.rb +28 -0
  88. data/lib/mongo_mapper/plugins/sci.rb +36 -0
  89. data/lib/mongo_mapper/plugins/scopes.rb +27 -0
  90. data/lib/mongo_mapper/plugins/serialization.rb +109 -0
  91. data/lib/mongo_mapper/plugins/timestamps.rb +22 -0
  92. data/lib/mongo_mapper/plugins/touch.rb +18 -0
  93. data/lib/mongo_mapper/plugins/userstamps.rb +18 -0
  94. data/lib/mongo_mapper/plugins/validations.rb +86 -0
  95. data/lib/mongo_mapper/railtie.rb +48 -0
  96. data/lib/mongo_mapper/railtie/database.rake +65 -0
  97. data/lib/mongo_mapper/translation.rb +10 -0
  98. data/lib/mongo_mapper/version.rb +4 -0
  99. data/lib/rails/generators/mongo_mapper/config/config_generator.rb +24 -0
  100. data/lib/rails/generators/mongo_mapper/config/templates/mongo.yml +18 -0
  101. data/lib/rails/generators/mongo_mapper/model/model_generator.rb +23 -0
  102. data/lib/rails/generators/mongo_mapper/model/templates/model.rb +13 -0
  103. data/test/_NOTE_ON_TESTING +1 -0
  104. data/test/functional/associations/test_belongs_to_polymorphic_proxy.rb +64 -0
  105. data/test/functional/associations/test_belongs_to_proxy.rb +238 -0
  106. data/test/functional/associations/test_in_array_proxy.rb +349 -0
  107. data/test/functional/associations/test_many_documents_as_proxy.rb +231 -0
  108. data/test/functional/associations/test_many_documents_proxy.rb +866 -0
  109. data/test/functional/associations/test_many_embedded_polymorphic_proxy.rb +239 -0
  110. data/test/functional/associations/test_many_embedded_proxy.rb +289 -0
  111. data/test/functional/associations/test_many_polymorphic_proxy.rb +303 -0
  112. data/test/functional/associations/test_one_as_proxy.rb +491 -0
  113. data/test/functional/associations/test_one_embedded_polymorphic_proxy.rb +208 -0
  114. data/test/functional/associations/test_one_embedded_proxy.rb +100 -0
  115. data/test/functional/associations/test_one_proxy.rb +383 -0
  116. data/test/functional/test_accessible.rb +198 -0
  117. data/test/functional/test_associations.rb +46 -0
  118. data/test/functional/test_binary.rb +27 -0
  119. data/test/functional/test_caching.rb +77 -0
  120. data/test/functional/test_callbacks.rb +232 -0
  121. data/test/functional/test_dirty.rb +301 -0
  122. data/test/functional/test_document.rb +282 -0
  123. data/test/functional/test_dynamic_querying.rb +75 -0
  124. data/test/functional/test_embedded_document.rb +288 -0
  125. data/test/functional/test_equality.rb +20 -0
  126. data/test/functional/test_identity_map.rb +513 -0
  127. data/test/functional/test_indexes.rb +50 -0
  128. data/test/functional/test_logger.rb +20 -0
  129. data/test/functional/test_modifiers.rb +537 -0
  130. data/test/functional/test_pagination.rb +91 -0
  131. data/test/functional/test_protected.rb +201 -0
  132. data/test/functional/test_querying.rb +935 -0
  133. data/test/functional/test_safe.rb +76 -0
  134. data/test/functional/test_sci.rb +240 -0
  135. data/test/functional/test_scopes.rb +171 -0
  136. data/test/functional/test_timestamps.rb +62 -0
  137. data/test/functional/test_touch.rb +125 -0
  138. data/test/functional/test_userstamps.rb +44 -0
  139. data/test/functional/test_validations.rb +414 -0
  140. data/test/models.rb +261 -0
  141. data/test/support/railtie.rb +4 -0
  142. data/test/support/railtie/autoloaded.rb +2 -0
  143. data/test/support/railtie/not_autoloaded.rb +3 -0
  144. data/test/support/railtie/parent.rb +3 -0
  145. data/test/test_active_model_lint.rb +18 -0
  146. data/test/test_helper.rb +93 -0
  147. data/test/unit/associations/test_base.rb +146 -0
  148. data/test/unit/associations/test_belongs_to_association.rb +29 -0
  149. data/test/unit/associations/test_many_association.rb +63 -0
  150. data/test/unit/associations/test_one_association.rb +47 -0
  151. data/test/unit/associations/test_proxy.rb +100 -0
  152. data/test/unit/serializers/test_json_serializer.rb +216 -0
  153. data/test/unit/serializers/test_xml_serializer.rb +196 -0
  154. data/test/unit/test_clone.rb +69 -0
  155. data/test/unit/test_document.rb +249 -0
  156. data/test/unit/test_dynamic_finder.rb +125 -0
  157. data/test/unit/test_embedded_document.rb +682 -0
  158. data/test/unit/test_equality.rb +38 -0
  159. data/test/unit/test_exceptions.rb +12 -0
  160. data/test/unit/test_extensions.rb +380 -0
  161. data/test/unit/test_identity_map_middleware.rb +34 -0
  162. data/test/unit/test_inspect.rb +47 -0
  163. data/test/unit/test_key.rb +205 -0
  164. data/test/unit/test_keys.rb +65 -0
  165. data/test/unit/test_mongo_mapper.rb +143 -0
  166. data/test/unit/test_pagination.rb +11 -0
  167. data/test/unit/test_plugins.rb +89 -0
  168. data/test/unit/test_rails.rb +183 -0
  169. data/test/unit/test_rails_compatibility.rb +38 -0
  170. data/test/unit/test_rails_reflect_on_association.rb +118 -0
  171. data/test/unit/test_railtie.rb +66 -0
  172. data/test/unit/test_serialization.rb +166 -0
  173. data/test/unit/test_time_zones.rb +44 -0
  174. data/test/unit/test_translation.rb +27 -0
  175. data/test/unit/test_validations.rb +562 -0
  176. metadata +285 -0
@@ -0,0 +1,349 @@
1
+ require 'test_helper'
2
+
3
+ class InArrayProxyTest < Test::Unit::TestCase
4
+ context "description" do
5
+ setup do
6
+ class ::List
7
+ include MongoMapper::Document
8
+ key :name, String, :required => true
9
+ end
10
+
11
+ class ::User
12
+ include MongoMapper::Document
13
+ key :name, String, :required => true
14
+ key :list_ids, Array
15
+ many :lists, :in => :list_ids
16
+ end
17
+ User.collection.remove
18
+ List.collection.remove
19
+ end
20
+
21
+ teardown do
22
+ Object.send :remove_const, 'List' if defined?(::List)
23
+ Object.send :remove_const, 'User' if defined?(::User)
24
+ end
25
+
26
+ should "default reader to empty array" do
27
+ User.new.lists.should == []
28
+ end
29
+
30
+ should "allow adding to association like it was an array" do
31
+ user = User.new(:name => 'John')
32
+ user.lists << List.new(:name => 'Foo1!')
33
+ user.lists.push List.new(:name => 'Foo2!')
34
+ user.lists.concat List.new(:name => 'Foo3!')
35
+ user.lists.size.should == 3
36
+ end
37
+
38
+ should "ignore adding duplicate ids" do
39
+ user = User.create(:name => 'John')
40
+ list = List.create(:name => 'Foo')
41
+ user.lists << list
42
+ user.lists << list
43
+ user.lists << list
44
+
45
+ user.list_ids.should == [list.id]
46
+ user.lists.count.should == 1
47
+ end
48
+
49
+ should "be able to replace the association" do
50
+ user = User.new(:name => 'John')
51
+ list = List.new(:name => 'Foo')
52
+ user.lists = [list]
53
+ user.save.should be_true
54
+
55
+ user.reload
56
+ user.list_ids.should == [list.id]
57
+ user.lists.size.should == 1
58
+ user.lists[0].name.should == 'Foo'
59
+ end
60
+
61
+ context "create" do
62
+ setup do
63
+ @user = User.create(:name => 'John')
64
+ @list = @user.lists.create(:name => 'Foo!')
65
+ end
66
+
67
+ should "add id to key" do
68
+ @user.list_ids.should include(@list.id)
69
+ end
70
+
71
+ should "persist id addition to key in database" do
72
+ @user.reload
73
+ @user.list_ids.should include(@list.id)
74
+ end
75
+
76
+ should "add doc to association" do
77
+ @user.lists.should include(@list)
78
+ end
79
+
80
+ should "save doc" do
81
+ @list.should_not be_new
82
+ end
83
+
84
+ should "reset cache" do
85
+ @user.lists.size.should == 1
86
+ @user.lists.create(:name => 'Moo!')
87
+ @user.lists.size.should == 2
88
+ end
89
+ end
90
+
91
+ context "create!" do
92
+ setup do
93
+ @user = User.create(:name => 'John')
94
+ @list = @user.lists.create!(:name => 'Foo!')
95
+ end
96
+
97
+ should "add id to key" do
98
+ @user.list_ids.should include(@list.id)
99
+ end
100
+
101
+ should "persist id addition to key in database" do
102
+ @user.reload
103
+ @user.list_ids.should include(@list.id)
104
+ end
105
+
106
+ should "add doc to association" do
107
+ @user.lists.should include(@list)
108
+ end
109
+
110
+ should "save doc" do
111
+ @list.should_not be_new
112
+ end
113
+
114
+ should "raise exception if invalid" do
115
+ assert_raises(MongoMapper::DocumentNotValid) do
116
+ @user.lists.create!
117
+ end
118
+ end
119
+
120
+ should "reset cache" do
121
+ @user.lists.size.should == 1
122
+ @user.lists.create!(:name => 'Moo!')
123
+ @user.lists.size.should == 2
124
+ end
125
+ end
126
+
127
+ context "Finding scoped to association" do
128
+ setup do
129
+ @user = User.create(:name => 'John')
130
+ @user2 = User.create(:name => 'Brandon')
131
+ @list1 = @user.lists.create!(:name => 'Foo 1', :position => 1)
132
+ @list2 = @user.lists.create!(:name => 'Foo 2', :position => 2)
133
+ @list3 = @user2.lists.create!(:name => 'Foo 3', :position => 1)
134
+ end
135
+
136
+ context "all" do
137
+ should "work" do
138
+ @user.lists.all(:order => :position.asc).should == [@list1, @list2]
139
+ end
140
+
141
+ should "work with conditions" do
142
+ @user.lists.all(:name => 'Foo 1').should == [@list1]
143
+ end
144
+
145
+ should "not hit the database if ids key is empty" do
146
+ @user.list_ids = []
147
+ @user.lists.expects(:query).never
148
+ @user.lists.all.should == []
149
+ end
150
+ end
151
+
152
+ context "first" do
153
+ should "work" do
154
+ @user.lists.first(:order => 'position').should == @list1
155
+ end
156
+
157
+ should "work with conditions" do
158
+ @user.lists.first(:position => 2).should == @list2
159
+ end
160
+
161
+ should "not hit the database if ids key is empty" do
162
+ @user.list_ids = []
163
+ @user.lists.expects(:query).never
164
+ @user.lists.first.should be_nil
165
+ end
166
+ end
167
+
168
+ context "last" do
169
+ should "work" do
170
+ @user.lists.last(:order => 'position').should == @list2
171
+ end
172
+
173
+ should "work with conditions" do
174
+ @user.lists.last(:position => 2, :order => 'position').should == @list2
175
+ end
176
+
177
+ should "not hit the database if ids key is empty" do
178
+ @user.list_ids = []
179
+ @user.lists.expects(:query).never
180
+ @user.lists.last.should be_nil
181
+ end
182
+ end
183
+
184
+ context "with one id" do
185
+ should "work for id in association" do
186
+ @user.lists.find(@list1.id).should == @list1
187
+ end
188
+
189
+ should "work with string ids" do
190
+ @user.lists.find(@list1.id.to_s).should == @list1
191
+ end
192
+
193
+ should "not work for id not in association" do
194
+ @user.lists.find(@list3.id).should be_nil
195
+ end
196
+
197
+ should "raise error when using ! and not found" do
198
+ assert_raises MongoMapper::DocumentNotFound do
199
+ @user.lists.find!(@list3.id)
200
+ end
201
+ end
202
+ end
203
+
204
+ context "with multiple ids" do
205
+ should "work for ids in association" do
206
+ @user.lists.find(@list1.id, @list2.id).should == [@list1, @list2]
207
+ end
208
+
209
+ should "not work for ids not in association" do
210
+ @user.lists.find(@list1.id, @list2.id, @list3.id).should == [@list1, @list2]
211
+ end
212
+ end
213
+
214
+ context "with #paginate" do
215
+ setup do
216
+ @lists = @user.lists.paginate(:per_page => 1, :page => 1, :order => 'position')
217
+ end
218
+
219
+ should "return total pages" do
220
+ @lists.total_pages.should == 2
221
+ end
222
+
223
+ should "return total entries" do
224
+ @lists.total_entries.should == 2
225
+ end
226
+
227
+ should "return the subject" do
228
+ @lists.collect(&:name).should == ['Foo 1']
229
+ end
230
+
231
+ should "not hit the database if ids key is empty" do
232
+ @user.list_ids = []
233
+ @user.lists.expects(:query).never
234
+ @user.lists.paginate(:page => 1).should == []
235
+ end
236
+ end
237
+
238
+ context "dynamic finders" do
239
+ should "work with single key" do
240
+ @user.lists.find_by_name('Foo 1').should == @list1
241
+ @user.lists.find_by_name!('Foo 1').should == @list1
242
+ @user.lists.find_by_name('Foo 3').should be_nil
243
+ end
244
+
245
+ should "work with multiple keys" do
246
+ @user.lists.find_by_name_and_position('Foo 1', 1).should == @list1
247
+ @user.lists.find_by_name_and_position!('Foo 1', 1).should == @list1
248
+ @user.lists.find_by_name_and_position('Foo 3', 1).should be_nil
249
+ end
250
+
251
+ should "raise error when using ! and not found" do
252
+ assert_raises(MongoMapper::DocumentNotFound) do
253
+ @user.lists.find_by_name!('Foo 3')
254
+ end
255
+ end
256
+
257
+ context "find_or_create_by" do
258
+ should "not create document if found" do
259
+ lambda {
260
+ list = @user.lists.find_or_create_by_name('Foo 1')
261
+ list.should == @list1
262
+ }.should_not change { List.count }
263
+ end
264
+
265
+ should "create document if not found" do
266
+ lambda {
267
+ list = @user.lists.find_or_create_by_name('Home')
268
+ @user.lists.should include(list)
269
+ }.should change { List.count }
270
+ end
271
+ end
272
+ end
273
+ end
274
+
275
+ context "count" do
276
+ setup do
277
+ @user = User.create(:name => 'John')
278
+ @user2 = User.create(:name => 'Brandon')
279
+ @list1 = @user.lists.create!(:name => 'Foo 1')
280
+ @list2 = @user.lists.create!(:name => 'Foo 2')
281
+ @list3 = @user2.lists.create!(:name => 'Foo 3')
282
+ end
283
+
284
+ should "return number of ids" do
285
+ @user.lists.count.should == 2
286
+ @user2.lists.count.should == 1
287
+ end
288
+
289
+ should "return correct count when given criteria" do
290
+ @user.lists.count(:name => 'Foo 1').should == 1
291
+ @user2.lists.count(:name => 'Foo 1').should == 0
292
+ end
293
+
294
+ should "not hit the database if ids key is empty" do
295
+ @user.list_ids = []
296
+ @user.lists.expects(:query).never
297
+ @user.lists.count(:name => 'Foo 1').should == 0
298
+ end
299
+ end
300
+
301
+ context "Removing documents" do
302
+ setup do
303
+ @user = User.create(:name => 'John')
304
+ @user2 = User.create(:name => 'Brandon')
305
+ @list1 = @user.lists.create!(:name => 'Foo 1', :position => 1)
306
+ @list2 = @user.lists.create!(:name => 'Foo 2', :position => 2)
307
+ @list3 = @user2.lists.create!(:name => 'Foo 3', :position => 1)
308
+ end
309
+
310
+ context "destroy_all" do
311
+ should "work" do
312
+ @user.lists.count.should == 2
313
+ @user.lists.destroy_all
314
+ @user.lists.count.should == 0
315
+ end
316
+
317
+ should "work with conditions" do
318
+ @user.lists.count.should == 2
319
+ @user.lists.destroy_all(:name => 'Foo 1')
320
+ @user.lists.count.should == 1
321
+ end
322
+ end
323
+
324
+ context "delete_all" do
325
+ should "work" do
326
+ @user.lists.count.should == 2
327
+ @user.lists.delete_all
328
+ @user.lists.count.should == 0
329
+ end
330
+
331
+ should "work with conditions" do
332
+ @user.lists.count.should == 2
333
+ @user.lists.delete_all(:name => 'Foo 1')
334
+ @user.lists.count.should == 1
335
+ end
336
+ end
337
+
338
+ should "work with nullify" do
339
+ @user.lists.count.should == 2
340
+
341
+ lambda {
342
+ @user.lists.nullify
343
+ }.should_not change { List.count }
344
+
345
+ @user.lists.count.should == 0
346
+ end
347
+ end
348
+ end
349
+ end
@@ -0,0 +1,231 @@
1
+ require 'test_helper'
2
+ require 'models'
3
+
4
+ class ManyDocumentsAsProxyTest < Test::Unit::TestCase
5
+ def setup
6
+ Post.collection.remove
7
+ PostComment.collection.remove
8
+ end
9
+
10
+ should "default reader to empty array" do
11
+ Post.new.comments.should == []
12
+ end
13
+
14
+ should "add type and id key to polymorphic class base" do
15
+ PostComment.keys.keys.should include('commentable_type')
16
+ PostComment.keys['commentable_type'].type.should == String
17
+ PostComment.keys.keys.should include('commentable_id')
18
+ PostComment.keys['commentable_id'].type.should == ObjectId
19
+ end
20
+
21
+ should "allow adding to association like it was an array" do
22
+ post = Post.new
23
+ post.comments << PostComment.new(:body => 'foo bar')
24
+ post.comments << PostComment.new(:body => 'baz')
25
+ post.comments.concat PostComment.new(:body => 'baz')
26
+
27
+ post.comments.size.should == 3
28
+ end
29
+
30
+ should "be able to replace the association" do
31
+ post = Post.new
32
+
33
+ lambda {
34
+ post.comments = [
35
+ PostComment.new(:body => 'foo'),
36
+ PostComment.new(:body => 'bar'),
37
+ PostComment.new(:body => 'baz')
38
+ ]
39
+ }.should change { PostComment.count }.by(3)
40
+
41
+ post = post.reload
42
+ post.comments.size.should == 3
43
+ bodies = post.comments.collect(&:body)
44
+ bodies.should include('foo')
45
+ bodies.should include('bar')
46
+ bodies.should include('baz')
47
+ end
48
+
49
+ context "build" do
50
+ should "assign foreign key" do
51
+ post = Post.new
52
+ comment = post.comments.build
53
+ comment.commentable_id.should == post._id
54
+ end
55
+
56
+ should "assign _type" do
57
+ post = Post.new
58
+ comment = post.comments.build
59
+ comment.commentable_type.should == "Post"
60
+ end
61
+
62
+ should "allow assigning attributes" do
63
+ post = Post.new
64
+ comment = post.comments.build(:body => 'foo bar')
65
+ comment.body.should == 'foo bar'
66
+ end
67
+ end
68
+
69
+ context "create" do
70
+ should "assign foreign key" do
71
+ post = Post.new
72
+ comment = post.comments.create
73
+ comment.commentable_id.should == post._id
74
+ end
75
+
76
+ should "assign _type" do
77
+ post = Post.new
78
+ comment = post.comments.create
79
+ comment.commentable_type.should == "Post"
80
+ end
81
+
82
+ should "save record" do
83
+ post = Post.new
84
+ lambda {
85
+ post.comments.create(:body => 'baz')
86
+ }.should change { PostComment.count }
87
+ end
88
+
89
+ should "allow passing attributes" do
90
+ post = Post.create
91
+ comment = post.comments.create(:body => 'foo bar')
92
+ comment.body.should == 'foo bar'
93
+ end
94
+ end
95
+
96
+ context "count" do
97
+ should "work scoped to association" do
98
+ post = Post.create
99
+ 3.times { post.comments.create(:body => 'foo bar') }
100
+
101
+ other_post = Post.create
102
+ 2.times { other_post.comments.create(:body => 'baz') }
103
+
104
+ post.comments.count.should == 3
105
+ other_post.comments.count.should == 2
106
+ end
107
+
108
+ should "work with conditions" do
109
+ post = Post.create
110
+ post.comments.create(:body => 'foo bar')
111
+ post.comments.create(:body => 'baz')
112
+ post.comments.create(:body => 'foo bar')
113
+
114
+ post.comments.count(:body => 'foo bar').should == 2
115
+ end
116
+ end
117
+
118
+ context "Finding scoped to association" do
119
+ setup do
120
+ @post = Post.new
121
+
122
+ @comment1 = PostComment.create(:body => 'comment1', :name => 'John')
123
+ @comment2 = PostComment.create(:body => 'comment2', :name => 'Steve')
124
+ @comment3 = PostComment.create(:body => 'comment3', :name => 'John')
125
+ @post.comments = [@comment1, @comment2]
126
+ @post.save
127
+
128
+ @post2 = Post.create(:body => "post #2")
129
+ @comment4 = PostComment.create(:body => 'comment1', :name => 'Chas')
130
+ @comment5 = PostComment.create(:body => 'comment2', :name => 'Dan')
131
+ @comment6 = PostComment.create(:body => 'comment3', :name => 'Ed')
132
+ @post2.comments = [@comment4, @comment5, @comment6]
133
+ @post2.save
134
+ end
135
+
136
+ context "with #all" do
137
+ should "work" do
138
+ @post.comments.all.should include(@comment1)
139
+ @post.comments.all.should include(@comment2)
140
+ end
141
+
142
+ should "work with conditions" do
143
+ comments = @post.comments.all(:body => 'comment1')
144
+ comments.should == [@comment1]
145
+ end
146
+
147
+ should "work with order" do
148
+ comments = @post.comments.all(:order => 'body desc')
149
+ comments.should == [@comment2, @comment1]
150
+ end
151
+ end
152
+
153
+ context "with one id" do
154
+ should "work for id in association" do
155
+ @post.comments.find(@comment2._id).should == @comment2
156
+ end
157
+
158
+ should "not work for id not in association" do
159
+ assert_raises(MongoMapper::DocumentNotFound) do
160
+ @post.comments.find!(@comment5._id)
161
+ end
162
+ end
163
+ end
164
+
165
+ context "with multiple ids" do
166
+ should "work for ids in association" do
167
+ posts = @post.comments.find!(@comment1._id, @comment2._id)
168
+ posts.should == [@comment1, @comment2]
169
+ end
170
+
171
+ should "not work for ids not in association" do
172
+ assert_raises(MongoMapper::DocumentNotFound) do
173
+ @post.comments.find!(@comment1._id, @comment2._id, @comment4._id)
174
+ end
175
+ end
176
+ end
177
+
178
+ context "dynamic finders" do
179
+ should "work with single key" do
180
+ @post.comments.find_by_body('comment1').should == @comment1
181
+ @post2.comments.find_by_body('comment1').should == @comment4
182
+ end
183
+
184
+ should "work with multiple keys" do
185
+ @post.comments.find_by_body_and_name('comment1', 'John').should == @comment1
186
+ @post.comments.find_by_body_and_name('comment1', 'Frank').should be_nil
187
+ end
188
+
189
+ should "raise error when using !" do
190
+ lambda {
191
+ @post.comments.find_by_body!('asdf')
192
+ }.should raise_error(MongoMapper::DocumentNotFound)
193
+ end
194
+
195
+ context "find_or_create_by" do
196
+ should "not create document if found" do
197
+ lambda {
198
+ comment = @post.comments.find_or_create_by_name('Steve')
199
+ comment.commentable.should == @post
200
+ comment.should == @comment2
201
+ }.should_not change { PostComment.count }
202
+ end
203
+
204
+ should "create document if not found" do
205
+ lambda {
206
+ @post.comments.find_or_create_by_name('Chas')
207
+ }.should change { PostComment.count }.by(1)
208
+ end
209
+ end
210
+ end
211
+
212
+ context "with #paginate" do
213
+ setup do
214
+ @comments = @post2.comments.paginate(:per_page => 2, :page => 1, :order => 'name')
215
+ end
216
+
217
+ should "return total pages" do
218
+ @comments.total_pages.should == 2
219
+ end
220
+
221
+ should "return total entries" do
222
+ @comments.total_entries.should == 3
223
+ end
224
+
225
+ should "return the subject" do
226
+ @comments.should include(@comment4)
227
+ @comments.should include(@comment5)
228
+ end
229
+ end
230
+ end
231
+ end