jonbell-mongo_mapper 0.8.6

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