djsun-mongomapper 0.3.5.5 → 0.4.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. data/README.rdoc +38 -38
  2. data/Rakefile +87 -73
  3. data/VERSION +1 -1
  4. data/lib/mongomapper.rb +67 -71
  5. data/lib/mongomapper/associations.rb +86 -84
  6. data/lib/mongomapper/associations/belongs_to_polymorphic_proxy.rb +34 -34
  7. data/lib/mongomapper/associations/many_embedded_proxy.rb +67 -17
  8. data/lib/mongomapper/associations/proxy.rb +74 -73
  9. data/lib/mongomapper/document.rb +342 -348
  10. data/lib/mongomapper/embedded_document.rb +354 -274
  11. data/lib/mongomapper/finder_options.rb +84 -84
  12. data/lib/mongomapper/key.rb +32 -76
  13. data/lib/mongomapper/rails_compatibility/document.rb +14 -14
  14. data/lib/mongomapper/rails_compatibility/embedded_document.rb +26 -24
  15. data/lib/mongomapper/support.rb +156 -29
  16. data/lib/mongomapper/validations.rb +69 -47
  17. data/test/custom_matchers.rb +48 -0
  18. data/test/functional/associations/test_belongs_to_polymorphic_proxy.rb +53 -56
  19. data/test/functional/associations/test_belongs_to_proxy.rb +48 -49
  20. data/test/functional/associations/test_many_documents_as_proxy.rb +208 -253
  21. data/test/functional/associations/test_many_embedded_polymorphic_proxy.rb +130 -130
  22. data/test/functional/associations/test_many_embedded_proxy.rb +168 -106
  23. data/test/functional/associations/test_many_polymorphic_proxy.rb +261 -262
  24. data/test/functional/test_binary.rb +21 -0
  25. data/test/functional/test_document.rb +946 -952
  26. data/test/functional/test_embedded_document.rb +98 -0
  27. data/test/functional/test_pagination.rb +87 -80
  28. data/test/functional/test_rails_compatibility.rb +29 -29
  29. data/test/functional/test_validations.rb +262 -172
  30. data/test/models.rb +169 -169
  31. data/test/test_helper.rb +28 -66
  32. data/test/unit/serializers/test_json_serializer.rb +193 -193
  33. data/test/unit/test_document.rb +161 -123
  34. data/test/unit/test_embedded_document.rb +643 -547
  35. data/test/unit/test_finder_options.rb +183 -183
  36. data/test/unit/test_key.rb +175 -247
  37. data/test/unit/test_rails_compatibility.rb +38 -33
  38. data/test/unit/test_serializations.rb +52 -52
  39. data/test/unit/test_support.rb +268 -0
  40. data/test/unit/test_time_zones.rb +40 -0
  41. data/test/unit/test_validations.rb +499 -258
  42. metadata +22 -12
  43. data/History +0 -76
  44. data/mongomapper.gemspec +0 -145
