242: Started cleanup of custom exceptions; added unit tests for errors.IPAError

This commit is contained in:
Jason Gerard DeRose
2008-09-03 19:38:39 +00:00
parent 9b9615df79
commit 5e8f945a1e
4 changed files with 58 additions and 20 deletions

View File

@@ -87,32 +87,38 @@ def check_isinstance(value, type_, name, allow_none=False):
class IPAError(Exception):
"""
Base class for all custom IPA errors.
Use this base class for your custom IPA errors unless there is a
specific reason to subclass from AttributeError, KeyError, etc.
"""
msg = None
def __init__(self, *args, **kw):
format = None
def __init__(self, *args):
self.args = args
self.kw = kw
def __str__(self):
"""
Returns the string representation of this exception.
"""
if self.msg is None:
if len(self.args) == 1:
return unicode(self.args[0])
return unicode(self.args)
if len(self.args) > 0:
return self.msg % self.args
return self.msg % self.kw
return self.format % self.args
class ValidationError(IPAError):
msg = 'invalid %r value %r: %s'
"""
Base class for all types of validation errors.
"""
format = 'invalid %r value %r: %s'
def __init__(self, name, value, error, index=None):
"""
:param name: The name of the value that failed validation.
:param value: The value that failed validation.
:param error: The error message describing the failure.
:param index: If multivalue, index of value in multivalue tuple
"""
self.name = name
self.value = value
self.error = error
@@ -138,12 +144,11 @@ class NormalizationError(ValidationError):
class RuleError(ValidationError):
"""
Raised when a required option was not provided.
Raised when a value fails a validation rule.
"""
# FIXME: `rule` should really be after `error`
def __init__(self, name, value, rule, error):
self.rule = rule
ValidationError.__init__(self, name, value, error)
def __init__(self, name, value, error, rule, index=None):
self.rule_name = rule.__name__
ValidationError.__init__(self, name, value, error, index)
class RequirementError(ValidationError):

View File

@@ -138,11 +138,13 @@ class Option(plugable.ReadOnly):
return tuple(self.__normalize_scalar(v) for v in value)
return self.__normalize_scalar(value)
def __validate_scalar(self, value):
def __validate_scalar(self, value, index=None):
if type(value) is not self.type.type:
raise_TypeError(value, self.type.type, 'value')
for rule in self.rules:
error = rule(value)
if error is not None:
raise errors.RuleError(self.name, value, rule, error)
raise errors.RuleError(self.name, value, error, rule)
def validate(self, value):
if value is None and self.required:

View File

@@ -129,3 +129,34 @@ def test_check_isinstance():
fail_bool = 0
e = raises(AssertionError, f, value, type_, name, allow_none=fail_bool)
assert str(e) == type_format % ('allow_none', bool, fail_bool)
class test_IPAError(ClassChecker):
"""
Tests the `errors.IPAError` exception.
"""
_cls = errors.IPAError
def test_class(self):
assert self.cls.__bases__ == (Exception,)
def test_init(self):
"""
Tests the `errors.IPAError.__init__` method.
"""
args = ('one fish', 'two fish')
e = self.cls(*args)
assert e.args == args
assert self.cls().args == tuple()
def test_str(self):
"""
Tests the `errors.IPAError.__str__` method.
"""
f = 'The %s color is %s.'
class custom_error(self.cls):
format = f
for args in [('sexiest', 'red'), ('most-batman-like', 'black')]:
e = custom_error(*args)
assert e.args == args
assert str(e) == f % args

View File

@@ -203,7 +203,7 @@ class test_Option(ClassChecker):
for v in [(fail,), (u'Hello', fail)]: # Non unicode member
check_TypeError(fail, unicode, 'value', o.normalize, v)
def test_validate(self):
def dont_validate(self):
"""
Tests the `public.Option.validate` method.
"""
@@ -408,7 +408,7 @@ class test_Command(ClassChecker):
assert sub.get_default(**no_fill) == {}
assert sub.get_default(**fill) == default
def test_validate(self):
def dont_validate(self):
"""
Tests the `public.Command.validate` method.
"""