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
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2014 Thomas Cannon
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
7
|
+
the Software without restriction, including without limitation the rights to
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
9
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
10
|
+
subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
17
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
18
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
19
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
20
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,526 @@
|
|
1
|
+
# Duck Hunt
|
2
|
+
## A dependency-free object validator for Ruby
|
3
|
+
|
4
|
+
Duck Typing is pretty fantastic, but sometimes you need to be sure your inputs match what you expect.
|
5
|
+
|
6
|
+
REST APIs are a great example: you've defined the structure of your endpoints and the parameters you expect, down to the datatype. Now you *could* throw in a bunch of conditionals to check input parameters, but that gets out of hand quickly and is a nightmare to maintain.
|
7
|
+
|
8
|
+
What if you could define how an object should look, and check if you're getting back what you expect.
|
9
|
+
|
10
|
+
So instead of:
|
11
|
+
|
12
|
+
~~~ruby
|
13
|
+
def create
|
14
|
+
unless params[:user].present? and params[:user][:name].present? and params[:user][:age].present? and params[:user][:age].is_a? Integer and params[:user][:age] > 0 # ... you get the point
|
15
|
+
head :bad_request and return
|
16
|
+
end
|
17
|
+
|
18
|
+
# After that mouthful, actually do something
|
19
|
+
|
20
|
+
end
|
21
|
+
~~~
|
22
|
+
|
23
|
+
You had:
|
24
|
+
|
25
|
+
~~~ruby
|
26
|
+
module UserSchemas
|
27
|
+
def create
|
28
|
+
DuckHunt::Schemas::HashSchema.define :strict_mode => true do |user|
|
29
|
+
user.string "name", :required => true, :allow_nil => false
|
30
|
+
user.integer "age", :required => true, :allow_nil => false, :greater_than => 0
|
31
|
+
user.nested_hash "address", :required => true do |address|
|
32
|
+
address.string "state", :required => true
|
33
|
+
address.string "city", :required => false
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
class UserAPI
|
40
|
+
def create
|
41
|
+
head :bad_request and return unless UserSchemas.create.validate?(params[:user])
|
42
|
+
|
43
|
+
# the rest of your API call
|
44
|
+
end
|
45
|
+
end
|
46
|
+
~~~
|
47
|
+
|
48
|
+
It's also *blazing fast*, since it's dependency-free and deals with plain Ruby objects.
|
49
|
+
|
50
|
+
|
51
|
+
## Installation notes
|
52
|
+
|
53
|
+
Just add the following to your Gemfile:
|
54
|
+
|
55
|
+
~~~ruby
|
56
|
+
gem 'duck-hunt'
|
57
|
+
~~~
|
58
|
+
|
59
|
+
## Requirements
|
60
|
+
|
61
|
+
Ruby 1.8.7+
|
62
|
+
|
63
|
+
That's it. This library was designed to be dependency-free, built entirely with Ruby. There are some parts that have been borrowed from activesupport, but they're baked into the library.
|
64
|
+
|
65
|
+
|
66
|
+
## How it works
|
67
|
+
|
68
|
+
A schema has multiple properties, which can have multiple validators. That sounds complex, but the syntax is designed to help you understand exactly how an object's defined.
|
69
|
+
|
70
|
+
### Schemas
|
71
|
+
|
72
|
+
Schemas are the top-level structure of the object. There are two types of Schemas: a Hash and an Array. These are the two types of objects you'll be checking.
|
73
|
+
|
74
|
+
You define a schema using the following syntax:
|
75
|
+
|
76
|
+
~~~ruby
|
77
|
+
DuckHunt::Schemas::HashSchema.define do |hash|
|
78
|
+
# define hash key/valaue pairings here
|
79
|
+
end
|
80
|
+
|
81
|
+
# OR
|
82
|
+
|
83
|
+
DuckHunt::Schemas::ArraySchema.define do |array|
|
84
|
+
# define array entry properties here
|
85
|
+
end
|
86
|
+
~~~
|
87
|
+
|
88
|
+
`define` returns an instance of the schema defined by the block you gave it. Calling `validate?` on this instance with a ruby object validates the object against the and returns a boolean. If the object is not valid, the `errors` method returns the errors explaining what went wrong
|
89
|
+
|
90
|
+
~~~ruby
|
91
|
+
schema = DuckHunt::Schemas::HashSchema.define do |x|
|
92
|
+
x.string "name"
|
93
|
+
end
|
94
|
+
|
95
|
+
schema.validate?(:name => "hey")
|
96
|
+
#=> true
|
97
|
+
|
98
|
+
schema.validate?(:name => 12)
|
99
|
+
#=> false
|
100
|
+
|
101
|
+
schema.errors
|
102
|
+
#=> {"name"=>["wrong type"]}
|
103
|
+
~~~
|
104
|
+
|
105
|
+
#### Hash Schemas
|
106
|
+
|
107
|
+
When using Duck Hunt to validate hashes, you're asking "does this hash have the following keys, and is the key's value what I expect?"
|
108
|
+
|
109
|
+
The basic syntax for defining a hash schema is:
|
110
|
+
|
111
|
+
~~~ruby
|
112
|
+
DuckHunt::Schemas::HashSchema.define do |x|
|
113
|
+
#x.key_type "key_name", :any_other => 1, :validators => true
|
114
|
+
|
115
|
+
x.string "name", :matches => /\w+\s\w+/
|
116
|
+
x.string "title", :required => false
|
117
|
+
end
|
118
|
+
~~~
|
119
|
+
|
120
|
+
Any property added to the hash schema is required by default. You can change that behavior by adding `:required => false` to the property definition. For clarity, I recommend always setting the `:required` option.
|
121
|
+
|
122
|
+
A property can only be defined in a schema once. Otherwise, a `DuckHunt:::PropertyAlreadyDefined` exception is thrown.
|
123
|
+
|
124
|
+
There are two types of validation for hash schemas: Strict and Relaxed. The validation type is controlled by the `:strict_mode` option in the `define` method.
|
125
|
+
|
126
|
+
##### Strict Validation
|
127
|
+
|
128
|
+
Strict Validation is the default type of validation for a Hash Schema. It validates that the object does not have any keys that are not defined in the schema:
|
129
|
+
|
130
|
+
~~~ruby
|
131
|
+
strict_schema = DuckHunt::Schemas::HashSchema.define, :strict_mode => true do |x|
|
132
|
+
x.string "name"
|
133
|
+
end
|
134
|
+
|
135
|
+
strict_schema.validate?({:name => "Jane"})
|
136
|
+
#=> true
|
137
|
+
|
138
|
+
strict_schema.validate?({:name => "Jane", :age => 21})
|
139
|
+
#=> false
|
140
|
+
|
141
|
+
strict_schema.errors
|
142
|
+
#=> {"base"=>["has properties not defined in schema"]}
|
143
|
+
~~~
|
144
|
+
|
145
|
+
##### Relaxed Validation
|
146
|
+
|
147
|
+
Relaxed validation does not care if the object has keys that are not defined in the schema:
|
148
|
+
|
149
|
+
~~~ruby
|
150
|
+
relaxed_schema = DuckHunt::Schemas::HashSchema.define, :strict_mode => false do |x|
|
151
|
+
x.string "name"
|
152
|
+
end
|
153
|
+
|
154
|
+
relaxed_schema.validate?({:name => "Jane"})
|
155
|
+
#=> true
|
156
|
+
|
157
|
+
relaxed_schema.validate?({:name => "Jane", :age => 21})
|
158
|
+
#=> true
|
159
|
+
~~~
|
160
|
+
|
161
|
+
|
162
|
+
##### Allowing a nil object
|
163
|
+
|
164
|
+
If you don't care whether the object is `nil` or not, you can set `:allow_nil => true` in the `define` method:
|
165
|
+
|
166
|
+
~~~ruby
|
167
|
+
nil_schema = DuckHunt::Schemas::HashSchema.define, :allow_nil => false do |x|
|
168
|
+
x.string "name"
|
169
|
+
end
|
170
|
+
|
171
|
+
nil_schema.validate?({:name => "Jane"})
|
172
|
+
#=> true
|
173
|
+
|
174
|
+
nil_schema.validate?(nil)
|
175
|
+
#=> true
|
176
|
+
~~~
|
177
|
+
|
178
|
+
#### Array Schemas
|
179
|
+
|
180
|
+
When using Duck Hunt to validate hashes, you're asking "does this array contain the values that I expect?" There are two types of Array Schemas, each with vastly different definitions and behaviors.
|
181
|
+
|
182
|
+
##### Single-type Arrays
|
183
|
+
|
184
|
+
A single type array means that every item in the array has the same type and matches the same properties.
|
185
|
+
|
186
|
+
You define a single type array by adding a single property in the schema definition:
|
187
|
+
|
188
|
+
~~~ruby
|
189
|
+
schema = DuckHunt::Schemas::ArraySchema.define do |x|
|
190
|
+
x.integer
|
191
|
+
end
|
192
|
+
|
193
|
+
schema.validate?([1,2,3])
|
194
|
+
#=> true
|
195
|
+
|
196
|
+
schema.validate?([1,"whoops",3])
|
197
|
+
#=> false
|
198
|
+
|
199
|
+
schema.errors
|
200
|
+
#=> {"1"=>["wrong type"]}
|
201
|
+
~~~
|
202
|
+
|
203
|
+
You can also set a minmum size for the array, a maximum size, or both!
|
204
|
+
|
205
|
+
~~~ruby
|
206
|
+
minimum_schema = DuckHunt::Schemas::ArraySchema.define :min_size => 2 do |x|
|
207
|
+
x.integer
|
208
|
+
end
|
209
|
+
|
210
|
+
minimum_schema.validate?([1,2])
|
211
|
+
#=> true
|
212
|
+
|
213
|
+
minimum_schema.validate?([1])
|
214
|
+
#=> false
|
215
|
+
|
216
|
+
minimum_schema.errors
|
217
|
+
#=> {"base" => ["expected at least 2 item(s) but got 1 item(s)"]}
|
218
|
+
~~~
|
219
|
+
|
220
|
+
~~~ruby
|
221
|
+
max_schema = DuckHunt::Schemas::ArraySchema.define :max_size => 2 do |x|
|
222
|
+
x.integer
|
223
|
+
end
|
224
|
+
|
225
|
+
max_schema.validate?([1,2])
|
226
|
+
#=> true
|
227
|
+
|
228
|
+
max_schema.validate?([1,2,3])
|
229
|
+
#=> false
|
230
|
+
|
231
|
+
max_schema.errors
|
232
|
+
#=> {"base" => ["expected at most 2 item(s) but got 3 item(s)"]}
|
233
|
+
~~~
|
234
|
+
|
235
|
+
~~~ruby
|
236
|
+
max_schema = DuckHunt::Schemas::ArraySchema.define :min_size => 2 :max_size => 3 do |x|
|
237
|
+
x.integer
|
238
|
+
end
|
239
|
+
|
240
|
+
max_schema.validate?([1])
|
241
|
+
#=> false
|
242
|
+
|
243
|
+
max_schema.errors
|
244
|
+
#=> {"base" => ["expected at least 2 item(s) but got 1 item(s)"]}
|
245
|
+
|
246
|
+
max_schema.validate?([1,2])
|
247
|
+
#=> true
|
248
|
+
|
249
|
+
max_schema.validate?([1,2,3])
|
250
|
+
#=> true
|
251
|
+
|
252
|
+
max_schema.validate?([1,2,3,4])
|
253
|
+
#=> false
|
254
|
+
|
255
|
+
max_schema.errors
|
256
|
+
#=> {"base" => ["expected at most 3 item(s) but got 4 item(s)"]}
|
257
|
+
~~~
|
258
|
+
|
259
|
+
##### Tuple Arrays
|
260
|
+
|
261
|
+
A tuple array is an ordered array that can have mixed types. It expects a defined number of required items, and may have optional items at the end of the array. All items in the array must match the type defined for that index.
|
262
|
+
|
263
|
+
To define the required items for a tuple array, you call `items` in the `define` block:
|
264
|
+
|
265
|
+
~~~ruby
|
266
|
+
tuple_schema = DuckHunt::Schemas::ArraySchema.define do |x|
|
267
|
+
x.items do |s|
|
268
|
+
s.integer
|
269
|
+
s.string
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
tuple_schema.validate?([1,"hello"])
|
274
|
+
#=> true
|
275
|
+
|
276
|
+
tuple_schema.validate?([1])
|
277
|
+
#=> false
|
278
|
+
|
279
|
+
tuple_schema.errors
|
280
|
+
#=> { "base" => "expected at least 2 item(s) but got 1 item(s)"}
|
281
|
+
|
282
|
+
tuple_schema.validate?([1,"hello", 3])
|
283
|
+
#=> false
|
284
|
+
|
285
|
+
tuple_schema.errors
|
286
|
+
#=> { "base" => "expected at most 2 item(s) but got 3 item(s)"}
|
287
|
+
|
288
|
+
tuple_schema.validate?([1,2])
|
289
|
+
#=> false
|
290
|
+
|
291
|
+
tuple_schema.errors
|
292
|
+
#=> { "1" => "wrong type" }
|
293
|
+
~~~
|
294
|
+
|
295
|
+
Likewise, to define to optional itmes for a tuple array, you call `optional_items` in the `define` block. **Note that the object does not have to have *every* optional item.**
|
296
|
+
|
297
|
+
~~~ruby
|
298
|
+
tuple_schema = DuckHunt::Schemas::ArraySchema.define do |x|
|
299
|
+
x.items do |s|
|
300
|
+
s.integer
|
301
|
+
s.string
|
302
|
+
end
|
303
|
+
|
304
|
+
x.optional_items do |y|
|
305
|
+
y.string
|
306
|
+
y.integer
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
310
|
+
tuple_schema.validate?([1,"hello"])
|
311
|
+
#=> true
|
312
|
+
|
313
|
+
tuple_schema.validate?([1,"hello", 3])
|
314
|
+
#=> false
|
315
|
+
|
316
|
+
tuple_schema.errors
|
317
|
+
#=> { "2" => "wrong type"}
|
318
|
+
|
319
|
+
tuple_schema.validate?([1,"hello", "world"])
|
320
|
+
#=> true
|
321
|
+
|
322
|
+
tuple_schema.validate?([1,"hello", "world", 3, 4])
|
323
|
+
#=> false
|
324
|
+
|
325
|
+
tuple_schema.errors
|
326
|
+
#=> { "base" => "expected at most 4 item(s) but got 5 item(s)"}
|
327
|
+
~~~
|
328
|
+
|
329
|
+
##### Allowing a nil object
|
330
|
+
|
331
|
+
If you don't care whether the object is `nil` or not, you can set `:allow_nil => true` in the `define` method:
|
332
|
+
|
333
|
+
~~~ruby
|
334
|
+
nil_schema = DuckHunt::Schemas::Array.define, :allow_nil => false do |x|
|
335
|
+
x.integer
|
336
|
+
end
|
337
|
+
|
338
|
+
nil_schema.validate?([1,2,3])
|
339
|
+
#=> true
|
340
|
+
|
341
|
+
nil_schema.validate?(nil)
|
342
|
+
#=> true
|
343
|
+
~~~
|
344
|
+
|
345
|
+
### Properties
|
346
|
+
|
347
|
+
Properties are the datatypes you can validate against in your schemas. They cover the basic datatypes you'd see when converying JSON to a ruby object:
|
348
|
+
|
349
|
+
* Array
|
350
|
+
* Boolean
|
351
|
+
* Float
|
352
|
+
* Integer
|
353
|
+
* Nested Hash
|
354
|
+
* Nil
|
355
|
+
* String
|
356
|
+
|
357
|
+
#### Nested Arrays and Hashes
|
358
|
+
|
359
|
+
Sometimes you need nested objects, like nested hashes or multi-dimensional arrays. It's really easy to define these in Duck Hunt:
|
360
|
+
|
361
|
+
~~~
|
362
|
+
nested_hash = DuckHunt::Schemas::HashSchema.define do |x|
|
363
|
+
x.nested_hash "name" do |s|
|
364
|
+
s.string "first_name"
|
365
|
+
s.string "last_name"
|
366
|
+
end
|
367
|
+
end
|
368
|
+
|
369
|
+
nested_hash.validate?({:name => {:first_name => "Jane", :last_name => "Doe"}})
|
370
|
+
#=> true
|
371
|
+
|
372
|
+
nested_hash.validate?({:name => "hello"})
|
373
|
+
#=> false
|
374
|
+
|
375
|
+
nested_hash.errors
|
376
|
+
#=> {"name"=>{"base"=>["wrong type"]}}
|
377
|
+
|
378
|
+
nested_hash.validate?({:name => {:first_name => "Jane", :last_name => 1}})
|
379
|
+
#=> false
|
380
|
+
|
381
|
+
nested_hash.errors
|
382
|
+
#=> {"name"=>{"last_name"=>["wrong type"]}}
|
383
|
+
~~~
|
384
|
+
|
385
|
+
~~~ruby
|
386
|
+
multi_array = DuckHunt::Schemas::ArraySchema.define do |x|
|
387
|
+
x.array do |y|
|
388
|
+
y.integer
|
389
|
+
end
|
390
|
+
end
|
391
|
+
|
392
|
+
multi_array.validate?([[1,2],[3,4]])
|
393
|
+
#=> true
|
394
|
+
|
395
|
+
multi_array.validate?([[1,2],"hello"])
|
396
|
+
#=> false
|
397
|
+
|
398
|
+
multi_array.errors
|
399
|
+
#=> {"1"=>{"base"=>["wrong type"]}}
|
400
|
+
|
401
|
+
multi_array.validate?([[1,2],["hello",4]])
|
402
|
+
#=> false
|
403
|
+
|
404
|
+
multi_array.errors
|
405
|
+
#=> {"1"=>{"0"=>["wrong type"]}}
|
406
|
+
~~~
|
407
|
+
|
408
|
+
|
409
|
+
### Validators
|
410
|
+
|
411
|
+
Validators can be attached to any property to check if the value follows certain behavior. Each validator has its own error message
|
412
|
+
|
413
|
+
#### Accepted Values
|
414
|
+
|
415
|
+
This property can only have the values in this list
|
416
|
+
|
417
|
+
~~~ruby
|
418
|
+
schema = DuckHunt::Schemas::HashSchema.define do |x|
|
419
|
+
x.integer "cats" :accepted_values => [1,2,3]
|
420
|
+
end
|
421
|
+
|
422
|
+
schema.validates?({:cats => 4})
|
423
|
+
#=> false
|
424
|
+
|
425
|
+
schema.errors
|
426
|
+
#=> {"0" => "not an accepted value"}
|
427
|
+
~~~
|
428
|
+
|
429
|
+
#### Accepted Values
|
430
|
+
|
431
|
+
This property cannot have any of the values in this list
|
432
|
+
|
433
|
+
~~~ruby
|
434
|
+
schema = DuckHunt::Schemas::HashSchema.define do |x|
|
435
|
+
x.integer "cats" :rejected_values => [1,2,3]
|
436
|
+
end
|
437
|
+
|
438
|
+
schema.validates?({:cats => 1})
|
439
|
+
#=> false
|
440
|
+
|
441
|
+
schema.errors
|
442
|
+
#=> {"0" => "a rejected value"}
|
443
|
+
~~~
|
444
|
+
|
445
|
+
### Matches Regular Expression
|
446
|
+
|
447
|
+
This property is only valid if it matches the regular expression given
|
448
|
+
|
449
|
+
~~~ruby
|
450
|
+
schema = DuckHunt::Schemas::HashSchema.define do |x|
|
451
|
+
x.string "name" :matches => /\w+\s\w+/
|
452
|
+
end
|
453
|
+
|
454
|
+
schema.validates?({ :name => "Bob" })
|
455
|
+
#=> false
|
456
|
+
|
457
|
+
schema.errors
|
458
|
+
#=> {"0" => "No matches for Regexp"}
|
459
|
+
~~~
|
460
|
+
|
461
|
+
#### Divisible By
|
462
|
+
|
463
|
+
This property is only valid if it's divisble by the number provided
|
464
|
+
|
465
|
+
~~~ruby
|
466
|
+
schema = DuckHunt::Schemas::HashSchema.define do |x|
|
467
|
+
x.integer "cats" :divisible_by => 3
|
468
|
+
end
|
469
|
+
|
470
|
+
schema.validates?({:cats => 4})
|
471
|
+
#=> false
|
472
|
+
|
473
|
+
schema.errors
|
474
|
+
#=> {"0" => "not divisible by `3`"}
|
475
|
+
~~~
|
476
|
+
|
477
|
+
#### Not Divisible By
|
478
|
+
|
479
|
+
This property is only valid if it's not divisble by the number provided
|
480
|
+
|
481
|
+
~~~ruby
|
482
|
+
schema = DuckHunt::Schemas::HashSchema.define do |x|
|
483
|
+
x.integer "cats" :not_divisible_by => 3
|
484
|
+
end
|
485
|
+
|
486
|
+
schema.validates?({:cats => 6})
|
487
|
+
#=> false
|
488
|
+
|
489
|
+
schema.errors
|
490
|
+
#=> {"0" => "divisible by `3`"}
|
491
|
+
~~~
|
492
|
+
|
493
|
+
#### Standard comparisons: equal to, greater than (or equal to), less than (or equal to), not equal to
|
494
|
+
|
495
|
+
This property is only valid if it fits the comparison. The comparisons defined are:
|
496
|
+
|
497
|
+
* `:equal_to`
|
498
|
+
* `:not_equal_to`
|
499
|
+
* `:greater_than`
|
500
|
+
* `:greater_than_or_equal_to`
|
501
|
+
* `:less_than`
|
502
|
+
* `:less_than_or_equal_to`
|
503
|
+
|
504
|
+
~~~ruby
|
505
|
+
schema = DuckHunt::Schemas::HashSchema.define do |x|
|
506
|
+
x.integer "cats" :greater_than => 4
|
507
|
+
end
|
508
|
+
|
509
|
+
schema.validates?({:cats => 4})
|
510
|
+
#=> false
|
511
|
+
|
512
|
+
schema.errors
|
513
|
+
#=> {"0" => "not greater than `4`"}
|
514
|
+
~~~
|
515
|
+
|
516
|
+
~~~ruby
|
517
|
+
schema = DuckHunt::Schemas::HashSchema.define do |x|
|
518
|
+
x.integer "name" :equal => "bob"
|
519
|
+
end
|
520
|
+
|
521
|
+
schema.validates?({:name => "Jim"})
|
522
|
+
#=> false
|
523
|
+
|
524
|
+
schema.errors
|
525
|
+
#=> {"0" => "not equal to `bob`"}
|
526
|
+
~~~
|