duck-hunt 0.0.3
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.
- data/LICENSE +20 -0
- data/README.md +526 -0
- data/Rakefile +15 -0
- data/lib/duck-hunt.rb +17 -0
- data/lib/duck-hunt/hash_helpers.rb +28 -0
- data/lib/duck-hunt/properties.rb +13 -0
- data/lib/duck-hunt/properties/array.rb +81 -0
- data/lib/duck-hunt/properties/boolean.rb +10 -0
- data/lib/duck-hunt/properties/float.rb +10 -0
- data/lib/duck-hunt/properties/integer.rb +9 -0
- data/lib/duck-hunt/properties/nested_hash.rb +61 -0
- data/lib/duck-hunt/properties/nil.rb +15 -0
- data/lib/duck-hunt/properties/property.rb +85 -0
- data/lib/duck-hunt/properties/string.rb +10 -0
- data/lib/duck-hunt/properties/validator_lookup.rb +27 -0
- data/lib/duck-hunt/schemas.rb +8 -0
- data/lib/duck-hunt/schemas/array_schema.rb +254 -0
- data/lib/duck-hunt/schemas/hash_schema.rb +135 -0
- data/lib/duck-hunt/schemas/property_lookup.rb +32 -0
- data/lib/duck-hunt/schemas/schema_definition.rb +25 -0
- data/lib/duck-hunt/string_helpers.rb +25 -0
- data/lib/duck-hunt/validators.rb +16 -0
- data/lib/duck-hunt/validators/accepted_values.rb +19 -0
- data/lib/duck-hunt/validators/divisible_by.rb +19 -0
- data/lib/duck-hunt/validators/equal_to.rb +19 -0
- data/lib/duck-hunt/validators/greater_than.rb +19 -0
- data/lib/duck-hunt/validators/greater_than_or_equal_to.rb +19 -0
- data/lib/duck-hunt/validators/less_than.rb +19 -0
- data/lib/duck-hunt/validators/less_than_or_equal_to.rb +19 -0
- data/lib/duck-hunt/validators/matches.rb +18 -0
- data/lib/duck-hunt/validators/not_divisible_by.rb +19 -0
- data/lib/duck-hunt/validators/not_equal_to.rb +19 -0
- data/lib/duck-hunt/validators/rejected_values.rb +19 -0
- data/lib/duck-hunt/validators/validator.rb +16 -0
- data/lib/duck-hunt/version.rb +3 -0
- data/test/properties/array_test.rb +837 -0
- data/test/properties/boolean_test.rb +37 -0
- data/test/properties/float_test.rb +49 -0
- data/test/properties/integer_test.rb +48 -0
- data/test/properties/nested_hash_test.rb +465 -0
- data/test/properties/nil_test.rb +30 -0
- data/test/properties/property_test.rb +193 -0
- data/test/properties/string_test.rb +24 -0
- data/test/properties/validator_lookup_test.rb +25 -0
- data/test/schemas/array_schema_test.rb +797 -0
- data/test/schemas/hash_schema_test.rb +264 -0
- data/test/schemas/property_lookup_test.rb +41 -0
- data/test/schemas/schema_definition_test.rb +51 -0
- data/test/test_helper.rb +29 -0
- data/test/test_helper/test_classes.rb +74 -0
- data/test/validators/accepted_values_test.rb +46 -0
- data/test/validators/divisible_by_test.rb +38 -0
- data/test/validators/equal_to_test.rb +38 -0
- data/test/validators/greater_than_or_equal_to_test.rb +39 -0
- data/test/validators/greater_than_test.rb +39 -0
- data/test/validators/less_than_or_equal_to_test.rb +40 -0
- data/test/validators/less_than_test.rb +39 -0
- data/test/validators/matches_test.rb +43 -0
- data/test/validators/not_divisible_by_test.rb +38 -0
- data/test/validators/not_equal_to_test.rb +38 -0
- data/test/validators/rejected_values_test.rb +46 -0
- data/test/validators/validator_test.rb +23 -0
- metadata +196 -0
@@ -0,0 +1,19 @@
|
|
1
|
+
module DuckHunt
|
2
|
+
module Validators
|
3
|
+
class RejectedValues < Validator
|
4
|
+
attr_reader :values
|
5
|
+
def initialize(*args)
|
6
|
+
@values = args[0]
|
7
|
+
raise ArgumentError, "an array must be provided" unless @values.is_a? Array
|
8
|
+
end
|
9
|
+
|
10
|
+
def valid?(value)
|
11
|
+
return (@values.include? value) == false
|
12
|
+
end
|
13
|
+
|
14
|
+
def error_message
|
15
|
+
return "a rejected value"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,837 @@
|
|
1
|
+
require File.expand_path('../../test_helper', __FILE__)
|
2
|
+
|
3
|
+
describe DuckHunt::Properties::Array, "initialize using a block" do
|
4
|
+
it "should be able to set the property to required" do
|
5
|
+
property = DuckHunt::Properties::Array.new :required => true do |s|
|
6
|
+
s.test
|
7
|
+
end
|
8
|
+
property.required.must_equal true
|
9
|
+
property.required?.must_equal true
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should be able to define a single-type array" do
|
13
|
+
property = DuckHunt::Properties::Array.new do |s|
|
14
|
+
s.integer
|
15
|
+
end
|
16
|
+
|
17
|
+
property.single_type_property.must_be_instance_of DuckHunt::Properties::Integer
|
18
|
+
property.tuple_properties.must_be_nil
|
19
|
+
property.optional_tuple_properties.must_be_nil
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should be able to define a tuple array with no optional items" do
|
23
|
+
property = DuckHunt::Properties::Array.new do |s|
|
24
|
+
s.items do |x|
|
25
|
+
x.integer
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
property.tuple_properties.size.must_equal 1
|
30
|
+
property.tuple_properties.first.must_be_instance_of DuckHunt::Properties::Integer
|
31
|
+
|
32
|
+
property = DuckHunt::Properties::Array.new do |s|
|
33
|
+
s.items do |x|
|
34
|
+
x.integer
|
35
|
+
x.test
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
property.tuple_properties.size.must_equal 2
|
40
|
+
property.tuple_properties.first.must_be_instance_of DuckHunt::Properties::Integer
|
41
|
+
property.tuple_properties.last.must_be_instance_of DuckHunt::Properties::Test
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should be able to define a tuple array with optional items" do
|
45
|
+
property = DuckHunt::Properties::Array.new do |s|
|
46
|
+
s.items do |x|
|
47
|
+
x.integer
|
48
|
+
end
|
49
|
+
|
50
|
+
s.optional_items do |y|
|
51
|
+
y.integer
|
52
|
+
y.test
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
property.tuple_properties.size.must_equal 1
|
57
|
+
property.tuple_properties.first.must_be_instance_of DuckHunt::Properties::Integer
|
58
|
+
|
59
|
+
property.optional_tuple_properties.size.must_equal 2
|
60
|
+
property.optional_tuple_properties.first.must_be_instance_of DuckHunt::Properties::Integer
|
61
|
+
property.optional_tuple_properties.last.must_be_instance_of DuckHunt::Properties::Test
|
62
|
+
|
63
|
+
property = DuckHunt::Properties::Array.new do |s|
|
64
|
+
s.items do |x|
|
65
|
+
x.integer
|
66
|
+
x.test
|
67
|
+
end
|
68
|
+
|
69
|
+
s.optional_items do |x|
|
70
|
+
x.integer
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
property.tuple_properties.size.must_equal 2
|
75
|
+
property.tuple_properties.first.must_be_instance_of DuckHunt::Properties::Integer
|
76
|
+
property.tuple_properties.last.must_be_instance_of DuckHunt::Properties::Test
|
77
|
+
|
78
|
+
property.optional_tuple_properties.size.must_equal 1
|
79
|
+
property.optional_tuple_properties.first.must_be_instance_of DuckHunt::Properties::Integer
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should not allow single-type and tuple definitions in the same property" do
|
83
|
+
lambda{
|
84
|
+
property = DuckHunt::Properties::Array.new do |s|
|
85
|
+
s.integer
|
86
|
+
s.items do |x|
|
87
|
+
x.integer
|
88
|
+
end
|
89
|
+
end
|
90
|
+
}.must_raise DuckHunt::InvalidSchema
|
91
|
+
|
92
|
+
lambda{
|
93
|
+
property = DuckHunt::Properties::Array.new do |s|
|
94
|
+
s.items do |x|
|
95
|
+
x.integer
|
96
|
+
end
|
97
|
+
s.integer
|
98
|
+
end
|
99
|
+
}.must_raise DuckHunt::InvalidSchema
|
100
|
+
|
101
|
+
lambda{
|
102
|
+
property = DuckHunt::Properties::Array.new do |s|
|
103
|
+
s.integer
|
104
|
+
s.optional_items do |x|
|
105
|
+
x.integer
|
106
|
+
end
|
107
|
+
end
|
108
|
+
}.must_raise DuckHunt::InvalidSchema
|
109
|
+
|
110
|
+
lambda{
|
111
|
+
property = DuckHunt::Properties::Array.new do |s|
|
112
|
+
s.optional_items do |x|
|
113
|
+
x.integer
|
114
|
+
end
|
115
|
+
s.integer
|
116
|
+
end
|
117
|
+
}.must_raise DuckHunt::InvalidSchema
|
118
|
+
end
|
119
|
+
|
120
|
+
it "should be able to set options for the property" do
|
121
|
+
property = DuckHunt::Properties::Array.new :min_size => 3 do |s|
|
122
|
+
s.test
|
123
|
+
end
|
124
|
+
|
125
|
+
property.min_size.must_equal 3
|
126
|
+
end
|
127
|
+
|
128
|
+
it "should be able to set property-level and property-level options at the same time" do
|
129
|
+
property = DuckHunt::Properties::Array.new :required => true, :min_size => 3 do |s|
|
130
|
+
s.test
|
131
|
+
end
|
132
|
+
property.required.must_equal true
|
133
|
+
property.required?.must_equal true
|
134
|
+
property.min_size.must_equal 3
|
135
|
+
end
|
136
|
+
|
137
|
+
it "should require that a block be passed when setting tuple properties" do
|
138
|
+
lambda{
|
139
|
+
property = DuckHunt::Properties::Array.new do |s|
|
140
|
+
s.items
|
141
|
+
end
|
142
|
+
}.must_raise ArgumentError
|
143
|
+
|
144
|
+
lambda{
|
145
|
+
property = DuckHunt::Properties::Array.new do |s|
|
146
|
+
s.optional_items
|
147
|
+
end
|
148
|
+
}.must_raise ArgumentError
|
149
|
+
end
|
150
|
+
|
151
|
+
it "should allow the uniqueness flag to be set during initialization" do
|
152
|
+
property = DuckHunt::Properties::Array.new :validates_uniqueness => true do |s|
|
153
|
+
s.integer
|
154
|
+
end
|
155
|
+
|
156
|
+
property.validates_uniqueness?.must_equal true
|
157
|
+
property.validates_uniqueness.must_equal true
|
158
|
+
end
|
159
|
+
|
160
|
+
it "should allow the min and max size to be set during initialization" do
|
161
|
+
property = DuckHunt::Properties::Array.new :min_size => 10 do |s|
|
162
|
+
s.integer
|
163
|
+
end
|
164
|
+
|
165
|
+
property.min_size.must_equal 10
|
166
|
+
property.max_size.must_be_nil
|
167
|
+
|
168
|
+
property = DuckHunt::Properties::Array.new :max_size => 10 do |s|
|
169
|
+
s.integer
|
170
|
+
end
|
171
|
+
|
172
|
+
property.min_size.must_be_nil
|
173
|
+
property.max_size.must_equal 10
|
174
|
+
|
175
|
+
property = DuckHunt::Properties::Array.new :min_size => 5, :max_size => 10 do |s|
|
176
|
+
s.integer
|
177
|
+
end
|
178
|
+
|
179
|
+
property.min_size.must_equal 5
|
180
|
+
property.max_size.must_equal 10
|
181
|
+
end
|
182
|
+
|
183
|
+
it "should allow the 'allow nil' flag to be set during initialization" do
|
184
|
+
property = DuckHunt::Properties::Array.new :allow_nil => true do |s|
|
185
|
+
s.integer
|
186
|
+
end
|
187
|
+
|
188
|
+
property.allow_nil.must_equal true
|
189
|
+
property.allow_nil?.must_equal true
|
190
|
+
end
|
191
|
+
|
192
|
+
it "should default the uniqueness flag to false" do
|
193
|
+
property = DuckHunt::Properties::Array.new do |s|
|
194
|
+
s.integer
|
195
|
+
end
|
196
|
+
|
197
|
+
property.validates_uniqueness.must_equal false
|
198
|
+
property.validates_uniqueness?.must_equal false
|
199
|
+
end
|
200
|
+
|
201
|
+
it "should default the min and max size to nil" do
|
202
|
+
property = DuckHunt::Properties::Array.new do |s|
|
203
|
+
s.integer
|
204
|
+
end
|
205
|
+
|
206
|
+
property.min_size.must_be_nil
|
207
|
+
property.max_size.must_be_nil
|
208
|
+
end
|
209
|
+
|
210
|
+
it "should default the 'allow nil' flag to false" do
|
211
|
+
property = DuckHunt::Properties::Array.new do |s|
|
212
|
+
s.integer
|
213
|
+
end
|
214
|
+
|
215
|
+
property.allow_nil.must_equal false
|
216
|
+
property.allow_nil?.must_equal false
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
describe DuckHunt::Properties::Array, "initialize without a block" do
|
221
|
+
it "should raise an exception if a block is not provided" do
|
222
|
+
lambda{
|
223
|
+
DuckHunt::Properties::Array.new :required => false
|
224
|
+
}.must_raise(ArgumentError)
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
describe DuckHunt::Properties::Array, "single-type validation" do
|
229
|
+
before do
|
230
|
+
@property = DuckHunt::Properties::Array.new do |s|
|
231
|
+
s.integer
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
it "should return false if the object provided is not an array" do
|
236
|
+
@property.valid?("hello").must_equal false
|
237
|
+
@property.errors.size.must_equal 1
|
238
|
+
@property.errors["base"].must_equal ["wrong type"]
|
239
|
+
end
|
240
|
+
|
241
|
+
it "should return true if there are no entries in the array" do
|
242
|
+
@property.valid?([]).must_equal true
|
243
|
+
@property.errors.size.must_equal 0
|
244
|
+
end
|
245
|
+
|
246
|
+
it "should return true if every entry in the array is of the correct type" do
|
247
|
+
@property.valid?([1,2,3]).must_equal true
|
248
|
+
@property.errors.size.must_equal 0
|
249
|
+
end
|
250
|
+
|
251
|
+
it "should return false if any entry in the array is not of the correct type, and have a base error mesage" do
|
252
|
+
@property.valid?([1,"boo",3]).must_equal false
|
253
|
+
@property.errors.size.must_equal 1
|
254
|
+
@property.errors["1"].must_equal ["wrong type"]
|
255
|
+
end
|
256
|
+
|
257
|
+
it "should empty the errors array each time we validate" do
|
258
|
+
@property.valid?([1,"boo",3]).must_equal false
|
259
|
+
@property.errors.size.must_equal 1
|
260
|
+
@property.errors["1"].must_equal ["wrong type"]
|
261
|
+
|
262
|
+
@property.valid?(["boo",2,3]).must_equal false
|
263
|
+
@property.errors.size.must_equal 1
|
264
|
+
@property.errors["0"].must_equal ["wrong type"]
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
describe DuckHunt::Properties::Array, "tuple validation (no optional items)" do
|
269
|
+
before do
|
270
|
+
@property = DuckHunt::Properties::Array.new do |s|
|
271
|
+
s.items do |x|
|
272
|
+
x.always_right_type
|
273
|
+
x.integer
|
274
|
+
end
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
it "should return false if the object provided is not an array" do
|
279
|
+
@property.valid?("hello").must_equal false
|
280
|
+
@property.errors.size.must_equal 1
|
281
|
+
@property.errors["base"].must_equal ["wrong type"]
|
282
|
+
end
|
283
|
+
|
284
|
+
it "should return false if there are no items in the array" do
|
285
|
+
@property.valid?([]).must_equal false
|
286
|
+
@property.errors.size.must_equal 1
|
287
|
+
@property.errors["base"].must_equal ["expected at least 2 item(s) but got 0 item(s)"]
|
288
|
+
end
|
289
|
+
|
290
|
+
it "should return false if there are fewer items in the array than what is defined in the tuple" do
|
291
|
+
@property.valid?([1]).must_equal false
|
292
|
+
@property.errors.size.must_equal 1
|
293
|
+
@property.errors["base"].must_equal ["expected at least 2 item(s) but got 1 item(s)"]
|
294
|
+
end
|
295
|
+
|
296
|
+
it "should return false if there are more items in the array than what is defined in the tuple" do
|
297
|
+
@property.valid?([1,2,3]).must_equal false
|
298
|
+
@property.errors.size.must_equal 1
|
299
|
+
@property.errors["base"].must_equal ["expected at most 2 item(s) but got 3 item(s)"]
|
300
|
+
end
|
301
|
+
|
302
|
+
it "should return false if any of the items are not the correct type specified for that index" do
|
303
|
+
@property.valid?([1, "hello"]).must_equal false
|
304
|
+
@property.errors.size.must_equal 1
|
305
|
+
@property.errors["1"].must_equal ["wrong type"]
|
306
|
+
end
|
307
|
+
|
308
|
+
it "should return true if the items in the array match their defined type" do
|
309
|
+
@property.valid?([1, 2]).must_equal true
|
310
|
+
@property.errors.size.must_equal 0
|
311
|
+
end
|
312
|
+
|
313
|
+
it "should empty the errors array each time we validate" do
|
314
|
+
@property.valid?([1, "hello"]).must_equal false
|
315
|
+
@property.errors.size.must_equal 1
|
316
|
+
@property.errors["1"].must_equal ["wrong type"]
|
317
|
+
|
318
|
+
@property.valid?([1]).must_equal false
|
319
|
+
@property.errors.size.must_equal 1
|
320
|
+
@property.errors["base"].must_equal ["expected at least 2 item(s) but got 1 item(s)"]
|
321
|
+
end
|
322
|
+
end
|
323
|
+
|
324
|
+
describe DuckHunt::Properties::Array, "tuple validation (with optional items)" do
|
325
|
+
before do
|
326
|
+
@property = DuckHunt::Properties::Array.new do |s|
|
327
|
+
s.items do |x|
|
328
|
+
x.always_right_type
|
329
|
+
x.integer
|
330
|
+
end
|
331
|
+
|
332
|
+
s.optional_items do |y|
|
333
|
+
y.integer
|
334
|
+
y.always_right_type
|
335
|
+
end
|
336
|
+
end
|
337
|
+
end
|
338
|
+
|
339
|
+
it "should return false if there are no items in the array" do
|
340
|
+
@property.valid?([]).must_equal false
|
341
|
+
@property.errors.size.must_equal 1
|
342
|
+
@property.errors["base"].must_equal ["expected at least 2 item(s) but got 0 item(s)"]
|
343
|
+
end
|
344
|
+
|
345
|
+
it "should return false if there are fewer items in the array than what is defined in the tuple" do
|
346
|
+
@property.valid?([1]).must_equal false
|
347
|
+
@property.errors.size.must_equal 1
|
348
|
+
@property.errors["base"].must_equal ["expected at least 2 item(s) but got 1 item(s)"]
|
349
|
+
end
|
350
|
+
|
351
|
+
it "should return true if we have extended beyond the required tuple items and into the optional items" do
|
352
|
+
@property.valid?([1,2,3,4]).must_equal true
|
353
|
+
@property.errors.size.must_equal 0
|
354
|
+
end
|
355
|
+
|
356
|
+
it "should return false if there are more items in the array than what is defined in the tuple (including the optional items)" do
|
357
|
+
@property.valid?([1,2,3,4,5]).must_equal false
|
358
|
+
@property.errors.size.must_equal 1
|
359
|
+
@property.errors["base"].must_equal ["expected at most 4 item(s) but got 5 item(s)"]
|
360
|
+
end
|
361
|
+
|
362
|
+
it "should return false if any of the required items are not the correct type specified for that index" do
|
363
|
+
@property.valid?([1, "hello"]).must_equal false
|
364
|
+
@property.errors.size.must_equal 1
|
365
|
+
@property.errors["1"].must_equal ["wrong type"]
|
366
|
+
end
|
367
|
+
|
368
|
+
it "should return false if any of the optional items are not the correct type specified for that index" do
|
369
|
+
@property.valid?([1,2,"hello"]).must_equal false
|
370
|
+
@property.errors.size.must_equal 1
|
371
|
+
@property.errors["2"].must_equal ["wrong type"]
|
372
|
+
end
|
373
|
+
|
374
|
+
it "should return true if the items in the array match their defined type" do
|
375
|
+
@property.valid?([1,2,3,4]).must_equal true
|
376
|
+
@property.errors.size.must_equal 0
|
377
|
+
end
|
378
|
+
|
379
|
+
it "should return true if we only have the required items in the array" do
|
380
|
+
@property.valid?([1,2]).must_equal true
|
381
|
+
@property.errors.size.must_equal 0
|
382
|
+
end
|
383
|
+
|
384
|
+
it "should return true if we only have some of the optional items in the array" do
|
385
|
+
@property.valid?([1,2,3]).must_equal true
|
386
|
+
@property.errors.size.must_equal 0
|
387
|
+
end
|
388
|
+
|
389
|
+
it "should empty the errors array each time we validate" do
|
390
|
+
@property.valid?([1, "hello"]).must_equal false
|
391
|
+
@property.errors.size.must_equal 1
|
392
|
+
@property.errors["1"].must_equal ["wrong type"]
|
393
|
+
|
394
|
+
@property.valid?([1]).must_equal false
|
395
|
+
@property.errors.size.must_equal 1
|
396
|
+
@property.errors["base"].must_equal ["expected at least 2 item(s) but got 1 item(s)"]
|
397
|
+
|
398
|
+
@property.valid?([1,2,"hello"]).must_equal false
|
399
|
+
@property.errors.size.must_equal 1
|
400
|
+
@property.errors["2"].must_equal ["wrong type"]
|
401
|
+
end
|
402
|
+
end
|
403
|
+
|
404
|
+
describe DuckHunt::Properties::Array, "tuple validation (all optional items)" do
|
405
|
+
before do
|
406
|
+
@property = DuckHunt::Properties::Array.new do |s|
|
407
|
+
s.optional_items do |y|
|
408
|
+
y.integer
|
409
|
+
y.always_right_type
|
410
|
+
end
|
411
|
+
end
|
412
|
+
end
|
413
|
+
|
414
|
+
it "should return true if there are no items in the array" do
|
415
|
+
@property.valid?([]).must_equal true
|
416
|
+
@property.errors.size.must_equal 0
|
417
|
+
end
|
418
|
+
|
419
|
+
it "should return true if there are fewer items in the array than what is defined in the tuple" do
|
420
|
+
@property.valid?([1]).must_equal true
|
421
|
+
@property.errors.size.must_equal 0
|
422
|
+
end
|
423
|
+
|
424
|
+
it "should return false if there are more items in the array than what is defined in the tuple" do
|
425
|
+
@property.valid?([1,2,3]).must_equal false
|
426
|
+
@property.errors.size.must_equal 1
|
427
|
+
@property.errors["base"].must_equal ["expected at most 2 item(s) but got 3 item(s)"]
|
428
|
+
end
|
429
|
+
|
430
|
+
it "should return false if any of the items are not the correct type specified for that index" do
|
431
|
+
@property.valid?(["hello",2]).must_equal false
|
432
|
+
@property.errors.size.must_equal 1
|
433
|
+
@property.errors["0"].must_equal ["wrong type"]
|
434
|
+
end
|
435
|
+
|
436
|
+
it "should return true if the items in the array match their defined type" do
|
437
|
+
@property.valid?([1,2]).must_equal true
|
438
|
+
@property.errors.size.must_equal 0
|
439
|
+
end
|
440
|
+
|
441
|
+
it "should return true if we only have some of the optional items in the array" do
|
442
|
+
@property.valid?([1]).must_equal true
|
443
|
+
@property.errors.size.must_equal 0
|
444
|
+
end
|
445
|
+
|
446
|
+
it "should empty the errors array each time we validate" do
|
447
|
+
@property.valid?(["hello",2]).must_equal false
|
448
|
+
@property.errors.size.must_equal 1
|
449
|
+
@property.errors["0"].must_equal ["wrong type"]
|
450
|
+
|
451
|
+
@property.valid?([1,2,3]).must_equal false
|
452
|
+
@property.errors.size.must_equal 1
|
453
|
+
@property.errors["base"].must_equal ["expected at most 2 item(s) but got 3 item(s)"]
|
454
|
+
end
|
455
|
+
end
|
456
|
+
|
457
|
+
describe DuckHunt::Properties::Array, "validating uniqueness" do
|
458
|
+
it "should return false if there were duplicates in a single-type array" do
|
459
|
+
property = DuckHunt::Properties::Array.new :validates_uniqueness => true do |s|
|
460
|
+
s.integer
|
461
|
+
end
|
462
|
+
|
463
|
+
property.valid?([1,2,1]).must_equal false
|
464
|
+
property.errors.size.must_equal 1
|
465
|
+
property.errors["base"].must_equal ["duplicate items are not allowed"]
|
466
|
+
end
|
467
|
+
|
468
|
+
it "should return false if there were duplicates in a tuple array (no optional items)" do
|
469
|
+
property = DuckHunt::Properties::Array.new :validates_uniqueness => true do |s|
|
470
|
+
s.items do |x|
|
471
|
+
x.integer
|
472
|
+
x.integer
|
473
|
+
x.integer
|
474
|
+
end
|
475
|
+
end
|
476
|
+
|
477
|
+
property.valid?([1,2,1]).must_equal false
|
478
|
+
property.errors.size.must_equal 1
|
479
|
+
property.errors["base"].must_equal ["duplicate items are not allowed"]
|
480
|
+
end
|
481
|
+
|
482
|
+
it "should return false if there were duplicates in a tuple array (with optional items)" do
|
483
|
+
property = DuckHunt::Properties::Array.new :validates_uniqueness => true do |s|
|
484
|
+
s.items do |x|
|
485
|
+
x.integer
|
486
|
+
x.integer
|
487
|
+
end
|
488
|
+
|
489
|
+
s.optional_items do |x|
|
490
|
+
x.integer
|
491
|
+
end
|
492
|
+
end
|
493
|
+
|
494
|
+
property.valid?([1,2,1]).must_equal false
|
495
|
+
property.errors.size.must_equal 1
|
496
|
+
property.errors["base"].must_equal ["duplicate items are not allowed"]
|
497
|
+
end
|
498
|
+
|
499
|
+
it "should return false if there were duplicates in a tuple array (all optional items)" do
|
500
|
+
property = DuckHunt::Properties::Array.new :validates_uniqueness => true do |s|
|
501
|
+
s.optional_items do |x|
|
502
|
+
x.integer
|
503
|
+
x.integer
|
504
|
+
x.integer
|
505
|
+
end
|
506
|
+
end
|
507
|
+
|
508
|
+
property.valid?([1,2,1]).must_equal false
|
509
|
+
property.errors.size.must_equal 1
|
510
|
+
property.errors["base"].must_equal ["duplicate items are not allowed"]
|
511
|
+
end
|
512
|
+
end
|
513
|
+
|
514
|
+
describe DuckHunt::Properties::Array, "validating minimum size" do
|
515
|
+
it "should return false if there were not enough items in a single-type array" do
|
516
|
+
property = DuckHunt::Properties::Array.new :min_size => 3 do |s|
|
517
|
+
s.integer
|
518
|
+
end
|
519
|
+
|
520
|
+
property.valid?([1,2]).must_equal false
|
521
|
+
property.errors.size.must_equal 1
|
522
|
+
property.errors["base"].must_equal ["expected at least 3 item(s) but got 2 item(s)"]
|
523
|
+
end
|
524
|
+
|
525
|
+
it "should return true if there were just enough items in a single-type array" do
|
526
|
+
property = DuckHunt::Properties::Array.new :min_size => 3 do |s|
|
527
|
+
s.integer
|
528
|
+
end
|
529
|
+
|
530
|
+
property.valid?([1,2,3]).must_equal true
|
531
|
+
property.errors.size.must_equal 0
|
532
|
+
end
|
533
|
+
|
534
|
+
it "should return true if there were more than enough items in a single-type array" do
|
535
|
+
property = DuckHunt::Properties::Array.new :min_size => 3 do |s|
|
536
|
+
s.integer
|
537
|
+
end
|
538
|
+
|
539
|
+
property.valid?([1,2,3,4]).must_equal true
|
540
|
+
property.errors.size.must_equal 0
|
541
|
+
end
|
542
|
+
end
|
543
|
+
|
544
|
+
describe DuckHunt::Properties::Array, "validating maximum size" do
|
545
|
+
it "should return false if there were too many items in a single-type array" do
|
546
|
+
property = DuckHunt::Properties::Array.new :max_size => 3 do |s|
|
547
|
+
s.integer
|
548
|
+
end
|
549
|
+
|
550
|
+
property.valid?([1,2,3,4]).must_equal false
|
551
|
+
property.errors.size.must_equal 1
|
552
|
+
property.errors["base"].must_equal ["expected at most 3 item(s) but got 4 item(s)"]
|
553
|
+
end
|
554
|
+
|
555
|
+
it "should return true if we were at the limit of items in a single-type array" do
|
556
|
+
property = DuckHunt::Properties::Array.new :max_size => 3 do |s|
|
557
|
+
s.integer
|
558
|
+
end
|
559
|
+
|
560
|
+
property.valid?([1,2,3]).must_equal true
|
561
|
+
property.errors.size.must_equal 0
|
562
|
+
end
|
563
|
+
|
564
|
+
it "should return true if we were not close to the limit in a single-type array" do
|
565
|
+
property = DuckHunt::Properties::Array.new :max_size => 3 do |s|
|
566
|
+
s.integer
|
567
|
+
end
|
568
|
+
|
569
|
+
property.valid?([1]).must_equal true
|
570
|
+
property.errors.size.must_equal 0
|
571
|
+
end
|
572
|
+
end
|
573
|
+
|
574
|
+
describe DuckHunt::Properties::Array, "validating minimum and maximum size" do
|
575
|
+
before do
|
576
|
+
@property = DuckHunt::Properties::Array.new :min_size => 3, :max_size => 5 do |s|
|
577
|
+
s.integer
|
578
|
+
end
|
579
|
+
end
|
580
|
+
|
581
|
+
it "should return false if it is below the minimum" do
|
582
|
+
@property.valid?([1,2]).must_equal false
|
583
|
+
@property.errors.size.must_equal 1
|
584
|
+
@property.errors["base"].must_equal ["expected at least 3 item(s) but got 2 item(s)"]
|
585
|
+
end
|
586
|
+
|
587
|
+
it "should return false if it is above the maximum" do
|
588
|
+
@property.valid?([1,2,3,4,5,6]).must_equal false
|
589
|
+
@property.errors.size.must_equal 1
|
590
|
+
@property.errors["base"].must_equal ["expected at most 5 item(s) but got 6 item(s)"]
|
591
|
+
end
|
592
|
+
|
593
|
+
it "should return true if it is at the minimum" do
|
594
|
+
@property.valid?([1,2,3]).must_equal true
|
595
|
+
@property.errors.size.must_equal 0
|
596
|
+
end
|
597
|
+
|
598
|
+
it "should return true if it is at the maximum" do
|
599
|
+
@property.valid?([1,2,3,4,5]).must_equal true
|
600
|
+
@property.errors.size.must_equal 0
|
601
|
+
end
|
602
|
+
|
603
|
+
it "should return true if it is within the range" do
|
604
|
+
@property.valid?([1,2,3,4]).must_equal true
|
605
|
+
@property.errors.size.must_equal 0
|
606
|
+
end
|
607
|
+
|
608
|
+
it "should return true if the min and max are the same value" do
|
609
|
+
property = DuckHunt::Properties::Array.new :min_size => 3, :max_size => 3 do |s|
|
610
|
+
s.integer
|
611
|
+
end
|
612
|
+
property.valid?([1,2,3]).must_equal true
|
613
|
+
property.errors.size.must_equal 0
|
614
|
+
end
|
615
|
+
end
|
616
|
+
|
617
|
+
describe DuckHunt::Properties::Array, "validating `allow nil`" do
|
618
|
+
it "should return false if nil is not allowed and a nil object is given" do
|
619
|
+
property = DuckHunt::Properties::Array.new :allow_nil => false do |s|
|
620
|
+
s.integer
|
621
|
+
end
|
622
|
+
property.valid?(nil).must_equal false
|
623
|
+
property.errors.size.must_equal 1
|
624
|
+
property.errors["base"].must_equal ["nil object not allowed"]
|
625
|
+
end
|
626
|
+
|
627
|
+
it "should return true if nil is allowed and a nil object is given" do
|
628
|
+
property = DuckHunt::Properties::Array.new :allow_nil => true do |s|
|
629
|
+
s.integer
|
630
|
+
end
|
631
|
+
property.valid?(nil).must_equal true
|
632
|
+
property.errors.size.must_equal 0
|
633
|
+
end
|
634
|
+
end
|
635
|
+
|
636
|
+
describe DuckHunt::Properties::Array, "Nesting in single-type array schemas" do
|
637
|
+
before do
|
638
|
+
@schema = DuckHunt::Schemas::ArraySchema.define do |s|
|
639
|
+
s.array do |s|
|
640
|
+
s.integer
|
641
|
+
end
|
642
|
+
end
|
643
|
+
end
|
644
|
+
|
645
|
+
it "should be able to be nested in an array schema" do
|
646
|
+
@schema.single_type_property.must_be_instance_of DuckHunt::Properties::Array
|
647
|
+
end
|
648
|
+
|
649
|
+
it "should return true if the nested arrays are valid" do
|
650
|
+
@schema.validate?([[1,2,3], [4,5,6]]).must_equal true
|
651
|
+
@schema.errors.size.must_equal 0
|
652
|
+
end
|
653
|
+
|
654
|
+
it "should return false if one of the nested arrays is invalid" do
|
655
|
+
@schema.validate?([[1,2,3], [4,"herp",6]]).must_equal false
|
656
|
+
@schema.errors.size.must_equal 1
|
657
|
+
@schema.errors["1"].must_equal({"1" => ["wrong type"]})
|
658
|
+
end
|
659
|
+
|
660
|
+
it "should return false if both of the nested arrays are invalid" do
|
661
|
+
@schema.validate?([{}, {}]).must_equal false
|
662
|
+
@schema.errors.size.must_equal 2
|
663
|
+
@schema.errors["0"].must_equal({"base" => ["wrong type"]})
|
664
|
+
@schema.errors["1"].must_equal({"base" => ["wrong type"]})
|
665
|
+
end
|
666
|
+
end
|
667
|
+
|
668
|
+
describe DuckHunt::Properties::Array, "Nesting in tuple array schemas (no optional properties)" do
|
669
|
+
before do
|
670
|
+
@schema = DuckHunt::Schemas::ArraySchema.define do |s|
|
671
|
+
s.items do |x|
|
672
|
+
x.array do |z|
|
673
|
+
z.integer
|
674
|
+
end
|
675
|
+
|
676
|
+
x.array do |y|
|
677
|
+
y.integer
|
678
|
+
end
|
679
|
+
end
|
680
|
+
end
|
681
|
+
end
|
682
|
+
|
683
|
+
it "should be able to be nested in an array schema" do
|
684
|
+
@schema.tuple_properties.each{|x| x.must_be_instance_of DuckHunt::Properties::Array}
|
685
|
+
end
|
686
|
+
|
687
|
+
it "should return true if the nested arrays are valid" do
|
688
|
+
@schema.validate?([[1,2,3], [4,5,6]]).must_equal true
|
689
|
+
@schema.errors.size.must_equal 0
|
690
|
+
end
|
691
|
+
|
692
|
+
it "should return false if one of the nested arrays is invalid" do
|
693
|
+
@schema.validate?([[1,2,3], [4,"herp",6]]).must_equal false
|
694
|
+
@schema.errors.size.must_equal 1
|
695
|
+
@schema.errors["1"].must_equal({"1" => ["wrong type"]})
|
696
|
+
end
|
697
|
+
|
698
|
+
it "should return false if both of the nested arrays are invalid" do
|
699
|
+
@schema.validate?([{}, {}]).must_equal false
|
700
|
+
@schema.errors.size.must_equal 2
|
701
|
+
@schema.errors["0"].must_equal({"base" => ["wrong type"]})
|
702
|
+
@schema.errors["1"].must_equal({"base" => ["wrong type"]})
|
703
|
+
end
|
704
|
+
end
|
705
|
+
|
706
|
+
describe DuckHunt::Properties::Array, "Nesting in tuple array schemas (with optional properties)" do
|
707
|
+
before do
|
708
|
+
@schema = DuckHunt::Schemas::ArraySchema.define do |s|
|
709
|
+
s.items do |x|
|
710
|
+
x.array do |z|
|
711
|
+
z.integer
|
712
|
+
end
|
713
|
+
end
|
714
|
+
|
715
|
+
s.optional_items do |w|
|
716
|
+
w.array do |y|
|
717
|
+
y.integer
|
718
|
+
end
|
719
|
+
end
|
720
|
+
end
|
721
|
+
end
|
722
|
+
|
723
|
+
it "should be able to be nested in an array schema" do
|
724
|
+
@schema.tuple_properties.each{|x| x.must_be_instance_of DuckHunt::Properties::Array}
|
725
|
+
@schema.optional_tuple_properties.each{|x| x.must_be_instance_of DuckHunt::Properties::Array}
|
726
|
+
end
|
727
|
+
|
728
|
+
it "should return true if the nested arrays are valid" do
|
729
|
+
@schema.validate?([[1,2,3], [4,5,6]]).must_equal true
|
730
|
+
@schema.errors.size.must_equal 0
|
731
|
+
end
|
732
|
+
|
733
|
+
it "should return true if only the required arrays are provided" do
|
734
|
+
@schema.validate?([[1,2,3]]).must_equal true
|
735
|
+
@schema.errors.size.must_equal 0
|
736
|
+
end
|
737
|
+
|
738
|
+
it "should return false if one of the nested arrays is invalid" do
|
739
|
+
@schema.validate?([[1,2,3], [4,"herp",6]]).must_equal false
|
740
|
+
@schema.errors.size.must_equal 1
|
741
|
+
@schema.errors["1"].must_equal({"1" => ["wrong type"]})
|
742
|
+
|
743
|
+
@schema.validate?([[1,"herp",3], [4,5,6]]).must_equal false
|
744
|
+
@schema.errors.size.must_equal 1
|
745
|
+
@schema.errors["0"].must_equal({"1" => ["wrong type"]})
|
746
|
+
end
|
747
|
+
|
748
|
+
it "should return false if both of the nested arrays are invalid" do
|
749
|
+
@schema.validate?([{}, {}]).must_equal false
|
750
|
+
@schema.errors.size.must_equal 2
|
751
|
+
@schema.errors["0"].must_equal({"base" => ["wrong type"]})
|
752
|
+
@schema.errors["1"].must_equal({"base" => ["wrong type"]})
|
753
|
+
end
|
754
|
+
end
|
755
|
+
|
756
|
+
describe DuckHunt::Properties::Array, "Nesting in tuple array schemas (all optional properties)" do
|
757
|
+
before do
|
758
|
+
@schema = DuckHunt::Schemas::ArraySchema.define do |s|
|
759
|
+
s.optional_items do |x|
|
760
|
+
x.array do |z|
|
761
|
+
z.integer
|
762
|
+
end
|
763
|
+
|
764
|
+
x.array do |w|
|
765
|
+
w.integer
|
766
|
+
end
|
767
|
+
end
|
768
|
+
end
|
769
|
+
end
|
770
|
+
|
771
|
+
it "should be able to be nested in an array schema" do
|
772
|
+
@schema.optional_tuple_properties.each{|x| x.must_be_instance_of DuckHunt::Properties::Array}
|
773
|
+
end
|
774
|
+
|
775
|
+
it "should return true if the nested arrays are valid" do
|
776
|
+
@schema.validate?([[1,2,3], [4,5,6]]).must_equal true
|
777
|
+
@schema.errors.size.must_equal 0
|
778
|
+
end
|
779
|
+
|
780
|
+
it "should return true if no arrays are provided" do
|
781
|
+
@schema.validate?([]).must_equal true
|
782
|
+
@schema.errors.size.must_equal 0
|
783
|
+
end
|
784
|
+
|
785
|
+
it "should return false if one of the nested arrays is invalid" do
|
786
|
+
@schema.validate?([[1,2,3], [4,"herp",6]]).must_equal false
|
787
|
+
@schema.errors.size.must_equal 1
|
788
|
+
@schema.errors["1"].must_equal({"1" => ["wrong type"]})
|
789
|
+
end
|
790
|
+
|
791
|
+
it "should return false if both of the nested arrays are invalid" do
|
792
|
+
@schema.validate?([{}, {}]).must_equal false
|
793
|
+
@schema.errors.size.must_equal 2
|
794
|
+
@schema.errors["0"].must_equal({"base" => ["wrong type"]})
|
795
|
+
@schema.errors["1"].must_equal({"base" => ["wrong type"]})
|
796
|
+
end
|
797
|
+
end
|
798
|
+
|
799
|
+
describe DuckHunt::Properties::Array, "Nesting in hash" do
|
800
|
+
before do
|
801
|
+
@schema = DuckHunt::Schemas::HashSchema.define do |s|
|
802
|
+
s.array "profile" do |x|
|
803
|
+
x.integer
|
804
|
+
end
|
805
|
+
|
806
|
+
s.array "info" do |x|
|
807
|
+
x.integer
|
808
|
+
end
|
809
|
+
end
|
810
|
+
end
|
811
|
+
|
812
|
+
it "should be able to be nested in a hash schema" do
|
813
|
+
@schema.properties["profile"].must_be_instance_of DuckHunt::Properties::Array
|
814
|
+
end
|
815
|
+
|
816
|
+
it "should return true if the nested arrays are valid" do
|
817
|
+
@schema.validate?({:profile => [1,2,3], :info => [4,5,6]}).must_equal true
|
818
|
+
@schema.errors.size.must_equal 0
|
819
|
+
end
|
820
|
+
|
821
|
+
it "should return false if one of the nested arrays is invalid" do
|
822
|
+
@schema.validate?({:profile => [1,2,3], :info => {:birthdate => 35}}).must_equal false
|
823
|
+
@schema.errors.size.must_equal 1
|
824
|
+
@schema.errors["info"].must_equal({"base" => ["wrong type"]})
|
825
|
+
|
826
|
+
@schema.validate?({:profile => {:name => "John"}, :info => [4,5,6]}).must_equal false
|
827
|
+
@schema.errors.size.must_equal 1
|
828
|
+
@schema.errors["profile"].must_equal({"base" => ["wrong type"]})
|
829
|
+
end
|
830
|
+
|
831
|
+
it "should return false if both of the nested arrays are invalid" do
|
832
|
+
@schema.validate?({:profile => {}, :info => {}}).must_equal false
|
833
|
+
@schema.errors.size.must_equal 2
|
834
|
+
@schema.errors["profile"].must_equal({"base" => ["wrong type"]})
|
835
|
+
@schema.errors["info"].must_equal({"base" => ["wrong type"]})
|
836
|
+
end
|
837
|
+
end
|