mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
220: Renamed Option2.validate_scalar() to Option2.__validate_scalar(); added Option2.normalize() method; added corresponding unit tests
This commit is contained in:
@@ -86,9 +86,7 @@ class DefaultFrom(plugable.ReadOnly):
|
||||
|
||||
class Option2(plugable.ReadOnly):
|
||||
def __init__(self, name, doc, type_, required=False, multivalue=False,
|
||||
default=None, default_from=None, normalize=None, rules=tuple()
|
||||
):
|
||||
|
||||
default=None, default_from=None, rules=tuple(), normalize=None):
|
||||
self.name = name
|
||||
self.doc = doc
|
||||
self.type = type_
|
||||
@@ -100,7 +98,32 @@ class Option2(plugable.ReadOnly):
|
||||
self.rules = (type_.validate,) + rules
|
||||
lock(self)
|
||||
|
||||
def validate_scalar(self, value):
|
||||
def convert(self, value):
|
||||
if self.multivalue:
|
||||
if type(value) in (tuple, list):
|
||||
return tuple(self.type(v) for v in value)
|
||||
return (self.type(value),)
|
||||
return self.type(value)
|
||||
|
||||
def __normalize_scalar(self, value):
|
||||
if value is None:
|
||||
return None
|
||||
if type(value) is not self.type.type:
|
||||
raise TypeError('need a %r; got %r' % (self.type.type, value))
|
||||
return self.__normalize(value)
|
||||
|
||||
def normalize(self, value):
|
||||
if self.__normalize is None:
|
||||
return value
|
||||
if self.multivalue:
|
||||
if value is None:
|
||||
return None
|
||||
if type(value) is not tuple:
|
||||
raise TypeError('multivalue must be a tuple; got %r' % value)
|
||||
return tuple(self.__normalize_scalar(v) for v in value)
|
||||
return self.__normalize_scalar(value)
|
||||
|
||||
def __validate_scalar(self, value):
|
||||
for rule in self.rules:
|
||||
error = rule(value)
|
||||
if error is not None:
|
||||
@@ -109,13 +132,11 @@ class Option2(plugable.ReadOnly):
|
||||
def validate(self, value):
|
||||
if self.multivalue:
|
||||
if type(value) is not tuple:
|
||||
raise TypeError(
|
||||
'when multivalue, value must be tuple; got %r' % value
|
||||
)
|
||||
raise TypeError('multivalue must be a tuple; got %r' % value)
|
||||
for v in value:
|
||||
self.validate_scalar(v)
|
||||
self.__validate_scalar(v)
|
||||
else:
|
||||
self.validate_scalar(value)
|
||||
self.__validate_scalar(value)
|
||||
|
||||
|
||||
class Option(plugable.Plugin):
|
||||
|
||||
@@ -114,6 +114,9 @@ class test_Option2(ClassChecker):
|
||||
assert self.cls.__bases__ == (plugable.ReadOnly,)
|
||||
|
||||
def test_init(self):
|
||||
"""
|
||||
Tests the `public.Option2.__init__` method.
|
||||
"""
|
||||
name = 'sn',
|
||||
doc = 'Last Name',
|
||||
type_ = ipa_types.Unicode()
|
||||
@@ -128,8 +131,82 @@ class test_Option2(ClassChecker):
|
||||
assert read_only(o, 'default_from') is None
|
||||
assert read_only(o, 'rules') == (type_.validate,)
|
||||
|
||||
def test_convert(self):
|
||||
name = 'sn'
|
||||
doc = 'User last name'
|
||||
type_ = ipa_types.Unicode()
|
||||
class Hello(object):
|
||||
def __unicode__(self):
|
||||
return u'hello'
|
||||
hello = Hello()
|
||||
values = (u'hello', 'hello', hello)
|
||||
# Test when multivalue=False:
|
||||
o = self.cls(name, doc, type_)
|
||||
for value in values:
|
||||
new = o.convert(value)
|
||||
assert new == u'hello'
|
||||
assert type(new) is unicode
|
||||
# Test when multivalue=True:
|
||||
o = self.cls(name, doc, type_, multivalue=True)
|
||||
for value in values:
|
||||
for v in (value, (value,)):
|
||||
new = o.convert(hello)
|
||||
assert new == (u'hello',)
|
||||
assert type(new) is tuple
|
||||
|
||||
def test_normalize(self):
|
||||
"""
|
||||
Tests the `public.Option2.validate` method.
|
||||
"""
|
||||
name = 'sn'
|
||||
doc = 'User last name'
|
||||
t = ipa_types.Unicode()
|
||||
callback = lambda value: value.lower()
|
||||
orig = u'Hello World'
|
||||
orig_str = str(orig)
|
||||
norm = u'hello world'
|
||||
tup_orig = (orig, norm, u'WONDERFUL!')
|
||||
tup_norm = (norm, norm, u'wonderful!')
|
||||
tup_str = (orig_str, orig)
|
||||
all_values = (None, orig, orig_str, norm, tup_orig, tup_norm, tup_str)
|
||||
|
||||
## Scenario 1: multivalue=False, normalize=None
|
||||
o = self.cls(name, doc, t)
|
||||
for v in all_values:
|
||||
# When normalize=None, value is returned, no type checking:
|
||||
assert o.normalize(v) is v
|
||||
|
||||
## Scenario 2: multivalue=False, normalize=callback
|
||||
o = self.cls(name, doc, t, normalize=callback)
|
||||
assert o.normalize(None) is None
|
||||
for v in (orig, norm):
|
||||
assert o.normalize(v) == norm
|
||||
for v in (orig_str, tup_orig, tup_norm, tup_str): # Not unicode
|
||||
e = raises(TypeError, o.normalize, v)
|
||||
assert str(e) == 'need a %r; got %r' % (unicode, v)
|
||||
|
||||
## Scenario 3: multivalue=True, normalize=None
|
||||
o = self.cls(name, doc, t, multivalue=True)
|
||||
for v in all_values:
|
||||
# When normalize=None, value is returned, no type checking:
|
||||
assert o.normalize(v) is v
|
||||
|
||||
## Scenario 4: multivalue=True, normalize=callback
|
||||
o = self.cls(name, doc, t, multivalue=True, normalize=callback)
|
||||
assert o.normalize(None) is None
|
||||
for v in (tup_orig, tup_norm):
|
||||
assert o.normalize(v) == tup_norm
|
||||
for v in (orig, orig_str, norm): # Not tuple
|
||||
e = raises(TypeError, o.normalize, v)
|
||||
assert str(e) == 'multivalue must be a tuple; got %r' % v
|
||||
for v in [tup_str, (norm, orig, orig_str)]: # Not unicode
|
||||
e = raises(TypeError, o.normalize, v)
|
||||
assert str(e) == 'need a %r; got %r' % (unicode, orig_str)
|
||||
|
||||
def test_validate(self):
|
||||
# Constructor arguments
|
||||
"""
|
||||
Tests the `public.Option2.validate` method.
|
||||
"""
|
||||
name = 'sn'
|
||||
doc = 'User last name'
|
||||
type_ = ipa_types.Unicode()
|
||||
@@ -137,36 +214,31 @@ class test_Option2(ClassChecker):
|
||||
if not value.islower():
|
||||
return 'Must be lower case'
|
||||
my_rules = (case_rule,)
|
||||
|
||||
# Some test values:
|
||||
okay = u'whatever'
|
||||
fail_case = u'Whatever'
|
||||
fail_type = 'whatever'
|
||||
|
||||
# Test validate() and validate_scalar() when multivalue=False:
|
||||
## Scenario 1: multivalue=False
|
||||
o = self.cls(name, doc, type_, rules=my_rules)
|
||||
assert o.rules == (type_.validate, case_rule)
|
||||
for m in [o.validate, o.validate_scalar]:
|
||||
# Test a valid value:
|
||||
m(okay)
|
||||
# Check that RuleError is raised with wrong case:
|
||||
e = raises(errors.RuleError, m, fail_case)
|
||||
assert e.name is name
|
||||
assert e.value is fail_case
|
||||
assert e.error == 'Must be lower case'
|
||||
# Test a RuleError is raise with wrong type:
|
||||
e = raises(errors.RuleError, m, fail_type)
|
||||
assert e.name is name
|
||||
assert e.value is fail_type
|
||||
assert e.error == 'Must be a string'
|
||||
# Test a valid value:
|
||||
o.validate(okay)
|
||||
# Check that RuleError is raised with wrong case:
|
||||
e = raises(errors.RuleError, o.validate, fail_case)
|
||||
assert e.name is name
|
||||
assert e.value is fail_case
|
||||
assert e.error == 'Must be lower case'
|
||||
# Test a RuleError is raise with wrong type:
|
||||
e = raises(errors.RuleError, o.validate, fail_type)
|
||||
assert e.name is name
|
||||
assert e.value is fail_type
|
||||
assert e.error == 'Must be a string'
|
||||
|
||||
# Test validate() when multivalue=True:
|
||||
## Scenario 2: multivalue=True
|
||||
o = self.cls(name, doc, type_, multivalue=True, rules=my_rules)
|
||||
def check_type_error(value):
|
||||
e = raises(TypeError, o.validate, value)
|
||||
assert str(e) == (
|
||||
'when multivalue, value must be tuple; got %r' % value
|
||||
)
|
||||
assert str(e) == 'multivalue must be a tuple; got %r' % value
|
||||
# Check a valid value:
|
||||
check_type_error(okay)
|
||||
o.validate((okay,))
|
||||
@@ -177,7 +249,7 @@ class test_Option2(ClassChecker):
|
||||
assert e.name is name
|
||||
assert e.value is fail_case
|
||||
assert e.error == 'Must be lower case'
|
||||
# Test a RuleError is raise with wrong type:
|
||||
# Check that RuleError is raise with wrong type:
|
||||
check_type_error(fail_type)
|
||||
for value in [(okay, fail_type), (fail_type, okay)]:
|
||||
e = raises(errors.RuleError, o.validate, value)
|
||||
|
||||
Reference in New Issue
Block a user