djsun-mongomapper 0.3.5.5 → 0.4.1.2

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 (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
@@ -0,0 +1,98 @@
1
+ require 'test_helper'
2
+ require 'models'
3
+
4
+ class EmbeddedDocumentTest < Test::Unit::TestCase
5
+ def setup
6
+ @document = Class.new do
7
+ include MongoMapper::Document
8
+ set_collection_name 'users'
9
+
10
+ key :first_name, String
11
+ key :last_name, String
12
+ end
13
+
14
+ clear_all_collections
15
+ end
16
+
17
+ context "Saving a document with an embedded document" do
18
+ setup do
19
+ @document.class_eval do
20
+ key :foo, Address
21
+ end
22
+
23
+ @address = Address.new(:city => 'South Bend', :state => 'IN')
24
+ @doc = @document.new(:foo => @address)
25
+ end
26
+
27
+ should "embed embedded document" do
28
+ @doc.save
29
+ @doc.foo.city.should == 'South Bend'
30
+ @doc.foo.state.should == 'IN'
31
+
32
+ from_db = @document.find(@doc.id)
33
+ from_db.foo.city.should == 'South Bend'
34
+ from_db.foo.state.should == 'IN'
35
+ end
36
+ end
37
+
38
+ context "new?" do
39
+ setup do
40
+ @document.class_eval do
41
+ key :foo, Address
42
+ end
43
+ end
44
+
45
+ should "be new until document is saved" do
46
+ address = Address.new(:city => 'South Bend', :state => 'IN')
47
+ doc = @document.new(:foo => address)
48
+ address.new?.should == true
49
+ end
50
+
51
+ should "not be new after document is saved" do
52
+ address = Address.new(:city => 'South Bend', :state => 'IN')
53
+ doc = @document.new(:foo => address)
54
+ doc.save
55
+ doc.foo.new?.should == false
56
+ end
57
+
58
+ should "not be new when document is read back" do
59
+ address = Address.new(:city => 'South Bend', :state => 'IN')
60
+ doc = @document.new(:foo => address)
61
+ doc.save
62
+ read_doc = @document.find(doc.id)
63
+ read_doc.foo.new?.should == false
64
+ end
65
+ end
66
+
67
+ context "save" do
68
+ should "save the root document" do
69
+ person = RealPerson.create
70
+
71
+ pet = Pet.new :name => 'sparky'
72
+ person.pets << pet
73
+ pet.save
74
+
75
+ doc = RealPerson.find(person.id)
76
+ doc.pets.first.should == pet
77
+ end
78
+ end
79
+
80
+ context "update_attributes" do
81
+ should "save the root document" do
82
+ person = RealPerson.create
83
+
84
+ pet = Pet.new(:name => 'sparky')
85
+ person.pets << pet
86
+ pet.save
87
+
88
+ doc = RealPerson.find(person.id)
89
+ pet = doc.pets.first
90
+ pet.update_attributes :name => 'koda'
91
+
92
+ doc = RealPerson.find(person.id)
93
+ embedded = doc.pets.first
94
+ embedded.id.should == pet.id
95
+ embedded.name.should == 'koda'
96
+ end
97
+ end
98
+ end
@@ -1,81 +1,88 @@
1
- require 'test_helper'
2
-
3
- class PaginationTest < Test::Unit::TestCase
4
- context "Paginating" do
5
- setup do
6
- @document = Class.new do
7
- include MongoMapper::Document
8
- collection 'users'
9
-
10
- key :first_name, String
11
- key :last_name, String
12
- key :age, Integer
13
- end
14
-
15
- @document.collection.clear
16
-
17
- @doc1 = @document.create({:first_name => 'John', :last_name => 'Nunemaker', :age => '27'})
18
- @doc2 = @document.create({:first_name => 'Steve', :last_name => 'Smith', :age => '28'})
19
- @doc3 = @document.create({:first_name => 'Steph', :last_name => 'Nunemaker', :age => '26'})
20
- end
21
-
22
- should "return the total pages" do
23
- result = @document.paginate(:per_page => 2, :page => 1)
24
- result.total_pages.should == 2
25
- end
26
-
27
- should "return the total of records" do
28
- result = @document.paginate(:per_page => 2, :page => 1)
29
- result.total_entries.should == 3
30
- end
31
-
32
- should "return the items" do
33
- result = @document.paginate(:per_page => 2, :page => 1, :order => 'first_name')
34
- result.size.should == 2
35
- result.should == [@doc1, @doc3]
36
- end
37
-
38
- should "accept conditions" do
39
- result = @document.paginate({
40
- :conditions => {:last_name => 'Nunemaker'},
41
- :order => "age DESC",
42
- :per_page => 2,
43
- :page => 1,
44
- })
45
- result.should == [@doc1, @doc3]
46
- result.first.age.should == 27
47
- end
48
-
49
- should "withstand rigor" do
50
- result = @document.paginate({
51
- :per_page => 1,
52
- :page => 1,
53
- :order => 'age desc',
54
- :conditions => {:last_name => 'Nunemaker'}
55
- })
56
- result.should == [@doc1]
57
- result.total_entries.should == 2
58
- result.total_pages.should == 2
59
-
60
- result = @document.paginate({
61
- :per_page => 1,
62
- :page => 2,
63
- :order => 'age desc',
64
- :conditions => {:last_name => 'Nunemaker'}
65
- })
66
- result.should == [@doc3]
67
- result.total_entries.should == 2
68
- result.total_pages.should == 2
69
-
70
- result = @document.paginate({
71
- :per_page => 2,
72
- :page => 1,
73
- :order => 'age desc',
74
- :conditions => {:last_name => 'Nunemaker'}
75
- })
76
- result.should == [@doc1, @doc3]
77
- result.total_entries.should == 2
78
- result.total_pages.should == 1
79
- end
80
- end
1
+ require 'test_helper'
2
+
3
+ class PaginationTest < Test::Unit::TestCase
4
+ context "Paginating" do
5
+ setup do
6
+ @document = Class.new do
7
+ include MongoMapper::Document
8
+ set_collection_name 'users'
9
+
10
+ key :first_name, String
11
+ key :last_name, String
12
+ key :age, Integer
13
+
14
+ def self.per_page; 1 end
15
+ end
16
+
17
+ clear_all_collections
18
+
19
+ @doc1 = @document.create({:first_name => 'John', :last_name => 'Nunemaker', :age => '27'})
20
+ @doc2 = @document.create({:first_name => 'Steve', :last_name => 'Smith', :age => '28'})
21
+ @doc3 = @document.create({:first_name => 'Steph', :last_name => 'Nunemaker', :age => '26'})
22
+ end
23
+
24
+ should "return the total pages" do
25
+ result = @document.paginate(:per_page => 2, :page => 1)
26
+ result.total_pages.should == 2
27
+ end
28
+
29
+ should "return the total pages when defaulting to the document class per_page" do
30
+ result = @document.paginate(:page => 1)
31
+ result.total_pages.should == 3
32
+ end
33
+
34
+ should "return the total of records" do
35
+ result = @document.paginate(:per_page => 2, :page => 1)
36
+ result.total_entries.should == 3
37
+ end
38
+
39
+ should "return the items" do
40
+ result = @document.paginate(:per_page => 2, :page => 1, :order => 'first_name')
41
+ result.size.should == 2
42
+ result.should == [@doc1, @doc3]
43
+ end
44
+
45
+ should "accept conditions" do
46
+ result = @document.paginate({
47
+ :conditions => {:last_name => 'Nunemaker'},
48
+ :order => "age DESC",
49
+ :per_page => 2,
50
+ :page => 1,
51
+ })
52
+ result.should == [@doc1, @doc3]
53
+ result.first.age.should == 27
54
+ end
55
+
56
+ should "withstand rigor" do
57
+ result = @document.paginate({
58
+ :per_page => 1,
59
+ :page => 1,
60
+ :order => 'age desc',
61
+ :conditions => {:last_name => 'Nunemaker'}
62
+ })
63
+ result.should == [@doc1]
64
+ result.total_entries.should == 2
65
+ result.total_pages.should == 2
66
+
67
+ result = @document.paginate({
68
+ :per_page => 1,
69
+ :page => 2,
70
+ :order => 'age desc',
71
+ :conditions => {:last_name => 'Nunemaker'}
72
+ })
73
+ result.should == [@doc3]
74
+ result.total_entries.should == 2
75
+ result.total_pages.should == 2
76
+
77
+ result = @document.paginate({
78
+ :per_page => 2,
79
+ :page => 1,
80
+ :order => 'age desc',
81
+ :conditions => {:last_name => 'Nunemaker'}
82
+ })
83
+ result.should == [@doc1, @doc3]
84
+ result.total_entries.should == 2
85
+ result.total_pages.should == 1
86
+ end
87
+ end
81
88
  end
@@ -1,30 +1,30 @@
1
- require 'test_helper'
2
-
3
- class TestRailsCompatibility < Test::Unit::TestCase
4
- class Item
5
- include MongoMapper::EmbeddedDocument
6
- key :for_all, String
7
- end
8
-
9
- class Order
10
- include MongoMapper::Document
11
- many :items, :class_name => 'TestRailsCompatibility::Item'
12
- key :order_only, String
13
- end
14
-
15
- context "Document" do
16
- setup do
17
- Order.collection.clear
18
- end
19
-
20
- should "have to_param that returns id" do
21
- instance = Order.create('_id' => 1234)
22
- instance.to_param.should == '1234'
23
- end
24
-
25
- should "alias new to new_record?" do
26
- instance = Order.new
27
- instance.new_record?.should == instance.new?
28
- end
29
- end
1
+ require 'test_helper'
2
+
3
+ class TestRailsCompatibility < Test::Unit::TestCase
4
+ class Item
5
+ include MongoMapper::EmbeddedDocument
6
+ key :for_all, String
7
+ end
8
+
9
+ class Order
10
+ include MongoMapper::Document
11
+ many :items, :class_name => 'TestRailsCompatibility::Item'
12
+ key :order_only, String
13
+ end
14
+
15
+ context "Document" do
16
+ setup do
17
+ clear_all_collections
18
+ end
19
+
20
+ should "have to_param that returns id" do
21
+ instance = Order.create('_id' => 1234)
22
+ instance.to_param.should == '1234'
23
+ end
24
+
25
+ should "alias new to new_record?" do
26
+ instance = Order.new
27
+ instance.new_record?.should == instance.new?
28
+ end
29
+ end
30
30
  end
@@ -1,172 +1,262 @@
1
- require 'test_helper'
2
-
3
- class ValidationsTest < Test::Unit::TestCase
4
- context "Saving a new document that is invalid" do
5
- setup do
6
- @document = Class.new do
7
- include MongoMapper::Document
8
- key :name, String, :required => true
9
- end
10
- @document.collection.clear
11
- end
12
-
13
- should "not insert document" do
14
- doc = @document.new
15
- doc.save
16
- @document.count.should == 0
17
- end
18
-
19
- should "populate document's errors" do
20
- doc = @document.new
21
- doc.errors.size.should == 0
22
- doc.save
23
- doc.errors.full_messages.should == ["Name can't be empty"]
24
- end
25
- end
26
-
27
- context "Saving a document that is invalid (destructive)" do
28
- setup do
29
- @document = Class.new do
30
- include MongoMapper::Document
31
- key :name, String, :required => true
32
- end
33
- @document.collection.clear
34
- end
35
-
36
- should "raise error" do
37
- doc = @document.new
38
- lambda { doc.save! }.should raise_error(MongoMapper::DocumentNotValid)
39
- end
40
- end
41
-
42
- context "Saving an existing document that is invalid" do
43
- setup do
44
- @document = Class.new do
45
- include MongoMapper::Document
46
- key :name, String, :required => true
47
- end
48
- @document.collection.clear
49
-
50
- @doc = @document.create(:name => 'John Nunemaker')
51
- end
52
-
53
- should "not update document" do
54
- @doc.name = nil
55
- @doc.save
56
- @document.find(@doc.id).name.should == 'John Nunemaker'
57
- end
58
-
59
- should "populate document's errors" do
60
- @doc.name = nil
61
- @doc.save
62
- @doc.errors.full_messages.should == ["Name can't be empty"]
63
- end
64
- end
65
-
66
- context "Adding validation errors" do
67
- setup do
68
- @document = Class.new do
69
- include MongoMapper::Document
70
- key :action, String
71
- def action_present
72
- errors.add(:action, 'is invalid') if action.blank?
73
- end
74
- end
75
- @document.collection.clear
76
- end
77
-
78
- should "work with validate_on_create callback" do
79
- @document.validate_on_create :action_present
80
-
81
- doc = @document.new
82
- doc.action = nil
83
- doc.should have_error_on(:action)
84
-
85
- doc.action = 'kick'
86
- doc.should_not have_error_on(:action)
87
- doc.save
88
-
89
- doc.action = nil
90
- doc.should_not have_error_on(:action)
91
- end
92
-
93
- should "work with validate_on_update callback" do
94
- @document.validate_on_update :action_present
95
-
96
- doc = @document.new
97
- doc.action = nil
98
- doc.should_not have_error_on(:action)
99
- doc.save
100
-
101
- doc.action = nil
102
- doc.should have_error_on(:action)
103
-
104
- doc.action = 'kick'
105
- doc.should_not have_error_on(:action)
106
- end
107
- end
108
-
109
- context "validating uniqueness of" do
110
- setup do
111
- @document = Class.new do
112
- include MongoMapper::Document
113
- key :name, String
114
- validates_uniqueness_of :name
115
- end
116
- @document.collection.clear
117
- end
118
-
119
- should "not fail if object is new" do
120
- doc = @document.new
121
- doc.should_not have_error_on(:name)
122
- end
123
-
124
- should "allow to update an object" do
125
- doc = @document.new("name" => "joe")
126
- doc.save.should be_true
127
-
128
- @document \
129
- .stubs(:find) \
130
- .with(:first, :conditions => {:name => 'joe'}, :limit => 1) \
131
- .returns(doc)
132
-
133
- doc.name = "joe"
134
- doc.valid?.should be_true
135
- doc.should_not have_error_on(:name)
136
- end
137
-
138
- should "fail if object name is not unique" do
139
- doc = @document.new("name" => "joe")
140
- doc.save.should be_true
141
-
142
- @document \
143
- .stubs(:find) \
144
- .with(:first, :conditions => {:name => 'joe'}, :limit => 1) \
145
- .returns(doc)
146
-
147
- doc2 = @document.new("name" => "joe")
148
- doc2.should have_error_on(:name)
149
- end
150
- end
151
-
152
- context "validates uniqueness of with :unique shortcut" do
153
- should "work" do
154
- @document = Class.new do
155
- include MongoMapper::Document
156
- key :name, String, :unique => true
157
- end
158
- @document.collection.clear
159
-
160
- doc = @document.create(:name => 'John')
161
- doc.should_not have_error_on(:name)
162
-
163
- @document \
164
- .stubs(:find) \
165
- .with(:first, :conditions => {:name => 'John'}, :limit => 1) \
166
- .returns(doc)
167
-
168
- second_john = @document.create(:name => 'John')
169
- second_john.should have_error_on(:name, 'has already been taken')
170
- end
171
- end
172
- end
1
+ require 'test_helper'
2
+
3
+ class ValidationsTest < Test::Unit::TestCase
4
+ def setup
5
+ clear_all_collections
6
+ end
7
+
8
+ context "Saving a new document that is invalid" do
9
+ setup do
10
+ @document = Class.new do
11
+ include MongoMapper::Document
12
+ key :name, String, :required => true
13
+ end
14
+ end
15
+
16
+ should "not insert document" do
17
+ doc = @document.new
18
+ doc.save
19
+ @document.count.should == 0
20
+ end
21
+
22
+ should "populate document's errors" do
23
+ doc = @document.new
24
+ doc.errors.size.should == 0
25
+ doc.save
26
+ doc.errors.full_messages.should == ["Name can't be empty"]
27
+ end
28
+ end
29
+
30
+ context "Saving a document that is invalid (destructive)" do
31
+ setup do
32
+ @document = Class.new do
33
+ include MongoMapper::Document
34
+ key :name, String, :required => true
35
+ end
36
+ end
37
+
38
+ should "raise error" do
39
+ doc = @document.new
40
+ lambda { doc.save! }.should raise_error(MongoMapper::DocumentNotValid)
41
+ end
42
+ end
43
+
44
+ context "Saving an existing document that is invalid" do
45
+ setup do
46
+ @document = Class.new do
47
+ include MongoMapper::Document
48
+ key :name, String, :required => true
49
+ end
50
+
51
+ @doc = @document.create(:name => 'John Nunemaker')
52
+ end
53
+
54
+ should "not update document" do
55
+ @doc.name = nil
56
+ @doc.save
57
+ @document.find(@doc.id).name.should == 'John Nunemaker'
58
+ end
59
+
60
+ should "populate document's errors" do
61
+ @doc.name = nil
62
+ @doc.save
63
+ @doc.errors.full_messages.should == ["Name can't be empty"]
64
+ end
65
+ end
66
+
67
+ context "Adding validation errors" do
68
+ setup do
69
+ @document = Class.new do
70
+ include MongoMapper::Document
71
+ key :action, String
72
+ def action_present
73
+ errors.add(:action, 'is invalid') if action.blank?
74
+ end
75
+ end
76
+ end
77
+
78
+ should "work with validate_on_create callback" do
79
+ @document.validate_on_create :action_present
80
+
81
+ doc = @document.new
82
+ doc.action = nil
83
+ doc.should have_error_on(:action)
84
+
85
+ doc.action = 'kick'
86
+ doc.should_not have_error_on(:action)
87
+ doc.save
88
+
89
+ doc.action = nil
90
+ doc.should_not have_error_on(:action)
91
+ end
92
+
93
+ should "work with validate_on_update callback" do
94
+ @document.validate_on_update :action_present
95
+
96
+ doc = @document.new
97
+ doc.action = nil
98
+ doc.should_not have_error_on(:action)
99
+ doc.save
100
+
101
+ doc.action = nil
102
+ doc.should have_error_on(:action)
103
+
104
+ doc.action = 'kick'
105
+ doc.should_not have_error_on(:action)
106
+ end
107
+ end
108
+
109
+ context "validating uniqueness of" do
110
+ setup do
111
+ @document = Class.new do
112
+ include MongoMapper::Document
113
+ key :name, String
114
+ validates_uniqueness_of :name
115
+ end
116
+ end
117
+
118
+ should "not fail if object is new" do
119
+ doc = @document.new
120
+ doc.should_not have_error_on(:name)
121
+ end
122
+
123
+ should "not fail when new object is out of scope" do
124
+ document = Class.new do
125
+ include MongoMapper::Document
126
+ key :name
127
+ key :adult
128
+ validates_uniqueness_of :name, :scope => :adult
129
+ end
130
+ doc = document.new("name" => "joe", :adult => true)
131
+ doc.save.should be_true
132
+
133
+ doc2 = document.new("name" => "joe", :adult => false)
134
+ doc2.should be_valid
135
+
136
+ end
137
+
138
+ should "allow to update an object" do
139
+ doc = @document.new("name" => "joe")
140
+ doc.save.should be_true
141
+
142
+ @document \
143
+ .stubs(:find) \
144
+ .with(:first, :conditions => {:name => 'joe'}, :limit => 1) \
145
+ .returns(doc)
146
+
147
+ doc.name = "joe"
148
+ doc.valid?.should be_true
149
+ doc.should_not have_error_on(:name)
150
+ end
151
+
152
+ should "fail if object name is not unique" do
153
+ doc = @document.new("name" => "joe")
154
+ doc.save.should be_true
155
+
156
+ @document \
157
+ .stubs(:find) \
158
+ .with(:first, :conditions => {:name => 'joe'}, :limit => 1) \
159
+ .returns(doc)
160
+
161
+ doc2 = @document.new("name" => "joe")
162
+ doc2.should have_error_on(:name)
163
+ end
164
+
165
+ context "scoped by a single attribute" do
166
+ setup do
167
+ @document = Class.new do
168
+ include MongoMapper::Document
169
+ key :name, String
170
+ key :scope, String
171
+ validates_uniqueness_of :name, :scope => :scope
172
+ end
173
+ @document.collection.clear
174
+ end
175
+
176
+ should "fail if the same name exists in the scope" do
177
+ doc = @document.new("name" => "joe", "scope" => "one")
178
+ doc.save.should be_true
179
+
180
+ @document \
181
+ .stubs(:find) \
182
+ .with(:first, :conditions => {:name => 'joe', :scope => "one"}, :limit => 1) \
183
+ .returns(doc)
184
+
185
+ doc2 = @document.new("name" => "joe", "scope" => "one")
186
+ doc2.should have_error_on(:name)
187
+ end
188
+
189
+ should "pass if the same name exists in a different scope" do
190
+ doc = @document.new("name" => "joe", "scope" => "one")
191
+ doc.save.should be_true
192
+
193
+ @document \
194
+ .stubs(:find) \
195
+ .with(:first, :conditions => {:name => 'joe', :scope => "two"}, :limit => 1) \
196
+ .returns(nil)
197
+
198
+ doc2 = @document.new("name" => "joe", "scope" => "two")
199
+ doc2.should_not have_error_on(:name)
200
+ end
201
+ end
202
+
203
+ context "scoped by a multiple attributes" do
204
+ setup do
205
+ @document = Class.new do
206
+ include MongoMapper::Document
207
+ key :name, String
208
+ key :first_scope, String
209
+ key :second_scope, String
210
+ validates_uniqueness_of :name, :scope => [:first_scope, :second_scope]
211
+ end
212
+ @document.collection.clear
213
+ end
214
+
215
+ should "fail if the same name exists in the scope" do
216
+ doc = @document.new("name" => "joe", "first_scope" => "one", "second_scope" => "two")
217
+ doc.save.should be_true
218
+
219
+ @document \
220
+ .stubs(:find) \
221
+ .with(:first, :conditions => {:name => 'joe', :first_scope => "one", :second_scope => "two"}, :limit => 1) \
222
+ .returns(doc)
223
+
224
+ doc2 = @document.new("name" => "joe", "first_scope" => "one", "second_scope" => "two")
225
+ doc2.should have_error_on(:name)
226
+ end
227
+
228
+ should "pass if the same name exists in a different scope" do
229
+ doc = @document.new("name" => "joe", "first_scope" => "one", "second_scope" => "two")
230
+ doc.save.should be_true
231
+
232
+ @document \
233
+ .stubs(:find) \
234
+ .with(:first, :conditions => {:name => 'joe', :first_scope => "one", :second_scope => "one"}, :limit => 1) \
235
+ .returns(nil)
236
+
237
+ doc2 = @document.new("name" => "joe", "first_scope" => "one", "second_scope" => "one")
238
+ doc2.should_not have_error_on(:name)
239
+ end
240
+ end
241
+ end
242
+
243
+ context "validates uniqueness of with :unique shortcut" do
244
+ should "work" do
245
+ @document = Class.new do
246
+ include MongoMapper::Document
247
+ key :name, String, :unique => true
248
+ end
249
+
250
+ doc = @document.create(:name => 'John')
251
+ doc.should_not have_error_on(:name)
252
+
253
+ @document \
254
+ .stubs(:find) \
255
+ .with(:first, :conditions => {:name => 'John'}, :limit => 1) \
256
+ .returns(doc)
257
+
258
+ second_john = @document.create(:name => 'John')
259
+ second_john.should have_error_on(:name, 'has already been taken')
260
+ end
261
+ end
262
+ end