From 7721443a625b2efd0744ad347c62795e5ba6bb91 Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Tue, 7 Oct 2008 20:41:15 -0600 Subject: Moved ipalib/tests/ into tests/test_ipalib/ --- tests/test_ipalib/test_frontend.py | 1080 ++++++++++++++++++++++++++++++++++++ 1 file changed, 1080 insertions(+) create mode 100644 tests/test_ipalib/test_frontend.py (limited to 'tests/test_ipalib/test_frontend.py') diff --git a/tests/test_ipalib/test_frontend.py b/tests/test_ipalib/test_frontend.py new file mode 100644 index 00000000..c70cc00d --- /dev/null +++ b/tests/test_ipalib/test_frontend.py @@ -0,0 +1,1080 @@ +# Authors: +# Jason Gerard DeRose +# +# 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 + +""" +Unit tests for `ipalib.frontend` module. +""" + +from tstutil import raises, getitem, no_set, no_del, read_only, ClassChecker +from tstutil import check_TypeError +from ipalib import frontend, backend, plugable, errors, ipa_types, config + + +def test_RULE_FLAG(): + assert frontend.RULE_FLAG == 'validation_rule' + + +def test_rule(): + """ + Tests the `frontend.rule` function. + """ + flag = frontend.RULE_FLAG + rule = frontend.rule + def my_func(): + pass + assert not hasattr(my_func, flag) + rule(my_func) + assert getattr(my_func, flag) is True + @rule + def my_func2(): + pass + assert getattr(my_func2, flag) is True + + +def test_is_rule(): + """ + Tests the `frontend.is_rule` function. + """ + is_rule = frontend.is_rule + flag = frontend.RULE_FLAG + + class no_call(object): + def __init__(self, value): + if value is not None: + assert value in (True, False) + setattr(self, flag, value) + + class call(no_call): + def __call__(self): + pass + + assert is_rule(call(True)) + assert not is_rule(no_call(True)) + assert not is_rule(call(False)) + assert not is_rule(call(None)) + + +class test_DefaultFrom(ClassChecker): + """ + Tests the `frontend.DefaultFrom` class. + """ + _cls = frontend.DefaultFrom + + def test_class(self): + assert self.cls.__bases__ == (plugable.ReadOnly,) + + def test_init(self): + """ + Tests the `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): + """ + Tests the `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 + 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 + + +def test_parse_param_spec(): + """ + Test the `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 `frontend.Param` class. + """ + _cls = frontend.Param + + def test_class(self): + assert self.cls.__bases__ == (plugable.ReadOnly,) + + def test_init(self): + """ + Test the `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 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, '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, 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' + 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_clone(self): + """ + Test the `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 `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 `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): + """ + Tests the `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): + """ + Tests the `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): + """ + Tests the `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_create_param(): + """ + Test the `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): + """ + Tests the `frontend.Command` class. + """ + _cls = frontend.Command + + def get_subcls(self): + class Rule(object): + def __init__(self, name): + self.name = name + + def __call__(self, value): + if value != self.name: + return 'must equal %s' % self.name + + default_from = frontend.DefaultFrom( + lambda arg: arg, + 'default_from' + ) + normalize = lambda value: value.lower() + + class example(self.cls): + takes_options = ( + frontend.Param('option0', + normalize=normalize, + default_from=default_from, + rules=(Rule('option0'),) + ), + frontend.Param('option1', + normalize=normalize, + default_from=default_from, + rules=(Rule('option1'),), + required=True, + ), + ) + return example + + def get_instance(self, args=tuple(), options=tuple()): + """ + Helper method used to test args and options. + """ + class example(self.cls): + takes_args = args + takes_options = options + o = example() + o.finalize() + return o + + def test_class(self): + assert self.cls.__bases__ == (plugable.Plugin,) + assert self.cls.takes_options == tuple() + assert self.cls.takes_args == tuple() + + def test_get_args(self): + """ + Tests the `frontend.Command.get_args` method. + """ + assert list(self.cls().get_args()) == [] + args = ('login', 'stuff') + o = self.get_instance(args=args) + assert o.get_args() is args + + def test_get_options(self): + """ + Tests the `frontend.Command.get_options` method. + """ + assert list(self.cls().get_options()) == [] + options = ('verbose', 'debug') + o = self.get_instance(options=options) + assert o.get_options() is options + + def test_args(self): + """ + Tests the ``Command.args`` instance attribute. + """ + assert 'args' in self.cls.__public__ # Public + assert self.cls().args is None + o = self.cls() + o.finalize() + assert type(o.args) is plugable.NameSpace + assert len(o.args) == 0 + args = ('destination', 'source?') + ns = self.get_instance(args=args).args + assert type(ns) is plugable.NameSpace + assert len(ns) == len(args) + assert list(ns) == ['destination', 'source'] + assert type(ns.destination) is frontend.Param + assert type(ns.source) is frontend.Param + assert ns.destination.required is True + assert ns.destination.multivalue is False + assert ns.source.required is False + assert ns.source.multivalue is False + + # Test TypeError: + e = raises(TypeError, self.get_instance, args=(u'whatever',)) + assert str(e) == \ + 'create_param() takes %r or %r; got %r' % (str, frontend.Param, u'whatever') + + # Test ValueError, required after optional: + e = raises(ValueError, self.get_instance, args=('arg1?', 'arg2')) + assert str(e) == 'arg2: required argument after optional' + + # Test ValueError, scalar after multivalue: + e = raises(ValueError, self.get_instance, args=('arg1+', 'arg2')) + assert str(e) == 'arg2: only final argument can be multivalue' + + def test_max_args(self): + """ + Test the ``Command.max_args`` instance attribute. + """ + o = self.get_instance() + assert o.max_args == 0 + o = self.get_instance(args=('one?',)) + assert o.max_args == 1 + o = self.get_instance(args=('one', 'two?')) + assert o.max_args == 2 + o = self.get_instance(args=('one', 'multi+',)) + assert o.max_args is None + o = self.get_instance(args=('one', 'multi*',)) + assert o.max_args is None + + def test_options(self): + """ + Tests the ``Command.options`` instance attribute. + """ + assert 'options' in self.cls.__public__ # Public + assert self.cls().options is None + o = self.cls() + o.finalize() + assert type(o.options) is plugable.NameSpace + assert len(o.options) == 0 + options = ('target', 'files*') + ns = self.get_instance(options=options).options + assert type(ns) is plugable.NameSpace + assert len(ns) == len(options) + assert list(ns) == ['target', 'files'] + assert type(ns.target) is frontend.Param + assert type(ns.files) is frontend.Param + assert ns.target.required is True + assert ns.target.multivalue is False + assert ns.files.required is False + assert ns.files.multivalue is True + + def test_convert(self): + """ + Tests the `frontend.Command.convert` method. + """ + assert 'convert' in self.cls.__public__ # Public + kw = dict( + option0='option0', + option1='option1', + ) + expected = dict(kw) + expected.update(dict(option0=u'option0', option1=u'option1')) + o = self.subcls() + o.finalize() + for (key, value) in o.convert(**kw).iteritems(): + v = expected[key] + assert value == v + assert type(value) is type(v) + + def test_normalize(self): + """ + Tests the `frontend.Command.normalize` method. + """ + assert 'normalize' in self.cls.__public__ # Public + kw = dict( + option0=u'OPTION0', + option1=u'OPTION1', + ) + norm = dict((k, v.lower()) for (k, v) in kw.items()) + sub = self.subcls() + sub.finalize() + assert sub.normalize(**kw) == norm + + def test_get_default(self): + """ + Tests the `frontend.Command.get_default` method. + """ + assert 'get_default' in self.cls.__public__ # Public + no_fill = dict( + option0='value0', + option1='value1', + whatever='hello world', + ) + fill = dict( + default_from='the default', + ) + default = dict( + option0='the default', + option1='the default', + ) + sub = self.subcls() + sub.finalize() + assert sub.get_default(**no_fill) == {} + assert sub.get_default(**fill) == default + + def test_validate(self): + """ + Tests the `frontend.Command.validate` method. + """ + assert 'validate' in self.cls.__public__ # Public + + sub = self.subcls() + sub.finalize() + + # Check with valid args + okay = dict( + option0=u'option0', + option1=u'option1', + another_option='some value', + ) + sub.validate(**okay) + + # Check with an invalid arg + fail = dict(okay) + fail['option0'] = u'whatever' + e = raises(errors.RuleError, sub.validate, **fail) + assert e.name == 'option0' + assert e.value == u'whatever' + assert e.error == 'must equal option0' + assert e.rule.__class__.__name__ == 'Rule' + assert e.index is None + + # Check with a missing required arg + fail = dict(okay) + fail.pop('option1') + e = raises(errors.RequirementError, sub.validate, **fail) + assert e.name == 'option1' + assert e.value is None + assert e.index is None + + def test_execute(self): + """ + Tests the `frontend.Command.execute` method. + """ + assert 'execute' in self.cls.__public__ # Public + + def test_args_to_kw(self): + """ + Test the `frontend.Command.args_to_kw` method. + """ + assert 'args_to_kw' in self.cls.__public__ # Public + o = self.get_instance(args=('one', 'two?')) + assert o.args_to_kw(1) == dict(one=1) + assert o.args_to_kw(1, 2) == dict(one=1, two=2) + + o = self.get_instance(args=('one', 'two*')) + assert o.args_to_kw(1) == dict(one=1) + assert o.args_to_kw(1, 2) == dict(one=1, two=(2,)) + assert o.args_to_kw(1, 2, 3) == dict(one=1, two=(2, 3)) + + o = self.get_instance(args=('one', 'two+')) + assert o.args_to_kw(1) == dict(one=1) + assert o.args_to_kw(1, 2) == dict(one=1, two=(2,)) + assert o.args_to_kw(1, 2, 3) == dict(one=1, two=(2, 3)) + + o = self.get_instance() + e = raises(errors.ArgumentError, o.args_to_kw, 1) + assert str(e) == 'example takes no arguments' + + o = self.get_instance(args=('one?',)) + e = raises(errors.ArgumentError, o.args_to_kw, 1, 2) + assert str(e) == 'example takes at most 1 argument' + + o = self.get_instance(args=('one', 'two?')) + e = raises(errors.ArgumentError, o.args_to_kw, 1, 2, 3) + assert str(e) == 'example takes at most 2 arguments' + + def test_kw_to_args(self): + """ + Tests the `frontend.Command.kw_to_args` method. + """ + assert 'kw_to_args' in self.cls.__public__ # Public + o = self.get_instance(args=('one', 'two?')) + assert o.kw_to_args() == (None, None) + assert o.kw_to_args(whatever='hello') == (None, None) + assert o.kw_to_args(one='the one') == ('the one', None) + assert o.kw_to_args(two='the two') == (None, 'the two') + assert o.kw_to_args(whatever='hello', two='Two', one='One') == \ + ('One', 'Two') + + def test_run(self): + """ + Test the `frontend.Command.run` method. + """ + class my_cmd(self.cls): + def execute(self, *args, **kw): + return ('execute', args, kw) + + def forward(self, *args, **kw): + return ('forward', args, kw) + + args = ('Hello,', 'world,') + kw = dict(how_are='you', on_this='fine day?') + + # Test in server context: + api = plugable.API(self.cls) + api.env.update(dict(server_context=True)) + api.finalize() + o = my_cmd() + o.set_api(api) + assert o.run.im_func is self.cls.run.im_func + assert ('execute', args, kw) == o.run(*args, **kw) + assert o.run.im_func is my_cmd.execute.im_func + + # Test in non-server context + api = plugable.API(self.cls) + api.env.update(dict(server_context=False)) + api.finalize() + o = my_cmd() + o.set_api(api) + assert o.run.im_func is self.cls.run.im_func + assert ('forward', args, kw) == o.run(*args, **kw) + assert o.run.im_func is my_cmd.forward.im_func + + +class test_Object(ClassChecker): + """ + Test the `frontend.Object` class. + """ + _cls = frontend.Object + + def test_class(self): + assert self.cls.__bases__ == (plugable.Plugin,) + assert self.cls.backend is None + assert self.cls.methods is None + assert self.cls.properties is None + assert self.cls.params is None + assert self.cls.params_minus_pk is None + assert self.cls.takes_params == tuple() + + def test_init(self): + """ + Test the `frontend.Object.__init__` method. + """ + o = self.cls() + assert o.backend is None + assert o.methods is None + assert o.properties is None + assert o.params is None + assert o.params_minus_pk is None + assert o.properties is None + + def test_set_api(self): + """ + Test the `frontend.Object.set_api` method. + """ + # Setup for test: + class DummyAttribute(object): + def __init__(self, obj_name, attr_name, name=None): + self.obj_name = obj_name + self.attr_name = attr_name + if name is None: + self.name = '%s_%s' % (obj_name, attr_name) + else: + self.name = name + self.param = frontend.create_param(attr_name) + + def __clone__(self, attr_name): + return self.__class__( + self.obj_name, + self.attr_name, + getattr(self, attr_name) + ) + + def get_attributes(cnt, format): + for name in ['other', 'user', 'another']: + for i in xrange(cnt): + yield DummyAttribute(name, format % i) + + cnt = 10 + formats = dict( + methods='method_%d', + properties='property_%d', + ) + + + _d = dict( + Method=plugable.NameSpace( + get_attributes(cnt, formats['methods']) + ), + Property=plugable.NameSpace( + get_attributes(cnt, formats['properties']) + ), + ) + api = plugable.MagicDict(_d) + assert len(api.Method) == cnt * 3 + assert len(api.Property) == cnt * 3 + + class user(self.cls): + pass + + # Actually perform test: + o = user() + o.set_api(api) + assert read_only(o, 'api') is api + for name in ['methods', 'properties']: + namespace = getattr(o, name) + assert isinstance(namespace, plugable.NameSpace) + assert len(namespace) == cnt + f = formats[name] + for i in xrange(cnt): + attr_name = f % i + attr = namespace[attr_name] + assert isinstance(attr, DummyAttribute) + assert attr is getattr(namespace, attr_name) + assert attr.obj_name == 'user' + assert attr.attr_name == attr_name + assert attr.name == attr_name + + # Test params instance attribute + o = self.cls() + o.set_api(api) + ns = o.params + assert type(ns) is plugable.NameSpace + assert len(ns) == 0 + class example(self.cls): + takes_params = ('banana', 'apple') + o = example() + o.set_api(api) + ns = o.params + assert type(ns) is plugable.NameSpace + assert len(ns) == 2, repr(ns) + assert list(ns) == ['banana', 'apple'] + for p in ns(): + assert type(p) is frontend.Param + assert p.required is True + assert p.multivalue is False + + def test_primary_key(self): + """ + Test the `frontend.Object.primary_key` attribute. + """ + api = plugable.API( + frontend.Method, + frontend.Property, + ) + api.env.update(config.generate_env()) + api.finalize() + + # Test with no primary keys: + class example1(self.cls): + takes_params = ( + 'one', + 'two', + ) + o = example1() + o.set_api(api) + assert o.primary_key is None + assert o.params_minus_pk is None + + # Test with 1 primary key: + class example2(self.cls): + takes_params = ( + 'one', + 'two', + frontend.Param('three', + primary_key=True, + ), + 'four', + ) + o = example2() + o.set_api(api) + pk = o.primary_key + assert isinstance(pk, frontend.Param) + assert pk.name == 'three' + assert pk.primary_key is True + assert o.params[2] is o.primary_key + assert isinstance(o.params_minus_pk, plugable.NameSpace) + assert list(o.params_minus_pk) == ['one', 'two', 'four'] + + # Test with multiple primary_key: + class example3(self.cls): + takes_params = ( + frontend.Param('one', primary_key=True), + frontend.Param('two', primary_key=True), + 'three', + frontend.Param('four', primary_key=True), + ) + o = example3() + e = raises(ValueError, o.set_api, api) + assert str(e) == \ + 'example3 (Object) has multiple primary keys: one, two, four' + + def test_backend(self): + """ + Test the `frontend.Object.backend` attribute. + """ + api = plugable.API( + frontend.Object, + frontend.Method, + frontend.Property, + backend.Backend, + ) + api.env.update(config.generate_env()) + class ldap(backend.Backend): + whatever = 'It worked!' + api.register(ldap) + class user(frontend.Object): + backend_name = 'ldap' + api.register(user) + api.finalize() + b = api.Object.user.backend + assert isinstance(b, ldap) + assert b.whatever == 'It worked!' + + +class test_Attribute(ClassChecker): + """ + Tests the `frontend.Attribute` class. + """ + _cls = frontend.Attribute + + def test_class(self): + assert self.cls.__bases__ == (plugable.Plugin,) + assert type(self.cls.obj) is property + assert type(self.cls.obj_name) is property + assert type(self.cls.attr_name) is property + + def test_init(self): + """ + Tests the `frontend.Attribute.__init__` method. + """ + class user_add(self.cls): + pass + o = user_add() + assert read_only(o, 'obj') is None + assert read_only(o, 'obj_name') == 'user' + assert read_only(o, 'attr_name') == 'add' + + def test_set_api(self): + """ + Tests the `frontend.Attribute.set_api` method. + """ + user_obj = 'The user frontend.Object instance' + class api(object): + Object = dict(user=user_obj) + class user_add(self.cls): + pass + o = user_add() + assert read_only(o, 'api') is None + assert read_only(o, 'obj') is None + o.set_api(api) + assert read_only(o, 'api') is api + assert read_only(o, 'obj') is user_obj + + +class test_Method(ClassChecker): + """ + Test the `frontend.Method` class. + """ + _cls = frontend.Method + + def test_class(self): + assert self.cls.__bases__ == (frontend.Attribute, frontend.Command) + assert self.cls.implements(frontend.Command) + assert self.cls.implements(frontend.Attribute) + + def test_init(self): + """ + Test the `frontend.Method.__init__` method. + """ + class user_add(self.cls): + pass + o = user_add() + assert o.name == 'user_add' + assert o.obj_name == 'user' + assert o.attr_name == 'add' + assert frontend.Command.implemented_by(o) + assert frontend.Attribute.implemented_by(o) + + +class test_Property(ClassChecker): + """ + Tests the `frontend.Property` class. + """ + _cls = frontend.Property + + def get_subcls(self): + class user_givenname(self.cls): + 'User first name' + + @frontend.rule + def rule0_lowercase(self, value): + if not value.islower(): + return 'Must be lowercase' + return user_givenname + + def test_class(self): + assert self.cls.__bases__ == (frontend.Attribute,) + assert isinstance(self.cls.type, ipa_types.Unicode) + assert self.cls.required is False + assert self.cls.multivalue is False + assert self.cls.default is None + assert self.cls.default_from is None + assert self.cls.normalize is None + + def test_init(self): + """ + Tests the `frontend.Property.__init__` method. + """ + o = self.subcls() + assert len(o.rules) == 1 + assert o.rules[0].__name__ == 'rule0_lowercase' + param = o.param + assert isinstance(param, frontend.Param) + assert param.name == 'givenname' + assert param.doc == 'User first name' + + +class test_Application(ClassChecker): + """ + Tests the `frontend.Application` class. + """ + _cls = frontend.Application + + def test_class(self): + assert self.cls.__bases__ == (frontend.Command,) + assert type(self.cls.application) is property + + def test_application(self): + """ + Tests the `frontend.Application.application` property. + """ + assert 'application' in self.cls.__public__ # Public + assert 'set_application' in self.cls.__public__ # Public + app = 'The external application' + class example(self.cls): + 'A subclass' + for o in (self.cls(), example()): + assert read_only(o, 'application') is None + e = raises(TypeError, o.set_application, None) + assert str(e) == ( + '%s.application cannot be None' % o.__class__.__name__ + ) + o.set_application(app) + assert read_only(o, 'application') is app + e = raises(AttributeError, o.set_application, app) + assert str(e) == ( + '%s.application can only be set once' % o.__class__.__name__ + ) + assert read_only(o, 'application') is app -- cgit From af56c71d506c2573f99a1ca8334cfa90dc7f74d7 Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Tue, 7 Oct 2008 21:25:23 -0600 Subject: Cleaned up package and module level docstrings for everything in tests/ --- tests/test_ipalib/test_frontend.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests/test_ipalib/test_frontend.py') diff --git a/tests/test_ipalib/test_frontend.py b/tests/test_ipalib/test_frontend.py index c70cc00d..d99c7bd9 100644 --- a/tests/test_ipalib/test_frontend.py +++ b/tests/test_ipalib/test_frontend.py @@ -18,7 +18,7 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA """ -Unit tests for `ipalib.frontend` module. +Test the `ipalib.frontend` module. """ from tstutil import raises, getitem, no_set, no_del, read_only, ClassChecker -- cgit From f6ac2df6bd7ceddd0f3eb968198cc3ebd1388087 Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Tue, 7 Oct 2008 21:59:47 -0600 Subject: Moved tstutil.py into base of tests so it can be used by all test subpackages more easily --- tests/test_ipalib/test_frontend.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tests/test_ipalib/test_frontend.py') diff --git a/tests/test_ipalib/test_frontend.py b/tests/test_ipalib/test_frontend.py index d99c7bd9..320e2078 100644 --- a/tests/test_ipalib/test_frontend.py +++ b/tests/test_ipalib/test_frontend.py @@ -21,8 +21,8 @@ Test the `ipalib.frontend` module. """ -from tstutil import raises, getitem, no_set, no_del, read_only, ClassChecker -from tstutil import check_TypeError +from tests.tstutil import raises, getitem, no_set, no_del, read_only, ClassChecker +from tests.tstutil import check_TypeError from ipalib import frontend, backend, plugable, errors, ipa_types, config -- cgit From deb8e3dfc899cfc7ee31f47c1ba7c4301c58fc51 Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Tue, 7 Oct 2008 22:30:53 -0600 Subject: Renamed tests/tstutil.py to tests/util.py --- tests/test_ipalib/test_frontend.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tests/test_ipalib/test_frontend.py') diff --git a/tests/test_ipalib/test_frontend.py b/tests/test_ipalib/test_frontend.py index 320e2078..4b1b56cf 100644 --- a/tests/test_ipalib/test_frontend.py +++ b/tests/test_ipalib/test_frontend.py @@ -21,8 +21,8 @@ Test the `ipalib.frontend` module. """ -from tests.tstutil import raises, getitem, no_set, no_del, read_only, ClassChecker -from tests.tstutil import check_TypeError +from tests.util import raises, getitem, no_set, no_del, read_only, ClassChecker +from tests.util import check_TypeError from ipalib import frontend, backend, plugable, errors, ipa_types, config -- cgit From ad2cd6560b9fb45ee1b8c52213f3d36eac70bec7 Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Wed, 8 Oct 2008 00:58:53 -0600 Subject: PEP 257: cleaned up docstrings in test_frontend.py --- tests/test_ipalib/test_frontend.py | 121 +++++++++++++++++++++++-------------- 1 file changed, 76 insertions(+), 45 deletions(-) (limited to 'tests/test_ipalib/test_frontend.py') diff --git a/tests/test_ipalib/test_frontend.py b/tests/test_ipalib/test_frontend.py index 4b1b56cf..b798d2ee 100644 --- a/tests/test_ipalib/test_frontend.py +++ b/tests/test_ipalib/test_frontend.py @@ -21,8 +21,8 @@ Test the `ipalib.frontend` module. """ -from tests.util import raises, getitem, no_set, no_del, read_only, ClassChecker -from tests.util import check_TypeError +from tests.util import raises, getitem, no_set, no_del, read_only +from tests.util import check_TypeError, ClassChecker from ipalib import frontend, backend, plugable, errors, ipa_types, config @@ -32,7 +32,7 @@ def test_RULE_FLAG(): def test_rule(): """ - Tests the `frontend.rule` function. + Test the `ipalib.frontend.rule` function. """ flag = frontend.RULE_FLAG rule = frontend.rule @@ -49,7 +49,7 @@ def test_rule(): def test_is_rule(): """ - Tests the `frontend.is_rule` function. + Test the `ipalib.frontend.is_rule` function. """ is_rule = frontend.is_rule flag = frontend.RULE_FLAG @@ -72,16 +72,19 @@ def test_is_rule(): class test_DefaultFrom(ClassChecker): """ - Tests the `frontend.DefaultFrom` class. + 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): """ - Tests the `frontend.DefaultFrom.__init__` method. + Test the `ipalib.frontend.DefaultFrom.__init__` method. """ def callback(*args): return args @@ -95,7 +98,7 @@ class test_DefaultFrom(ClassChecker): def test_call(self): """ - Tests the `frontend.DefaultFrom.__call__` method. + Test the `ipalib.frontend.DefaultFrom.__call__` method. """ def callback(givenname, sn): return givenname[0] + sn[0] @@ -120,7 +123,7 @@ class test_DefaultFrom(ClassChecker): def test_parse_param_spec(): """ - Test the `frontend.parse_param_spec` function. + Test the `ipalib.frontend.parse_param_spec` function. """ f = frontend.parse_param_spec @@ -132,16 +135,19 @@ def test_parse_param_spec(): class test_Param(ClassChecker): """ - Test the `frontend.Param` class. + 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 `frontend.Param.__init__` method. + Test the `ipalib.frontend.Param.__init__` method. """ name = 'sn' o = self.cls(name) @@ -207,7 +213,7 @@ class test_Param(ClassChecker): def test_clone(self): """ - Test the `frontend.Param.__clone__` method. + Test the `ipalib.frontend.Param.__clone__` method. """ def compare(o, kw): for (k, v) in kw.iteritems(): @@ -234,7 +240,7 @@ class test_Param(ClassChecker): def test_convert(self): """ - Test the `frontend.Param.convert` method. + Test the `ipalib.frontend.Param.convert` method. """ name = 'some_number' type_ = ipa_types.Int() @@ -279,7 +285,7 @@ class test_Param(ClassChecker): def test_normalize(self): """ - Test the `frontend.Param.normalize` method. + Test the `ipalib.frontend.Param.normalize` method. """ name = 'sn' callback = lambda value: value.lower() @@ -321,7 +327,7 @@ class test_Param(ClassChecker): def test_validate(self): """ - Tests the `frontend.Param.validate` method. + Test the `ipalib.frontend.Param.validate` method. """ name = 'sn' type_ = ipa_types.Unicode() @@ -367,7 +373,7 @@ class test_Param(ClassChecker): def test_get_default(self): """ - Tests the `frontend.Param.get_default` method. + Test the `ipalib.frontend.Param.get_default` method. """ name = 'greeting' default = u'Hello, world!' @@ -400,7 +406,7 @@ class test_Param(ClassChecker): def test_get_value(self): """ - Tests the `frontend.Param.get_values` method. + Test the `ipalib.frontend.Param.get_values` method. """ name = 'status' values = (u'Active', u'Inactive') @@ -412,7 +418,7 @@ class test_Param(ClassChecker): def test_create_param(): """ - Test the `frontend.create_param` function. + Test the `ipalib.frontend.create_param` function. """ f = frontend.create_param for name in ['arg', 'arg?', 'arg*', 'arg+']: @@ -437,11 +443,15 @@ def test_create_param(): class test_Command(ClassChecker): """ - Tests the `frontend.Command` class. + Test the `ipalib.frontend.Command` class. """ + _cls = frontend.Command def get_subcls(self): + """ + Return a standard subclass of `ipalib.frontend.Command`. + """ class Rule(object): def __init__(self, name): self.name = name @@ -484,13 +494,16 @@ class test_Command(ClassChecker): return o def test_class(self): + """ + Test the `ipalib.frontend.Command` class. + """ assert self.cls.__bases__ == (plugable.Plugin,) assert self.cls.takes_options == tuple() assert self.cls.takes_args == tuple() def test_get_args(self): """ - Tests the `frontend.Command.get_args` method. + Test the `ipalib.frontend.Command.get_args` method. """ assert list(self.cls().get_args()) == [] args = ('login', 'stuff') @@ -499,7 +512,7 @@ class test_Command(ClassChecker): def test_get_options(self): """ - Tests the `frontend.Command.get_options` method. + Test the `ipalib.frontend.Command.get_options` method. """ assert list(self.cls().get_options()) == [] options = ('verbose', 'debug') @@ -508,7 +521,7 @@ class test_Command(ClassChecker): def test_args(self): """ - Tests the ``Command.args`` instance attribute. + Test the ``ipalib.frontend.Command.args`` instance attribute. """ assert 'args' in self.cls.__public__ # Public assert self.cls().args is None @@ -543,7 +556,7 @@ class test_Command(ClassChecker): def test_max_args(self): """ - Test the ``Command.max_args`` instance attribute. + Test the ``ipalib.frontend.Command.max_args`` instance attribute. """ o = self.get_instance() assert o.max_args == 0 @@ -558,7 +571,7 @@ class test_Command(ClassChecker): def test_options(self): """ - Tests the ``Command.options`` instance attribute. + Test the ``ipalib.frontend.Command.options`` instance attribute. """ assert 'options' in self.cls.__public__ # Public assert self.cls().options is None @@ -580,7 +593,7 @@ class test_Command(ClassChecker): def test_convert(self): """ - Tests the `frontend.Command.convert` method. + Test the `ipalib.frontend.Command.convert` method. """ assert 'convert' in self.cls.__public__ # Public kw = dict( @@ -598,7 +611,7 @@ class test_Command(ClassChecker): def test_normalize(self): """ - Tests the `frontend.Command.normalize` method. + Test the `ipalib.frontend.Command.normalize` method. """ assert 'normalize' in self.cls.__public__ # Public kw = dict( @@ -612,7 +625,7 @@ class test_Command(ClassChecker): def test_get_default(self): """ - Tests the `frontend.Command.get_default` method. + Test the `ipalib.frontend.Command.get_default` method. """ assert 'get_default' in self.cls.__public__ # Public no_fill = dict( @@ -634,7 +647,7 @@ class test_Command(ClassChecker): def test_validate(self): """ - Tests the `frontend.Command.validate` method. + Test the `ipalib.frontend.Command.validate` method. """ assert 'validate' in self.cls.__public__ # Public @@ -669,13 +682,13 @@ class test_Command(ClassChecker): def test_execute(self): """ - Tests the `frontend.Command.execute` method. + Test the `ipalib.frontend.Command.execute` method. """ assert 'execute' in self.cls.__public__ # Public def test_args_to_kw(self): """ - Test the `frontend.Command.args_to_kw` method. + Test the `ipalib.frontend.Command.args_to_kw` method. """ assert 'args_to_kw' in self.cls.__public__ # Public o = self.get_instance(args=('one', 'two?')) @@ -706,7 +719,7 @@ class test_Command(ClassChecker): def test_kw_to_args(self): """ - Tests the `frontend.Command.kw_to_args` method. + Test the `ipalib.frontend.Command.kw_to_args` method. """ assert 'kw_to_args' in self.cls.__public__ # Public o = self.get_instance(args=('one', 'two?')) @@ -719,7 +732,7 @@ class test_Command(ClassChecker): def test_run(self): """ - Test the `frontend.Command.run` method. + Test the `ipalib.frontend.Command.run` method. """ class my_cmd(self.cls): def execute(self, *args, **kw): @@ -754,11 +767,14 @@ class test_Command(ClassChecker): class test_Object(ClassChecker): """ - Test the `frontend.Object` class. + Test the `ipalib.frontend.Object` class. """ _cls = frontend.Object def test_class(self): + """ + Test the `ipalib.frontend.Object` class. + """ assert self.cls.__bases__ == (plugable.Plugin,) assert self.cls.backend is None assert self.cls.methods is None @@ -769,7 +785,7 @@ class test_Object(ClassChecker): def test_init(self): """ - Test the `frontend.Object.__init__` method. + Test the `ipalib.frontend.Object.__init__` method. """ o = self.cls() assert o.backend is None @@ -781,7 +797,7 @@ class test_Object(ClassChecker): def test_set_api(self): """ - Test the `frontend.Object.set_api` method. + Test the `ipalib.frontend.Object.set_api` method. """ # Setup for test: class DummyAttribute(object): @@ -867,7 +883,7 @@ class test_Object(ClassChecker): def test_primary_key(self): """ - Test the `frontend.Object.primary_key` attribute. + Test the `ipalib.frontend.Object.primary_key` attribute. """ api = plugable.API( frontend.Method, @@ -922,7 +938,7 @@ class test_Object(ClassChecker): def test_backend(self): """ - Test the `frontend.Object.backend` attribute. + Test the `ipalib.frontend.Object.backend` attribute. """ api = plugable.API( frontend.Object, @@ -945,11 +961,14 @@ class test_Object(ClassChecker): class test_Attribute(ClassChecker): """ - Tests the `frontend.Attribute` class. + Test the `ipalib.frontend.Attribute` class. """ _cls = frontend.Attribute def test_class(self): + """ + Test the `ipalib.frontend.Attribute` class. + """ assert self.cls.__bases__ == (plugable.Plugin,) assert type(self.cls.obj) is property assert type(self.cls.obj_name) is property @@ -957,7 +976,7 @@ class test_Attribute(ClassChecker): def test_init(self): """ - Tests the `frontend.Attribute.__init__` method. + Test the `ipalib.frontend.Attribute.__init__` method. """ class user_add(self.cls): pass @@ -968,7 +987,7 @@ class test_Attribute(ClassChecker): def test_set_api(self): """ - Tests the `frontend.Attribute.set_api` method. + Test the `ipalib.frontend.Attribute.set_api` method. """ user_obj = 'The user frontend.Object instance' class api(object): @@ -985,18 +1004,21 @@ class test_Attribute(ClassChecker): class test_Method(ClassChecker): """ - Test the `frontend.Method` class. + Test the `ipalib.frontend.Method` class. """ _cls = frontend.Method def test_class(self): + """ + Test the `ipalib.frontend.Method` class. + """ assert self.cls.__bases__ == (frontend.Attribute, frontend.Command) assert self.cls.implements(frontend.Command) assert self.cls.implements(frontend.Attribute) def test_init(self): """ - Test the `frontend.Method.__init__` method. + Test the `ipalib.frontend.Method.__init__` method. """ class user_add(self.cls): pass @@ -1010,11 +1032,14 @@ class test_Method(ClassChecker): class test_Property(ClassChecker): """ - Tests the `frontend.Property` class. + Test the `ipalib.frontend.Property` class. """ _cls = frontend.Property def get_subcls(self): + """ + Return a standard subclass of `ipalib.frontend.Property`. + """ class user_givenname(self.cls): 'User first name' @@ -1025,6 +1050,9 @@ class test_Property(ClassChecker): return user_givenname def test_class(self): + """ + Test the `ipalib.frontend.Property` class. + """ assert self.cls.__bases__ == (frontend.Attribute,) assert isinstance(self.cls.type, ipa_types.Unicode) assert self.cls.required is False @@ -1035,7 +1063,7 @@ class test_Property(ClassChecker): def test_init(self): """ - Tests the `frontend.Property.__init__` method. + Test the `ipalib.frontend.Property.__init__` method. """ o = self.subcls() assert len(o.rules) == 1 @@ -1048,17 +1076,20 @@ class test_Property(ClassChecker): class test_Application(ClassChecker): """ - Tests the `frontend.Application` class. + Test the `ipalib.frontend.Application` class. """ _cls = frontend.Application def test_class(self): + """ + Test the `ipalib.frontend.Application` class. + """ assert self.cls.__bases__ == (frontend.Command,) assert type(self.cls.application) is property def test_application(self): """ - Tests the `frontend.Application.application` property. + Test the `ipalib.frontend.Application.application` property. """ assert 'application' in self.cls.__public__ # Public assert 'set_application' in self.cls.__public__ # Public -- cgit From 887016e69d6678892a2ff53735623ce5d413b074 Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Wed, 8 Oct 2008 18:18:13 -0600 Subject: Base Command.execute() method now raises NotImplementedError; updated unit tests --- tests/test_ipalib/test_frontend.py | 3 +++ 1 file changed, 3 insertions(+) (limited to 'tests/test_ipalib/test_frontend.py') diff --git a/tests/test_ipalib/test_frontend.py b/tests/test_ipalib/test_frontend.py index b798d2ee..89b77ad7 100644 --- a/tests/test_ipalib/test_frontend.py +++ b/tests/test_ipalib/test_frontend.py @@ -685,6 +685,9 @@ class test_Command(ClassChecker): Test the `ipalib.frontend.Command.execute` method. """ assert 'execute' in self.cls.__public__ # Public + o = self.cls() + e = raises(NotImplementedError, o.execute) + assert str(e) == 'Command.execute()' def test_args_to_kw(self): """ -- cgit From 8674086b8536f64947ca8cdb97d7a1cd3bf1c684 Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Mon, 13 Oct 2008 17:24:23 -0600 Subject: Param now takes cli_name kwarg that sets Param.cli_name attribute --- tests/test_ipalib/test_frontend.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tests/test_ipalib/test_frontend.py') diff --git a/tests/test_ipalib/test_frontend.py b/tests/test_ipalib/test_frontend.py index 89b77ad7..297aa8da 100644 --- a/tests/test_ipalib/test_frontend.py +++ b/tests/test_ipalib/test_frontend.py @@ -155,6 +155,7 @@ class test_Param(ClassChecker): # 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 @@ -167,6 +168,7 @@ class test_Param(ClassChecker): # 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 -- cgit From 446037fd60d59f671b9a402b9111ab041c1c1439 Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Mon, 13 Oct 2008 23:26:24 -0600 Subject: Added Object.get_dn() method; added corresponding unit tests --- tests/test_ipalib/test_frontend.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'tests/test_ipalib/test_frontend.py') diff --git a/tests/test_ipalib/test_frontend.py b/tests/test_ipalib/test_frontend.py index 297aa8da..9ab0504b 100644 --- a/tests/test_ipalib/test_frontend.py +++ b/tests/test_ipalib/test_frontend.py @@ -963,6 +963,20 @@ class test_Object(ClassChecker): assert isinstance(b, ldap) assert b.whatever == 'It worked!' + def test_get_dn(self): + """ + Test the `ipalib.frontend.Object.get_dn` method. + """ + assert 'get_dn' in self.cls.__public__ # Public + o = self.cls() + e = raises(NotImplementedError, o.get_dn, 'primary key') + assert str(e) == 'Object.get_dn()' + class user(self.cls): + pass + o = user() + e = raises(NotImplementedError, o.get_dn, 'primary key') + assert str(e) == 'user.get_dn()' + class test_Attribute(ClassChecker): """ -- cgit From 3a80297b04d6fbfd2367ec76c5651d20293adccc Mon Sep 17 00:00:00 2001 From: Martin Nagy Date: Fri, 17 Oct 2008 22:55:03 +0200 Subject: Reworking Environment, moved it to config.py --- tests/test_ipalib/test_frontend.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tests/test_ipalib/test_frontend.py') diff --git a/tests/test_ipalib/test_frontend.py b/tests/test_ipalib/test_frontend.py index 9ab0504b..c5742886 100644 --- a/tests/test_ipalib/test_frontend.py +++ b/tests/test_ipalib/test_frontend.py @@ -894,7 +894,7 @@ class test_Object(ClassChecker): frontend.Method, frontend.Property, ) - api.env.update(config.generate_env()) + config.set_default_env(api.env) api.finalize() # Test with no primary keys: @@ -951,7 +951,7 @@ class test_Object(ClassChecker): frontend.Property, backend.Backend, ) - api.env.update(config.generate_env()) + config.set_default_env(api.env) class ldap(backend.Backend): whatever = 'It worked!' api.register(ldap) -- cgit From 8322138f38a4f9c826e4ab148a4fee7df5e93b34 Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Fri, 17 Oct 2008 19:34:26 -0600 Subject: Added new Param.flags attribute (set with flags=foo kwarg) --- tests/test_ipalib/test_frontend.py | 3 +++ 1 file changed, 3 insertions(+) (limited to 'tests/test_ipalib/test_frontend.py') diff --git a/tests/test_ipalib/test_frontend.py b/tests/test_ipalib/test_frontend.py index c5742886..7760ffbe 100644 --- a/tests/test_ipalib/test_frontend.py +++ b/tests/test_ipalib/test_frontend.py @@ -162,6 +162,7 @@ class test_Param(ClassChecker): 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 @@ -183,6 +184,8 @@ class test_Param(ClassChecker): 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 -- cgit From bb978e591b08b3388345c848fb866c22239094ac Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Mon, 20 Oct 2008 16:45:32 -0600 Subject: Fixed bug in DefaultFrom where impleied keys were using entire func_code.co_varnames instead of an approprate slice --- tests/test_ipalib/test_frontend.py | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'tests/test_ipalib/test_frontend.py') diff --git a/tests/test_ipalib/test_frontend.py b/tests/test_ipalib/test_frontend.py index 7760ffbe..966b5e93 100644 --- a/tests/test_ipalib/test_frontend.py +++ b/tests/test_ipalib/test_frontend.py @@ -115,11 +115,21 @@ class test_DefaultFrom(ClassChecker): 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(): """ -- cgit From d76202fea37e63fbc660ed2cf2059f455b8e2213 Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Mon, 27 Oct 2008 01:35:40 -0600 Subject: API.env is now an Env instance rather than an Environment instance --- tests/test_ipalib/test_frontend.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'tests/test_ipalib/test_frontend.py') diff --git a/tests/test_ipalib/test_frontend.py b/tests/test_ipalib/test_frontend.py index 966b5e93..5a678b5b 100644 --- a/tests/test_ipalib/test_frontend.py +++ b/tests/test_ipalib/test_frontend.py @@ -764,7 +764,8 @@ class test_Command(ClassChecker): # Test in server context: api = plugable.API(self.cls) - api.env.update(dict(server_context=True)) + #api.env.update(dict(server_context=True)) + api.env.in_server = True api.finalize() o = my_cmd() o.set_api(api) @@ -774,7 +775,8 @@ class test_Command(ClassChecker): # Test in non-server context api = plugable.API(self.cls) - api.env.update(dict(server_context=False)) + #api.env.update(dict(server_context=False)) + api.env.in_server = False api.finalize() o = my_cmd() o.set_api(api) @@ -907,7 +909,7 @@ class test_Object(ClassChecker): frontend.Method, frontend.Property, ) - config.set_default_env(api.env) + #config.set_default_env(api.env) api.finalize() # Test with no primary keys: @@ -964,7 +966,7 @@ class test_Object(ClassChecker): frontend.Property, backend.Backend, ) - config.set_default_env(api.env) + #config.set_default_env(api.env) class ldap(backend.Backend): whatever = 'It worked!' api.register(ldap) -- cgit From f04aaff97c9c8c22b36706f2c6d4de6f23d06b95 Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Wed, 12 Nov 2008 09:55:11 -0700 Subject: output_for_cli signature is now output_for_cli(textui, result, *args, **options) --- tests/test_ipalib/test_frontend.py | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'tests/test_ipalib/test_frontend.py') diff --git a/tests/test_ipalib/test_frontend.py b/tests/test_ipalib/test_frontend.py index 5a678b5b..75e098a4 100644 --- a/tests/test_ipalib/test_frontend.py +++ b/tests/test_ipalib/test_frontend.py @@ -735,18 +735,17 @@ class test_Command(ClassChecker): e = raises(errors.ArgumentError, o.args_to_kw, 1, 2, 3) assert str(e) == 'example takes at most 2 arguments' - def test_kw_to_args(self): + def test_params_2_args_options(self): """ - Test the `ipalib.frontend.Command.kw_to_args` method. + Test the `ipalib.frontend.Command.params_2_args_options` method. """ - assert 'kw_to_args' in self.cls.__public__ # Public - o = self.get_instance(args=('one', 'two?')) - assert o.kw_to_args() == (None, None) - assert o.kw_to_args(whatever='hello') == (None, None) - assert o.kw_to_args(one='the one') == ('the one', None) - assert o.kw_to_args(two='the two') == (None, 'the two') - assert o.kw_to_args(whatever='hello', two='Two', one='One') == \ - ('One', 'Two') + assert 'params_2_args_options' in self.cls.__public__ # Public + o = self.get_instance(args=['one'], options=['two']) + assert o.params_2_args_options({}) == ((None,), dict(two=None)) + assert o.params_2_args_options(dict(one=1)) == ((1,), dict(two=None)) + assert o.params_2_args_options(dict(two=2)) == ((None,), dict(two=2)) + assert o.params_2_args_options(dict(two=2, one=1)) == \ + ((1,), dict(two=2)) def test_run(self): """ -- cgit From 860d391f3e905e20ba3f409c92d98e68450f3137 Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Thu, 13 Nov 2008 22:16:04 -0700 Subject: Change Param.__repr__() so it returns the exact expression that could create it; added unit test for Param.__repre__() --- tests/test_ipalib/test_frontend.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'tests/test_ipalib/test_frontend.py') diff --git a/tests/test_ipalib/test_frontend.py b/tests/test_ipalib/test_frontend.py index 75e098a4..2a8c08fe 100644 --- a/tests/test_ipalib/test_frontend.py +++ b/tests/test_ipalib/test_frontend.py @@ -430,6 +430,18 @@ class test_Param(ClassChecker): 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(): """ -- cgit From 36737c2d913716eb99aece5cc1f6a21234abe46a Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Fri, 14 Nov 2008 21:29:46 -0700 Subject: Added frontend.LocalOrRemote command base class for commands like env --- tests/test_ipalib/test_frontend.py | 56 +++++++++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) (limited to 'tests/test_ipalib/test_frontend.py') diff --git a/tests/test_ipalib/test_frontend.py b/tests/test_ipalib/test_frontend.py index 2a8c08fe..45c6bb80 100644 --- a/tests/test_ipalib/test_frontend.py +++ b/tests/test_ipalib/test_frontend.py @@ -22,7 +22,7 @@ Test the `ipalib.frontend` module. """ from tests.util import raises, getitem, no_set, no_del, read_only -from tests.util import check_TypeError, ClassChecker +from tests.util import check_TypeError, ClassChecker, get_api from ipalib import frontend, backend, plugable, errors, ipa_types, config @@ -796,6 +796,60 @@ class test_Command(ClassChecker): assert o.run.im_func is my_cmd.forward.im_func +class test_LocalOrRemote(ClassChecker): + """ + Test the `ipalib.frontend.LocalOrRemote` class. + """ + _cls = frontend.LocalOrRemote + + def test_init(self): + """ + Test the `ipalib.frontend.LocalOrRemote.__init__` method. + """ + o = self.cls() + o.finalize() + assert list(o.args) == [] + assert list(o.options) == ['server'] + op = o.options.server + assert op.required is True + assert op.default is False + + def test_run(self): + """ + Test the `ipalib.frontend.LocalOrRemote.run` method. + """ + class example(self.cls): + takes_args = ['key?'] + + def forward(self, *args, **options): + return ('forward', args, options) + + def execute(self, *args, **options): + return ('execute', args, options) + + # Test when in_server=False: + (api, home) = get_api(in_server=False) + api.register(example) + api.finalize() + cmd = api.Command.example + assert cmd() == ('execute', (None,), dict(server=False)) + assert cmd('var') == ('execute', (u'var',), dict(server=False)) + assert cmd(server=True) == ('forward', (None,), dict(server=True)) + assert cmd('var', server=True) == \ + ('forward', (u'var',), dict(server=True)) + + # Test when in_server=True (should always call execute): + (api, home) = get_api(in_server=True) + api.register(example) + api.finalize() + cmd = api.Command.example + assert cmd() == ('execute', (None,), dict(server=False)) + assert cmd('var') == ('execute', (u'var',), dict(server=False)) + assert cmd(server=True) == ('execute', (None,), dict(server=True)) + assert cmd('var', server=True) == \ + ('execute', (u'var',), dict(server=True)) + + class test_Object(ClassChecker): """ Test the `ipalib.frontend.Object` class. -- cgit From 9de56d43f054bc5e509e38bda1a048e5af6d73d7 Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Fri, 14 Nov 2008 21:58:39 -0700 Subject: env plugin now subclasses from RemoteOrLocal --- tests/test_ipalib/test_frontend.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'tests/test_ipalib/test_frontend.py') diff --git a/tests/test_ipalib/test_frontend.py b/tests/test_ipalib/test_frontend.py index 45c6bb80..771fdb91 100644 --- a/tests/test_ipalib/test_frontend.py +++ b/tests/test_ipalib/test_frontend.py @@ -811,7 +811,7 @@ class test_LocalOrRemote(ClassChecker): assert list(o.args) == [] assert list(o.options) == ['server'] op = o.options.server - assert op.required is True + assert op.required is False assert op.default is False def test_run(self): @@ -832,8 +832,8 @@ class test_LocalOrRemote(ClassChecker): api.register(example) api.finalize() cmd = api.Command.example - assert cmd() == ('execute', (None,), dict(server=False)) - assert cmd('var') == ('execute', (u'var',), dict(server=False)) + assert cmd() == ('execute', (None,), dict(server=None)) + assert cmd('var') == ('execute', (u'var',), dict(server=None)) assert cmd(server=True) == ('forward', (None,), dict(server=True)) assert cmd('var', server=True) == \ ('forward', (u'var',), dict(server=True)) @@ -843,8 +843,8 @@ class test_LocalOrRemote(ClassChecker): api.register(example) api.finalize() cmd = api.Command.example - assert cmd() == ('execute', (None,), dict(server=False)) - assert cmd('var') == ('execute', (u'var',), dict(server=False)) + assert cmd() == ('execute', (None,), dict(server=None)) + assert cmd('var') == ('execute', (u'var',), dict(server=None)) assert cmd(server=True) == ('execute', (None,), dict(server=True)) assert cmd('var', server=True) == \ ('execute', (u'var',), dict(server=True)) -- cgit From 8474bd01da13b9b72ba06e832d4c35ef6ccf5c9e Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Mon, 17 Nov 2008 18:50:30 -0700 Subject: Command.get_defaults() now returns param.default if param.type is a Bool --- tests/test_ipalib/test_frontend.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'tests/test_ipalib/test_frontend.py') diff --git a/tests/test_ipalib/test_frontend.py b/tests/test_ipalib/test_frontend.py index 771fdb91..44d8e54c 100644 --- a/tests/test_ipalib/test_frontend.py +++ b/tests/test_ipalib/test_frontend.py @@ -832,8 +832,8 @@ class test_LocalOrRemote(ClassChecker): api.register(example) api.finalize() cmd = api.Command.example - assert cmd() == ('execute', (None,), dict(server=None)) - assert cmd('var') == ('execute', (u'var',), dict(server=None)) + assert cmd() == ('execute', (None,), dict(server=False)) + assert cmd('var') == ('execute', (u'var',), dict(server=False)) assert cmd(server=True) == ('forward', (None,), dict(server=True)) assert cmd('var', server=True) == \ ('forward', (u'var',), dict(server=True)) @@ -843,8 +843,8 @@ class test_LocalOrRemote(ClassChecker): api.register(example) api.finalize() cmd = api.Command.example - assert cmd() == ('execute', (None,), dict(server=None)) - assert cmd('var') == ('execute', (u'var',), dict(server=None)) + assert cmd() == ('execute', (None,), dict(server=False)) + assert cmd('var') == ('execute', (u'var',), dict(server=False)) assert cmd(server=True) == ('execute', (None,), dict(server=True)) assert cmd('var', server=True) == \ ('execute', (u'var',), dict(server=True)) -- cgit From 500b8166811e39ac63bdbaee8dcf01eb0643d868 Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Tue, 18 Nov 2008 16:29:08 -0700 Subject: Added unit test for Param.ispassword() method --- tests/test_ipalib/test_frontend.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'tests/test_ipalib/test_frontend.py') diff --git a/tests/test_ipalib/test_frontend.py b/tests/test_ipalib/test_frontend.py index 44d8e54c..87296705 100644 --- a/tests/test_ipalib/test_frontend.py +++ b/tests/test_ipalib/test_frontend.py @@ -226,6 +226,22 @@ class test_Param(ClassChecker): 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. -- cgit From 7e21ea5ad826e65da10d7a12917fd4d0d4f1874e Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Mon, 8 Dec 2008 16:56:24 -0700 Subject: Fixed Warning messages about log dir in unit test --- tests/test_ipalib/test_frontend.py | 28 +++++++--------------------- 1 file changed, 7 insertions(+), 21 deletions(-) (limited to 'tests/test_ipalib/test_frontend.py') diff --git a/tests/test_ipalib/test_frontend.py b/tests/test_ipalib/test_frontend.py index 87296705..94e586fe 100644 --- a/tests/test_ipalib/test_frontend.py +++ b/tests/test_ipalib/test_frontend.py @@ -22,7 +22,7 @@ Test the `ipalib.frontend` module. """ from tests.util import raises, getitem, no_set, no_del, read_only -from tests.util import check_TypeError, ClassChecker, get_api +from tests.util import check_TypeError, ClassChecker, create_test_api from ipalib import frontend, backend, plugable, errors, ipa_types, config @@ -790,9 +790,7 @@ class test_Command(ClassChecker): kw = dict(how_are='you', on_this='fine day?') # Test in server context: - api = plugable.API(self.cls) - #api.env.update(dict(server_context=True)) - api.env.in_server = True + (api, home) = create_test_api(in_server=True) api.finalize() o = my_cmd() o.set_api(api) @@ -801,9 +799,7 @@ class test_Command(ClassChecker): assert o.run.im_func is my_cmd.execute.im_func # Test in non-server context - api = plugable.API(self.cls) - #api.env.update(dict(server_context=False)) - api.env.in_server = False + (api, home) = create_test_api(in_server=False) api.finalize() o = my_cmd() o.set_api(api) @@ -844,7 +840,7 @@ class test_LocalOrRemote(ClassChecker): return ('execute', args, options) # Test when in_server=False: - (api, home) = get_api(in_server=False) + (api, home) = create_test_api(in_server=False) api.register(example) api.finalize() cmd = api.Command.example @@ -855,7 +851,7 @@ class test_LocalOrRemote(ClassChecker): ('forward', (u'var',), dict(server=True)) # Test when in_server=True (should always call execute): - (api, home) = get_api(in_server=True) + (api, home) = create_test_api(in_server=True) api.register(example) api.finalize() cmd = api.Command.example @@ -986,11 +982,7 @@ class test_Object(ClassChecker): """ Test the `ipalib.frontend.Object.primary_key` attribute. """ - api = plugable.API( - frontend.Method, - frontend.Property, - ) - #config.set_default_env(api.env) + (api, home) = create_test_api() api.finalize() # Test with no primary keys: @@ -1041,13 +1033,7 @@ class test_Object(ClassChecker): """ Test the `ipalib.frontend.Object.backend` attribute. """ - api = plugable.API( - frontend.Object, - frontend.Method, - frontend.Property, - backend.Backend, - ) - #config.set_default_env(api.env) + (api, home) = create_test_api() class ldap(backend.Backend): whatever = 'It worked!' api.register(ldap) -- cgit From 2b2e73e7df90d38175e035d6ada4d752120dc0ec Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Wed, 14 Jan 2009 11:39:29 -0700 Subject: Removed depreciated code from frontend.py; frontend.py no longer imports ipa_types --- tests/test_ipalib/test_frontend.py | 414 ------------------------------------- 1 file changed, 414 deletions(-) (limited to 'tests/test_ipalib/test_frontend.py') diff --git a/tests/test_ipalib/test_frontend.py b/tests/test_ipalib/test_frontend.py index 94e586fe..c4093317 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. -- cgit From 69acff450c043bdd7d70da473c3adafdd9d3fe03 Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Wed, 14 Jan 2009 12:00:47 -0700 Subject: New Param: removed more depreciated 'import ipa_types' --- tests/test_ipalib/test_frontend.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests/test_ipalib/test_frontend.py') diff --git a/tests/test_ipalib/test_frontend.py b/tests/test_ipalib/test_frontend.py index c4093317..4a0e48d0 100644 --- a/tests/test_ipalib/test_frontend.py +++ b/tests/test_ipalib/test_frontend.py @@ -23,7 +23,7 @@ Test the `ipalib.frontend` module. from tests.util import raises, getitem, no_set, no_del, read_only from tests.util import check_TypeError, ClassChecker, create_test_api -from ipalib import frontend, backend, plugable, errors, ipa_types, config +from ipalib import frontend, backend, plugable, errors, parameters, config def test_RULE_FLAG(): -- cgit From 09e2f5d615a17943ba572fd02a2e0d9b15ca1076 Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Wed, 14 Jan 2009 13:17:30 -0700 Subject: New Param: got most of unit tests ported (still have 6 errors); haven't ported doctests yet --- tests/test_ipalib/test_frontend.py | 76 +++++++++++++------------------------- 1 file changed, 26 insertions(+), 50 deletions(-) (limited to 'tests/test_ipalib/test_frontend.py') diff --git a/tests/test_ipalib/test_frontend.py b/tests/test_ipalib/test_frontend.py index 4a0e48d0..6b3e0f71 100644 --- a/tests/test_ipalib/test_frontend.py +++ b/tests/test_ipalib/test_frontend.py @@ -23,6 +23,7 @@ Test the `ipalib.frontend` module. from tests.util import raises, getitem, no_set, no_del, read_only from tests.util import check_TypeError, ClassChecker, create_test_api +from ipalib.constants import TYPE_ERROR from ipalib import frontend, backend, plugable, errors, parameters, config @@ -89,24 +90,21 @@ class test_Command(ClassChecker): if value != self.name: return 'must equal %s' % self.name - default_from = frontend.DefaultFrom( + default_from = parameters.DefaultFrom( lambda arg: arg, 'default_from' ) - normalize = lambda value: value.lower() + normalizer = lambda value: value.lower() class example(self.cls): takes_options = ( - frontend.Param('option0', - normalize=normalize, + frontend.Param('option0', Rule('option0'), + normalizer=normalizer, default_from=default_from, - rules=(Rule('option0'),) ), - frontend.Param('option1', - normalize=normalize, + frontend.Param('option1', Rule('option1'), + normalizer=normalizer, default_from=default_from, - rules=(Rule('option1'),), - required=True, ), ) return example @@ -163,8 +161,8 @@ class test_Command(ClassChecker): assert type(ns) is plugable.NameSpace assert len(ns) == len(args) assert list(ns) == ['destination', 'source'] - assert type(ns.destination) is frontend.Param - assert type(ns.source) is frontend.Param + assert type(ns.destination) is parameters.Str + assert type(ns.source) is parameters.Str assert ns.destination.required is True assert ns.destination.multivalue is False assert ns.source.required is False @@ -172,8 +170,8 @@ class test_Command(ClassChecker): # Test TypeError: e = raises(TypeError, self.get_instance, args=(u'whatever',)) - assert str(e) == \ - 'create_param() takes %r or %r; got %r' % (str, frontend.Param, u'whatever') + assert str(e) == TYPE_ERROR % ( + 'spec', (str, parameters.Param), u'whatever', unicode) # Test ValueError, required after optional: e = raises(ValueError, self.get_instance, args=('arg1?', 'arg2')) @@ -213,8 +211,8 @@ class test_Command(ClassChecker): assert type(ns) is plugable.NameSpace assert len(ns) == len(options) assert list(ns) == ['target', 'files'] - assert type(ns.target) is frontend.Param - assert type(ns.files) is frontend.Param + assert type(ns.target) is parameters.Str + assert type(ns.files) is parameters.Str assert ns.target.required is True assert ns.target.multivalue is False assert ns.files.required is False @@ -257,22 +255,7 @@ class test_Command(ClassChecker): Test the `ipalib.frontend.Command.get_default` method. """ assert 'get_default' in self.cls.__public__ # Public - no_fill = dict( - option0='value0', - option1='value1', - whatever='hello world', - ) - fill = dict( - default_from='the default', - ) - default = dict( - option0='the default', - option1='the default', - ) - sub = self.subcls() - sub.finalize() - assert sub.get_default(**no_fill) == {} - assert sub.get_default(**fill) == default + # FIXME: Add an updated unit tests for get_default() def test_validate(self): """ @@ -431,9 +414,9 @@ class test_LocalOrRemote(ClassChecker): api.finalize() cmd = api.Command.example assert cmd() == ('execute', (None,), dict(server=False)) - assert cmd('var') == ('execute', (u'var',), dict(server=False)) + assert cmd(u'var') == ('execute', (u'var',), dict(server=False)) assert cmd(server=True) == ('forward', (None,), dict(server=True)) - assert cmd('var', server=True) == \ + assert cmd(u'var', server=True) == \ ('forward', (u'var',), dict(server=True)) # Test when in_server=True (should always call execute): @@ -442,9 +425,9 @@ class test_LocalOrRemote(ClassChecker): api.finalize() cmd = api.Command.example assert cmd() == ('execute', (None,), dict(server=False)) - assert cmd('var') == ('execute', (u'var',), dict(server=False)) + assert cmd(u'var') == ('execute', (u'var',), dict(server=False)) assert cmd(server=True) == ('execute', (None,), dict(server=True)) - assert cmd('var', server=True) == \ + assert cmd(u'var', server=True) == \ ('execute', (u'var',), dict(server=True)) @@ -560,7 +543,7 @@ class test_Object(ClassChecker): assert len(ns) == 2, repr(ns) assert list(ns) == ['banana', 'apple'] for p in ns(): - assert type(p) is frontend.Param + assert type(p) is parameters.Str assert p.required is True assert p.multivalue is False @@ -587,15 +570,13 @@ class test_Object(ClassChecker): takes_params = ( 'one', 'two', - frontend.Param('three', - primary_key=True, - ), + parameters.Str('three', primary_key=True), 'four', ) o = example2() o.set_api(api) pk = o.primary_key - assert isinstance(pk, frontend.Param) + assert type(pk) is parameters.Str assert pk.name == 'three' assert pk.primary_key is True assert o.params[2] is o.primary_key @@ -605,10 +586,10 @@ class test_Object(ClassChecker): # Test with multiple primary_key: class example3(self.cls): takes_params = ( - frontend.Param('one', primary_key=True), - frontend.Param('two', primary_key=True), + parameters.Str('one', primary_key=True), + parameters.Str('two', primary_key=True), 'three', - frontend.Param('four', primary_key=True), + parameters.Str('four', primary_key=True), ) o = example3() e = raises(ValueError, o.set_api, api) @@ -741,12 +722,7 @@ class test_Property(ClassChecker): Test the `ipalib.frontend.Property` class. """ assert self.cls.__bases__ == (frontend.Attribute,) - assert isinstance(self.cls.type, ipa_types.Unicode) - assert self.cls.required is False - assert self.cls.multivalue is False - assert self.cls.default is None - assert self.cls.default_from is None - assert self.cls.normalize is None + assert self.cls.klass is parameters.Str def test_init(self): """ @@ -756,7 +732,7 @@ class test_Property(ClassChecker): assert len(o.rules) == 1 assert o.rules[0].__name__ == 'rule0_lowercase' param = o.param - assert isinstance(param, frontend.Param) + assert isinstance(param, parameters.Str) assert param.name == 'givenname' assert param.doc == 'User first name' -- cgit From 79422d048959a7f6a5fff981caf91de924788e85 Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Wed, 14 Jan 2009 13:51:37 -0700 Subject: All unit tests now working (except for doctests and Rob's xmlrpc tests) --- tests/test_ipalib/test_frontend.py | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) (limited to 'tests/test_ipalib/test_frontend.py') diff --git a/tests/test_ipalib/test_frontend.py b/tests/test_ipalib/test_frontend.py index 6b3e0f71..071a70fd 100644 --- a/tests/test_ipalib/test_frontend.py +++ b/tests/test_ipalib/test_frontend.py @@ -23,8 +23,9 @@ Test the `ipalib.frontend` module. from tests.util import raises, getitem, no_set, no_del, read_only from tests.util import check_TypeError, ClassChecker, create_test_api +from tests.util import assert_equal from ipalib.constants import TYPE_ERROR -from ipalib import frontend, backend, plugable, errors, parameters, config +from ipalib import frontend, backend, plugable, errors2, errors, parameters, config def test_RULE_FLAG(): @@ -86,9 +87,9 @@ class test_Command(ClassChecker): def __init__(self, name): self.name = name - def __call__(self, value): + def __call__(self, _, value): if value != self.name: - return 'must equal %s' % self.name + return _('must equal %r') % self.name default_from = parameters.DefaultFrom( lambda arg: arg, @@ -98,11 +99,11 @@ class test_Command(ClassChecker): class example(self.cls): takes_options = ( - frontend.Param('option0', Rule('option0'), + parameters.Str('option0', Rule('option0'), normalizer=normalizer, default_from=default_from, ), - frontend.Param('option1', Rule('option1'), + parameters.Str('option1', Rule('option1'), normalizer=normalizer, default_from=default_from, ), @@ -224,17 +225,13 @@ class test_Command(ClassChecker): """ assert 'convert' in self.cls.__public__ # Public kw = dict( - option0='option0', - option1='option1', + option0=u'1.5', + option1=u'7', ) - expected = dict(kw) - expected.update(dict(option0=u'option0', option1=u'option1')) o = self.subcls() o.finalize() for (key, value) in o.convert(**kw).iteritems(): - v = expected[key] - assert value == v - assert type(value) is type(v) + assert_equal(unicode(kw[key]), value) def test_normalize(self): """ @@ -266,7 +263,7 @@ class test_Command(ClassChecker): sub = self.subcls() sub.finalize() - # Check with valid args + # Check with valid values okay = dict( option0=u'option0', option1=u'option1', @@ -274,13 +271,13 @@ class test_Command(ClassChecker): ) sub.validate(**okay) - # Check with an invalid arg + # Check with an invalid value fail = dict(okay) fail['option0'] = u'whatever' - e = raises(errors.RuleError, sub.validate, **fail) - assert e.name == 'option0' - assert e.value == u'whatever' - assert e.error == 'must equal option0' + e = raises(errors2.ValidationError, sub.validate, **fail) + assert_equal(e.name, 'option0') + assert_equal(e.value, u'whatever') + assert_equal(e.error, u"must equal 'option0'") assert e.rule.__class__.__name__ == 'Rule' assert e.index is None -- cgit