Add validator which succeeds if at least one of its subvalidators succeeded.
This commit is contained in:
@@ -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)
|
||||
------------------
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -53,6 +53,8 @@ Validators
|
||||
|
||||
.. autoclass:: All
|
||||
|
||||
.. autoclass:: Any
|
||||
|
||||
.. autoclass:: Range
|
||||
|
||||
.. autoclass:: Length
|
||||
|
||||
Reference in New Issue
Block a user