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,37 @@
|
|
1
|
+
require File.expand_path('../../test_helper', __FILE__)
|
2
|
+
|
3
|
+
describe DuckHunt::Properties::Boolean, "validation" do
|
4
|
+
before do
|
5
|
+
@property = DuckHunt::Properties::Boolean.new
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should be able to validate a boolean" do
|
9
|
+
@property.valid?(true).must_equal true
|
10
|
+
@property.errors.size.must_equal 0
|
11
|
+
|
12
|
+
@property.valid?(false).must_equal true
|
13
|
+
@property.errors.size.must_equal 0
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should be invalid if there's a type mismatch" do
|
17
|
+
@property.valid?([1,2,3]).must_equal false
|
18
|
+
@property.errors.size.must_equal 1
|
19
|
+
@property.errors.first.must_equal "wrong type"
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should not be able to validate a string of a boolean" do
|
23
|
+
@property.valid?("true").must_equal false
|
24
|
+
@property.errors.size.must_equal 1
|
25
|
+
@property.errors.first.must_equal "wrong type"
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should not be able to validate the integer 'representations' of a boolean" do
|
29
|
+
@property.valid?(0).must_equal false
|
30
|
+
@property.errors.size.must_equal 1
|
31
|
+
@property.errors.first.must_equal "wrong type"
|
32
|
+
|
33
|
+
@property.valid?(1).must_equal false
|
34
|
+
@property.errors.size.must_equal 1
|
35
|
+
@property.errors.first.must_equal "wrong type"
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require File.expand_path('../../test_helper', __FILE__)
|
2
|
+
|
3
|
+
describe DuckHunt::Properties::Float, "validation" do
|
4
|
+
before do
|
5
|
+
@property = DuckHunt::Properties::Float.new
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should be able to validate a float" do
|
9
|
+
float = 1.17
|
10
|
+
float.must_be_instance_of Float
|
11
|
+
@property.valid?(float).must_equal true
|
12
|
+
@property.errors.size.must_equal 0
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should be able to validate a BigDecimal floating point" do
|
16
|
+
bigdecimal = BigDecimal.new("3.4")
|
17
|
+
bigdecimal.must_be_instance_of BigDecimal
|
18
|
+
@property.valid?(bigdecimal).must_equal true
|
19
|
+
@property.errors.size.must_equal 0
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should be invalid if there's a type mismatch" do
|
23
|
+
@property.valid?([1,2,3]).must_equal false
|
24
|
+
@property.errors.size.must_equal 1
|
25
|
+
@property.errors.first.must_equal "wrong type"
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should not be validate to parse a Fixnum" do
|
29
|
+
integer = 3
|
30
|
+
integer.must_be_instance_of Fixnum
|
31
|
+
@property.valid?(integer).must_equal false
|
32
|
+
@property.errors.size.must_equal 1
|
33
|
+
@property.errors.first.must_equal "wrong type"
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should not be able to validate a Bignum" do
|
37
|
+
integer = 18446744073709551616
|
38
|
+
integer.must_be_instance_of Bignum
|
39
|
+
@property.valid?(integer).must_equal false
|
40
|
+
@property.errors.size.must_equal 1
|
41
|
+
@property.errors.first.must_equal "wrong type"
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should not be able to validate a string of an float" do
|
45
|
+
@property.valid?("3.17").must_equal false
|
46
|
+
@property.errors.size.must_equal 1
|
47
|
+
@property.errors.first.must_equal "wrong type"
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require File.expand_path('../../test_helper', __FILE__)
|
2
|
+
|
3
|
+
describe DuckHunt::Properties::Integer, "validation" do
|
4
|
+
before do
|
5
|
+
@property = DuckHunt::Properties::Integer.new
|
6
|
+
end
|
7
|
+
it "should be invalid if there's a type mismatch" do
|
8
|
+
@property.valid?([1,2,3]).must_equal false
|
9
|
+
@property.errors.size.must_equal 1
|
10
|
+
@property.errors.first.must_equal "wrong type"
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should be able to parse a Fixnum" do
|
14
|
+
integer = 3
|
15
|
+
integer.must_be_instance_of Fixnum
|
16
|
+
@property.valid?(integer).must_equal true
|
17
|
+
@property.errors.size.must_equal 0
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should be able to parse a Bignum" do
|
21
|
+
integer = 18446744073709551616
|
22
|
+
integer.must_be_instance_of Bignum
|
23
|
+
@property.valid?(integer).must_equal true
|
24
|
+
@property.errors.size.must_equal 0
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should not be able to parse a string of an integer" do
|
28
|
+
@property.valid?("3").must_equal false
|
29
|
+
@property.errors.size.must_equal 1
|
30
|
+
@property.errors.first.must_equal "wrong type"
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should not be able to parse a float" do
|
34
|
+
float = 1.17
|
35
|
+
float.must_be_instance_of Float
|
36
|
+
@property.valid?(float).must_equal false
|
37
|
+
@property.errors.size.must_equal 1
|
38
|
+
@property.errors.first.must_equal "wrong type"
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should not be able to parse a BigDecimal floating point" do
|
42
|
+
bigdecimal = BigDecimal.new("3.4")
|
43
|
+
bigdecimal.must_be_instance_of BigDecimal
|
44
|
+
@property.valid?(bigdecimal).must_equal false
|
45
|
+
@property.errors.size.must_equal 1
|
46
|
+
@property.errors.first.must_equal "wrong type"
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,465 @@
|
|
1
|
+
require File.expand_path('../../test_helper', __FILE__)
|
2
|
+
|
3
|
+
describe DuckHunt::Properties::NestedHash, "initialize using a block" do
|
4
|
+
it "should be able to set the property to required" do
|
5
|
+
property = DuckHunt::Properties::NestedHash.new :required => true do |s|
|
6
|
+
s.test "name"
|
7
|
+
end
|
8
|
+
property.required.must_equal true
|
9
|
+
property.required?.must_equal true
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should be able to define the property" do
|
13
|
+
property = DuckHunt::Properties::NestedHash.new :required => true do |s|
|
14
|
+
s.test "name"
|
15
|
+
end
|
16
|
+
|
17
|
+
property.properties["name"].must_be_instance_of DuckHunt::Properties::Test
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should be able to set options for the property" do
|
21
|
+
property = DuckHunt::Properties::NestedHash.new :strict_mode => false do |s|
|
22
|
+
s.test "name"
|
23
|
+
end
|
24
|
+
|
25
|
+
property.strict_mode?.must_equal false
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should be able to set property-level and property-level options at the same time" do
|
29
|
+
property = DuckHunt::Properties::NestedHash.new :required => true, :strict_mode => false do |s|
|
30
|
+
s.test "name"
|
31
|
+
end
|
32
|
+
property.required.must_equal true
|
33
|
+
property.required?.must_equal true
|
34
|
+
property.strict_mode?.must_equal false
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should default the `strict mode` to `true`" do
|
38
|
+
property = DuckHunt::Properties::NestedHash.new do |s|
|
39
|
+
end
|
40
|
+
|
41
|
+
property.strict_mode.must_equal true
|
42
|
+
property.strict_mode?.must_equal true
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
describe DuckHunt::Properties::NestedHash, "initialize without a block" do
|
48
|
+
it "should raise an exception if a block is not provided" do
|
49
|
+
lambda{
|
50
|
+
DuckHunt::Properties::NestedHash.new :required => false
|
51
|
+
}.must_raise(ArgumentError)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe DuckHunt::Properties::NestedHash, "defining properties" do
|
56
|
+
it "should be able to add a new property to the property, which is required by default" do
|
57
|
+
property = DuckHunt::Properties::NestedHash.new do |s|
|
58
|
+
s.test "name"
|
59
|
+
end
|
60
|
+
|
61
|
+
property.properties.size.must_equal 1
|
62
|
+
property.properties["name"].wont_be_nil
|
63
|
+
property.properties["name"].required.must_equal true
|
64
|
+
property.properties["name"].required?.must_equal true
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should allow a property to be explictly set as required" do
|
68
|
+
property = DuckHunt::Properties::NestedHash.new do |s|
|
69
|
+
s.test "name", :required => true
|
70
|
+
s.test "item", "required" => true
|
71
|
+
end
|
72
|
+
|
73
|
+
property.properties.size.must_equal 2
|
74
|
+
|
75
|
+
property.properties["name"].wont_be_nil
|
76
|
+
property.properties["name"].required.must_equal true
|
77
|
+
property.properties["name"].required?.must_equal true
|
78
|
+
property.properties["item"].wont_be_nil
|
79
|
+
property.properties["item"].required.must_equal true
|
80
|
+
property.properties["item"].required?.must_equal true
|
81
|
+
end
|
82
|
+
|
83
|
+
it "should allow a property to be set as not required" do
|
84
|
+
property = DuckHunt::Properties::NestedHash.new do |s|
|
85
|
+
s.test "name", :required => false
|
86
|
+
s.test "item", "required" => false
|
87
|
+
end
|
88
|
+
|
89
|
+
property.properties.size.must_equal 2
|
90
|
+
property.properties["name"].wont_be_nil
|
91
|
+
property.properties["name"].required.must_equal false
|
92
|
+
property.properties["name"].required?.must_equal false
|
93
|
+
property.properties["item"].wont_be_nil
|
94
|
+
property.properties["item"].required.must_equal false
|
95
|
+
property.properties["item"].required?.must_equal false
|
96
|
+
end
|
97
|
+
|
98
|
+
it "should require that properties are named" do
|
99
|
+
lambda{
|
100
|
+
DuckHunt::Properties::NestedHash.new do |s|
|
101
|
+
s.test
|
102
|
+
end
|
103
|
+
}.must_raise(ArgumentError)
|
104
|
+
|
105
|
+
lambda{
|
106
|
+
DuckHunt::Properties::NestedHash.new do |s|
|
107
|
+
s.test ""
|
108
|
+
end
|
109
|
+
}.must_raise(ArgumentError)
|
110
|
+
end
|
111
|
+
|
112
|
+
|
113
|
+
it "should prevent a property from being defined multiple times in a property" do
|
114
|
+
lambda {
|
115
|
+
property = DuckHunt::Properties::NestedHash.new do |s|
|
116
|
+
s.test "name"
|
117
|
+
s.test "name"
|
118
|
+
end
|
119
|
+
}.must_raise(DuckHunt::PropertyAlreadyDefined)
|
120
|
+
end
|
121
|
+
|
122
|
+
it "should ensure the list of properties cannot be modified" do
|
123
|
+
property = DuckHunt::Properties::NestedHash.new do |s|
|
124
|
+
s.test "name"
|
125
|
+
end
|
126
|
+
|
127
|
+
property.properties.size.must_equal 1
|
128
|
+
|
129
|
+
property.properties["malicious"] = "muwah ha ha"
|
130
|
+
property.properties.size.must_equal 1
|
131
|
+
|
132
|
+
lambda{
|
133
|
+
property.properties = {:malicious => "mwuah ha ha"}
|
134
|
+
}.must_raise(NoMethodError)
|
135
|
+
end
|
136
|
+
|
137
|
+
it "should ensure the list of required properties cannot be modified" do
|
138
|
+
property = DuckHunt::Properties::NestedHash.new do |s|
|
139
|
+
s.test "name"
|
140
|
+
end
|
141
|
+
|
142
|
+
lambda{
|
143
|
+
property.required_properties = {:malicious => "mwuah ha ha"}
|
144
|
+
}.must_raise(NoMethodError)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
describe DuckHunt::Properties::NestedHash, "validation (strict mode)" do
|
149
|
+
it "should return false if the object provided is not a hash" do
|
150
|
+
property = DuckHunt::Properties::NestedHash.new do |s|
|
151
|
+
s.test "name"
|
152
|
+
end
|
153
|
+
|
154
|
+
property.valid?("hello").must_equal false
|
155
|
+
property.errors.size.must_equal 1
|
156
|
+
property.errors["base"].must_equal ["wrong type"]
|
157
|
+
end
|
158
|
+
|
159
|
+
it "should return false if one of the properties is not valid" do
|
160
|
+
property = DuckHunt::Properties::NestedHash.new do |s|
|
161
|
+
s.always_wrong_type "name"
|
162
|
+
end
|
163
|
+
|
164
|
+
property.valid?({:name => "hello"}).must_equal false
|
165
|
+
property.errors.size.must_equal 1
|
166
|
+
property.errors["name"].must_equal ["wrong type"]
|
167
|
+
end
|
168
|
+
|
169
|
+
it "should return false if the object is missing a required property" do
|
170
|
+
property = DuckHunt::Properties::NestedHash.new do |s|
|
171
|
+
s.test "name", :required => true
|
172
|
+
s.always_right_type "hello", :required => false
|
173
|
+
end
|
174
|
+
|
175
|
+
property.valid?({:hello => "hello"}).must_equal false
|
176
|
+
property.errors.size.must_equal 1
|
177
|
+
property.errors["name"].must_equal ["required"]
|
178
|
+
end
|
179
|
+
|
180
|
+
it "should return false if the property has been set to strict mode and the hash provided has extra properties" do
|
181
|
+
property = DuckHunt::Properties::NestedHash.new do |s|
|
182
|
+
s.test "name", :required => true
|
183
|
+
end
|
184
|
+
|
185
|
+
property.valid?({:name => "hello", :hello => "hello"}).must_equal false
|
186
|
+
property.errors.size.must_equal 1
|
187
|
+
property.errors["base"].must_equal ["has properties not defined in schema"]
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
describe DuckHunt::Properties::NestedHash, "validation (relaxed mode)" do
|
192
|
+
it "should return false if the object provided is not a hash" do
|
193
|
+
property = DuckHunt::Properties::NestedHash.new :strict_mode => false do |s|
|
194
|
+
s.test "name"
|
195
|
+
end
|
196
|
+
|
197
|
+
property.valid?("hello").must_equal false
|
198
|
+
property.errors.size.must_equal 1
|
199
|
+
property.errors["base"].must_equal ["wrong type"]
|
200
|
+
end
|
201
|
+
|
202
|
+
it "should return false if one of the properties is not valid" do
|
203
|
+
property = DuckHunt::Properties::NestedHash.new :strict_mode => false do |s|
|
204
|
+
s.always_wrong_type "name"
|
205
|
+
end
|
206
|
+
|
207
|
+
property.valid?({:name => "hello"}).must_equal false
|
208
|
+
property.errors.size.must_equal 1
|
209
|
+
property.errors["name"].must_equal ["wrong type"]
|
210
|
+
end
|
211
|
+
|
212
|
+
it "should return false if the object is missing a required property" do
|
213
|
+
property = DuckHunt::Properties::NestedHash.new :strict_mode => false do |s|
|
214
|
+
s.test "name", :required => true
|
215
|
+
s.always_right_type "hello", :required => false
|
216
|
+
end
|
217
|
+
|
218
|
+
property.valid?({:hello => "hello"}).must_equal false
|
219
|
+
property.errors.size.must_equal 1
|
220
|
+
property.errors["name"].must_equal ["required"]
|
221
|
+
end
|
222
|
+
|
223
|
+
it "should return true if the property has been set to relaxed mode and the hash provided has extra properties" do
|
224
|
+
property = DuckHunt::Properties::NestedHash.new :strict_mode => false do |s|
|
225
|
+
s.always_right_type "name", :required => true
|
226
|
+
end
|
227
|
+
|
228
|
+
property.valid?({:name => "hello", :hello => "hello"}).must_equal true
|
229
|
+
property.errors.size.must_equal 0
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
describe DuckHunt::Properties::NestedHash, "validating `allow nil`" do
|
234
|
+
it "should return false if nil is not allowed and a nil object is given" do
|
235
|
+
property = DuckHunt::Properties::NestedHash.new :allow_nil => false do |s|
|
236
|
+
s.test "name"
|
237
|
+
end
|
238
|
+
property.valid?(nil).must_equal false
|
239
|
+
property.errors.size.must_equal 1
|
240
|
+
property.errors["base"].must_equal ["nil object not allowed"]
|
241
|
+
end
|
242
|
+
|
243
|
+
it "should return true if nil is allowed and a nil object is given" do
|
244
|
+
property = DuckHunt::Properties::NestedHash.new :allow_nil => true do |s|
|
245
|
+
s.test "name"
|
246
|
+
end
|
247
|
+
property.valid?(nil).must_equal true
|
248
|
+
property.errors.size.must_equal 0
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
describe DuckHunt::Properties::NestedHash, "Nesting in single-type array schemas" do
|
253
|
+
before do
|
254
|
+
@schema = DuckHunt::Schemas::ArraySchema.define do |s|
|
255
|
+
s.nested_hash do |s|
|
256
|
+
s.always_right_type "name", :required => true
|
257
|
+
end
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
it "should be able to be nested in an array schema" do
|
262
|
+
@schema.single_type_property.must_be_instance_of DuckHunt::Properties::NestedHash
|
263
|
+
end
|
264
|
+
|
265
|
+
it "should return true if the nested hashes are valid" do
|
266
|
+
@schema.validate?([{:name => "Hello"}, {:name => "World"}]).must_equal true
|
267
|
+
@schema.errors.size.must_equal 0
|
268
|
+
end
|
269
|
+
|
270
|
+
it "should return false if one of the nested hashes is invalid" do
|
271
|
+
@schema.validate?([{:name => "Hello"}, {:world => "World"}]).must_equal false
|
272
|
+
@schema.errors.size.must_equal 1
|
273
|
+
@schema.errors["1"].must_equal({"base" => ["has properties not defined in schema"]})
|
274
|
+
|
275
|
+
@schema.validate?([{:name => "Hello"}, {}]).must_equal false
|
276
|
+
@schema.errors.size.must_equal 1
|
277
|
+
@schema.errors["1"].must_equal({"name" => ["required"]})
|
278
|
+
end
|
279
|
+
|
280
|
+
it "should return false if both of the nested hashes are invalid" do
|
281
|
+
@schema.validate?([{}, {}]).must_equal false
|
282
|
+
@schema.errors.size.must_equal 2
|
283
|
+
@schema.errors["0"].must_equal({"name" => ["required"]})
|
284
|
+
@schema.errors["1"].must_equal({"name" => ["required"]})
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
288
|
+
describe DuckHunt::Properties::NestedHash, "Nesting in tuple array schemas (no optional properties)" do
|
289
|
+
before do
|
290
|
+
@schema = DuckHunt::Schemas::ArraySchema.define do |s|
|
291
|
+
s.items do |x|
|
292
|
+
x.nested_hash do |z|
|
293
|
+
z.always_right_type "name", :required => true
|
294
|
+
end
|
295
|
+
|
296
|
+
x.nested_hash do |y|
|
297
|
+
y.always_right_type "age", :required => true
|
298
|
+
end
|
299
|
+
end
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|
303
|
+
it "should be able to be nested in an array schema" do
|
304
|
+
@schema.tuple_properties.each{|x| x.must_be_instance_of DuckHunt::Properties::NestedHash}
|
305
|
+
end
|
306
|
+
|
307
|
+
it "should return true if the nested hashes are valid" do
|
308
|
+
@schema.validate?([{:name => "Hello"}, {:age => "World"}]).must_equal true
|
309
|
+
@schema.errors.size.must_equal 0
|
310
|
+
end
|
311
|
+
|
312
|
+
it "should return false if one of the nested hashes is invalid" do
|
313
|
+
@schema.validate?([{:name => "Hello"}, {:world => "World"}]).must_equal false
|
314
|
+
@schema.errors.size.must_equal 1
|
315
|
+
@schema.errors["1"].must_equal({"base" => ["has properties not defined in schema"]})
|
316
|
+
|
317
|
+
@schema.validate?([{:name => "Hello"}, {}]).must_equal false
|
318
|
+
@schema.errors.size.must_equal 1
|
319
|
+
@schema.errors["1"].must_equal({"age" => ["required"]})
|
320
|
+
end
|
321
|
+
|
322
|
+
it "should return false if both of the nested hashes are invalid" do
|
323
|
+
@schema.validate?([{}, {}]).must_equal false
|
324
|
+
@schema.errors.size.must_equal 2
|
325
|
+
@schema.errors["0"].must_equal({"name" => ["required"]})
|
326
|
+
@schema.errors["1"].must_equal({"age" => ["required"]})
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
330
|
+
describe DuckHunt::Properties::NestedHash, "Nesting in tuple array schemas (with optional properties)" do
|
331
|
+
before do
|
332
|
+
@schema = DuckHunt::Schemas::ArraySchema.define do |s|
|
333
|
+
s.items do |x|
|
334
|
+
x.nested_hash do |z|
|
335
|
+
z.always_right_type "name", :required => true
|
336
|
+
end
|
337
|
+
end
|
338
|
+
|
339
|
+
s.optional_items do |w|
|
340
|
+
w.nested_hash do |y|
|
341
|
+
y.always_right_type "age", :required => true
|
342
|
+
end
|
343
|
+
end
|
344
|
+
end
|
345
|
+
end
|
346
|
+
|
347
|
+
it "should be able to be nested in an array schema" do
|
348
|
+
@schema.tuple_properties.each{|x| x.must_be_instance_of DuckHunt::Properties::NestedHash}
|
349
|
+
@schema.optional_tuple_properties.each{|x| x.must_be_instance_of DuckHunt::Properties::NestedHash}
|
350
|
+
end
|
351
|
+
|
352
|
+
it "should return true if the nested hashes are valid" do
|
353
|
+
@schema.validate?([{:name => "Hello"}, {:age => "World"}]).must_equal true
|
354
|
+
@schema.errors.size.must_equal 0
|
355
|
+
end
|
356
|
+
|
357
|
+
it "should return true if only the required hashes are provided" do
|
358
|
+
@schema.validate?([{:name => "Hello"}]).must_equal true
|
359
|
+
@schema.errors.size.must_equal 0
|
360
|
+
end
|
361
|
+
|
362
|
+
it "should return false if one of the nested hashes is invalid" do
|
363
|
+
@schema.validate?([{:name => "Hello"}, {:world => "World"}]).must_equal false
|
364
|
+
@schema.errors.size.must_equal 1
|
365
|
+
@schema.errors["1"].must_equal({"base" => ["has properties not defined in schema"]})
|
366
|
+
|
367
|
+
@schema.validate?([{:name => "Hello"}, {}]).must_equal false
|
368
|
+
@schema.errors.size.must_equal 1
|
369
|
+
@schema.errors["1"].must_equal({"age" => ["required"]})
|
370
|
+
end
|
371
|
+
|
372
|
+
it "should return false if both of the nested hashes are invalid" do
|
373
|
+
@schema.validate?([{}, {}]).must_equal false
|
374
|
+
@schema.errors.size.must_equal 2
|
375
|
+
@schema.errors["0"].must_equal({"name" => ["required"]})
|
376
|
+
@schema.errors["1"].must_equal({"age" => ["required"]})
|
377
|
+
end
|
378
|
+
end
|
379
|
+
|
380
|
+
describe DuckHunt::Properties::NestedHash, "Nesting in tuple array schemas (all optional properties)" do
|
381
|
+
before do
|
382
|
+
@schema = DuckHunt::Schemas::ArraySchema.define do |s|
|
383
|
+
s.optional_items do |x|
|
384
|
+
x.nested_hash do |z|
|
385
|
+
z.always_right_type "name", :required => true
|
386
|
+
end
|
387
|
+
|
388
|
+
x.nested_hash do |w|
|
389
|
+
w.always_right_type "age", :required => true
|
390
|
+
end
|
391
|
+
end
|
392
|
+
end
|
393
|
+
end
|
394
|
+
|
395
|
+
it "should be able to be nested in an array schema" do
|
396
|
+
@schema.optional_tuple_properties.each{|x| x.must_be_instance_of DuckHunt::Properties::NestedHash}
|
397
|
+
end
|
398
|
+
|
399
|
+
it "should return true if the nested hashes are valid" do
|
400
|
+
@schema.validate?([{:name => "Hello"}, {:age => "World"}]).must_equal true
|
401
|
+
@schema.errors.size.must_equal 0
|
402
|
+
end
|
403
|
+
|
404
|
+
it "should return true if no hashes are provided" do
|
405
|
+
@schema.validate?([]).must_equal true
|
406
|
+
@schema.errors.size.must_equal 0
|
407
|
+
end
|
408
|
+
|
409
|
+
it "should return false if one of the nested hashes is invalid" do
|
410
|
+
@schema.validate?([{:name => "Hello"}, {:world => "World"}]).must_equal false
|
411
|
+
@schema.errors.size.must_equal 1
|
412
|
+
@schema.errors["1"].must_equal({"base" => ["has properties not defined in schema"]})
|
413
|
+
|
414
|
+
@schema.validate?([{}, {:age => "World"}]).must_equal false
|
415
|
+
@schema.errors.size.must_equal 1
|
416
|
+
@schema.errors["0"].must_equal({"name" => ["required"]})
|
417
|
+
end
|
418
|
+
|
419
|
+
it "should return false if both of the nested hashes are invalid" do
|
420
|
+
@schema.validate?([{}, {}]).must_equal false
|
421
|
+
@schema.errors.size.must_equal 2
|
422
|
+
@schema.errors["0"].must_equal({"name" => ["required"]})
|
423
|
+
@schema.errors["1"].must_equal({"age" => ["required"]})
|
424
|
+
end
|
425
|
+
end
|
426
|
+
|
427
|
+
describe DuckHunt::Properties::NestedHash, "Nesting in hashes" do
|
428
|
+
before do
|
429
|
+
@schema = DuckHunt::Schemas::HashSchema.define do |s|
|
430
|
+
s.nested_hash "profile" do |x|
|
431
|
+
x.always_right_type "name", :required => true
|
432
|
+
end
|
433
|
+
|
434
|
+
s.nested_hash "info" do |x|
|
435
|
+
x.always_right_type "age", :required => true
|
436
|
+
end
|
437
|
+
end
|
438
|
+
end
|
439
|
+
|
440
|
+
it "should be able to be nested in an array schema" do
|
441
|
+
@schema.properties["profile"].must_be_instance_of DuckHunt::Properties::NestedHash
|
442
|
+
end
|
443
|
+
|
444
|
+
it "should return true if the nested hashes are valid" do
|
445
|
+
@schema.validate?({:profile => {:name => "John"}, :info => {:age => 35}}).must_equal true
|
446
|
+
@schema.errors.size.must_equal 0
|
447
|
+
end
|
448
|
+
|
449
|
+
it "should return false if one of the nested hashes is invalid" do
|
450
|
+
@schema.validate?({:profile => {:name => "John"}, :info => {:birthdate => 35}}).must_equal false
|
451
|
+
@schema.errors.size.must_equal 1
|
452
|
+
@schema.errors["info"].must_equal({"base" => ["has properties not defined in schema"]})
|
453
|
+
|
454
|
+
@schema.validate?({:profile => {:name => "John"}, :info => {}}).must_equal false
|
455
|
+
@schema.errors.size.must_equal 1
|
456
|
+
@schema.errors["info"].must_equal({"age" => ["required"]})
|
457
|
+
end
|
458
|
+
|
459
|
+
it "should return false if both of the nested hashes are invalid" do
|
460
|
+
@schema.validate?({:profile => {}, :info => {}}).must_equal false
|
461
|
+
@schema.errors.size.must_equal 2
|
462
|
+
@schema.errors["profile"].must_equal({"name" => ["required"]})
|
463
|
+
@schema.errors["info"].must_equal({"age" => ["required"]})
|
464
|
+
end
|
465
|
+
end
|