jmonteiro-mongo_mapper 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. data/.gitignore +10 -0
  2. data/LICENSE +20 -0
  3. data/README.rdoc +38 -0
  4. data/Rakefile +55 -0
  5. data/VERSION +1 -0
  6. data/bin/mmconsole +60 -0
  7. data/jmonteiro-mongo_mapper.gemspec +195 -0
  8. data/lib/mongo_mapper.rb +128 -0
  9. data/lib/mongo_mapper/descendant_appends.rb +44 -0
  10. data/lib/mongo_mapper/document.rb +402 -0
  11. data/lib/mongo_mapper/dynamic_finder.rb +74 -0
  12. data/lib/mongo_mapper/embedded_document.rb +61 -0
  13. data/lib/mongo_mapper/finder_options.rb +127 -0
  14. data/lib/mongo_mapper/plugins.rb +19 -0
  15. data/lib/mongo_mapper/plugins/associations.rb +104 -0
  16. data/lib/mongo_mapper/plugins/associations/base.rb +121 -0
  17. data/lib/mongo_mapper/plugins/associations/belongs_to_polymorphic_proxy.rb +28 -0
  18. data/lib/mongo_mapper/plugins/associations/belongs_to_proxy.rb +23 -0
  19. data/lib/mongo_mapper/plugins/associations/collection.rb +21 -0
  20. data/lib/mongo_mapper/plugins/associations/embedded_collection.rb +49 -0
  21. data/lib/mongo_mapper/plugins/associations/in_array_proxy.rb +139 -0
  22. data/lib/mongo_mapper/plugins/associations/many_documents_as_proxy.rb +28 -0
  23. data/lib/mongo_mapper/plugins/associations/many_documents_proxy.rb +117 -0
  24. data/lib/mongo_mapper/plugins/associations/many_embedded_polymorphic_proxy.rb +31 -0
  25. data/lib/mongo_mapper/plugins/associations/many_embedded_proxy.rb +23 -0
  26. data/lib/mongo_mapper/plugins/associations/many_polymorphic_proxy.rb +13 -0
  27. data/lib/mongo_mapper/plugins/associations/one_proxy.rb +66 -0
  28. data/lib/mongo_mapper/plugins/associations/proxy.rb +118 -0
  29. data/lib/mongo_mapper/plugins/callbacks.rb +65 -0
  30. data/lib/mongo_mapper/plugins/clone.rb +13 -0
  31. data/lib/mongo_mapper/plugins/descendants.rb +16 -0
  32. data/lib/mongo_mapper/plugins/dirty.rb +119 -0
  33. data/lib/mongo_mapper/plugins/equality.rb +11 -0
  34. data/lib/mongo_mapper/plugins/identity_map.rb +66 -0
  35. data/lib/mongo_mapper/plugins/inspect.rb +14 -0
  36. data/lib/mongo_mapper/plugins/keys.rb +295 -0
  37. data/lib/mongo_mapper/plugins/logger.rb +17 -0
  38. data/lib/mongo_mapper/plugins/pagination.rb +85 -0
  39. data/lib/mongo_mapper/plugins/protected.rb +31 -0
  40. data/lib/mongo_mapper/plugins/rails.rb +80 -0
  41. data/lib/mongo_mapper/plugins/serialization.rb +109 -0
  42. data/lib/mongo_mapper/plugins/validations.rb +48 -0
  43. data/lib/mongo_mapper/support.rb +213 -0
  44. data/performance/read_write.rb +52 -0
  45. data/specs.watchr +51 -0
  46. data/test/NOTE_ON_TESTING +1 -0
  47. data/test/functional/associations/test_belongs_to_polymorphic_proxy.rb +63 -0
  48. data/test/functional/associations/test_belongs_to_proxy.rb +93 -0
  49. data/test/functional/associations/test_in_array_proxy.rb +309 -0
  50. data/test/functional/associations/test_many_documents_as_proxy.rb +246 -0
  51. data/test/functional/associations/test_many_documents_proxy.rb +437 -0
  52. data/test/functional/associations/test_many_embedded_polymorphic_proxy.rb +175 -0
  53. data/test/functional/associations/test_many_embedded_proxy.rb +216 -0
  54. data/test/functional/associations/test_many_polymorphic_proxy.rb +340 -0
  55. data/test/functional/associations/test_one_proxy.rb +149 -0
  56. data/test/functional/test_associations.rb +44 -0
  57. data/test/functional/test_binary.rb +27 -0
  58. data/test/functional/test_callbacks.rb +81 -0
  59. data/test/functional/test_dirty.rb +156 -0
  60. data/test/functional/test_document.rb +1171 -0
  61. data/test/functional/test_embedded_document.rb +125 -0
  62. data/test/functional/test_identity_map.rb +233 -0
  63. data/test/functional/test_logger.rb +20 -0
  64. data/test/functional/test_modifiers.rb +252 -0
  65. data/test/functional/test_pagination.rb +93 -0
  66. data/test/functional/test_protected.rb +41 -0
  67. data/test/functional/test_string_id_compatibility.rb +67 -0
  68. data/test/functional/test_validations.rb +329 -0
  69. data/test/models.rb +232 -0
  70. data/test/support/custom_matchers.rb +55 -0
  71. data/test/support/timing.rb +16 -0
  72. data/test/test_helper.rb +60 -0
  73. data/test/unit/associations/test_base.rb +207 -0
  74. data/test/unit/associations/test_proxy.rb +103 -0
  75. data/test/unit/serializers/test_json_serializer.rb +189 -0
  76. data/test/unit/test_descendant_appends.rb +71 -0
  77. data/test/unit/test_document.rb +203 -0
  78. data/test/unit/test_dynamic_finder.rb +125 -0
  79. data/test/unit/test_embedded_document.rb +628 -0
  80. data/test/unit/test_finder_options.rb +325 -0
  81. data/test/unit/test_keys.rb +169 -0
  82. data/test/unit/test_mongo_mapper.rb +65 -0
  83. data/test/unit/test_pagination.rb +127 -0
  84. data/test/unit/test_plugins.rb +42 -0
  85. data/test/unit/test_rails.rb +139 -0
  86. data/test/unit/test_rails_compatibility.rb +42 -0
  87. data/test/unit/test_serialization.rb +51 -0
  88. data/test/unit/test_support.rb +350 -0
  89. data/test/unit/test_time_zones.rb +39 -0
  90. data/test/unit/test_validations.rb +492 -0
  91. metadata +260 -0
