jmonteiro-mongo_mapper 0.1.0

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