diff options
author | Jason Gerard DeRose <jderose@redhat.com> | 2008-09-03 19:38:39 +0000 |
---|---|---|
committer | Jason Gerard DeRose <jderose@redhat.com> | 2008-09-03 19:38:39 +0000 |
commit | 5e8f945a1ea2f34f40a5e033801d66162fc63850 (patch) | |
tree | 020febcf5d604fb2e986bafc5449366c9318fff9 | |
parent | 9b9615df79d27a74b3cefd1dab708c98a5832b71 (diff) | |
download | freeipa-5e8f945a1ea2f34f40a5e033801d66162fc63850.tar.gz freeipa-5e8f945a1ea2f34f40a5e033801d66162fc63850.tar.xz freeipa-5e8f945a1ea2f34f40a5e033801d66162fc63850.zip |
242: Started cleanup of custom exceptions; added unit tests for errors.IPAError
-rw-r--r-- | ipalib/errors.py | 37 | ||||
-rw-r--r-- | ipalib/public.py | 6 | ||||
-rw-r--r-- | ipalib/tests/test_errors.py | 31 | ||||
-rw-r--r-- | ipalib/tests/test_public.py | 4 |
4 files changed, 58 insertions, 20 deletions
diff --git a/ipalib/errors.py b/ipalib/errors.py index 7629d8f57..eb08a7be2 100644 --- a/ipalib/errors.py +++ b/ipalib/errors.py @@ -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): diff --git a/ipalib/public.py b/ipalib/public.py index 24d416c91..34acbe6f7 100644 --- a/ipalib/public.py +++ b/ipalib/public.py @@ -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: diff --git a/ipalib/tests/test_errors.py b/ipalib/tests/test_errors.py index 34b195e85..b0b5483c8 100644 --- a/ipalib/tests/test_errors.py +++ b/ipalib/tests/test_errors.py @@ -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 diff --git a/ipalib/tests/test_public.py b/ipalib/tests/test_public.py index c184ac154..bbdd37f35 100644 --- a/ipalib/tests/test_public.py +++ b/ipalib/tests/test_public.py @@ -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. """ |