- Add Email and Regex validators.
This commit is contained in:
@@ -4,6 +4,8 @@ Changes
|
||||
Next release
|
||||
------------
|
||||
|
||||
- Add Email and Regex validators.
|
||||
|
||||
- Raise a ``colander.Invalid`` error if a ``colander.SequenceSchema``
|
||||
is created with more than one member.
|
||||
|
||||
|
@@ -2,6 +2,7 @@ import datetime
|
||||
import itertools
|
||||
import iso8601
|
||||
import pprint
|
||||
import re
|
||||
|
||||
class _missing(object):
|
||||
pass
|
||||
@@ -170,6 +171,39 @@ class Function(object):
|
||||
if isinstance(result, basestring):
|
||||
raise Invalid(node, result)
|
||||
|
||||
class Regex(object):
|
||||
""" Regular expression validator. Initialize it with the string
|
||||
regular expression ``regex`` that will be compiled and matched
|
||||
against ``value`` when validator is called. If ``msg`` is
|
||||
supplied, it will be the error message to be used; otherwise,
|
||||
defaults to 'String does not match expected pattern'.
|
||||
|
||||
When calling, if ``value`` matches the regular expression,
|
||||
validation succeeds; otherwise, :exc:`colander.Invalid` is
|
||||
raised with the ``msg`` error message.
|
||||
"""
|
||||
def __init__(self, regex, msg=None):
|
||||
self.match_object = re.compile(regex)
|
||||
if msg is None:
|
||||
self.msg = "String does not match expected pattern"
|
||||
else:
|
||||
self.msg = msg
|
||||
|
||||
def __call__(self, node, value):
|
||||
if self.match_object.match(value) is None:
|
||||
raise Invalid(self.msg)
|
||||
|
||||
class Email(Regex):
|
||||
""" Email address validator. If ``msg`` is supplied, it will be
|
||||
the error message to be used when raising :exc:`colander.Invalid`;
|
||||
otherwise, defaults to "Invalid email address".
|
||||
"""
|
||||
def __init__(self, msg=None):
|
||||
if msg is None:
|
||||
msg = "Invalid email address"
|
||||
super(Email, self).__init__(
|
||||
u'(?i)^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$', msg=msg)
|
||||
|
||||
class Range(object):
|
||||
""" Validator which succeeds if the value it is passed is greater
|
||||
or equal to ``min`` and less than or equal to ``max``. If ``min``
|
||||
@@ -214,7 +248,6 @@ class Length(object):
|
||||
node,
|
||||
'Longer than maximum length %s' % self.max)
|
||||
|
||||
|
||||
class OneOf(object):
|
||||
""" Validator which succeeds if the value passed to it is one of
|
||||
a fixed set of values """
|
||||
|
@@ -194,6 +194,48 @@ class TestRange(unittest.TestCase):
|
||||
e = invalid_exc(validator, None, 2)
|
||||
self.assertEqual(e.msg, '2 is greater than maximum value 1')
|
||||
|
||||
class TestRegex(unittest.TestCase):
|
||||
def _makeOne(self, pattern):
|
||||
from colander import Regex
|
||||
return Regex(pattern)
|
||||
|
||||
def test_valid_regex(self):
|
||||
self.assertEqual(self._makeOne('a')(None, 'a'), None)
|
||||
self.assertEqual(self._makeOne('[0-9]+')(None, '1111'), None)
|
||||
self.assertEqual(self._makeOne('')(None, ''), None)
|
||||
self.assertEqual(self._makeOne('.*')(None, ''), None)
|
||||
|
||||
def test_invalid_regexs(self):
|
||||
from colander import Invalid
|
||||
self.assertRaises(Invalid, self._makeOne('[0-9]+'), None, 'a')
|
||||
self.assertRaises(Invalid, self._makeOne('a{2,4}'), None, 'ba')
|
||||
|
||||
class TestEmail(unittest.TestCase):
|
||||
def _makeOne(self):
|
||||
from colander import Email
|
||||
return Email()
|
||||
|
||||
def test_valid_emails(self):
|
||||
validator = self._makeOne()
|
||||
self.assertEqual(validator(None, 'me@here.com'), None)
|
||||
self.assertEqual(validator(None, 'me1@here1.com'), None)
|
||||
self.assertEqual(validator(None, 'name@here1.us'), None)
|
||||
self.assertEqual(validator(None, 'name@here1.info'), None)
|
||||
self.assertEqual(validator(None, 'foo@bar.baz.biz'), None)
|
||||
|
||||
def test_empty_email(self):
|
||||
validator = self._makeOne()
|
||||
from colander import Invalid
|
||||
self.assertRaises(Invalid, validator, None, '')
|
||||
|
||||
def test_invalid_emails(self):
|
||||
validator = self._makeOne()
|
||||
from colander import Invalid
|
||||
self.assertRaises(Invalid, validator, None, 'me@here.')
|
||||
self.assertRaises(Invalid, validator, None, 'name@here.comcom')
|
||||
self.assertRaises(Invalid, validator, None, '@here.us')
|
||||
self.assertRaises(Invalid, validator, None, '(name)@here.info')
|
||||
|
||||
class TestLength(unittest.TestCase):
|
||||
def _makeOne(self, min=None, max=None):
|
||||
from colander import Length
|
||||
|
@@ -22,6 +22,10 @@ Validators
|
||||
|
||||
.. autoclass:: Function
|
||||
|
||||
.. autoclass:: Regex
|
||||
|
||||
.. autoclass:: Email
|
||||
|
||||
Types
|
||||
~~~~~
|
||||
|
||||
|
Reference in New Issue
Block a user