@@ -0,0 +1,350 @@
1
+ require 'test_helper'
2
+
3
+ class SupportTest < Test::Unit::TestCase
4
+ context "Array#to_mongo" do
5
+ should "convert value to_a" do
6
+ Array.to_mongo([1, 2, 3, 4]).should == [1, 2, 3, 4]
7
+ Array.to_mongo('1').should == ['1']
8
+ Array.to_mongo({'1' => '2', '3' => '4'}).should == [['1', '2'], ['3', '4']]
9
+ end
10
+ end
11
+
12
+ context "Array#from_mongo" do
13
+ should "be array if array" do
14
+ Array.from_mongo([1, 2]).should == [1, 2]
15
+ end
16
+
17
+ should "be empty array if nil" do
18
+ Array.from_mongo(nil).should == []
19
+ end
20
+ end
21
+
22
+ context "Binary#to_mongo" do
23
+ should "convert to byte buffer if not byte buffer" do
24
+ Binary.to_mongo('asdfsadasdfs').is_a?(ByteBuffer).should be_true
25
+ end
26
+
27
+ should "be byte buffer if byte buffer" do
28
+ Binary.to_mongo(ByteBuffer.new('asdfsadasdfs')).is_a?(ByteBuffer).should be_true
29
+ end
30
+
31
+ should "be nil if nil" do
32
+ Binary.to_mongo(nil).should be_nil
33
+ end
34
+ end
35
+
36
+ context "Binary#from_mongo" do
37
+ should "return value" do
38
+ buffer = ByteBuffer.new('asdfasdfasdf')
39
+ Binary.from_mongo(buffer).to_s.should == buffer.to_s
40
+ end
41
+ end
42
+
43
+ context "Boolean#to_mongo" do
44
+ should "be true for true" do
45
+ Boolean.to_mongo(true).should be_true
46
+ end
47
+
48
+ should "be false for false" do
49
+ Boolean.to_mongo(false).should be_false
50
+ end
51
+
52
+ should "handle odd assortment of other values" do
53
+ Boolean.to_mongo('true').should be_true
54
+ Boolean.to_mongo('t').should be_true
55
+ Boolean.to_mongo('1').should be_true
56
+ Boolean.to_mongo(1).should be_true
57
+
58
+ Boolean.to_mongo('false').should be_false
59
+ Boolean.to_mongo('f').should be_false
60
+ Boolean.to_mongo('0').should be_false
61
+ Boolean.to_mongo(0).should be_false
62
+ end
63
+ end
64
+
65
+ context "Boolean#from_mongo" do
66
+ should "be true for true" do
67
+ Boolean.from_mongo(true).should be_true
68
+ end
69
+
70
+ should "be false for false" do
71
+ Boolean.from_mongo(false).should be_false
72
+ end
73
+
74
+ should "be false for nil" do
75
+ Boolean.from_mongo(nil).should be_false
76
+ end
77
+ end
78
+
79
+ context "Date#to_mongo" do
80
+ should "be time if string" do
81
+ date = Date.to_mongo('10/1/2009')
82
+ date.should == Time.utc(2009, 10, 1)
83
+ date.should == date
84
+ date.month.should == 10
85
+ date.day.should == 1
86
+ date.year.should == 2009
87
+ end
88
+
89
+ should "be time if date" do
90
+ Date.to_mongo(Date.new(2009, 10, 1)).should == Time.utc(2009, 10, 1)
91
+ end
92
+
93
+ should "be date if time" do
94
+ Date.to_mongo(Time.parse("2009-10-1T12:30:00")).should == Time.utc(2009, 10, 1)
95
+ end
96
+
97
+ should "be nil if bogus string" do
98
+ Date.to_mongo('jdsafop874').should be_nil
99
+ end
100
+
101
+ should "be nil if empty string" do
102
+ Date.to_mongo('').should be_nil
103
+ end
104
+ end
105
+
106
+ context "Date#from_mongo" do
107
+ should "be date if date" do
108
+ date = Date.new(2009, 10, 1)
109
+ from_date = Date.from_mongo(date)
110
+ from_date.should == date
111
+ from_date.month.should == 10
112
+ from_date.day.should == 1
113
+ from_date.year.should == 2009
114
+ end
115
+
116
+ should "be date if time" do
117
+ time = Time.now
118
+ Date.from_mongo(time).should == time.to_date
119
+ end
120
+
121
+ should "be nil if nil" do
122
+ Date.from_mongo(nil).should be_nil
123
+ end
124
+ end
125
+
126
+ context "Float#to_mongo" do
127
+ should "convert value to_f" do
128
+ [21, 21.0, '21'].each do |value|
129
+ Float.to_mongo(value).should == 21.0
130
+ end
131
+ end
132
+ end
133
+
134
+ context "Hash#from_mongo" do
135
+ should "convert hash to hash with indifferent access" do
136
+ hash = Hash.from_mongo(:foo => 'bar')
137
+ hash[:foo].should == 'bar'
138
+ hash['foo'].should == 'bar'
139
+ end
140
+
141
+ should "be hash if nil" do
142
+ hash = Hash.from_mongo(nil)
143
+ hash.should == {}
144
+ hash.is_a?(HashWithIndifferentAccess).should be_true
145
+ end
146
+ end
147
+
148
+ context "Hash#to_mongo instance method" do
149
+ should "have instance method that returns self" do
150
+ hash = HashWithIndifferentAccess.new('foo' => 'bar')
151
+ hash.to_mongo.should == {'foo' => 'bar'}
152
+ end
153
+ end
154
+
155
+ context "Integer#to_mongo" do
156
+ should "convert value to integer" do
157
+ [21, 21.0, '21'].each do |value|
158
+ Integer.to_mongo(value).should == 21
159
+ end
160
+ end
161
+
162
+ should "work fine with big integers" do
163
+ [9223372036854775807, '9223372036854775807'].each do |value|
164
+ Integer.to_mongo(value).should == 9223372036854775807
165
+ end
166
+ end
167
+ end
168
+
169
+ context "ObjectId#to_mongo" do
170
+ should "return nil for nil" do
171
+ ObjectId.to_mongo(nil).should be_nil
172
+ end
173
+
174
+ should "return nil if blank string" do
175
+ ObjectId.to_mongo('').should be_nil
176
+ end
177
+
178
+ should "return value if object id" do
179
+ id = Mongo::ObjectID.new
180
+ ObjectId.to_mongo(id).should be(id)
181
+ end
182
+
183
+ should "return object id if string" do
184
+ id = Mongo::ObjectID.new
185
+ ObjectId.to_mongo(id.to_s).should be(id)
186
+ end
187
+ end
188
+
189
+ context "ObjectId#from_mongo" do
190
+ should "return value" do
191
+ id = Mongo::ObjectID.new
192
+ ObjectId.from_mongo(id).should == id
193
+ end
194
+ end
195
+
196
+ context "NilClass#to_mongo" do
197
+ should "return nil" do
198
+ nil.to_mongo(nil).should be_nil
199
+ end
200
+ end
201
+
202
+ context "NilClass#from_mongo" do
203
+ should "return nil" do
204
+ nil.from_mongo(nil).should be_nil
205
+ end
206
+ end
207
+
208
+ context "Object#to_mongo" do
209
+ should "return value" do
210
+ Object.to_mongo(21).should == 21
211
+ Object.to_mongo('21').should == '21'
212
+ Object.to_mongo(9223372036854775807).should == 9223372036854775807
213
+ end
214
+ end
215
+
216
+ context "Object#from_mongo" do
217
+ should "return value" do
218
+ Object.from_mongo(21).should == 21
219
+ Object.from_mongo('21').should == '21'
220
+ Object.from_mongo(9223372036854775807).should == 9223372036854775807
221
+ end
222
+ end
223
+
224
+ context "Set#to_mongo" do
225
+ should "convert value to_a" do
226
+ Set.to_mongo(Set.new([1,2,3])).should == [1,2,3]
227
+ end
228
+
229
+ should "convert to empty array if nil" do
230
+ Set.to_mongo(nil).should == []
231
+ end
232
+ end
233
+
234
+ context "Set#from_mongo" do
235
+ should "be a set if array" do
236
+ Set.from_mongo([1,2,3]).should == Set.new([1,2,3])
237
+ end
238
+
239
+ should "be empty set if nil" do
240
+ Set.from_mongo(nil).should == Set.new([])
241
+ end
242
+ end
243
+
244
+ context "String#to_mongo" do
245
+ should "convert value to_s" do
246
+ [21, '21'].each do |value|
247
+ String.to_mongo(value).should == '21'
248
+ end
249
+ end
250
+
251
+ should "be nil if nil" do
252
+ String.to_mongo(nil).should be_nil
253
+ end
254
+ end
255
+
256
+ context "String#from_mongo" do
257
+ should "be string if value present" do
258
+ String.from_mongo('Scotch! Scotch! Scotch!').should == 'Scotch! Scotch! Scotch!'
259
+ end
260
+
261
+ should "return nil if nil" do
262
+ String.from_mongo(nil).should be_nil
263
+ end
264
+
265
+ should "return empty string if blank" do
266
+ String.from_mongo('').should == ''
267
+ end
268
+ end
269
+
270
+ context "Time#to_mongo without Time.zone" do
271
+ should "be time to milliseconds if string" do
272
+ Time.to_mongo('2000-01-01 01:01:01.123456').should == Time.local(2000, 1, 1, 1, 1, 1, 123000).utc
273
+ end
274
+
275
+ should "be time in utc if time" do
276
+ Time.to_mongo(Time.local(2009, 8, 15, 0, 0, 0)).zone.should == 'UTC'
277
+ end
278
+
279
+ should "be nil if blank string" do
280
+ Time.to_mongo('').should be_nil
281
+ end
282
+
283
+ should "not be nil if nil" do
284
+ Time.to_mongo(nil).should be_nil
285
+ end
286
+ end
287
+
288
+ context "Time#to_mongo with Time.zone" do
289
+ should "be time to milliseconds if time" do
290
+ Time.zone = 'Hawaii'
291
+ Time.to_mongo(Time.zone.local(2009, 8, 15, 14, 0, 0, 123456)).should == Time.utc(2009, 8, 16, 0, 0, 0, 123000)
292
+ Time.zone = nil
293
+ end
294
+
295
+ should "be time to milliseconds if string" do
296
+ Time.zone = 'Hawaii'
297
+ Time.to_mongo('2009-08-15 14:00:00.123456').should == Time.utc(2009, 8, 16, 0, 0, 0, 123000)
298
+ Time.zone = nil
299
+ end
300
+
301
+ should "be nil if blank string" do
302
+ Time.zone = 'Hawaii'
303
+ Time.to_mongo('').should be_nil
304
+ Time.zone = nil
305
+ end
306
+
307
+ should "be nil if nil" do
308
+ Time.zone = 'Hawaii'
309
+ Time.to_mongo(nil).should be_nil
310
+ Time.zone = nil
311
+ end
312
+ end
313
+
314
+ context "Time#from_mongo without Time.zone" do
315
+ should "be time" do
316
+ time = Time.now
317
+ Time.from_mongo(time).should == time
318
+ end
319
+
320
+ should "be nil if nil" do
321
+ Time.from_mongo(nil).should be_nil
322
+ end
323
+ end
324
+
325
+ context "Time#from_mongo with Time.zone" do
326
+ should "be time in Time.zone" do
327
+ Time.zone = 'Hawaii'
328
+
329
+ time = Time.from_mongo(Time.utc(2009, 10, 1))
330
+ time.should == Time.zone.local(2009, 9, 30, 14)
331
+ time.is_a?(ActiveSupport::TimeWithZone).should be_true
332
+
333
+ Time.zone = nil
334
+ end
335
+
336
+ should "be nil if nil" do
337
+ Time.zone = 'Hawaii'
338
+ Time.from_mongo(nil).should be_nil
339
+ Time.zone = nil
340
+ end
341
+ end
342
+
343
+ context "Mongo::ObjectID.to_json" do
344
+ should "convert object id to string" do
345
+ id = Mongo::ObjectID.new
346
+ id.to_json.should == %Q("#{id}")
347
+ end
348
+ end
349
+
350
+ end
@@ -0,0 +1,39 @@
1
+ require 'test_helper'
2
+
3
+ class TimeZonesTest < Test::Unit::TestCase
4
+ context "An instance of an embedded document" do
5
+ setup do
6
+ @document = EDoc do
7
+ key :name, String
8
+ key :created_at, Time
9
+ end
10
+ end
11
+
12
+ should "work without Time.zone" do
13
+ Time.zone = nil
14
+
15
+ doc = @document.new(:created_at => "2009-08-15 14:00:00")
16
+ doc.created_at.should == Time.local(2009, 8, 15, 14, 0, 0).utc
17
+ end
18
+
19
+ should "work with Time.zone set to the (default) UTC" do
20
+ Time.zone = 'UTC'
21
+
22
+ doc = @document.new(:created_at => "2009-08-15 14:00:00")
23
+ doc.created_at.is_a?(ActiveSupport::TimeWithZone).should be_true
24
+ doc.created_at.should == Time.utc(2009, 8, 15, 14)
25
+
26
+ Time.zone = nil
27
+ end
28
+
29
+ should "work with timezones that are not UTC" do
30
+ Time.zone = 'Hawaii'
31
+
32
+ doc = @document.new(:created_at => "2009-08-15 14:00:00")
33
+ doc.created_at.is_a?(ActiveSupport::TimeWithZone).should be_true
34
+ doc.created_at.should == Time.utc(2009, 8, 16)
35
+
36
+ Time.zone = nil
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,492 @@
1
+ require 'test_helper'
2
+
3
+ class ValidationsTest < Test::Unit::TestCase
4
+ context "Validations" do
5
+ context "on a Document" do
6
+ setup do
7
+ @document = Doc()
8
+ end
9
+
10
+ context "Validating acceptance of" do
11
+ should "work with validates_acceptance_of macro" do
12
+ @document.key :terms, String
13
+ @document.validates_acceptance_of :terms
14
+ doc = @document.new(:terms => '')
15
+ doc.should have_error_on(:terms)
16
+ doc.terms = '1'
17
+ doc.should_not have_error_on(:terms)
18
+ end
19
+ end
20
+
21
+ context "validating confirmation of" do
22
+ should "work with validates_confirmation_of macro" do
23
+ @document.key :password, String
24
+ @document.validates_confirmation_of :password
25
+ doc = @document.new
26
+ doc.password = 'foobar'
27
+ doc.should have_error_on(:password)
28
+ doc.password_confirmation = 'foobar'
29
+ doc.should_not have_error_on(:password)
30
+ end
31
+ end
32
+
33
+ context "validating format of" do
34
+ should "work with validates_format_of macro" do
35
+ @document.key :name, String
36
+ @document.validates_format_of :name, :with => /.+/
37
+ doc = @document.new
38
+ doc.should have_error_on(:name)
39
+ doc.name = 'John'
40
+ doc.should_not have_error_on(:name)
41
+ end
42
+
43
+ should "work with :format shorcut key" do
44
+ @document.key :name, String, :format => /.+/
45
+ doc = @document.new
46
+ doc.should have_error_on(:name)
47
+ doc.name = 'John'
48
+ doc.should_not have_error_on(:name)
49
+ end
50
+ end
51
+
52
+ context "validating length of" do
53
+ should "work with validates_length_of macro" do
54
+ @document.key :name, String
55
+ @document.validates_length_of :name, :minimum => 5
56
+ doc = @document.new
57
+ doc.should have_error_on(:name)
58
+ end
59
+
60
+ context "with :length => integer shortcut" do
61
+ should "set maximum of integer provided" do
62
+ @document.key :name, String, :length => 5
63
+ doc = @document.new
64
+ doc.name = '123456'
65
+ doc.should have_error_on(:name)
66
+ doc.name = '12345'
67
+ doc.should_not have_error_on(:name)
68
+ end
69
+ end
70
+
71
+ context "with :length => range shortcut" do
72
+ setup do
73
+ @document.key :name, String, :length => 5..7
74
+ end
75
+
76
+ should "set minimum of range min" do
77
+ doc = @document.new
78
+ doc.should have_error_on(:name)
79
+ doc.name = '123456'
80
+ doc.should_not have_error_on(:name)
81
+ end
82
+
83
+ should "set maximum of range max" do
84
+ doc = @document.new
85
+ doc.should have_error_on(:name)
86
+ doc.name = '12345678'
87
+ doc.should have_error_on(:name)
88
+ doc.name = '123456'
89
+ doc.should_not have_error_on(:name)
90
+ end
91
+ end
92
+
93
+ context "with :length => hash shortcut" do
94
+ should "pass options through" do
95
+ @document.key :name, String, :length => {:minimum => 2}
96
+ doc = @document.new
97
+ doc.should have_error_on(:name)
98
+ doc.name = '12'
99
+ doc.should_not have_error_on(:name)
100
+ end
101
+ end
102
+ end # validates_length_of
103
+
104
+ context "Validating numericality of" do
105
+ should "work with validates_numericality_of macro" do
106
+ @document.key :age, Integer
107
+ @document.validates_numericality_of :age
108
+ doc = @document.new
109
+ doc.age = 'String'
110
+ doc.should have_error_on(:age)
111
+ doc.age = 23
112
+ doc.should_not have_error_on(:age)
113
+ end
114
+
115
+ context "with :numeric shortcut" do
116
+ should "work with integer or float" do
117
+ @document.key :weight, Float, :numeric => true
118
+ doc = @document.new
119
+ doc.weight = 'String'
120
+ doc.should have_error_on(:weight)
121
+ doc.weight = 23.0
122
+ doc.should_not have_error_on(:weight)
123
+ doc.weight = 23
124
+ doc.should_not have_error_on(:weight)
125
+ end
126
+ end
127
+
128
+ context "with :numeric shortcut on Integer key" do
129
+ should "only work with integers" do
130
+ @document.key :age, Integer, :numeric => true
131
+ doc = @document.new
132
+ doc.age = 'String'
133
+ doc.should have_error_on(:age)
134
+ doc.age = 23.1
135
+ doc.should have_error_on(:age)
136
+ doc.age = 23
137
+ doc.should_not have_error_on(:age)
138
+ end
139
+ end
140
+ end # numericality of
141
+
142
+ context "validating presence of" do
143
+ should "work with validates_presence_of macro" do
144
+ @document.key :name, String
145
+ @document.validates_presence_of :name
146
+ doc = @document.new
147
+ doc.should have_error_on(:name)
148
+ end
149
+
150
+ should "work with :required shortcut on key definition" do
151
+ @document.key :name, String, :required => true
152
+ doc = @document.new
153
+ doc.should have_error_on(:name)
154
+ end
155
+ end
156
+
157
+ context "validating exclusion of" do
158
+ should "throw error if enumerator not provided" do
159
+ @document.key :action, String
160
+ lambda {
161
+ @document.validates_exclusion_of :action
162
+ }.should raise_error(ArgumentError)
163
+ end
164
+
165
+ should "work with validates_exclusion_of macro" do
166
+ @document.key :action, String
167
+ @document.validates_exclusion_of :action, :within => %w(kick run)
168
+
169
+ doc = @document.new
170
+ doc.should_not have_error_on(:action)
171
+
172
+ doc.action = 'fart'
173
+ doc.should_not have_error_on(:action)
174
+
175
+ doc.action = 'kick'
176
+ doc.should have_error_on(:action, 'is reserved')
177
+ end
178
+
179
+ should "not have error if allow nil is true and value is nil" do
180
+ @document.key :action, String
181
+ @document.validates_exclusion_of :action, :within => %w(kick run), :allow_nil => true
182
+
183
+ doc = @document.new
184
+ doc.should_not have_error_on(:action)
185
+ end
186
+
187
+ should "not have error if allow blank is true and value is blank" do
188
+ @document.key :action, String
189
+ @document.validates_exclusion_of :action, :within => %w(kick run), :allow_nil => true
190
+
191
+ doc = @document.new(:action => '')
192
+ doc.should_not have_error_on(:action)
193
+ end
194
+ end
195
+
196
+ context "validating inclusion of" do
197
+ should "throw error if enumerator not provided" do
198
+ @document.key :action, String
199
+ lambda {
200
+ @document.validates_inclusion_of :action
201
+ }.should raise_error(ArgumentError)
202
+ end
203
+
204
+ should "work with validates_inclusion_of macro" do
205
+ @document.key :action, String
206
+ @document.validates_inclusion_of :action, :within => %w(kick run)
207
+
208
+ doc = @document.new
209
+ doc.should have_error_on(:action, 'is not in the list')
210
+
211
+ doc.action = 'fart'
212
+ doc.should have_error_on(:action, 'is not in the list')
213
+
214
+ doc.action = 'kick'
215
+ doc.should_not have_error_on(:action)
216
+ end
217
+
218
+ should "not have error if allow nil is true and value is nil" do
219
+ @document.key :action, String
220
+ @document.validates_inclusion_of :action, :within => %w(kick run), :allow_nil => true
221
+
222
+ doc = @document.new
223
+ doc.should_not have_error_on(:action)
224
+ end
225
+
226
+ should "not have error if allow blank is true and value is blank" do
227
+ @document.key :action, String
228
+ @document.validates_inclusion_of :action, :within => %w(kick run), :allow_blank => true
229
+
230
+ doc = @document.new(:action => '')
231
+ doc.should_not have_error_on(:action)
232
+ end
233
+ end
234
+
235
+ end # End on a Document
236
+
237
+ context "On an EmbeddedDocument" do
238
+ setup do
239
+ @embedded_doc = EDoc()
240
+ end
241
+
242
+ context "Validating acceptance of" do
243
+ should "work with validates_acceptance_of macro" do
244
+ @embedded_doc.key :terms, String
245
+ @embedded_doc.validates_acceptance_of :terms
246
+ doc = @embedded_doc.new(:terms => '')
247
+ doc.should have_error_on(:terms)
248
+ doc.terms = '1'
249
+ doc.should_not have_error_on(:terms)
250
+ end
251
+ end
252
+
253
+ context "validating confirmation of" do
254
+ should "work with validates_confirmation_of macro" do
255
+ @embedded_doc.key :password, String
256
+ @embedded_doc.validates_confirmation_of :password
257
+ doc = @embedded_doc.new
258
+ doc.password = 'foobar'
259
+ doc.should have_error_on(:password)
260
+ doc.password_confirmation = 'foobar'
261
+ doc.should_not have_error_on(:password)
262
+ end
263
+ end
264
+
265
+ context "validating format of" do
266
+ should "work with validates_format_of macro" do
267
+ @embedded_doc.key :name, String
268
+ @embedded_doc.validates_format_of :name, :with => /.+/
269
+ doc = @embedded_doc.new
270
+ doc.should have_error_on(:name)
271
+ doc.name = 'John'
272
+ doc.should_not have_error_on(:name)
273
+ end
274
+
275
+ should "work with :format shorcut key" do
276
+ @embedded_doc.key :name, String, :format => /.+/
277
+ doc = @embedded_doc.new
278
+ doc.should have_error_on(:name)
279
+ doc.name = 'John'
280
+ doc.should_not have_error_on(:name)
281
+ end
282
+ end
283
+
284
+ context "validating length of" do
285
+ should "work with validates_length_of macro" do
286
+ @embedded_doc.key :name, String
287
+ @embedded_doc.validates_length_of :name, :minimum => 5
288
+ doc = @embedded_doc.new
289
+ doc.should have_error_on(:name)
290
+ end
291
+
292
+ context "with :length => integer shortcut" do
293
+ should "set maximum of integer provided" do
294
+ @embedded_doc.key :name, String, :length => 5
295
+ doc = @embedded_doc.new
296
+ doc.name = '123456'
297
+ doc.should have_error_on(:name)
298
+ doc.name = '12345'
299
+ doc.should_not have_error_on(:name)
300
+ end
301
+ end
302
+
303
+ context "with :length => range shortcut" do
304
+ setup do
305
+ @embedded_doc.key :name, String, :length => 5..7
306
+ end
307
+
308
+ should "set minimum of range min" do
309
+ doc = @embedded_doc.new
310
+ doc.should have_error_on(:name)
311
+ doc.name = '123456'
312
+ doc.should_not have_error_on(:name)
313
+ end
314
+
315
+ should "set maximum of range max" do
316
+ doc = @embedded_doc.new
317
+ doc.should have_error_on(:name)
318
+ doc.name = '12345678'
319
+ doc.should have_error_on(:name)
320
+ doc.name = '123456'
321
+ doc.should_not have_error_on(:name)
322
+ end
323
+ end
324
+
325
+ context "with :length => hash shortcut" do
326
+ should "pass options through" do
327
+ @embedded_doc.key :name, String, :length => {:minimum => 2}
328
+ doc = @embedded_doc.new
329
+ doc.should have_error_on(:name)
330
+ doc.name = '12'
331
+ doc.should_not have_error_on(:name)
332
+ end
333
+ end
334
+ end # validates_length_of
335
+
336
+ context "Validating numericality of" do
337
+ should "work with validates_numericality_of macro" do
338
+ @embedded_doc.key :age, Integer
339
+ @embedded_doc.validates_numericality_of :age
340
+ doc = @embedded_doc.new
341
+ doc.age = 'String'
342
+ doc.should have_error_on(:age)
343
+ doc.age = 23
344
+ doc.should_not have_error_on(:age)
345
+ end
346
+
347
+ context "with :numeric shortcut" do
348
+ should "work with integer or float" do
349
+ @embedded_doc.key :weight, Float, :numeric => true
350
+ doc = @embedded_doc.new
351
+ doc.weight = 'String'
352
+ doc.should have_error_on(:weight)
353
+ doc.weight = 23.0
354
+ doc.should_not have_error_on(:weight)
355
+ doc.weight = 23
356
+ doc.should_not have_error_on(:weight)
357
+ end
358
+ end
359
+
360
+ context "with :numeric shortcut on Integer key" do
361
+ should "only work with integers" do
362
+ @embedded_doc.key :age, Integer, :numeric => true
363
+ doc = @embedded_doc.new
364
+ doc.age = 'String'
365
+ doc.should have_error_on(:age)
366
+ doc.age = 23.1
367
+ doc.should have_error_on(:age)
368
+ doc.age = 23
369
+ doc.should_not have_error_on(:age)
370
+ end
371
+ end
372
+ end # numericality of
373
+
374
+ context "validating presence of" do
375
+ should "work with validates_presence_of macro" do
376
+ @embedded_doc.key :name, String
377
+ @embedded_doc.validates_presence_of :name
378
+ doc = @embedded_doc.new
379
+ doc.should have_error_on(:name)
380
+ end
381
+
382
+ should "work with :required shortcut on key definition" do
383
+ @embedded_doc.key :name, String, :required => true
384
+ doc = @embedded_doc.new
385
+ doc.should have_error_on(:name)
386
+ end
387
+ end
388
+
389
+ context "validating exclusion of" do
390
+ should "throw error if enumerator not provided" do
391
+ @embedded_doc.key :action, String
392
+ lambda {
393
+ @embedded_doc.validates_exclusion_of :action
394
+ }.should raise_error(ArgumentError)
395
+ end
396
+
397
+ should "work with validates_exclusion_of macro" do
398
+ @embedded_doc.key :action, String
399
+ @embedded_doc.validates_exclusion_of :action, :within => %w(kick run)
400
+
401
+ doc = @embedded_doc.new
402
+ doc.should_not have_error_on(:action)
403
+
404
+ doc.action = 'fart'
405
+ doc.should_not have_error_on(:action)
406
+
407
+ doc.action = 'kick'
408
+ doc.should have_error_on(:action, 'is reserved')
409
+ end
410
+
411
+ should "not have error if allow nil is true and value is nil" do
412
+ @embedded_doc.key :action, String
413
+ @embedded_doc.validates_exclusion_of :action, :within => %w(kick run), :allow_nil => true
414
+
415
+ doc = @embedded_doc.new
416
+ doc.should_not have_error_on(:action)
417
+ end
418
+
419
+ should "not have error if allow blank is true and value is blank" do
420
+ @embedded_doc.key :action, String
421
+ @embedded_doc.validates_exclusion_of :action, :within => %w(kick run), :allow_nil => true
422
+
423
+ doc = @embedded_doc.new(:action => '')
424
+ doc.should_not have_error_on(:action)
425
+ end
426
+ end
427
+
428
+ context "validating inclusion of" do
429
+ should "throw error if enumerator not provided" do
430
+ @embedded_doc.key :action, String
431
+ lambda {
432
+ @embedded_doc.validates_inclusion_of :action
433
+ }.should raise_error(ArgumentError)
434
+ end
435
+
436
+ should "work with validates_inclusion_of macro" do
437
+ @embedded_doc.key :action, String
438
+ @embedded_doc.validates_inclusion_of :action, :within => %w(kick run)
439
+
440
+ doc = @embedded_doc.new
441
+ doc.should have_error_on(:action, 'is not in the list')
442
+
443
+ doc.action = 'fart'
444
+ doc.should have_error_on(:action, 'is not in the list')
445
+
446
+ doc.action = 'kick'
447
+ doc.should_not have_error_on(:action)
448
+ end
449
+
450
+ should "not have error if allow nil is true and value is nil" do
451
+ @embedded_doc.key :action, String
452
+ @embedded_doc.validates_inclusion_of :action, :within => %w(kick run), :allow_nil => true
453
+
454
+ doc = @embedded_doc.new
455
+ doc.should_not have_error_on(:action)
456
+ end
457
+
458
+ should "not have error if allow blank is true and value is blank" do
459
+ @embedded_doc.key :action, String
460
+ @embedded_doc.validates_inclusion_of :action, :within => %w(kick run), :allow_blank => true
461
+
462
+ doc = @embedded_doc.new(:action => '')
463
+ doc.should_not have_error_on(:action)
464
+ end
465
+ end
466
+
467
+ end # End on an EmbeddedDocument
468
+
469
+ end # Validations
470
+
471
+ context "Adding validation errors" do
472
+ setup do
473
+ @document = Doc do
474
+ key :action, String
475
+ def action_present
476
+ errors.add(:action, 'is invalid') if action.blank?
477
+ end
478
+ end
479
+ end
480
+
481
+ should "work with validate callback" do
482
+ @document.validate :action_present
483
+
484
+ doc = @document.new
485
+ doc.action = nil
486
+ doc.should have_error_on(:action)
487
+
488
+ doc.action = 'kick'
489
+ doc.should_not have_error_on(:action)
490
+ end
491
+ end
492
+ end