Ducktator - the Duck Type Validator
Ducktator is a small library to enable Ruby systems to generically validate objects introspectively. In plain speak, check certain common methods of objects, and see if they match what your schema expects the values to be. This capability is not necessary for most applications, but sometimes it’s highly useful. For example, validating objects that have been serialized or marshallad. Validating what you get when loading YAML files, so that the object graph matches what your code does. Write test cases that expect a complicated object back. The possibilities are many.
Ducktator can be configured either with YAML or directly using simple Hashes. The syntax is very recursive, extensible and easy. I will use YAML for the examples in this document, but for easier validations it may be better just creating the Hash
directly.
Validator usage
The main way into the Ducktator validator framework are a couple of factory methods in the Ducktator namespace. To create a new Validator
from a YAML file you could do it like this: (in this case, there must be a root key inside the YAML document)
Ducktator::from_file('validations.yml') # => #<Ducktator::Validator ...>
You can also create a Validator
from a String
directly.
Ducktator::from('class: String') # => #<Ducktator::Validator ...>
If you just want to do a one time validation, this can be done like this:
Ducktator::valid?('class: String', 123) # => false
or like this:
Ducktator::valid?('class' => String, 'abc') # => true
Using the Validator
object is mostly as simple as calling the method valid?
and send it the objects you want to validate. valid?
will return true
only if all its arguments are valid ackording to its validation rules:
p v # => #<Ducktator::Validator ...>
v.valid?("str1")
v.valid?("str1","str2","str3")
Validators can be combined with & and |, like this:
vx = v1 & (v2 | v3) & v4
Validation specification
The validation specification will contain one or more validations to check against. A validation always has a value. It can be scalar, a sequence or a mapping. If it’s a mapping, it will be interpolated as a new specification. A simple YAML file that validates a Hash
, that should have String
keys and values that are Array
‘s with index 0 being a Symbol
and index 1 an Integer
which is maximum 256: (note that the root:
is necessary, unless loading the YAML directly from a String
)
---
root:
class: Hash
each_key: {class: String}
each_value:
class: Array
value:
- - 0
- class: Symbol
- - 1
- class: Integer
- max: 256
More than one validation can exist in the same file, just use Ducktator#from_file‘s second, optional argument, which defaults to “root”.
Author
Ola Bini <[email protected]>
License
Ducktator is distributed with a MIT license, which can be found in the file LICENSE.