@@ -1,47 +1,69 @@
1
- module MongoMapper
2
- module Validations
3
- class ValidatesUniquenessOf < Validatable::ValidationBase
4
- def valid?(instance)
5
- # TODO: scope
6
- doc = instance.class.find(:first, :conditions => {self.attribute => instance[attribute]}, :limit => 1)
7
- doc.nil? || instance.id == doc.id
8
- end
9
-
10
- def message(instance)
11
- super || "has already been taken"
12
- end
13
- end
14
-
15
- class ValidatesExclusionOf < Validatable::ValidationBase
16
- required_option :within
17
-
18
- def valid?(instance)
19
- value = instance[attribute]
20
- return true if allow_nil && value.nil?
21
- return true if allow_blank && value.blank?
22
-
23
- !within.include?(instance[attribute])
24
- end
25
-
26
- def message(instance)
27
- super || "is reserved"
28
- end
29
- end
30
-
31
- class ValidatesInclusionOf < Validatable::ValidationBase
32
- required_option :within
33
-
34
- def valid?(instance)
35
- value = instance[attribute]
36
- return true if allow_nil && value.nil?
37
- return true if allow_blank && value.blank?
38
-
39
- within.include?(value)
40
- end
41
-
42
- def message(instance)
43
- super || "is not in the list"
44
- end
45
- end
46
- end
47
- end
1
+ module MongoMapper
2
+ module Validations
3
+ module Macros
4
+ def validates_uniqueness_of(*args)
5
+ add_validations(args, MongoMapper::Validations::ValidatesUniquenessOf)
6
+ end
7
+
8
+ def validates_exclusion_of(*args)
9
+ add_validations(args, MongoMapper::Validations::ValidatesExclusionOf)
10
+ end
11
+
12
+ def validates_inclusion_of(*args)
13
+ add_validations(args, MongoMapper::Validations::ValidatesInclusionOf)
14
+ end
15
+ end
16
+
17
+ class ValidatesUniquenessOf < Validatable::ValidationBase
18
+ option :scope
19
+
20
+ def valid?(instance)
21
+ doc = instance.class.find(:first, :conditions => {self.attribute => instance[attribute]}.merge(scope_conditions(instance)), :limit => 1)
22
+ doc.nil? || instance.id == doc.id
23
+ end
24
+
25
+ def message(instance)
26
+ super || "has already been taken"
27
+ end
28
+
29
+ def scope_conditions(instance)
30
+ return {} unless scope
31
+ Array(scope).inject({}) do |conditions, key|
32
+ conditions.merge(key => instance[key])
33
+ end
34
+ end
35
+ end
36
+
37
+ class ValidatesExclusionOf < Validatable::ValidationBase
38
+ required_option :within
39
+
40
+ def valid?(instance)
41
+ value = instance[attribute]
42
+ return true if allow_nil && value.nil?
43
+ return true if allow_blank && value.blank?
44
+
45
+ !within.include?(instance[attribute])
46
+ end
47
+
48
+ def message(instance)
49
+ super || "is reserved"
50
+ end
51
+ end
52
+
53
+ class ValidatesInclusionOf < Validatable::ValidationBase
54
+ required_option :within
55
+
56
+ def valid?(instance)
57
+ value = instance[attribute]
58
+ return true if allow_nil && value.nil?
59
+ return true if allow_blank && value.blank?
60
+
61
+ within.include?(value)
62
+ end
63
+
64
+ def message(instance)
65
+ super || "is not in the list"
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,48 @@
1
+ module CustomMatchers
2
+ custom_matcher :be_nil do |receiver, matcher, args|
3
+ matcher.positive_failure_message = "Expected #{receiver} to be nil but it wasn't"
4
+ matcher.negative_failure_message = "Expected #{receiver} not to be nil but it was"
5
+ receiver.nil?
6
+ end
7
+
8
+ custom_matcher :be_blank do |receiver, matcher, args|
9
+ matcher.positive_failure_message = "Expected #{receiver} to be blank but it wasn't"
10
+ matcher.negative_failure_message = "Expected #{receiver} not to be blank but it was"
11
+ receiver.blank?
12
+ end
13
+
14
+ custom_matcher :be_true do |receiver, matcher, args|
15
+ matcher.positive_failure_message = "Expected #{receiver} to be true but it wasn't"
16
+ matcher.negative_failure_message = "Expected #{receiver} not to be true but it was"
17
+ receiver.eql?(true)
18
+ end
19
+
20
+ custom_matcher :be_false do |receiver, matcher, args|
21
+ matcher.positive_failure_message = "Expected #{receiver} to be false but it wasn't"
22
+ matcher.negative_failure_message = "Expected #{receiver} not to be false but it was"
23
+ receiver.eql?(false)
24
+ end
25
+
26
+ custom_matcher :be_valid do |receiver, matcher, args|
27
+ matcher.positive_failure_message = "Expected to be valid but it was invalid #{receiver.errors.inspect}"
28
+ matcher.negative_failure_message = "Expected to be invalid but it was valid #{receiver.errors.inspect}"
29
+ receiver.valid?
30
+ end
31
+
32
+ custom_matcher :have_error_on do |receiver, matcher, args|
33
+ receiver.valid?
34
+ attribute = args[0]
35
+ expected_message = args[1]
36
+
37
+ if expected_message.nil?
38
+ matcher.positive_failure_message = "#{receiver} had no errors on #{attribute}"
39
+ matcher.negative_failure_message = "#{receiver} had errors on #{attribute} #{receiver.errors.inspect}"
40
+ !receiver.errors.on(attribute).blank?
41
+ else
42
+ actual = receiver.errors.on(attribute)
43
+ matcher.positive_failure_message = %Q(Expected error on #{attribute} to be "#{expected_message}" but was "#{actual}")
44
+ matcher.negative_failure_message = %Q(Expected error on #{attribute} not to be "#{expected_message}" but was "#{actual}")
45
+ actual == expected_message
46
+ end
47
+ end
48
+ end
@@ -1,57 +1,54 @@
1
- require 'test_helper'
2
- require 'models'
3
-
4
- class BelongsToPolymorphicProxyTest < Test::Unit::TestCase
5
- def setup
6
- clear_all_collections
7
- end
8
-
9
- should "default to nil" do
10
- status = Status.new
11
- status.target.should be_nil
12
- status.target.inspect.should == "nil"
13
- end
14
-
15
- should "be able to replace the association" do
16
- status = Status.new
17
- project = Project.new(:name => "mongomapper")
18
- status.target = project
19
- status.save.should be_true
20
-
21
- from_db = Status.find(status.id)
22
- from_db.target.should_not be_nil
23
- from_db.target.inspect.should_not be_empty
24
- from_db.target_id.should == project.id
25
- from_db.target_type.should == "Project"
26
- from_db.target.name.should == "mongomapper"
27
- end
28
-
29
- should "unset the association" do
30
- status = Status.new
31
- project = Project.new(:name => "mongomapper")
32
- status.target = project
33
- status.save.should be_true
34
-
35
- from_db = Status.find(status.id)
36
- from_db.target = nil
37
- from_db.target_type.should be_nil
38
- from_db.target_id.should be_nil
39
- from_db.target.should be_nil
40
- from_db.target.inspect.should == "nil"
41
- end
42
-
43
- context "association id set but document not found" do
44
- setup do
45
- @status = Status.new
46
- project = Project.new(:name => "mongomapper")
47
- @status.target = project
48
- @status.save.should be_true
49
- project.destroy
50
- end
51
-
52
- should "return nil instead of raising error" do
53
- @status.target.should be_nil
54
- @status.target.inspect.should == "nil"
55
- end
56
- end
1
+ require 'test_helper'
2
+ require 'models'
3
+
4
+ class BelongsToPolymorphicProxyTest < Test::Unit::TestCase
5
+ def setup
6
+ clear_all_collections
7
+ end
8
+
9
+ should "default to nil" do
10
+ status = Status.new
11
+ status.target.nil?.should == true
12
+ status.target.inspect.should == "nil"
13
+ end
14
+
15
+ should "be able to replace the association" do
16
+ status = Status.new
17
+ project = Project.new(:name => "mongomapper")
18
+ status.target = project
19
+ status.save.should be_true
20
+
21
+ from_db = Status.find(status.id)
22
+ from_db.target.nil?.should == false
23
+ from_db.target_id.should == project.id
24
+ from_db.target_type.should == "Project"
25
+ from_db.target.name.should == "mongomapper"
26
+ end
27
+
28
+ should "unset the association" do
29
+ status = Status.new
30
+ project = Project.new(:name => "mongomapper")
31
+ status.target = project
32
+ status.save.should be_true
33
+
34
+ from_db = Status.find(status.id)
35
+ from_db.target = nil
36
+ from_db.target_type.nil?.should == true
37
+ from_db.target_id.nil?.should == true
38
+ from_db.target.nil?.should == true
39
+ end
40
+
41
+ context "association id set but document not found" do
42
+ setup do
43
+ @status = Status.new
44
+ project = Project.new(:name => "mongomapper")
45
+ @status.target = project
46
+ @status.save.should be_true
47
+ project.destroy
48
+ end
49
+
50
+ should "return nil instead of raising error" do
51
+ @status.target.nil?.should == true
52
+ end
53
+ end
57
54
  end
@@ -1,49 +1,48 @@
1
- require 'test_helper'
2
- require 'models'
3
-
4
- class BelongsToProxyTest < Test::Unit::TestCase
5
- def setup
6
- clear_all_collections
7
- end
8
-
9
- should "default to nil" do
10
- status = Status.new
11
- status.project.should be_nil
12
- status.project.inspect.should == "nil"
13
- end
14
-
15
- should "be able to replace the association" do
16
- status = Status.new
17
- project = Project.new(:name => "mongomapper")
18
- status.project = project
19
- status.save.should be_true
20
-
21
- from_db = Status.find(status.id)
22
- from_db.project.should_not be_nil
23
- from_db.project.inspect.should_not be_empty
24
- from_db.project.name.should == "mongomapper"
25
- end
26
-
27
- should "unset the association" do
28
- status = Status.new
29
- project = Project.new(:name => "mongomapper")
30
- status.project = project
31
- status.save.should be_true
32
-
33
- from_db = Status.find(status.id)
34
- from_db.project = nil
35
- from_db.project.should be_nil
36
- from_db.project.inspect.should == "nil"
37
- end
38
-
39
- context "association id set but document not found" do
40
- setup do
41
- @status = Status.new(:name => 'Foo', :project_id => '1234')
42
- end
43
-
44
- should "return nil instead of raising error" do
45
- @status.project.should be_nil
46
- @status.project.inspect.should == "nil"
47
- end
48
- end
49
- end
1
+ require 'test_helper'
2
+ require 'models'
3
+
4
+ class BelongsToProxyTest < Test::Unit::TestCase
5
+ def setup
6
+ clear_all_collections
7
+ end
8
+
9
+ should "default to nil" do
10
+ status = Status.new
11
+ status.project.nil?.should == true
12
+ status.project.inspect.should == "nil"
13
+ end
14
+
15
+ should "be able to replace the association" do
16
+ status = Status.new
17
+ project = Project.new(:name => "mongomapper")
18
+ status.project = project
19
+ status.save.should be_true
20
+
21
+ from_db = Status.find(status.id)
22
+ from_db.project.should_not be_nil
23
+ from_db.project.name.should == "mongomapper"
24
+ end
25
+
26
+ should "unset the association" do
27
+ status = Status.new
28
+ project = Project.new(:name => "mongomapper")
29
+ status.project = project
30
+ status.save.should be_true
31
+
32
+ from_db = Status.find(status.id)
33
+ from_db.project = nil
34
+ from_db.project.nil?.should == true
35
+ from_db.project.inspect.should == "nil"
36
+ end
37
+
38
+ context "association id set but document not found" do
39
+ setup do
40
+ @status = Status.new(:name => 'Foo', :project_id => '1234')
41
+ end
42
+
43
+ should "return nil instead of raising error" do
44
+ @status.project.nil?.should == true
45
+ @status.project.inspect.should == "nil"
46
+ end
47
+ end
48
+ end
@@ -1,254 +1,209 @@
1
- require 'test_helper'
2
- require 'models'
3
-
4
- class ManyDocumentsAsProxyTest < Test::Unit::TestCase
5
- def setup
6
- clear_all_collections
7
- end
8
-
9
- should "default reader to empty array" do
10
- Post.new.comments.should == []
11
- Post.new.comments.inspect.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
- from_db = Post.find(post.id)
40
- from_db.comments.size.should == 3
41
- from_db.comments[0].body.should == 'foo'
42
- from_db.comments[1].body.should == 'bar'
43
- from_db.comments[2].body.should == 'baz'
44
- end
45
-
46
- context "build" do
47
- should "assign foreign key" do
48
- post = Post.new
49
- comment = post.comments.build
50
- comment.commentable_id.should == post.id
51
- end
52
-
53
- should "assign _type" do
54
- post = Post.new
55
- comment = post.comments.build
56
- comment.commentable_type.should == "Post"
57
- end
58
-
59
- should "allow assigning attributes" do
60
- post = Post.new
61
- comment = post.comments.build(:body => 'foo bar')
62
- comment.body.should == 'foo bar'
63
- end
64
- end
65
-
66
- context "create" do
67
- should "assign foreign key" do
68
- post = Post.new
69
- comment = post.comments.create
70
- comment.commentable_id.should == post.id
71
- end
72
-
73
- should "assign _type" do
74
- post = Post.new
75
- comment = post.comments.create
76
- comment.commentable_type.should == "Post"
77
- end
78
-
79
- should "save record" do
80
- post = Post.new
81
- lambda {
82
- post.comments.create(:body => 'baz')
83
- }.should change { PostComment.count }
84
- end
85
-
86
- should "allow passing attributes" do
87
- post = Post.create
88
- comment = post.comments.create(:body => 'foo bar')
89
- comment.body.should == 'foo bar'
90
- end
91
- end
92
-
93
- context "count" do
94
- should "work scoped to association" do
95
- post = Post.create
96
- 3.times { post.comments.create(:body => 'foo bar') }
97
-
98
- other_post = Post.create
99
- 2.times { other_post.comments.create(:body => 'baz') }
100
-
101
- post.comments.count.should == 3
102
- other_post.comments.count.should == 2
103
- end
104
-
105
- should "work with conditions" do
106
- post = Post.create
107
- post.comments.create(:body => 'foo bar')
108
- post.comments.create(:body => 'baz')
109
- post.comments.create(:body => 'foo bar')
110
-
111
- post.comments.count(:body => 'foo bar').should == 2
112
- end
113
- end
114
-
115
- context "Finding scoped to association" do
116
- setup do
117
- @post = Post.new
118
-
119
- @comment1 = PostComment.create(:body => 'comment1')
120
- @comment2 = PostComment.create(:body => 'comment2')
121
- @comment3 = PostComment.create(:body => 'comment3')
122
- @post.comments = [@comment1, @comment2]
123
- @post.save
124
-
125
- @post2 = Post.create(:body => "post #2")
126
- @comment4 = PostComment.create(:body => 'comment4')
127
- @comment5 = PostComment.create(:body => 'comment5')
128
- @comment6 = PostComment.create(:body => 'comment6')
129
- @post2.comments = [@comment4, @comment5, @comment6]
130
- @post2.save
131
- end
132
-
133
- context "with :all" do
134
- should "work" do
135
- @post.comments.find(:all).should include(@comment1)
136
- @post.comments.find(:all).should include(@comment2)
137
- end
138
-
139
- should "work with conditions" do
140
- comments = @post.comments.find(:all, :conditions => {:body => 'comment1'})
141
- comments.should == [@comment1]
142
- end
143
-
144
- should "work with order" do
145
- comments = @post.comments.find(:all, :order => 'body desc')
146
- comments.should == [@comment2, @comment1]
147
- end
148
- end
149
-
150
- context "with #all" do
151
- should "work" do
152
- @post.comments.all.should == [@comment1, @comment2]
153
- end
154
-
155
- should "work with conditions" do
156
- comments = @post.comments.all(:conditions => {:body => 'comment1'})
157
- comments.should == [@comment1]
158
- end
159
-
160
- should "work with order" do
161
- comments = @post.comments.all(:order => '$natural desc')
162
- comments.should == [@comment2, @comment1]
163
- end
164
- end
165
-
166
- context "with :first" do
167
- should "work" do
168
- lambda {@post.comments.find(:first)}.should_not raise_error
169
- end
170
-
171
- should "work with conditions" do
172
- comment = @post.comments.find(:first, :conditions => {:body => 'comment2'})
173
- comment.body.should == 'comment2'
174
- end
175
- end
176
-
177
- context "with #first" do
178
- should "work" do
179
- @post.comments.first.should == @comment1
180
- end
181
-
182
- should "work with conditions" do
183
- comment = @post.comments.first(:conditions => {:body => 'comment2'}, :order => 'body desc')
184
- comment.should == @comment2
185
- end
186
- end
187
-
188
- context "with :last" do
189
- should "work" do
190
- @post.comments.find(:last, :order => 'created_at asc').should == @comment2
191
- end
192
-
193
- should "work with conditions" do
194
- post = @post.comments.find(:last, :conditions => {:body => 'comment1'})
195
- post.body.should == 'comment1'
196
- end
197
- end
198
-
199
- context "with #last" do
200
- should "work" do
201
- @post.comments.last.should == @comment2
202
- end
203
-
204
- should "work with conditions" do
205
- comment = @post.comments.last(:conditions => {:body => 'comment1'})
206
- comment.should == @comment1
207
- end
208
- end
209
-
210
- context "with one id" do
211
- should "work for id in association" do
212
- @post.comments.find(@comment2.id).should == @comment2
213
- end
214
-
215
- should "not work for id not in association" do
216
- lambda {
217
- @post.comments.find(@comment5.id)
218
- }.should raise_error(MongoMapper::DocumentNotFound)
219
- end
220
- end
221
-
222
- context "with multiple ids" do
223
- should "work for ids in association" do
224
- posts = @post.comments.find(@comment1.id, @comment2.id)
225
- posts.should == [@comment1, @comment2]
226
- end
227
-
228
- should "not work for ids not in association" do
229
- lambda {
230
- @post.comments.find(@comment1.id, @comment2.id, @comment4.id)
231
- }.should raise_error(MongoMapper::DocumentNotFound)
232
- end
233
- end
234
-
235
- context "with #paginate" do
236
- setup do
237
- @comments = @post2.comments.paginate(:per_page => 2, :page => 1, :order => 'created_at asc')
238
- end
239
-
240
- should "return total pages" do
241
- @comments.total_pages.should == 2
242
- end
243
-
244
- should "return total entries" do
245
- @comments.total_entries.should == 3
246
- end
247
-
248
- should "return the subject" do
249
- @comments.should include(@comment4)
250
- @comments.should include(@comment5)
251
- end
252
- end
253
- end
1
+ require 'test_helper'
2
+ require 'models'
3
+
4
+ class ManyDocumentsAsProxyTest < Test::Unit::TestCase
5
+ def setup
6
+ clear_all_collections
7
+ end
8
+
9
+ should "default reader to empty array" do
10
+ Post.new.comments.should == []
11
+ end
12
+
13
+ should "add type and id key to polymorphic class base" do
14
+ PostComment.keys.keys.should include('commentable_type')
15
+ PostComment.keys.keys.should include('commentable_id')
16
+ end
17
+
18
+ should "allow adding to association like it was an array" do
19
+ post = Post.new
20
+ post.comments << PostComment.new(:body => 'foo bar')
21
+ post.comments << PostComment.new(:body => 'baz')
22
+ post.comments.concat PostComment.new(:body => 'baz')
23
+
24
+ post.comments.size.should == 3
25
+ end
26
+
27
+ should "be able to replace the association" do
28
+ post = Post.new
29
+
30
+ lambda {
31
+ post.comments = [
32
+ PostComment.new(:body => 'foo'),
33
+ PostComment.new(:body => 'bar'),
34
+ PostComment.new(:body => 'baz')
35
+ ]
36
+ }.should change { PostComment.count }.by(3)
37
+
38
+ from_db = Post.find(post.id)
39
+ from_db.comments.size.should == 3
40
+ from_db.comments[0].body.should == 'foo'
41
+ from_db.comments[1].body.should == 'bar'
42
+ from_db.comments[2].body.should == 'baz'
43
+ end
44
+
45
+ context "build" do
46
+ should "assign foreign key" do
47
+ post = Post.new
48
+ comment = post.comments.build
49
+ comment.commentable_id.should == post.id
50
+ end
51
+
52
+ should "assign _type" do
53
+ post = Post.new
54
+ comment = post.comments.build
55
+ comment.commentable_type.should == "Post"
56
+ end
57
+
58
+ should "allow assigning attributes" do
59
+ post = Post.new
60
+ comment = post.comments.build(:body => 'foo bar')
61
+ comment.body.should == 'foo bar'
62
+ end
63
+ end
64
+
65
+ context "create" do
66
+ should "assign foreign key" do
67
+ post = Post.new
68
+ comment = post.comments.create
69
+ comment.commentable_id.should == post.id
70
+ end
71
+
72
+ should "assign _type" do
73
+ post = Post.new
74
+ comment = post.comments.create
75
+ comment.commentable_type.should == "Post"
76
+ end
77
+
78
+ should "save record" do
79
+ post = Post.new
80
+ lambda {
81
+ post.comments.create(:body => 'baz')
82
+ }.should change { PostComment.count }
83
+ end
84
+
85
+ should "allow passing attributes" do
86
+ post = Post.create
87
+ comment = post.comments.create(:body => 'foo bar')
88
+ comment.body.should == 'foo bar'
89
+ end
90
+ end
91
+
92
+ context "count" do
93
+ should "work scoped to association" do
94
+ post = Post.create
95
+ 3.times { post.comments.create(:body => 'foo bar') }
96
+
97
+ other_post = Post.create
98
+ 2.times { other_post.comments.create(:body => 'baz') }
99
+
100
+ post.comments.count.should == 3
101
+ other_post.comments.count.should == 2
102
+ end
103
+
104
+ should "work with conditions" do
105
+ post = Post.create
106
+ post.comments.create(:body => 'foo bar')
107
+ post.comments.create(:body => 'baz')
108
+ post.comments.create(:body => 'foo bar')
109
+
110
+ post.comments.count(:body => 'foo bar').should == 2
111
+ end
112
+ end
113
+
114
+ context "Finding scoped to association" do
115
+ setup do
116
+ @post = Post.new
117
+
118
+ @comment1 = PostComment.create(:body => 'comment1')
119
+ @comment2 = PostComment.create(:body => 'comment2')
120
+ @comment3 = PostComment.create(:body => 'comment3')
121
+ @post.comments = [@comment1, @comment2]
122
+ @post.save
123
+
124
+ @post2 = Post.create(:body => "post #2")
125
+ @comment4 = PostComment.create(:body => 'comment4')
126
+ @comment5 = PostComment.create(:body => 'comment5')
127
+ @comment6 = PostComment.create(:body => 'comment6')
128
+ @post2.comments = [@comment4, @comment5, @comment6]
129
+ @post2.save
130
+ end
131
+
132
+ context "with :all" do
133
+ should "work" do
134
+ @post.comments.find(:all).should include(@comment1)
135
+ @post.comments.find(:all).should include(@comment2)
136
+ end
137
+
138
+ should "work with conditions" do
139
+ comments = @post.comments.find(:all, :conditions => {:body => 'comment1'})
140
+ comments.should == [@comment1]
141
+ end
142
+
143
+ should "work with order" do
144
+ comments = @post.comments.find(:all, :order => 'body desc')
145
+ comments.should == [@comment2, @comment1]
146
+ end
147
+ end
148
+
149
+ context "with #all" do
150
+ should "work" do
151
+ @post.comments.all.should == [@comment1, @comment2]
152
+ end
153
+
154
+ should "work with conditions" do
155
+ comments = @post.comments.all(:conditions => {:body => 'comment1'})
156
+ comments.should == [@comment1]
157
+ end
158
+
159
+ should "work with order" do
160
+ comments = @post.comments.all(:order => '$natural desc')
161
+ comments.should == [@comment2, @comment1]
162
+ end
163
+ end
164
+
165
+ context "with one id" do
166
+ should "work for id in association" do
167
+ @post.comments.find(@comment2.id).should == @comment2
168
+ end
169
+
170
+ should "not work for id not in association" do
171
+ lambda {
172
+ @post.comments.find(@comment5.id)
173
+ }.should raise_error(MongoMapper::DocumentNotFound)
174
+ end
175
+ end
176
+
177
+ context "with multiple ids" do
178
+ should "work for ids in association" do
179
+ posts = @post.comments.find(@comment1.id, @comment2.id)
180
+ posts.should == [@comment1, @comment2]
181
+ end
182
+
183
+ should "not work for ids not in association" do
184
+ lambda {
185
+ @post.comments.find(@comment1.id, @comment2.id, @comment4.id)
186
+ }.should raise_error(MongoMapper::DocumentNotFound)
187
+ end
188
+ end
189
+
190
+ context "with #paginate" do
191
+ setup do
192
+ @comments = @post2.comments.paginate(:per_page => 2, :page => 1, :order => 'created_at asc')
193
+ end
194
+
195
+ should "return total pages" do
196
+ @comments.total_pages.should == 2
197
+ end
198
+
199
+ should "return total entries" do
200
+ @comments.total_entries.should == 3
201
+ end
202
+
203
+ should "return the subject" do
204
+ @comments.should include(@comment4)
205
+ @comments.should include(@comment5)
206
+ end
207
+ end
208
+ end
254
209
  end