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
@@ -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