82: Cleaned up unit tests for public.option; added some doodles in plugable.Base

This commit is contained in:
Jason Gerard DeRose 2008-08-08 19:53:45 +00:00
parent 8e46824815
commit d171dc9011
3 changed files with 77 additions and 24 deletions

View File

@ -54,6 +54,23 @@ def check_identifier(name):
raise errors.NameSpaceError(name, regex)
class Abstract(object):
__public__ = frozenset()
@classmethod
def implements(cls, arg):
assert type(cls.__public__) is frozenset
if isinstance(arg, str):
return arg in cls.__public__
if type(getattr(arg, '__public__', None)) is frozenset:
return cls.__public__.issuperset(arg.__public__)
if type(arg) is frozenset:
return cls.__public__.issuperset(arg)
raise TypeError(
"must be str, frozenset, or have frozenset '__public__' attribute"
)
class Plugin(object):
"""
Base class for all plugins.

View File

@ -102,7 +102,7 @@ class option(object):
def __rules_iter(self):
"""
Iterates through the attributes in this instance to retrieve the
methods implemented validation rules.
methods implementing validation rules.
"""
for name in dir(self.__class__):
if name.startswith('_'):
@ -117,6 +117,10 @@ class option(object):
"""
Returns a default or auto-completed value for this option. If no
default is available, this method should return None.
All the keywords are passed so it's possible to build an
auto-completed value from other options values, e.g., build 'initials'
from 'givenname' + 'sn'.
"""
return None
@ -177,11 +181,15 @@ class cmd(plugable.Plugin):
self.options.validate(value)
def default(self, **kw):
d = {}
for opt in self.options:
if opt.name not in kw:
value = opt.default(**kw)
if value is not None:
kw[opt.name] = value
d[opt.name] = value
assert not set(kw).intersection(d)
kw.update(d)
return kw
def __call__(self, **kw):
(args, kw) = self.normalize(*args, **kw)

View File

@ -63,13 +63,35 @@ def test_is_rule():
assert not is_rule(call(None))
class test_option():
def cls(self):
return public.option
class ClassChecker(object):
__cls = None
__subcls = None
def sub(self):
def __get_cls(self):
if self.__cls is None:
self.__cls = self._cls
return self.__cls
cls = property(__get_cls)
def __get_subcls(self):
if self.__subcls is None:
self.__subcls = self.get_subcls()
return self.__subcls
subcls = property(__get_subcls)
def get_subcls(self):
raise NotImplementedError(
self.__class__.__name__,
'get_subcls()'
)
class test_option(ClassChecker):
_cls = public.option
def get_subcls(self):
rule = public.rule
class int_opt(self.cls()):
class int_opt(self.cls):
type = int
@rule
def rule_0(self, value):
@ -89,13 +111,12 @@ class test_option():
"""
Perform some tests on the class (not an instance).
"""
cls = self.cls()
#assert issubclass(cls, plugable.ReadOnly)
assert type(cls.rules) is property
assert type(self.cls.rules) is property
def test_normalize(self):
sub = self.sub()
i = sub()
assert 'normalize' in self.cls.__public__
o = self.subcls()
# Test with values that can't be converted:
nope = (
'7.0'
@ -104,7 +125,7 @@ class test_option():
None,
)
for val in nope:
e = raises(errors.NormalizationError, i.normalize, val)
e = raises(errors.NormalizationError, o.normalize, val)
assert isinstance(e, errors.ValidationError)
assert e.name == 'int_opt'
assert e.value == val
@ -120,29 +141,36 @@ class test_option():
' 7 ',
)
for val in okay:
assert i.normalize(val) == 7
assert o.normalize(val) == 7
def test_validate(self):
"""
Test the validate method.
"""
assert 'validate' in self.cls.__public__
o = self.subcls()
o.validate(9)
for i in xrange(3):
e = raises(errors.RuleError, o.validate, i)
assert e.error == 'cannot be %d' % i
assert e.value == i
def test_rules(self):
"""
Test the rules property.
"""
o = self.sub()()
o = self.subcls()
assert len(o.rules) == 3
def get_rule(i):
return getattr(o, 'rule_%d' % i)
rules = tuple(get_rule(i) for i in xrange(3))
assert o.rules == rules
def test_validation(self):
"""
Test the validation method.
"""
o = self.sub()()
o.validate(9)
for i in xrange(3):
e = raises(errors.RuleError, o.validate, i)
assert e.error == 'cannot be %d' % i
assert e.value == i
def test_default(self):
assert 'default' in self.cls.__public__
assert self.cls().default() is None