Basic Validation
****************

All elements support validation.  The default, built-in validation
logic is simple: if the element is empty, it is invalid.  Otherwise it
is valid.

If that sounds too simple don’t worry- you can customize validation to
suit your needs.


Validating an Element
=====================

   >>> from flatland import String
   >>> form = String()
   >>> form.is_empty
   True
   >>> form.valid
   Unevaluated
   >>> form.validate()
   False
   >>> form.valid
   False

Validation sets the "valid" attribute of each element it inspects.
"validate()" may be invoked more than once.

   >>> form.set('Squiznart')
   True
   >>> form.is_empty
   False
   >>> form.validate()
   True
   >>> form.valid
   True

Note that default validation does not set any error messages that
might be displayed to an interactive user.  Messages are easily added
through custom validation.


Validating Entire Forms At Once
===============================

"validate()" is recursive by default.  Called on a parent node, it
will descend through all of its children, validating each.  If the
parent or any one of its children are invalid, "validate" returns
false. Note that recursion does **not** stop if it finds an invalid
child: all children are evaluated, and each will have its "valid"
attribute updated.


Optional Elements
=================

If an element is marked as "optional", it is exempt from validation
when empty.  With the default validation strategy, this effectively
means that element can never be invalid. With custom validation,
optional fields become more useful.

   >>> from flatland import Dict, Integer
   >>> schema = Dict.of(Integer.named('x'),
   ...                  Integer.named('y'),
   ...                  Integer.named('z').using(optional=True))
   >>> form = schema(dict(x=1))
   >>> form.validate()
   False
   >>> form.valid
   True
   >>> form['x'].valid
   True
   >>> form['y'].valid
   False
   >>> form['z'].valid
   True


Validation Signals
==================

The "flatland.signals.validator_validated" signal is emitted each time
a validator evaluates an element.  The signal’s sender is the
validator (or the symbol "flatland.validation.NotEmpty" for the
default validation strategy).  The signal also sends the "element",
the "state", and the "result" of the validation function.

During development, it can be convenient to connect the
"validator_validated" signal to a logging function to aid in
debugging.

   from flatland.signals import validator_validated

   @validator_validated.connect
   def monitor_validation(sender, element, state, result):
       # print or logging.debug validations as they happen:
       print "validation: %s(%s) valid == %r" % (
         sender, element.flattened_name(), result)

   >>> from flatland import String
   >>> form = String(name='surname')
   >>> form.validate()
   validation: NotEmpty(surname) valid == False
   False
