Add validator which succeeds if at least one of its subvalidators succeeded.

This commit is contained in:
Michael Howitz
2013-12-04 11:55:41 +01:00
parent fa8829b18e
commit 95e2734eac
4 changed files with 49 additions and 0 deletions

View File

@@ -7,6 +7,12 @@ Bug Fixes
- Un-break wrapping of callable instances as ``colander.deferred``.
See https://github.com/Pylons/colander/issues/141.
Features
~~~~~~~~
- Add `Any` validator which succeeds if at least one of its subvalidators
succeeded.
1.0b1 (2013-09-01)
------------------

View File

@@ -205,6 +205,18 @@ class All(object):
exc.children.extend(e.children)
raise exc
class Any(All):
""" Composite validator which succeeds if at least one of its
subvalidators does not raise an :class:`colander.Invalid` exception."""
def __call__(self, node, value):
try:
return super(Any, self).__call__(node, value)
except Invalid as e:
if len(e.msg) < len(self.validators):
# At least one validator did not fail:
return
raise
class Function(object):
""" Validator which accepts a function and an optional message;
the function is called with the ``value`` during validation.

View File

@@ -219,6 +219,35 @@ class TestAll(unittest.TestCase):
exc = invalid_exc(validator, node, None)
self.assertEqual(exc.children, [exc1, exc2])
class TestAny(unittest.TestCase):
def _makeOne(self, validators):
from colander import Any
return Any(*validators)
def test_success(self):
validator1 = DummyValidator('msg1')
validator2 = DummyValidator()
validator = self._makeOne([validator1, validator2])
self.assertEqual(validator(None, None), None)
def test_failure(self):
validator1 = DummyValidator('msg1')
validator2 = DummyValidator('msg2')
validator = self._makeOne([validator1, validator2])
e = invalid_exc(validator, None, None)
self.assertEqual(e.msg, ['msg1', 'msg2'])
def test_Invalid_children(self):
from colander import Invalid
node1 = DummySchemaNode(None, 'node1')
node = DummySchemaNode(None, 'node')
node.children = [node1]
exc1 = Invalid(node1, 'exc1')
validator1 = DummyValidator('validator1', [exc1])
validator2 = DummyValidator()
validator = self._makeOne([validator1, validator2])
self.assertEqual(validator(None, None), None)
class TestFunction(unittest.TestCase):
def _makeOne(self, *arg, **kw):
from colander import Function

View File

@@ -53,6 +53,8 @@ Validators
.. autoclass:: All
.. autoclass:: Any
.. autoclass:: Range
.. autoclass:: Length