mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2024-12-25 08:21:05 -06:00
1367 lines
46 KiB
Python
1367 lines
46 KiB
Python
# Authors:
|
|
# Jason Gerard DeRose <jderose@redhat.com>
|
|
#
|
|
# Copyright (C) 2008 Red Hat
|
|
# see file 'COPYING' for use and warranty information
|
|
#
|
|
# This program is free software; you can redistribute it and/or
|
|
# modify it under the terms of the GNU General Public License as
|
|
# published by the Free Software Foundation; version 2 only
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program; if not, write to the Free Software
|
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
"""
|
|
Test the `ipalib.parameters` module.
|
|
"""
|
|
|
|
import re
|
|
from types import NoneType
|
|
from inspect import isclass
|
|
from tests.util import raises, ClassChecker, read_only
|
|
from tests.util import dummy_ugettext, assert_equal
|
|
from tests.data import binary_bytes, utf8_bytes, unicode_str
|
|
from ipalib import parameters, request, errors, config
|
|
from ipalib.constants import TYPE_ERROR, CALLABLE_ERROR, NULLS
|
|
|
|
|
|
class test_DefaultFrom(ClassChecker):
|
|
"""
|
|
Test the `ipalib.parameters.DefaultFrom` class.
|
|
"""
|
|
_cls = parameters.DefaultFrom
|
|
|
|
def test_init(self):
|
|
"""
|
|
Test the `ipalib.parameters.DefaultFrom.__init__` method.
|
|
"""
|
|
def callback(*args):
|
|
return args
|
|
keys = ('givenname', 'sn')
|
|
o = self.cls(callback, *keys)
|
|
assert read_only(o, 'callback') is callback
|
|
assert read_only(o, 'keys') == keys
|
|
lam = lambda first, last: first[0] + last
|
|
o = self.cls(lam)
|
|
assert read_only(o, 'keys') == ('first', 'last')
|
|
|
|
# Test that TypeError is raised when callback isn't callable:
|
|
e = raises(TypeError, self.cls, 'whatever')
|
|
assert str(e) == CALLABLE_ERROR % ('callback', 'whatever', str)
|
|
|
|
# Test that TypeError is raised when a key isn't an str:
|
|
e = raises(TypeError, self.cls, callback, 'givenname', 17)
|
|
assert str(e) == TYPE_ERROR % ('keys', str, 17, int)
|
|
|
|
def test_call(self):
|
|
"""
|
|
Test the `ipalib.parameters.DefaultFrom.__call__` method.
|
|
"""
|
|
def callback(givenname, sn):
|
|
return givenname[0] + sn[0]
|
|
keys = ('givenname', 'sn')
|
|
o = self.cls(callback, *keys)
|
|
kw = dict(
|
|
givenname='John',
|
|
sn='Public',
|
|
hello='world',
|
|
)
|
|
assert o(**kw) == 'JP'
|
|
assert o() is None
|
|
for key in ('givenname', 'sn'):
|
|
kw_copy = dict(kw)
|
|
del kw_copy[key]
|
|
assert o(**kw_copy) is None
|
|
|
|
# Test using implied keys:
|
|
o = self.cls(lambda first, last: first[0] + last)
|
|
assert o(first='john', last='doe') == 'jdoe'
|
|
assert o(first='', last='doe') is None
|
|
assert o(one='john', two='doe') is None
|
|
|
|
# Test that co_varnames slice is used:
|
|
def callback2(first, last):
|
|
letter = first[0]
|
|
return letter + last
|
|
o = self.cls(callback2)
|
|
assert o.keys == ('first', 'last')
|
|
assert o(first='john', last='doe') == 'jdoe'
|
|
|
|
|
|
def test_parse_param_spec():
|
|
"""
|
|
Test the `ipalib.parameters.parse_param_spec` function.
|
|
"""
|
|
f = parameters.parse_param_spec
|
|
assert f('name') == ('name', dict(required=True, multivalue=False))
|
|
assert f('name?') == ('name', dict(required=False, multivalue=False))
|
|
assert f('name*') == ('name', dict(required=False, multivalue=True))
|
|
assert f('name+') == ('name', dict(required=True, multivalue=True))
|
|
|
|
# Make sure other "funny" endings are *not* treated special:
|
|
assert f('name^') == ('name^', dict(required=True, multivalue=False))
|
|
|
|
# Test that TypeError is raised if spec isn't an str:
|
|
e = raises(TypeError, f, u'name?')
|
|
assert str(e) == TYPE_ERROR % ('spec', str, u'name?', unicode)
|
|
|
|
# Test that ValueError is raised if len(spec) < 2:
|
|
e = raises(ValueError, f, 'n')
|
|
assert str(e) == "spec must be at least 2 characters; got 'n'"
|
|
|
|
|
|
class DummyRule(object):
|
|
def __init__(self, error=None):
|
|
assert error is None or type(error) is unicode
|
|
self.error = error
|
|
self.reset()
|
|
|
|
def __call__(self, *args):
|
|
self.calls.append(args)
|
|
return self.error
|
|
|
|
def reset(self):
|
|
self.calls = []
|
|
|
|
|
|
class test_Param(ClassChecker):
|
|
"""
|
|
Test the `ipalib.parameters.Param` class.
|
|
"""
|
|
_cls = parameters.Param
|
|
|
|
def test_init(self):
|
|
"""
|
|
Test the `ipalib.parameters.Param.__init__` method.
|
|
"""
|
|
name = 'my_param'
|
|
o = self.cls(name)
|
|
assert o.param_spec is name
|
|
assert o.name is name
|
|
assert o.nice == "Param('my_param')"
|
|
assert o.password is False
|
|
assert o.__islocked__() is True
|
|
|
|
# Test default rules:
|
|
assert o.rules == tuple()
|
|
assert o.class_rules == tuple()
|
|
assert o.all_rules == tuple()
|
|
|
|
# Test default kwarg values:
|
|
assert o.cli_name is name
|
|
assert o.label is None
|
|
assert o.doc == ''
|
|
assert o.required is True
|
|
assert o.multivalue is False
|
|
assert o.primary_key is False
|
|
assert o.normalizer is None
|
|
assert o.default is None
|
|
assert o.default_from is None
|
|
assert o.create_default is None
|
|
assert o._get_default is None
|
|
assert o.autofill is False
|
|
assert o.query is False
|
|
assert o.attribute is False
|
|
assert o.include is None
|
|
assert o.exclude is None
|
|
assert o.flags == frozenset()
|
|
|
|
# Test that ValueError is raised when a kwarg from a subclass
|
|
# conflicts with an attribute:
|
|
class Subclass(self.cls):
|
|
kwargs = self.cls.kwargs + (
|
|
('convert', callable, None),
|
|
)
|
|
e = raises(ValueError, Subclass, name)
|
|
assert str(e) == "kwarg 'convert' conflicts with attribute on Subclass"
|
|
|
|
# Test type validation of keyword arguments:
|
|
class Subclass(self.cls):
|
|
kwargs = self.cls.kwargs + (
|
|
('extra1', bool, True),
|
|
('extra2', str, 'Hello'),
|
|
('extra3', (int, float), 42),
|
|
('extra4', callable, lambda whatever: whatever + 7),
|
|
)
|
|
o = Subclass('my_param') # Test with no **kw:
|
|
for (key, kind, default) in o.kwargs:
|
|
# Test with a type invalid for all:
|
|
value = object()
|
|
kw = {key: value}
|
|
e = raises(TypeError, Subclass, 'my_param', **kw)
|
|
if kind is callable:
|
|
assert str(e) == CALLABLE_ERROR % (key, value, type(value))
|
|
else:
|
|
assert str(e) == TYPE_ERROR % (key, kind, value, type(value))
|
|
# Test with None:
|
|
kw = {key: None}
|
|
Subclass('my_param', **kw)
|
|
|
|
# Test when using unknown kwargs:
|
|
e = raises(TypeError, self.cls, 'my_param',
|
|
flags=['hello', 'world'],
|
|
whatever=u'Hooray!',
|
|
)
|
|
assert str(e) == \
|
|
"Param('my_param'): takes no such kwargs: 'whatever'"
|
|
e = raises(TypeError, self.cls, 'my_param', great='Yes', ape='he is!')
|
|
assert str(e) == \
|
|
"Param('my_param'): takes no such kwargs: 'ape', 'great'"
|
|
|
|
# Test that ValueError is raised if you provide both default_from and
|
|
# create_default:
|
|
e = raises(ValueError, self.cls, 'my_param',
|
|
default_from=lambda first, last: first[0] + last,
|
|
create_default=lambda **kw: 'The Default'
|
|
)
|
|
assert str(e) == '%s: cannot have both %r and %r' % (
|
|
"Param('my_param')", 'default_from', 'create_default',
|
|
)
|
|
|
|
# Test that ValueError is raised if you provide both include and
|
|
# exclude:
|
|
e = raises(ValueError, self.cls, 'my_param',
|
|
include=['server', 'foo'],
|
|
exclude=['client', 'bar'],
|
|
)
|
|
assert str(e) == '%s: cannot have both %s=%r and %s=%r' % (
|
|
"Param('my_param')",
|
|
'include', frozenset(['server', 'foo']),
|
|
'exclude', frozenset(['client', 'bar']),
|
|
)
|
|
|
|
# Test that _get_default gets set:
|
|
call1 = lambda first, last: first[0] + last
|
|
call2 = lambda **kw: 'The Default'
|
|
o = self.cls('my_param', default_from=call1)
|
|
assert o.default_from.callback is call1
|
|
assert o._get_default is o.default_from
|
|
o = self.cls('my_param', create_default=call2)
|
|
assert o.create_default is call2
|
|
assert o._get_default is call2
|
|
|
|
def test_repr(self):
|
|
"""
|
|
Test the `ipalib.parameters.Param.__repr__` method.
|
|
"""
|
|
for name in ['name', 'name?', 'name*', 'name+']:
|
|
o = self.cls(name)
|
|
assert repr(o) == 'Param(%r)' % name
|
|
o = self.cls('name', required=False)
|
|
assert repr(o) == "Param('name', required=False)"
|
|
o = self.cls('name', multivalue=True)
|
|
assert repr(o) == "Param('name', multivalue=True)"
|
|
|
|
def test_use_in_context(self):
|
|
"""
|
|
Test the `ipalib.parameters.Param.use_in_context` method.
|
|
"""
|
|
set1 = ('one', 'two', 'three')
|
|
set2 = ('four', 'five', 'six')
|
|
param1 = self.cls('param1')
|
|
param2 = self.cls('param2', include=set1)
|
|
param3 = self.cls('param3', exclude=set2)
|
|
for context in set1:
|
|
env = config.Env()
|
|
env.context = context
|
|
assert param1.use_in_context(env) is True, context
|
|
assert param2.use_in_context(env) is True, context
|
|
assert param3.use_in_context(env) is True, context
|
|
for context in set2:
|
|
env = config.Env()
|
|
env.context = context
|
|
assert param1.use_in_context(env) is True, context
|
|
assert param2.use_in_context(env) is False, context
|
|
assert param3.use_in_context(env) is False, context
|
|
|
|
def test_safe_value(self):
|
|
"""
|
|
Test the `ipalib.parameters.Param.safe_value` method.
|
|
"""
|
|
values = (unicode_str, binary_bytes, utf8_bytes)
|
|
o = self.cls('my_param')
|
|
for value in values:
|
|
assert o.safe_value(value) is value
|
|
assert o.safe_value(None) is None
|
|
p = parameters.Password('my_passwd')
|
|
for value in values:
|
|
assert_equal(p.safe_value(value), u'********')
|
|
assert p.safe_value(None) is None
|
|
|
|
def test_clone(self):
|
|
"""
|
|
Test the `ipalib.parameters.Param.clone` method.
|
|
"""
|
|
# Test with the defaults
|
|
orig = self.cls('my_param')
|
|
clone = orig.clone()
|
|
assert clone is not orig
|
|
assert type(clone) is self.cls
|
|
assert clone.name is orig.name
|
|
for (key, kind, default) in self.cls.kwargs:
|
|
assert getattr(clone, key) is getattr(orig, key)
|
|
|
|
# Test with a param spec:
|
|
orig = self.cls('my_param*')
|
|
assert orig.param_spec == 'my_param*'
|
|
clone = orig.clone()
|
|
assert clone.param_spec == 'my_param'
|
|
assert clone is not orig
|
|
assert type(clone) is self.cls
|
|
for (key, kind, default) in self.cls.kwargs:
|
|
assert getattr(clone, key) is getattr(orig, key)
|
|
|
|
# Test with overrides:
|
|
orig = self.cls('my_param*')
|
|
assert orig.required is False
|
|
assert orig.multivalue is True
|
|
clone = orig.clone(required=True)
|
|
assert clone is not orig
|
|
assert type(clone) is self.cls
|
|
assert clone.required is True
|
|
assert clone.multivalue is True
|
|
assert clone.param_spec == 'my_param'
|
|
assert clone.name == 'my_param'
|
|
|
|
def test_get_label(self):
|
|
"""
|
|
Test the `ipalib.parameters.get_label` method.
|
|
"""
|
|
context = request.context
|
|
cli_name = 'the_cli_name'
|
|
message = 'The Label'
|
|
label = lambda _: _(message)
|
|
o = self.cls('name', cli_name=cli_name, label=label)
|
|
assert o.label is label
|
|
|
|
## Scenario 1: label=callable (a lambda form)
|
|
|
|
# Test with no context.ugettext:
|
|
assert not hasattr(context, 'ugettext')
|
|
assert_equal(o.get_label(), u'The Label')
|
|
|
|
# Test with dummy context.ugettext:
|
|
assert not hasattr(context, 'ugettext')
|
|
dummy = dummy_ugettext()
|
|
context.ugettext = dummy
|
|
assert o.get_label() is dummy.translation
|
|
assert dummy.message is message
|
|
del context.ugettext
|
|
|
|
## Scenario 2: label=None
|
|
o = self.cls('name', cli_name=cli_name)
|
|
assert o.label is None
|
|
|
|
# Test with no context.ugettext:
|
|
assert not hasattr(context, 'ugettext')
|
|
assert_equal(o.get_label(), u'the_cli_name')
|
|
|
|
# Test with dummy context.ugettext:
|
|
assert not hasattr(context, 'ugettext')
|
|
dummy = dummy_ugettext()
|
|
context.ugettext = dummy
|
|
assert_equal(o.get_label(), u'the_cli_name')
|
|
assert not hasattr(dummy, 'message')
|
|
|
|
# Cleanup
|
|
del context.ugettext
|
|
assert not hasattr(context, 'ugettext')
|
|
|
|
def test_convert(self):
|
|
"""
|
|
Test the `ipalib.parameters.Param.convert` method.
|
|
"""
|
|
okay = ('Hello', u'Hello', 0, 4.2, True, False, unicode_str)
|
|
class Subclass(self.cls):
|
|
def _convert_scalar(self, value, index=None):
|
|
return value
|
|
|
|
# Test when multivalue=False:
|
|
o = Subclass('my_param')
|
|
for value in NULLS:
|
|
assert o.convert(value) is None
|
|
assert o.convert(None) is None
|
|
for value in okay:
|
|
assert o.convert(value) is value
|
|
|
|
# Test when multivalue=True:
|
|
o = Subclass('my_param', multivalue=True)
|
|
for value in NULLS:
|
|
assert o.convert(value) is None
|
|
assert o.convert(okay) == okay
|
|
assert o.convert(NULLS) is None
|
|
assert o.convert(okay + NULLS) == okay
|
|
assert o.convert(NULLS + okay) == okay
|
|
for value in okay:
|
|
assert o.convert(value) == (value,)
|
|
assert o.convert([None, value]) == (value,)
|
|
assert o.convert([value, None]) == (value,)
|
|
|
|
def test_convert_scalar(self):
|
|
"""
|
|
Test the `ipalib.parameters.Param._convert_scalar` method.
|
|
"""
|
|
dummy = dummy_ugettext()
|
|
|
|
# Test with correct type:
|
|
o = self.cls('my_param')
|
|
assert o._convert_scalar(None) is None
|
|
assert dummy.called() is False
|
|
# Test with incorrect type
|
|
e = raises(errors.ConversionError, o._convert_scalar, 'hello', index=17)
|
|
|
|
def test_validate(self):
|
|
"""
|
|
Test the `ipalib.parameters.Param.validate` method.
|
|
"""
|
|
|
|
# Test in default state (with no rules, no kwarg):
|
|
o = self.cls('my_param')
|
|
e = raises(errors.RequirementError, o.validate, None)
|
|
assert e.name == 'my_param'
|
|
|
|
# Test with required=False
|
|
o = self.cls('my_param', required=False)
|
|
assert o.required is False
|
|
assert o.validate(None) is None
|
|
|
|
# Test with query=True:
|
|
o = self.cls('my_param', query=True)
|
|
assert o.query is True
|
|
e = raises(errors.RequirementError, o.validate, None)
|
|
assert_equal(e.name, 'my_param')
|
|
|
|
# Test with multivalue=True:
|
|
o = self.cls('my_param', multivalue=True)
|
|
e = raises(TypeError, o.validate, [])
|
|
assert str(e) == TYPE_ERROR % ('value', tuple, [], list)
|
|
e = raises(ValueError, o.validate, tuple())
|
|
assert str(e) == 'value: empty tuple must be converted to None'
|
|
|
|
# Test with wrong (scalar) type:
|
|
e = raises(TypeError, o.validate, (None, None, 42, None))
|
|
assert str(e) == TYPE_ERROR % ('value[2]', NoneType, 42, int)
|
|
o = self.cls('my_param')
|
|
e = raises(TypeError, o.validate, 'Hello')
|
|
assert str(e) == TYPE_ERROR % ('value', NoneType, 'Hello', str)
|
|
|
|
class Example(self.cls):
|
|
type = int
|
|
|
|
# Test with some rules and multivalue=False
|
|
pass1 = DummyRule()
|
|
pass2 = DummyRule()
|
|
fail = DummyRule(u'no good')
|
|
o = Example('example', pass1, pass2)
|
|
assert o.multivalue is False
|
|
assert o.validate(11) is None
|
|
assert pass1.calls == [(request.ugettext, 11)]
|
|
assert pass2.calls == [(request.ugettext, 11)]
|
|
pass1.reset()
|
|
pass2.reset()
|
|
o = Example('example', pass1, pass2, fail)
|
|
e = raises(errors.ValidationError, o.validate, 42)
|
|
assert e.name == 'example'
|
|
assert e.error == u'no good'
|
|
assert e.index is None
|
|
assert pass1.calls == [(request.ugettext, 42)]
|
|
assert pass2.calls == [(request.ugettext, 42)]
|
|
assert fail.calls == [(request.ugettext, 42)]
|
|
|
|
# Test with some rules and multivalue=True
|
|
pass1 = DummyRule()
|
|
pass2 = DummyRule()
|
|
fail = DummyRule(u'this one is not good')
|
|
o = Example('example', pass1, pass2, multivalue=True)
|
|
assert o.multivalue is True
|
|
assert o.validate((3, 9)) is None
|
|
assert pass1.calls == [
|
|
(request.ugettext, 3),
|
|
(request.ugettext, 9),
|
|
]
|
|
assert pass2.calls == [
|
|
(request.ugettext, 3),
|
|
(request.ugettext, 9),
|
|
]
|
|
pass1.reset()
|
|
pass2.reset()
|
|
o = Example('multi_example', pass1, pass2, fail, multivalue=True)
|
|
assert o.multivalue is True
|
|
e = raises(errors.ValidationError, o.validate, (3, 9))
|
|
assert e.name == 'multi_example'
|
|
assert e.error == u'this one is not good'
|
|
assert e.index == 0
|
|
assert pass1.calls == [(request.ugettext, 3)]
|
|
assert pass2.calls == [(request.ugettext, 3)]
|
|
assert fail.calls == [(request.ugettext, 3)]
|
|
|
|
def test_validate_scalar(self):
|
|
"""
|
|
Test the `ipalib.parameters.Param._validate_scalar` method.
|
|
"""
|
|
class MyParam(self.cls):
|
|
type = bool
|
|
okay = DummyRule()
|
|
o = MyParam('my_param', okay)
|
|
|
|
# Test that TypeError is appropriately raised:
|
|
e = raises(TypeError, o._validate_scalar, 0)
|
|
assert str(e) == TYPE_ERROR % ('value', bool, 0, int)
|
|
e = raises(TypeError, o._validate_scalar, 'Hi', index=4)
|
|
assert str(e) == TYPE_ERROR % ('value[4]', bool, 'Hi', str)
|
|
e = raises(TypeError, o._validate_scalar, True, index=3.0)
|
|
assert str(e) == TYPE_ERROR % ('index', int, 3.0, float)
|
|
|
|
# Test with passing rule:
|
|
assert o._validate_scalar(True, index=None) is None
|
|
assert o._validate_scalar(False, index=None) is None
|
|
assert okay.calls == [
|
|
(request.ugettext, True),
|
|
(request.ugettext, False),
|
|
]
|
|
|
|
# Test with a failing rule:
|
|
okay = DummyRule()
|
|
fail = DummyRule(u'this describes the error')
|
|
o = MyParam('my_param', okay, fail)
|
|
e = raises(errors.ValidationError, o._validate_scalar, True)
|
|
assert e.name == 'my_param'
|
|
assert e.error == u'this describes the error'
|
|
assert e.index is None
|
|
e = raises(errors.ValidationError, o._validate_scalar, False, index=2)
|
|
assert e.name == 'my_param'
|
|
assert e.error == u'this describes the error'
|
|
assert e.index == 2
|
|
assert okay.calls == [
|
|
(request.ugettext, True),
|
|
(request.ugettext, False),
|
|
]
|
|
assert fail.calls == [
|
|
(request.ugettext, True),
|
|
(request.ugettext, False),
|
|
]
|
|
|
|
def test_get_default(self):
|
|
"""
|
|
Test the `ipalib.parameters.Param._get_default` method.
|
|
"""
|
|
class PassThrough(object):
|
|
value = None
|
|
|
|
def __call__(self, value):
|
|
assert self.value is None
|
|
assert value is not None
|
|
self.value = value
|
|
return value
|
|
|
|
def reset(self):
|
|
assert self.value is not None
|
|
self.value = None
|
|
|
|
class Str(self.cls):
|
|
type = unicode
|
|
|
|
def __init__(self, name, **kw):
|
|
self._convert_scalar = PassThrough()
|
|
super(Str, self).__init__(name, **kw)
|
|
|
|
# Test with only a static default:
|
|
o = Str('my_str',
|
|
normalizer=PassThrough(),
|
|
default=u'Static Default',
|
|
)
|
|
assert_equal(o.get_default(), u'Static Default')
|
|
assert o._convert_scalar.value is None
|
|
assert o.normalizer.value is None
|
|
|
|
# Test with default_from:
|
|
o = Str('my_str',
|
|
normalizer=PassThrough(),
|
|
default=u'Static Default',
|
|
default_from=lambda first, last: first[0] + last,
|
|
)
|
|
assert_equal(o.get_default(), u'Static Default')
|
|
assert o._convert_scalar.value is None
|
|
assert o.normalizer.value is None
|
|
default = o.get_default(first=u'john', last='doe')
|
|
assert_equal(default, u'jdoe')
|
|
assert o._convert_scalar.value is default
|
|
assert o.normalizer.value is default
|
|
|
|
# Test with create_default:
|
|
o = Str('my_str',
|
|
normalizer=PassThrough(),
|
|
default=u'Static Default',
|
|
create_default=lambda **kw: u'The created default',
|
|
)
|
|
default = o.get_default(first=u'john', last='doe')
|
|
assert_equal(default, u'The created default')
|
|
assert o._convert_scalar.value is default
|
|
assert o.normalizer.value is default
|
|
|
|
|
|
class test_Flag(ClassChecker):
|
|
"""
|
|
Test the `ipalib.parameters.Flag` class.
|
|
"""
|
|
_cls = parameters.Flag
|
|
|
|
def test_init(self):
|
|
"""
|
|
Test the `ipalib.parameters.Flag.__init__` method.
|
|
"""
|
|
# Test with no kwargs:
|
|
o = self.cls('my_flag')
|
|
assert o.type is bool
|
|
assert isinstance(o, parameters.Bool)
|
|
assert o.autofill is True
|
|
assert o.default is False
|
|
|
|
# Test that TypeError is raise if default is not a bool:
|
|
e = raises(TypeError, self.cls, 'my_flag', default=None)
|
|
assert str(e) == TYPE_ERROR % ('default', bool, None, NoneType)
|
|
|
|
# Test with autofill=False, default=True
|
|
o = self.cls('my_flag', autofill=False, default=True)
|
|
assert o.autofill is True
|
|
assert o.default is True
|
|
|
|
# Test when cloning:
|
|
orig = self.cls('my_flag')
|
|
for clone in [orig.clone(), orig.clone(autofill=False)]:
|
|
assert clone.autofill is True
|
|
assert clone.default is False
|
|
assert clone is not orig
|
|
assert type(clone) is self.cls
|
|
|
|
# Test when cloning with default=True/False
|
|
orig = self.cls('my_flag')
|
|
assert orig.clone().default is False
|
|
assert orig.clone(default=True).default is True
|
|
orig = self.cls('my_flag', default=True)
|
|
assert orig.clone().default is True
|
|
assert orig.clone(default=False).default is False
|
|
|
|
|
|
class test_Data(ClassChecker):
|
|
"""
|
|
Test the `ipalib.parameters.Data` class.
|
|
"""
|
|
_cls = parameters.Data
|
|
|
|
def test_init(self):
|
|
"""
|
|
Test the `ipalib.parameters.Data.__init__` method.
|
|
"""
|
|
o = self.cls('my_data')
|
|
assert o.type is NoneType
|
|
assert o.password is False
|
|
assert o.rules == tuple()
|
|
assert o.class_rules == tuple()
|
|
assert o.all_rules == tuple()
|
|
assert o.minlength is None
|
|
assert o.maxlength is None
|
|
assert o.length is None
|
|
assert o.pattern is None
|
|
|
|
# Test mixing length with minlength or maxlength:
|
|
o = self.cls('my_data', length=5)
|
|
assert o.length == 5
|
|
permutations = [
|
|
dict(minlength=3),
|
|
dict(maxlength=7),
|
|
dict(minlength=3, maxlength=7),
|
|
]
|
|
for kw in permutations:
|
|
o = self.cls('my_data', **kw)
|
|
for (key, value) in kw.iteritems():
|
|
assert getattr(o, key) == value
|
|
e = raises(ValueError, self.cls, 'my_data', length=5, **kw)
|
|
assert str(e) == \
|
|
"Data('my_data'): cannot mix length with minlength or maxlength"
|
|
|
|
# Test when minlength or maxlength are less than 1:
|
|
e = raises(ValueError, self.cls, 'my_data', minlength=0)
|
|
assert str(e) == "Data('my_data'): minlength must be >= 1; got 0"
|
|
e = raises(ValueError, self.cls, 'my_data', maxlength=0)
|
|
assert str(e) == "Data('my_data'): maxlength must be >= 1; got 0"
|
|
|
|
# Test when minlength > maxlength:
|
|
e = raises(ValueError, self.cls, 'my_data', minlength=22, maxlength=15)
|
|
assert str(e) == \
|
|
"Data('my_data'): minlength > maxlength (minlength=22, maxlength=15)"
|
|
|
|
# Test when minlength == maxlength
|
|
e = raises(ValueError, self.cls, 'my_data', minlength=7, maxlength=7)
|
|
assert str(e) == \
|
|
"Data('my_data'): minlength == maxlength; use length=7 instead"
|
|
|
|
|
|
class test_Bytes(ClassChecker):
|
|
"""
|
|
Test the `ipalib.parameters.Bytes` class.
|
|
"""
|
|
_cls = parameters.Bytes
|
|
|
|
def test_init(self):
|
|
"""
|
|
Test the `ipalib.parameters.Bytes.__init__` method.
|
|
"""
|
|
o = self.cls('my_bytes')
|
|
assert o.type is str
|
|
assert o.password is False
|
|
assert o.rules == tuple()
|
|
assert o.class_rules == tuple()
|
|
assert o.all_rules == tuple()
|
|
assert o.minlength is None
|
|
assert o.maxlength is None
|
|
assert o.length is None
|
|
assert o.pattern is None
|
|
assert o.re is None
|
|
|
|
# Test mixing length with minlength or maxlength:
|
|
o = self.cls('my_bytes', length=5)
|
|
assert o.length == 5
|
|
assert len(o.class_rules) == 1
|
|
assert len(o.rules) == 0
|
|
assert len(o.all_rules) == 1
|
|
permutations = [
|
|
dict(minlength=3),
|
|
dict(maxlength=7),
|
|
dict(minlength=3, maxlength=7),
|
|
]
|
|
for kw in permutations:
|
|
o = self.cls('my_bytes', **kw)
|
|
assert len(o.class_rules) == len(kw)
|
|
assert len(o.rules) == 0
|
|
assert len(o.all_rules) == len(kw)
|
|
for (key, value) in kw.iteritems():
|
|
assert getattr(o, key) == value
|
|
e = raises(ValueError, self.cls, 'my_bytes', length=5, **kw)
|
|
assert str(e) == \
|
|
"Bytes('my_bytes'): cannot mix length with minlength or maxlength"
|
|
|
|
# Test when minlength or maxlength are less than 1:
|
|
e = raises(ValueError, self.cls, 'my_bytes', minlength=0)
|
|
assert str(e) == "Bytes('my_bytes'): minlength must be >= 1; got 0"
|
|
e = raises(ValueError, self.cls, 'my_bytes', maxlength=0)
|
|
assert str(e) == "Bytes('my_bytes'): maxlength must be >= 1; got 0"
|
|
|
|
# Test when minlength > maxlength:
|
|
e = raises(ValueError, self.cls, 'my_bytes', minlength=22, maxlength=15)
|
|
assert str(e) == \
|
|
"Bytes('my_bytes'): minlength > maxlength (minlength=22, maxlength=15)"
|
|
|
|
# Test when minlength == maxlength
|
|
e = raises(ValueError, self.cls, 'my_bytes', minlength=7, maxlength=7)
|
|
assert str(e) == \
|
|
"Bytes('my_bytes'): minlength == maxlength; use length=7 instead"
|
|
|
|
def test_rule_minlength(self):
|
|
"""
|
|
Test the `ipalib.parameters.Bytes._rule_minlength` method.
|
|
"""
|
|
o = self.cls('my_bytes', minlength=3)
|
|
assert o.minlength == 3
|
|
rule = o._rule_minlength
|
|
translation = u'minlength=%(minlength)r'
|
|
dummy = dummy_ugettext(translation)
|
|
assert dummy.translation is translation
|
|
|
|
# Test with passing values:
|
|
for value in ('abc', 'four', '12345'):
|
|
assert rule(dummy, value) is None
|
|
assert dummy.called() is False
|
|
|
|
# Test with failing values:
|
|
for value in ('', 'a', '12'):
|
|
assert_equal(
|
|
rule(dummy, value),
|
|
translation % dict(minlength=3)
|
|
)
|
|
assert dummy.message == 'must be at least %(minlength)d bytes'
|
|
assert dummy.called() is True
|
|
dummy.reset()
|
|
|
|
def test_rule_maxlength(self):
|
|
"""
|
|
Test the `ipalib.parameters.Bytes._rule_maxlength` method.
|
|
"""
|
|
o = self.cls('my_bytes', maxlength=4)
|
|
assert o.maxlength == 4
|
|
rule = o._rule_maxlength
|
|
translation = u'maxlength=%(maxlength)r'
|
|
dummy = dummy_ugettext(translation)
|
|
assert dummy.translation is translation
|
|
|
|
# Test with passing values:
|
|
for value in ('ab', '123', 'four'):
|
|
assert rule(dummy, value) is None
|
|
assert dummy.called() is False
|
|
|
|
# Test with failing values:
|
|
for value in ('12345', 'sixsix'):
|
|
assert_equal(
|
|
rule(dummy, value),
|
|
translation % dict(maxlength=4)
|
|
)
|
|
assert dummy.message == 'can be at most %(maxlength)d bytes'
|
|
assert dummy.called() is True
|
|
dummy.reset()
|
|
|
|
def test_rule_length(self):
|
|
"""
|
|
Test the `ipalib.parameters.Bytes._rule_length` method.
|
|
"""
|
|
o = self.cls('my_bytes', length=4)
|
|
assert o.length == 4
|
|
rule = o._rule_length
|
|
translation = u'length=%(length)r'
|
|
dummy = dummy_ugettext(translation)
|
|
assert dummy.translation is translation
|
|
|
|
# Test with passing values:
|
|
for value in ('1234', 'four'):
|
|
assert rule(dummy, value) is None
|
|
assert dummy.called() is False
|
|
|
|
# Test with failing values:
|
|
for value in ('ab', '123', '12345', 'sixsix'):
|
|
assert_equal(
|
|
rule(dummy, value),
|
|
translation % dict(length=4),
|
|
)
|
|
assert dummy.message == 'must be exactly %(length)d bytes'
|
|
assert dummy.called() is True
|
|
dummy.reset()
|
|
|
|
def test_rule_pattern(self):
|
|
"""
|
|
Test the `ipalib.parameters.Bytes._rule_pattern` method.
|
|
"""
|
|
# Test our assumptions about Python re module and Unicode:
|
|
pat = '\w+$'
|
|
r = re.compile(pat)
|
|
assert r.match('Hello_World') is not None
|
|
assert r.match(utf8_bytes) is None
|
|
assert r.match(binary_bytes) is None
|
|
|
|
# Create instance:
|
|
o = self.cls('my_bytes', pattern=pat)
|
|
assert o.pattern is pat
|
|
rule = o._rule_pattern
|
|
translation = u'pattern=%(pattern)r'
|
|
dummy = dummy_ugettext(translation)
|
|
|
|
# Test with passing values:
|
|
for value in ('HELLO', 'hello', 'Hello_World'):
|
|
assert rule(dummy, value) is None
|
|
assert dummy.called() is False
|
|
|
|
# Test with failing values:
|
|
for value in ('Hello!', 'Hello World', utf8_bytes, binary_bytes):
|
|
assert_equal(
|
|
rule(dummy, value),
|
|
translation % dict(pattern=pat),
|
|
)
|
|
assert_equal(dummy.message, 'must match pattern "%(pattern)s"')
|
|
assert dummy.called() is True
|
|
dummy.reset()
|
|
|
|
|
|
class test_Str(ClassChecker):
|
|
"""
|
|
Test the `ipalib.parameters.Str` class.
|
|
"""
|
|
_cls = parameters.Str
|
|
|
|
def test_init(self):
|
|
"""
|
|
Test the `ipalib.parameters.Str.__init__` method.
|
|
"""
|
|
o = self.cls('my_str')
|
|
assert o.type is unicode
|
|
assert o.password is False
|
|
assert o.minlength is None
|
|
assert o.maxlength is None
|
|
assert o.length is None
|
|
assert o.pattern is None
|
|
|
|
def test_convert_scalar(self):
|
|
"""
|
|
Test the `ipalib.parameters.Str._convert_scalar` method.
|
|
"""
|
|
o = self.cls('my_str')
|
|
mthd = o._convert_scalar
|
|
for value in (u'Hello', 42, 1.2, unicode_str):
|
|
assert mthd(value) == unicode(value)
|
|
bad = [True, 'Hello', (u'Hello',), [42.3], dict(one=1), utf8_bytes]
|
|
for value in bad:
|
|
e = raises(errors.ConversionError, mthd, value)
|
|
assert e.name == 'my_str'
|
|
assert e.index is None
|
|
assert_equal(e.error, u'must be Unicode text')
|
|
e = raises(errors.ConversionError, mthd, value, index=18)
|
|
assert e.name == 'my_str'
|
|
assert e.index == 18
|
|
assert_equal(e.error, u'must be Unicode text')
|
|
assert o.convert(None) is None
|
|
|
|
def test_rule_minlength(self):
|
|
"""
|
|
Test the `ipalib.parameters.Str._rule_minlength` method.
|
|
"""
|
|
o = self.cls('my_str', minlength=3)
|
|
assert o.minlength == 3
|
|
rule = o._rule_minlength
|
|
translation = u'minlength=%(minlength)r'
|
|
dummy = dummy_ugettext(translation)
|
|
assert dummy.translation is translation
|
|
|
|
# Test with passing values:
|
|
for value in (u'abc', u'four', u'12345'):
|
|
assert rule(dummy, value) is None
|
|
assert dummy.called() is False
|
|
|
|
# Test with failing values:
|
|
for value in (u'', u'a', u'12'):
|
|
assert_equal(
|
|
rule(dummy, value),
|
|
translation % dict(minlength=3)
|
|
)
|
|
assert dummy.message == 'must be at least %(minlength)d characters'
|
|
assert dummy.called() is True
|
|
dummy.reset()
|
|
|
|
def test_rule_maxlength(self):
|
|
"""
|
|
Test the `ipalib.parameters.Str._rule_maxlength` method.
|
|
"""
|
|
o = self.cls('my_str', maxlength=4)
|
|
assert o.maxlength == 4
|
|
rule = o._rule_maxlength
|
|
translation = u'maxlength=%(maxlength)r'
|
|
dummy = dummy_ugettext(translation)
|
|
assert dummy.translation is translation
|
|
|
|
# Test with passing values:
|
|
for value in (u'ab', u'123', u'four'):
|
|
assert rule(dummy, value) is None
|
|
assert dummy.called() is False
|
|
|
|
# Test with failing values:
|
|
for value in (u'12345', u'sixsix'):
|
|
assert_equal(
|
|
rule(dummy, value),
|
|
translation % dict(maxlength=4)
|
|
)
|
|
assert dummy.message == 'can be at most %(maxlength)d characters'
|
|
assert dummy.called() is True
|
|
dummy.reset()
|
|
|
|
def test_rule_length(self):
|
|
"""
|
|
Test the `ipalib.parameters.Str._rule_length` method.
|
|
"""
|
|
o = self.cls('my_str', length=4)
|
|
assert o.length == 4
|
|
rule = o._rule_length
|
|
translation = u'length=%(length)r'
|
|
dummy = dummy_ugettext(translation)
|
|
assert dummy.translation is translation
|
|
|
|
# Test with passing values:
|
|
for value in (u'1234', u'four'):
|
|
assert rule(dummy, value) is None
|
|
assert dummy.called() is False
|
|
|
|
# Test with failing values:
|
|
for value in (u'ab', u'123', u'12345', u'sixsix'):
|
|
assert_equal(
|
|
rule(dummy, value),
|
|
translation % dict(length=4),
|
|
)
|
|
assert dummy.message == 'must be exactly %(length)d characters'
|
|
assert dummy.called() is True
|
|
dummy.reset()
|
|
|
|
def test_rule_pattern(self):
|
|
"""
|
|
Test the `ipalib.parameters.Str._rule_pattern` method.
|
|
"""
|
|
# Test our assumptions about Python re module and Unicode:
|
|
pat = '\w{5}$'
|
|
r1 = re.compile(pat)
|
|
r2 = re.compile(pat, re.UNICODE)
|
|
assert r1.match(unicode_str) is None
|
|
assert r2.match(unicode_str) is not None
|
|
|
|
# Create instance:
|
|
o = self.cls('my_str', pattern=pat)
|
|
assert o.pattern is pat
|
|
rule = o._rule_pattern
|
|
translation = u'pattern=%(pattern)r'
|
|
dummy = dummy_ugettext(translation)
|
|
|
|
# Test with passing values:
|
|
for value in (u'HELLO', u'hello', unicode_str):
|
|
assert rule(dummy, value) is None
|
|
assert dummy.called() is False
|
|
|
|
# Test with failing values:
|
|
for value in (u'H LLO', u'***lo', unicode_str + unicode_str):
|
|
assert_equal(
|
|
rule(dummy, value),
|
|
translation % dict(pattern=pat),
|
|
)
|
|
assert_equal(dummy.message, 'must match pattern "%(pattern)s"')
|
|
assert dummy.called() is True
|
|
dummy.reset()
|
|
|
|
|
|
class test_Password(ClassChecker):
|
|
"""
|
|
Test the `ipalib.parameters.Password` class.
|
|
"""
|
|
_cls = parameters.Password
|
|
|
|
def test_init(self):
|
|
"""
|
|
Test the `ipalib.parameters.Password.__init__` method.
|
|
"""
|
|
o = self.cls('my_password')
|
|
assert o.type is unicode
|
|
assert o.minlength is None
|
|
assert o.maxlength is None
|
|
assert o.length is None
|
|
assert o.pattern is None
|
|
assert o.password is True
|
|
|
|
|
|
class test_StrEnum(ClassChecker):
|
|
"""
|
|
Test the `ipalib.parameters.StrEnum` class.
|
|
"""
|
|
_cls = parameters.StrEnum
|
|
|
|
def test_init(self):
|
|
"""
|
|
Test the `ipalib.parameters.StrEnum.__init__` method.
|
|
"""
|
|
values = (u'Hello', u'naughty', u'nurse!')
|
|
o = self.cls('my_strenum', values=values)
|
|
assert o.type is unicode
|
|
assert o.values is values
|
|
assert o.class_rules == (o._rule_values,)
|
|
assert o.rules == tuple()
|
|
assert o.all_rules == (o._rule_values,)
|
|
|
|
badvalues = (u'Hello', 'naughty', u'nurse!')
|
|
e = raises(TypeError, self.cls, 'my_enum', values=badvalues)
|
|
assert str(e) == TYPE_ERROR % (
|
|
"StrEnum('my_enum') values[1]", unicode, 'naughty', str
|
|
)
|
|
|
|
def test_rules_values(self):
|
|
"""
|
|
Test the `ipalib.parameters.StrEnum._rule_values` method.
|
|
"""
|
|
values = (u'Hello', u'naughty', u'nurse!')
|
|
o = self.cls('my_enum', values=values)
|
|
rule = o._rule_values
|
|
translation = u'values=%(values)s'
|
|
dummy = dummy_ugettext(translation)
|
|
|
|
# Test with passing values:
|
|
for v in values:
|
|
assert rule(dummy, v) is None
|
|
assert dummy.called() is False
|
|
|
|
# Test with failing values:
|
|
for val in (u'Howdy', u'quiet', u'library!'):
|
|
assert_equal(
|
|
rule(dummy, val),
|
|
translation % dict(values=values),
|
|
)
|
|
assert_equal(dummy.message, 'must be one of %(values)r')
|
|
dummy.reset()
|
|
|
|
|
|
class test_Number(ClassChecker):
|
|
"""
|
|
Test the `ipalib.parameters.Number` class.
|
|
"""
|
|
_cls = parameters.Number
|
|
|
|
def test_init(self):
|
|
"""
|
|
Test the `ipalib.parameters.Number.__init__` method.
|
|
"""
|
|
o = self.cls('my_number')
|
|
assert o.type is NoneType
|
|
assert o.password is False
|
|
assert o.rules == tuple()
|
|
assert o.class_rules == tuple()
|
|
assert o.all_rules == tuple()
|
|
|
|
|
|
|
|
class test_Int(ClassChecker):
|
|
"""
|
|
Test the `ipalib.parameters.Int` class.
|
|
"""
|
|
_cls = parameters.Int
|
|
|
|
def test_init(self):
|
|
"""
|
|
Test the `ipalib.parameters.Int.__init__` method.
|
|
"""
|
|
# Test with no kwargs:
|
|
o = self.cls('my_number')
|
|
assert o.type is int
|
|
assert isinstance(o, parameters.Int)
|
|
assert o.minvalue is None
|
|
assert o.maxvalue is None
|
|
|
|
# Test when min > max:
|
|
e = raises(ValueError, self.cls, 'my_number', minvalue=22, maxvalue=15)
|
|
assert str(e) == \
|
|
"Int('my_number'): minvalue > maxvalue (minvalue=22, maxvalue=15)"
|
|
|
|
def test_rule_minvalue(self):
|
|
"""
|
|
Test the `ipalib.parameters.Int._rule_minvalue` method.
|
|
"""
|
|
o = self.cls('my_number', minvalue=3)
|
|
assert o.minvalue == 3
|
|
rule = o._rule_minvalue
|
|
translation = u'minvalue=%(minvalue)r'
|
|
dummy = dummy_ugettext(translation)
|
|
assert dummy.translation is translation
|
|
|
|
# Test with passing values:
|
|
for value in (4, 99, 1001):
|
|
assert rule(dummy, value) is None
|
|
assert dummy.called() is False
|
|
|
|
# Test with failing values:
|
|
for value in (-1, 0, 2):
|
|
assert_equal(
|
|
rule(dummy, value),
|
|
translation % dict(minvalue=3)
|
|
)
|
|
assert dummy.message == 'must be at least %(minvalue)d'
|
|
assert dummy.called() is True
|
|
dummy.reset()
|
|
|
|
def test_rule_maxvalue(self):
|
|
"""
|
|
Test the `ipalib.parameters.Int._rule_maxvalue` method.
|
|
"""
|
|
o = self.cls('my_number', maxvalue=4)
|
|
assert o.maxvalue == 4
|
|
rule = o._rule_maxvalue
|
|
translation = u'maxvalue=%(maxvalue)r'
|
|
dummy = dummy_ugettext(translation)
|
|
assert dummy.translation is translation
|
|
|
|
# Test with passing values:
|
|
for value in (-1, 0, 4):
|
|
assert rule(dummy, value) is None
|
|
assert dummy.called() is False
|
|
|
|
# Test with failing values:
|
|
for value in (5, 99, 1009):
|
|
assert_equal(
|
|
rule(dummy, value),
|
|
translation % dict(maxvalue=4)
|
|
)
|
|
assert dummy.message == 'can be at most %(maxvalue)d'
|
|
assert dummy.called() is True
|
|
dummy.reset()
|
|
|
|
class test_Float(ClassChecker):
|
|
"""
|
|
Test the `ipalib.parameters.Float` class.
|
|
"""
|
|
_cls = parameters.Float
|
|
|
|
def test_init(self):
|
|
"""
|
|
Test the `ipalib.parameters.Float.__init__` method.
|
|
"""
|
|
# Test with no kwargs:
|
|
o = self.cls('my_number')
|
|
assert o.type is float
|
|
assert isinstance(o, parameters.Float)
|
|
assert o.minvalue is None
|
|
assert o.maxvalue is None
|
|
|
|
# Test when min > max:
|
|
e = raises(ValueError, self.cls, 'my_number', minvalue=22.5, maxvalue=15.1)
|
|
assert str(e) == \
|
|
"Float('my_number'): minvalue > maxvalue (minvalue=22.5, maxvalue=15.1)"
|
|
|
|
def test_rule_minvalue(self):
|
|
"""
|
|
Test the `ipalib.parameters.Float._rule_minvalue` method.
|
|
"""
|
|
o = self.cls('my_number', minvalue=3.1)
|
|
assert o.minvalue == 3.1
|
|
rule = o._rule_minvalue
|
|
translation = u'minvalue=%(minvalue)r'
|
|
dummy = dummy_ugettext(translation)
|
|
assert dummy.translation is translation
|
|
|
|
# Test with passing values:
|
|
for value in (3.2, 99.0):
|
|
assert rule(dummy, value) is None
|
|
assert dummy.called() is False
|
|
|
|
# Test with failing values:
|
|
for value in (-1.2, 0.0, 3.0):
|
|
assert_equal(
|
|
rule(dummy, value),
|
|
translation % dict(minvalue=3.1)
|
|
)
|
|
assert dummy.message == 'must be at least %(minvalue)f'
|
|
assert dummy.called() is True
|
|
dummy.reset()
|
|
|
|
def test_rule_maxvalue(self):
|
|
"""
|
|
Test the `ipalib.parameters.Float._rule_maxvalue` method.
|
|
"""
|
|
o = self.cls('my_number', maxvalue=4.7)
|
|
assert o.maxvalue == 4.7
|
|
rule = o._rule_maxvalue
|
|
translation = u'maxvalue=%(maxvalue)r'
|
|
dummy = dummy_ugettext(translation)
|
|
assert dummy.translation is translation
|
|
|
|
# Test with passing values:
|
|
for value in (-1.0, 0.1, 4.2):
|
|
assert rule(dummy, value) is None
|
|
assert dummy.called() is False
|
|
|
|
# Test with failing values:
|
|
for value in (5.3, 99.9):
|
|
assert_equal(
|
|
rule(dummy, value),
|
|
translation % dict(maxvalue=4.7)
|
|
)
|
|
assert dummy.message == 'can be at most %(maxvalue)f'
|
|
assert dummy.called() is True
|
|
dummy.reset()
|
|
|
|
|
|
class test_List(ClassChecker):
|
|
"""
|
|
Test the `ipalib.parameters.List` class.
|
|
"""
|
|
_cls = parameters.List
|
|
|
|
def test_init(self):
|
|
"""
|
|
Test the `ipalib.parameters.List.__init__` method.
|
|
"""
|
|
# Test with no kwargs:
|
|
o = self.cls('my_list')
|
|
assert o.type is tuple
|
|
assert isinstance(o, parameters.List)
|
|
assert o.multivalue is True
|
|
assert o.skipspace is True
|
|
|
|
def test_normalize(self):
|
|
"""
|
|
Test the `ipalib.parameters.List.normalize` method.
|
|
"""
|
|
o = self.cls('my_list')
|
|
n = o.normalize('a,b')
|
|
assert type(n) is tuple
|
|
assert len(n) is 2
|
|
|
|
n = o.normalize('bar, "hi, there",foo')
|
|
assert type(n) is tuple
|
|
assert len(n) is 3
|
|
|
|
def test_normalize_separator(self):
|
|
"""
|
|
Test the `ipalib.parameters.List.normalize` method with a separator.
|
|
"""
|
|
o = self.cls('my_list', separator='|')
|
|
|
|
n = o.normalize('a')
|
|
assert type(n) is tuple
|
|
assert len(n) is 1
|
|
|
|
n = o.normalize('a|b')
|
|
assert type(n) is tuple
|
|
assert len(n) is 2
|
|
|
|
def test_normalize_skipspace(self):
|
|
"""
|
|
Test the `ipalib.parameters.List.normalize` method without skipping spaces.
|
|
"""
|
|
o = self.cls('my_list', skipspace=False)
|
|
|
|
n = o.normalize('a')
|
|
assert type(n) is tuple
|
|
assert len(n) is 1
|
|
|
|
n = o.normalize('a, "b,c", d')
|
|
assert type(n) is tuple
|
|
# the output w/o skipspace is ['a',' "b','c"',' d']
|
|
assert len(n) is 4
|
|
|
|
def test_create_param():
|
|
"""
|
|
Test the `ipalib.parameters.create_param` function.
|
|
"""
|
|
f = parameters.create_param
|
|
|
|
# Test that Param instances are returned unchanged:
|
|
params = (
|
|
parameters.Param('one?'),
|
|
parameters.Int('two+'),
|
|
parameters.Str('three*'),
|
|
parameters.Bytes('four'),
|
|
)
|
|
for p in params:
|
|
assert f(p) is p
|
|
|
|
# Test that the spec creates an Str instance:
|
|
for spec in ('one?', 'two+', 'three*', 'four'):
|
|
(name, kw) = parameters.parse_param_spec(spec)
|
|
p = f(spec)
|
|
assert p.param_spec is spec
|
|
assert p.name == name
|
|
assert p.required is kw['required']
|
|
assert p.multivalue is kw['multivalue']
|
|
|
|
# Test that TypeError is raised when spec is neither a Param nor a str:
|
|
for spec in (u'one', 42, parameters.Param, parameters.Str):
|
|
e = raises(TypeError, f, spec)
|
|
assert str(e) == \
|
|
TYPE_ERROR % ('spec', (str, parameters.Param), spec, type(spec))
|
|
|
|
|
|
def test_messages():
|
|
"""
|
|
Test module level message in `ipalib.parameters`.
|
|
"""
|
|
for name in dir(parameters):
|
|
if name.startswith('_'):
|
|
continue
|
|
attr = getattr(parameters, name)
|
|
if not (isclass(attr) and issubclass(attr, parameters.Param)):
|
|
continue
|
|
assert type(attr.type_error) is str
|
|
assert attr.type_error in parameters.__messages
|