summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Gerard DeRose <jderose@redhat.com>2009-01-14 11:39:29 -0700
committerJason Gerard DeRose <jderose@redhat.com>2009-01-14 11:39:29 -0700
commit2b2e73e7df90d38175e035d6ada4d752120dc0ec (patch)
tree1aa7e31836b7476049e01420e5de2413b1f85828
parentf3e0900ebc01d8fae8ce4068b0fae8d14c8069bb (diff)
downloadfreeipa-2b2e73e7df90d38175e035d6ada4d752120dc0ec.tar.gz
freeipa-2b2e73e7df90d38175e035d6ada4d752120dc0ec.tar.xz
freeipa-2b2e73e7df90d38175e035d6ada4d752120dc0ec.zip
Removed depreciated code from frontend.py; frontend.py no longer imports ipa_types
-rw-r--r--ipalib/frontend.py453
-rw-r--r--tests/test_ipalib/test_frontend.py414
2 files changed, 3 insertions, 864 deletions
diff --git a/ipalib/frontend.py b/ipalib/frontend.py
index c614e5479..baa37b176 100644
--- a/ipalib/frontend.py
+++ b/ipalib/frontend.py
@@ -27,7 +27,7 @@ import plugable
from plugable import lock, check_name
import errors
from errors import check_type, check_isinstance, raise_TypeError
-import ipa_types
+import parameters
from util import make_repr
@@ -42,453 +42,6 @@ def is_rule(obj):
return callable(obj) and getattr(obj, RULE_FLAG, False) is True
-class DefaultFrom(plugable.ReadOnly):
- """
- Derive a default value from other supplied values.
-
- For example, say you wanted to create a default for the user's login from
- the user's first and last names. It could be implemented like this:
-
- >>> login = DefaultFrom(lambda first, last: first[0] + last)
- >>> login(first='John', last='Doe')
- 'JDoe'
-
- If you do not explicitly provide keys when you create a DefaultFrom
- instance, the keys are implicitly derived from your callback by
- inspecting ``callback.func_code.co_varnames``. The keys are available
- through the ``DefaultFrom.keys`` instance attribute, like this:
-
- >>> login.keys
- ('first', 'last')
-
- The callback is available through the ``DefaultFrom.callback`` instance
- attribute, like this:
-
- >>> login.callback # doctest:+ELLIPSIS
- <function <lambda> at 0x...>
- >>> login.callback.func_code.co_varnames # The keys
- ('first', 'last')
-
- The keys can be explicitly provided as optional positional arguments after
- the callback. For example, this is equivalent to the ``login`` instance
- above:
-
- >>> login2 = DefaultFrom(lambda a, b: a[0] + b, 'first', 'last')
- >>> login2.keys
- ('first', 'last')
- >>> login2.callback.func_code.co_varnames # Not the keys
- ('a', 'b')
- >>> login2(first='John', last='Doe')
- 'JDoe'
-
- If any keys are missing when calling your DefaultFrom instance, your
- callback is not called and None is returned. For example:
-
- >>> login(first='John', lastname='Doe') is None
- True
- >>> login() is None
- True
-
- Any additional keys are simply ignored, like this:
-
- >>> login(last='Doe', first='John', middle='Whatever')
- 'JDoe'
-
- As above, because `DefaultFrom.__call__` takes only pure keyword
- arguments, they can be supplied in any order.
-
- Of course, the callback need not be a lambda expression. This third
- example is equivalent to both the ``login`` and ``login2`` instances
- above:
-
- >>> def get_login(first, last):
- ... return first[0] + last
- ...
- >>> login3 = DefaultFrom(get_login)
- >>> login3.keys
- ('first', 'last')
- >>> login3.callback.func_code.co_varnames
- ('first', 'last')
- >>> login3(first='John', last='Doe')
- 'JDoe'
- """
-
- def __init__(self, callback, *keys):
- """
- :param callback: The callable to call when all keys are present.
- :param keys: Optional keys used for source values.
- """
- if not callable(callback):
- raise TypeError('callback must be callable; got %r' % callback)
- self.callback = callback
- if len(keys) == 0:
- fc = callback.func_code
- self.keys = fc.co_varnames[:fc.co_argcount]
- else:
- self.keys = keys
- for key in self.keys:
- if type(key) is not str:
- raise_TypeError(key, str, 'keys')
- lock(self)
-
- def __call__(self, **kw):
- """
- If all keys are present, calls the callback; otherwise returns None.
-
- :param kw: The keyword arguments.
- """
- vals = tuple(kw.get(k, None) for k in self.keys)
- if None in vals:
- return
- try:
- return self.callback(*vals)
- except StandardError:
- pass
-
-
-def parse_param_spec(spec):
- """
- Parse a param spec into to (name, kw).
-
- The ``spec`` string determines the param name, whether the param is
- required, and whether the param is multivalue according the following
- syntax:
-
- ====== ===== ======== ==========
- Spec Name Required Multivalue
- ====== ===== ======== ==========
- 'var' 'var' True False
- 'var?' 'var' False False
- 'var*' 'var' False True
- 'var+' 'var' True True
- ====== ===== ======== ==========
-
- For example,
-
- >>> parse_param_spec('login')
- ('login', {'required': True, 'multivalue': False})
- >>> parse_param_spec('gecos?')
- ('gecos', {'required': False, 'multivalue': False})
- >>> parse_param_spec('telephone_numbers*')
- ('telephone_numbers', {'required': False, 'multivalue': True})
- >>> parse_param_spec('group+')
- ('group', {'required': True, 'multivalue': True})
-
- :param spec: A spec string.
- """
- if type(spec) is not str:
- raise_TypeError(spec, str, 'spec')
- if len(spec) < 2:
- raise ValueError(
- 'param spec must be at least 2 characters; got %r' % spec
- )
- _map = {
- '?': dict(required=False, multivalue=False),
- '*': dict(required=False, multivalue=True),
- '+': dict(required=True, multivalue=True),
- }
- end = spec[-1]
- if end in _map:
- return (spec[:-1], _map[end])
- return (spec, dict(required=True, multivalue=False))
-
-
-class Param(plugable.ReadOnly):
- """
- A parameter accepted by a `Command`.
-
- ============ ================= ==================
- Keyword Type Default
- ============ ================= ==================
- cli_name str defaults to name
- type ipa_type.Type ipa_type.Unicode()
- doc str ""
- required bool True
- multivalue bool False
- primary_key bool False
- normalize callable None
- default same as type.type None
- default_from callable None
- flags frozenset frozenset()
- ============ ================= ==================
- """
- __nones = (None, '', tuple(), [])
- __defaults = dict(
- cli_name=None,
- type=ipa_types.Unicode(),
- doc='',
- required=True,
- multivalue=False,
- primary_key=False,
- normalize=None,
- default=None,
- default_from=None,
- flags=frozenset(),
- rules=tuple(),
- )
-
- def __init__(self, name, **override):
- self.__param_spec = name
- self.__override = override
- self.__kw = dict(self.__defaults)
- if not ('required' in override or 'multivalue' in override):
- (name, kw_from_spec) = parse_param_spec(name)
- self.__kw.update(kw_from_spec)
- self.__kw['cli_name'] = name
- if not set(self.__kw).issuperset(override):
- extra = sorted(set(override) - set(self.__kw))
- raise TypeError(
- 'Param.__init__() takes no such kwargs: %s' % ', '.join(extra)
- )
- self.__kw.update(override)
- self.name = check_name(name)
- self.cli_name = check_name(self.__kw.get('cli_name', name))
- self.type = self.__check_isinstance(ipa_types.Type, 'type')
- self.doc = self.__check_type(str, 'doc')
- self.required = self.__check_type(bool, 'required')
- self.multivalue = self.__check_type(bool, 'multivalue')
- self.default = self.__kw['default']
- df = self.__kw['default_from']
- if callable(df) and not isinstance(df, DefaultFrom):
- df = DefaultFrom(df)
- self.default_from = check_type(df, DefaultFrom, 'default_from',
- allow_none=True
- )
- self.flags = frozenset(self.__kw['flags'])
- self.__normalize = self.__kw['normalize']
- self.rules = self.__check_type(tuple, 'rules')
- self.all_rules = (self.type.validate,) + self.rules
- self.primary_key = self.__check_type(bool, 'primary_key')
- lock(self)
-
- def ispassword(self):
- """
- Return ``True`` is this Param is a password.
- """
- return 'password' in self.flags
-
- def __clone__(self, **override):
- """
- Return a new `Param` instance similar to this one.
- """
- kw = dict(self.__kw)
- kw.update(override)
- return self.__class__(self.name, **kw)
-
- def __check_type(self, type_, name, allow_none=False):
- value = self.__kw[name]
- return check_type(value, type_, name, allow_none)
-
- def __check_isinstance(self, type_, name, allow_none=False):
- value = self.__kw[name]
- return check_isinstance(value, type_, name, allow_none)
-
- def __dispatch(self, value, scalar):
- """
- Helper method used by `normalize` and `convert`.
- """
- if value in self.__nones:
- return
- if self.multivalue:
- if type(value) in (tuple, list):
- return tuple(
- scalar(v, i) for (i, v) in enumerate(value)
- )
- return (scalar(value, 0),) # tuple
- return scalar(value)
-
- def __normalize_scalar(self, value, index=None):
- """
- Normalize a scalar value.
-
- This method is called once with each value in multivalue.
- """
- if not isinstance(value, basestring):
- return value
- try:
- return self.__normalize(value)
- except StandardError:
- return value
-
- def normalize(self, value):
- """
- Normalize ``value`` using normalize callback.
-
- For example:
-
- >>> param = Param('telephone',
- ... normalize=lambda value: value.replace('.', '-')
- ... )
- >>> param.normalize('800.123.4567')
- '800-123-4567'
-
- If this `Param` instance does not have a normalize callback,
- ``value`` is returned unchanged.
-
- If this `Param` instance has a normalize callback and ``value`` is
- a basestring, the normalize callback is called and its return value
- is returned.
-
- If ``value`` is not a basestring, or if an exception is caught
- when calling the normalize callback, ``value`` is returned unchanged.
-
- :param value: A proposed value for this parameter.
- """
- if self.__normalize is None:
- return value
- return self.__dispatch(value, self.__normalize_scalar)
-
- def __convert_scalar(self, value, index=None):
- """
- Convert a scalar value.
-
- This method is called once with each value in multivalue.
- """
- if value in self.__nones:
- return
- converted = self.type(value)
- if converted is None:
- raise errors.ConversionError(
- self.name, value, self.type, index=index
- )
- return converted
-
- def convert(self, value):
- """
- Convert/coerce ``value`` to Python type for this `Param`.
-
- For example:
-
- >>> param = Param('an_int', type=ipa_types.Int())
- >>> param.convert(7.2)
- 7
- >>> param.convert(" 7 ")
- 7
-
- If ``value`` can not be converted, ConversionError is raised, which
- is as subclass of ValidationError.
-
- If ``value`` is None, conversion is not attempted and None is
- returned.
-
- :param value: A proposed value for this parameter.
- """
- return self.__dispatch(value, self.__convert_scalar)
-
- def __validate_scalar(self, value, index=None):
- """
- Validate a scalar value.
-
- This method is called once with each value in multivalue.
- """
- 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, error, rule, index=index
- )
-
- def validate(self, value):
- """
- Check validity of a value.
-
- Each validation rule is called in turn and if any returns and error,
- RuleError is raised, which is a subclass of ValidationError.
-
- :param value: A proposed value for this parameter.
- """
- if value is None:
- if self.required:
- raise errors.RequirementError(self.name)
- return
- if self.multivalue:
- if type(value) is not tuple:
- raise_TypeError(value, tuple, 'value')
- for (i, v) in enumerate(value):
- self.__validate_scalar(v, i)
- else:
- self.__validate_scalar(value)
-
- def get_default(self, **kw):
- """
- Return a default value for this parameter.
-
- If this `Param` instance does not have a default_from() callback, this
- method always returns the static Param.default instance attribute.
-
- On the other hand, if this `Param` instance has a default_from()
- callback, the callback is called and its return value is returned
- (assuming that value is not None).
-
- If the default_from() callback returns None, or if an exception is
- caught when calling the default_from() callback, the static
- Param.default instance attribute is returned.
-
- :param kw: Optional keyword arguments to pass to default_from().
- """
- if self.default_from is not None:
- default = self.default_from(**kw)
- if default is not None:
- try:
- return self.convert(self.normalize(default))
- except errors.ValidationError:
- return None
- return self.default
-
- def get_values(self):
- """
- Return a tuple of possible values.
-
- For enumerable types, a tuple containing the possible values is
- returned. For all other types, an empty tuple is returned.
- """
- if self.type.name in ('Enum', 'CallbackEnum'):
- return self.type.values
- return tuple()
-
- def __call__(self, value, **kw):
- if value in self.__nones:
- value = self.get_default(**kw)
- else:
- value = self.convert(self.normalize(value))
- self.validate(value)
- return value
-
- def __repr__(self):
- """
- Return an expresion that could construct this `Param` instance.
- """
- return make_repr(
- self.__class__.__name__,
- self.__param_spec,
- **self.__override
- )
-
-
-def create_param(spec):
- """
- Create a `Param` instance from a param spec.
-
- If ``spec`` is a `Param` instance, ``spec`` is returned unchanged.
-
- If ``spec`` is an str instance, then ``spec`` is parsed and an
- appropriate `Param` instance is created and returned.
-
- See `parse_param_spec` for the definition of the spec syntax.
-
- :param spec: A spec string or a `Param` instance.
- """
- if type(spec) is Param:
- return spec
- if type(spec) is not str:
- raise TypeError(
- 'create_param() takes %r or %r; got %r' % (str, Param, spec)
- )
- return Param(spec)
-
-
class Command(plugable.Plugin):
"""
A public IPA atomic operation.
@@ -810,7 +363,7 @@ class LocalOrRemote(Command):
"""
takes_options = (
- Param('server?', type=ipa_types.Bool(), default=False,
+ parameters.Flag('server?',
doc='Forward to server instead of running locally',
),
)
@@ -1064,7 +617,7 @@ class Property(Attribute):
'type',
)).union(Attribute.__public__)
- type = ipa_types.Unicode()
+ type = parameters.Str
required = False
multivalue = False
default = None
diff --git a/tests/test_ipalib/test_frontend.py b/tests/test_ipalib/test_frontend.py
index 94e586fe9..c40933175 100644
--- a/tests/test_ipalib/test_frontend.py
+++ b/tests/test_ipalib/test_frontend.py
@@ -70,420 +70,6 @@ def test_is_rule():
assert not is_rule(call(None))
-class test_DefaultFrom(ClassChecker):
- """
- Test the `ipalib.frontend.DefaultFrom` class.
- """
- _cls = frontend.DefaultFrom
-
- def test_class(self):
- """
- Test the `ipalib.frontend.DefaultFrom` class.
- """
- assert self.cls.__bases__ == (plugable.ReadOnly,)
-
- def test_init(self):
- """
- Test the `ipalib.frontend.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')
-
- def test_call(self):
- """
- Test the `ipalib.frontend.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.frontend.parse_param_spec` function.
- """
- f = frontend.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))
-
-
-class test_Param(ClassChecker):
- """
- Test the `ipalib.frontend.Param` class.
- """
- _cls = frontend.Param
-
- def test_class(self):
- """
- Test the `ipalib.frontend.Param` class.
- """
- assert self.cls.__bases__ == (plugable.ReadOnly,)
-
- def test_init(self):
- """
- Test the `ipalib.frontend.Param.__init__` method.
- """
- name = 'sn'
- o = self.cls(name)
- assert o.__islocked__() is True
-
- # Test default values
- assert read_only(o, 'name') is name
- assert read_only(o, 'cli_name') is name
- assert isinstance(read_only(o, 'type'), ipa_types.Unicode)
- assert read_only(o, 'doc') == ''
- assert read_only(o, 'required') is True
- assert read_only(o, 'multivalue') is False
- assert read_only(o, 'default') is None
- assert read_only(o, 'default_from') is None
- assert read_only(o, 'flags') == frozenset()
- assert read_only(o, 'rules') == tuple()
- assert len(read_only(o, 'all_rules')) == 1
- assert read_only(o, 'primary_key') is False
-
- # Test all kw args:
- t = ipa_types.Int()
- assert self.cls(name, cli_name='last').cli_name == 'last'
- assert self.cls(name, type=t).type is t
- assert self.cls(name, doc='the doc').doc == 'the doc'
- assert self.cls(name, required=False).required is False
- assert self.cls(name, multivalue=True).multivalue is True
- assert self.cls(name, default=u'Hello').default == u'Hello'
- df = frontend.DefaultFrom(lambda f, l: f + l,
- 'first', 'last',
- )
- lam = lambda first, last: first + last
- for cb in (df, lam):
- o = self.cls(name, default_from=cb)
- assert type(o.default_from) is frontend.DefaultFrom
- assert o.default_from.keys == ('first', 'last')
- assert o.default_from.callback('butt', 'erfly') == 'butterfly'
- assert self.cls(name, flags=('one', 'two', 'three')).flags == \
- frozenset(['one', 'two', 'three'])
- rules = (lambda whatever: 'Not okay!',)
- o = self.cls(name, rules=rules)
- assert o.rules is rules
- assert o.all_rules[1:] == rules
- assert self.cls(name, primary_key=True).primary_key is True
-
- # Test default type_:
- o = self.cls(name)
- assert isinstance(o.type, ipa_types.Unicode)
-
- # Test param spec parsing:
- o = self.cls('name?')
- assert o.name == 'name'
- assert o.required is False
- assert o.multivalue is False
-
- o = self.cls('name*')
- assert o.name == 'name'
- assert o.required is False
- assert o.multivalue is True
-
- o = self.cls('name+')
- assert o.name == 'name'
- assert o.required is True
- assert o.multivalue is True
-
- e = raises(TypeError, self.cls, name, whatever=True, another=False)
- assert str(e) == \
- 'Param.__init__() takes no such kwargs: another, whatever'
-
- def test_ispassword(self):
- """
- Test the `ipalib.frontend.Param.ispassword` method.
- """
- name = 'userpassword'
- okay = 'password'
- nope = ['', 'pass', 'word', 'passwd']
- for flag in nope:
- o = self.cls(name, flags=[flag])
- assert o.ispassword() is False
- o = self.cls(name, flags=[flag, okay])
- assert o.ispassword() is True
- assert self.cls(name).ispassword() is False
- assert self.cls(name, flags=[okay]).ispassword() is True
- assert self.cls(name, flags=[okay]+nope).ispassword() is True
-
- def test_clone(self):
- """
- Test the `ipalib.frontend.Param.__clone__` method.
- """
- def compare(o, kw):
- for (k, v) in kw.iteritems():
- assert getattr(o, k) == v, (k, v, getattr(o, k))
- default = dict(
- required=False,
- multivalue=False,
- default=None,
- default_from=None,
- rules=tuple(),
- )
- name = 'hair_color?'
- type_ = ipa_types.Int()
- o = self.cls(name, type=type_)
- compare(o, default)
-
- override = dict(multivalue=True, default=42)
- d = dict(default)
- d.update(override)
- clone = o.__clone__(**override)
- assert clone.name == 'hair_color'
- assert clone.type is o.type
- compare(clone, d)
-
- def test_convert(self):
- """
- Test the `ipalib.frontend.Param.convert` method.
- """
- name = 'some_number'
- type_ = ipa_types.Int()
- okay = (7, 7L, 7.0, ' 7 ')
- fail = ('7.0', '7L', 'whatever', object)
- none = (None, '', u'', tuple(), [])
-
- # Scenario 1: multivalue=False
- o = self.cls(name, type=type_)
- for n in none:
- assert o.convert(n) is None
- for value in okay:
- new = o.convert(value)
- assert new == 7
- assert type(new) is int
- for value in fail:
- e = raises(errors.ConversionError, o.convert, value)
- assert e.name is name
- assert e.value is value
- assert e.error is type_.conversion_error
- assert e.index is None
-
- # Scenario 2: multivalue=True
- o = self.cls(name, type=type_, multivalue=True)
- for n in none:
- assert o.convert(n) is None
- for value in okay:
- assert o.convert((value,)) == (7,)
- assert o.convert([value]) == (7,)
- assert o.convert(okay) == tuple(int(v) for v in okay)
- cnt = 5
- for value in fail:
- for i in xrange(cnt):
- others = list(7 for x in xrange(cnt))
- others[i] = value
- for v in [tuple(others), list(others)]:
- e = raises(errors.ConversionError, o.convert, v)
- assert e.name is name
- assert e.value is value
- assert e.error is type_.conversion_error
- assert e.index == i
-
- def test_normalize(self):
- """
- Test the `ipalib.frontend.Param.normalize` method.
- """
- name = 'sn'
- callback = lambda value: value.lower()
- values = (None, u'Hello', (u'Hello',), 'hello', ['hello'])
- none = (None, '', u'', tuple(), [])
-
- # Scenario 1: multivalue=False, normalize=None
- o = self.cls(name)
- for v in 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, normalize=callback)
- for v in (u'Hello', u'hello', 'Hello'): # Okay
- assert o.normalize(v) == 'hello'
- for v in [None, 42, (u'Hello',)]: # Not basestring
- assert o.normalize(v) is v
- for n in none:
- assert o.normalize(n) is None
-
- # Scenario 3: multivalue=True, normalize=None
- o = self.cls(name, multivalue=True)
- for v in 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, multivalue=True, normalize=callback)
- assert o.normalize([]) is None
- assert o.normalize(tuple()) is None
- for value in [(u'Hello',), (u'hello',), 'Hello', ['Hello']]: # Okay
- assert o.normalize(value) == (u'hello',)
- fail = 42 # Not basestring
- for v in [[fail], (u'hello', fail)]: # Non basestring member
- assert o.normalize(v) == tuple(v)
- for n in none:
- assert o.normalize(n) is None
-
- def test_validate(self):
- """
- Test the `ipalib.frontend.Param.validate` method.
- """
- name = 'sn'
- type_ = ipa_types.Unicode()
- def case_rule(value):
- if not value.islower():
- return 'Must be lower case'
- my_rules = (case_rule,)
- okay = u'whatever'
- fail_case = u'Whatever'
- fail_type = 'whatever'
-
- # Scenario 1: multivalue=False
- o = self.cls(name, type=type_, rules=my_rules)
- assert o.rules == my_rules
- assert o.all_rules == (type_.validate, case_rule)
- o.validate(okay)
- 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'
- assert e.rule is case_rule
- assert e.index is None
- check_TypeError(fail_type, unicode, 'value', o.validate, fail_type)
-
- ## Scenario 2: multivalue=True
- o = self.cls(name, type=type_, multivalue=True, rules=my_rules)
- o.validate((okay,))
- cnt = 5
- for i in xrange(cnt):
- others = list(okay for x in xrange(cnt))
- others[i] = fail_case
- value = tuple(others)
- e = raises(errors.RuleError, o.validate, value)
- assert e.name is name
- assert e.value is fail_case
- assert e.error == 'Must be lower case'
- assert e.rule is case_rule
- assert e.index == i
- for not_tuple in (okay, [okay]):
- check_TypeError(not_tuple, tuple, 'value', o.validate, not_tuple)
- for has_str in [(fail_type,), (okay, fail_type)]:
- check_TypeError(fail_type, unicode, 'value', o.validate, has_str)
-
- def test_get_default(self):
- """
- Test the `ipalib.frontend.Param.get_default` method.
- """
- name = 'greeting'
- default = u'Hello, world!'
- default_from = frontend.DefaultFrom(
- lambda first, last: u'Hello, %s %s!' % (first, last),
- 'first', 'last'
- )
-
- # Scenario 1: multivalue=False
- o = self.cls(name,
- default=default,
- default_from=default_from,
- )
- assert o.default is default
- assert o.default_from is default_from
- assert o.get_default() == default
- assert o.get_default(first='John', last='Doe') == 'Hello, John Doe!'
-
- # Scenario 2: multivalue=True
- default = (default,)
- o = self.cls(name,
- default=default,
- default_from=default_from,
- multivalue=True,
- )
- assert o.default is default
- assert o.default_from is default_from
- assert o.get_default() == default
- assert o.get_default(first='John', last='Doe') == ('Hello, John Doe!',)
-
- def test_get_value(self):
- """
- Test the `ipalib.frontend.Param.get_values` method.
- """
- name = 'status'
- values = (u'Active', u'Inactive')
- o = self.cls(name, type=ipa_types.Unicode())
- assert o.get_values() == tuple()
- o = self.cls(name, type=ipa_types.Enum(*values))
- assert o.get_values() == values
-
- def test_repr(self):
- """
- Test the `ipalib.frontend.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_create_param():
- """
- Test the `ipalib.frontend.create_param` function.
- """
- f = frontend.create_param
- for name in ['arg', 'arg?', 'arg*', 'arg+']:
- o = f(name)
- assert type(o) is frontend.Param
- assert type(o.type) is ipa_types.Unicode
- assert o.name == 'arg'
- assert f(o) is o
- o = f('arg')
- assert o.required is True
- assert o.multivalue is False
- o = f('arg?')
- assert o.required is False
- assert o.multivalue is False
- o = f('arg*')
- assert o.required is False
- assert o.multivalue is True
- o = f('arg+')
- assert o.required is True
- assert o.multivalue is True
-
-
class test_Command(ClassChecker):
"""
Test the `ipalib.frontend.Command` class.