mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
Moved ipalib/tests/ into tests/test_ipalib/
This commit is contained in:
@@ -1,22 +0,0 @@
|
||||
# Authors:
|
||||
# Jason Gerard DeRose <jderose@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2008 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; version 2 only
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
"""
|
||||
Unit tests for `ipalib` package.
|
||||
"""
|
||||
@@ -1,37 +0,0 @@
|
||||
# Authors:
|
||||
# Jason Gerard DeRose <jderose@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2008 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; version 2 only
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
"""
|
||||
Unit tests for `ipalib.backend` module.
|
||||
"""
|
||||
|
||||
from ipalib import backend, plugable, errors
|
||||
from tstutil import ClassChecker
|
||||
|
||||
|
||||
class test_Backend(ClassChecker):
|
||||
"""
|
||||
Test the `backend.Backend` class.
|
||||
"""
|
||||
|
||||
_cls = backend.Backend
|
||||
|
||||
def test_class(self):
|
||||
assert self.cls.__bases__ == (plugable.Plugin,)
|
||||
assert self.cls.__proxy__ is False
|
||||
@@ -1,138 +0,0 @@
|
||||
# Authors:
|
||||
# Jason Gerard DeRose <jderose@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2008 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; version 2 only
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
"""
|
||||
Unit tests for `ipalib.cli` module.
|
||||
"""
|
||||
|
||||
from tstutil import raises, getitem, no_set, no_del, read_only, ClassChecker
|
||||
from ipalib import cli, plugable
|
||||
|
||||
|
||||
def test_to_cli():
|
||||
"""
|
||||
Tests the `cli.to_cli` function.
|
||||
"""
|
||||
f = cli.to_cli
|
||||
assert f('initialize') == 'initialize'
|
||||
assert f('user_add') == 'user-add'
|
||||
|
||||
|
||||
def test_from_cli():
|
||||
"""
|
||||
Tests the `cli.from_cli` function.
|
||||
"""
|
||||
f = cli.from_cli
|
||||
assert f('initialize') == 'initialize'
|
||||
assert f('user-add') == 'user_add'
|
||||
|
||||
|
||||
def get_cmd_name(i):
|
||||
return 'cmd_%d' % i
|
||||
|
||||
class DummyCommand(object):
|
||||
def __init__(self, name):
|
||||
self.__name = name
|
||||
|
||||
def __get_name(self):
|
||||
return self.__name
|
||||
name = property(__get_name)
|
||||
|
||||
class DummyAPI(object):
|
||||
def __init__(self, cnt):
|
||||
self.__cmd = plugable.NameSpace(self.__cmd_iter(cnt))
|
||||
|
||||
def __get_cmd(self):
|
||||
return self.__cmd
|
||||
Command = property(__get_cmd)
|
||||
|
||||
def __cmd_iter(self, cnt):
|
||||
for i in xrange(cnt):
|
||||
yield DummyCommand(get_cmd_name(i))
|
||||
|
||||
def finalize(self):
|
||||
pass
|
||||
|
||||
def register(self, *args, **kw):
|
||||
pass
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class test_CLI(ClassChecker):
|
||||
"""
|
||||
Tests the `cli.CLI` class.
|
||||
"""
|
||||
_cls = cli.CLI
|
||||
|
||||
def test_class(self):
|
||||
assert type(self.cls.api) is property
|
||||
|
||||
def test_api(self):
|
||||
"""
|
||||
Tests the `cli.CLI.api` property.
|
||||
"""
|
||||
api = 'the plugable.API instance'
|
||||
o = self.cls(api)
|
||||
assert read_only(o, 'api') is api
|
||||
|
||||
def dont_parse(self):
|
||||
"""
|
||||
Tests the `cli.CLI.parse` method.
|
||||
"""
|
||||
o = self.cls(None)
|
||||
args = ['hello', 'naughty', 'nurse']
|
||||
kw = dict(
|
||||
first_name='Naughty',
|
||||
last_name='Nurse',
|
||||
)
|
||||
opts = ['--%s=%s' % (k.replace('_', '-'), v) for (k, v) in kw.items()]
|
||||
assert o.parse(args + []) == (args, {})
|
||||
assert o.parse(opts + []) == ([], kw)
|
||||
assert o.parse(args + opts) == (args, kw)
|
||||
assert o.parse(opts + args) == (args, kw)
|
||||
|
||||
def test_mcl(self):
|
||||
"""
|
||||
Tests the `cli.CLI.mcl` (Max Command Length) property .
|
||||
"""
|
||||
cnt = 100
|
||||
api = DummyAPI(cnt)
|
||||
len(api.Command) == cnt
|
||||
o = self.cls(api)
|
||||
assert o.mcl is None
|
||||
o.build_map()
|
||||
assert o.mcl == 6 # len('cmd_99')
|
||||
|
||||
def test_dict(self):
|
||||
"""
|
||||
Tests the `cli.CLI.__contains__` and `cli.CLI.__getitem__` methods.
|
||||
"""
|
||||
cnt = 25
|
||||
api = DummyAPI(cnt)
|
||||
assert len(api.Command) == cnt
|
||||
o = self.cls(api)
|
||||
o.build_map()
|
||||
for cmd in api.Command():
|
||||
key = cli.to_cli(cmd.name)
|
||||
assert key in o
|
||||
assert o[key] is cmd
|
||||
assert cmd.name not in o
|
||||
raises(KeyError, getitem, o, cmd.name)
|
||||
@@ -1,101 +0,0 @@
|
||||
# Authors:
|
||||
# Martin Nagy <mnagy@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2008 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; version 2 only
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
"""
|
||||
Unit tests for `ipalib.config` module.
|
||||
"""
|
||||
|
||||
import types
|
||||
|
||||
from tstutil import raises
|
||||
from ipalib import config
|
||||
|
||||
|
||||
def test_generate_env():
|
||||
"""
|
||||
Test the `config.generate_env` function
|
||||
"""
|
||||
|
||||
# Make sure we don't overwrite any properties
|
||||
env = dict(
|
||||
query_dns = False,
|
||||
server = ('first', 'second'),
|
||||
realm = 'myrealm',
|
||||
)
|
||||
d = config.generate_env(env)
|
||||
assert d['query_dns'] == False
|
||||
|
||||
# Make sure the servers is overwrote properly (that it is still LazyProp)
|
||||
iter = d['server'].get_value()
|
||||
assert iter.next() == 'first'
|
||||
assert iter.next() == 'second'
|
||||
|
||||
|
||||
def test_LazyProp():
|
||||
"""
|
||||
Test the `config.LazyProp` class
|
||||
"""
|
||||
|
||||
def dummy():
|
||||
return 1
|
||||
|
||||
# Basic sanity testing with no initial value
|
||||
prop = config.LazyProp(dummy)
|
||||
assert prop.get_value() == 1
|
||||
prop.set_value(2)
|
||||
assert prop.get_value() == 2
|
||||
|
||||
# Basic sanity testing with initial value
|
||||
prop = config.LazyProp(dummy, 3)
|
||||
assert prop.get_value() == 3
|
||||
prop.set_value(4)
|
||||
assert prop.get_value() == 4
|
||||
|
||||
|
||||
def test_LazyIter():
|
||||
"""
|
||||
Test the `config.LazyIter` class
|
||||
"""
|
||||
|
||||
def dummy():
|
||||
yield 1
|
||||
yield 2
|
||||
|
||||
# Basic sanity testing with no initial value
|
||||
prop = config.LazyIter(dummy)
|
||||
iter = prop.get_value()
|
||||
assert iter.next() == 1
|
||||
assert iter.next() == 2
|
||||
raises(StopIteration, iter.next)
|
||||
|
||||
# Basic sanity testing with initial value
|
||||
prop = config.LazyIter(dummy, 0)
|
||||
iter = prop.get_value()
|
||||
assert iter.next() == 0
|
||||
assert iter.next() == 1
|
||||
assert iter.next() == 2
|
||||
raises(StopIteration, iter.next)
|
||||
|
||||
|
||||
def test_read_config():
|
||||
"""
|
||||
Test the `config.read_config` class
|
||||
"""
|
||||
|
||||
raises(AssertionError, config.read_config, 1)
|
||||
@@ -1,168 +0,0 @@
|
||||
# Authors:
|
||||
# Jason Gerard DeRose <jderose@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2008 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; version 2 only
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
"""
|
||||
Unit tests for `ipalib.crud` module.
|
||||
"""
|
||||
|
||||
from tstutil import read_only, raises, ClassChecker
|
||||
from ipalib import crud, frontend, plugable, config
|
||||
|
||||
def get_api():
|
||||
api = plugable.API(
|
||||
frontend.Object,
|
||||
frontend.Method,
|
||||
frontend.Property,
|
||||
)
|
||||
api.env.update(config.generate_env())
|
||||
class user(frontend.Object):
|
||||
takes_params = (
|
||||
'givenname',
|
||||
'sn',
|
||||
frontend.Param('uid', primary_key=True),
|
||||
'initials',
|
||||
)
|
||||
api.register(user)
|
||||
return api
|
||||
|
||||
|
||||
class test_Add(ClassChecker):
|
||||
"""
|
||||
Test the `crud.Add` class.
|
||||
"""
|
||||
|
||||
_cls = crud.Add
|
||||
|
||||
def test_class(self):
|
||||
assert self.cls.__bases__ == (frontend.Method,)
|
||||
|
||||
def test_options_args(self):
|
||||
"""
|
||||
Test `crud.Add.get_args` and `crud.Add.get_options` methods.
|
||||
"""
|
||||
api = get_api()
|
||||
class user_add(self.cls):
|
||||
pass
|
||||
api.register(user_add)
|
||||
api.finalize()
|
||||
assert list(api.Method.user_add.args) == ['uid']
|
||||
assert list(api.Method.user_add.options) == \
|
||||
['givenname', 'sn', 'initials']
|
||||
for param in api.Method.user_add.options():
|
||||
assert param.required is True
|
||||
|
||||
|
||||
class test_Get(ClassChecker):
|
||||
"""
|
||||
Test the `crud.Get` class.
|
||||
"""
|
||||
|
||||
_cls = crud.Get
|
||||
|
||||
def test_class(self):
|
||||
assert self.cls.__bases__ == (frontend.Method,)
|
||||
|
||||
def test_options_args(self):
|
||||
"""
|
||||
Test `crud.Get.get_args` and `crud.Get.get_options` methods.
|
||||
"""
|
||||
api = get_api()
|
||||
class user_get(self.cls):
|
||||
pass
|
||||
api.register(user_get)
|
||||
api.finalize()
|
||||
assert list(api.Method.user_get.args) == ['uid']
|
||||
assert list(api.Method.user_get.options) == []
|
||||
|
||||
|
||||
class test_Del(ClassChecker):
|
||||
"""
|
||||
Test the `crud.Del` class.
|
||||
"""
|
||||
|
||||
_cls = crud.Del
|
||||
|
||||
def test_class(self):
|
||||
assert self.cls.__bases__ == (frontend.Method,)
|
||||
|
||||
def test_options_args(self):
|
||||
"""
|
||||
Test `crud.Del.get_args` and `crud.Del.get_options` methods.
|
||||
"""
|
||||
api = get_api()
|
||||
class user_del(self.cls):
|
||||
pass
|
||||
api.register(user_del)
|
||||
api.finalize()
|
||||
assert list(api.Method.user_del.args) == ['uid']
|
||||
assert list(api.Method.user_del.options) == []
|
||||
|
||||
|
||||
class test_Mod(ClassChecker):
|
||||
"""
|
||||
Test the `crud.Mod` class.
|
||||
"""
|
||||
|
||||
_cls = crud.Mod
|
||||
|
||||
def test_class(self):
|
||||
assert self.cls.__bases__ == (frontend.Method,)
|
||||
|
||||
def test_options_args(self):
|
||||
"""
|
||||
Test `crud.Mod.get_args` and `crud.Mod.get_options` methods.
|
||||
"""
|
||||
api = get_api()
|
||||
class user_mod(self.cls):
|
||||
pass
|
||||
api.register(user_mod)
|
||||
api.finalize()
|
||||
assert list(api.Method.user_mod.args) == ['uid']
|
||||
assert api.Method.user_mod.args[0].required is True
|
||||
assert list(api.Method.user_mod.options) == \
|
||||
['givenname', 'sn', 'initials']
|
||||
for param in api.Method.user_mod.options():
|
||||
assert param.required is False
|
||||
|
||||
|
||||
class test_Find(ClassChecker):
|
||||
"""
|
||||
Test the `crud.Find` class.
|
||||
"""
|
||||
|
||||
_cls = crud.Find
|
||||
|
||||
def test_class(self):
|
||||
assert self.cls.__bases__ == (frontend.Method,)
|
||||
|
||||
def test_options_args(self):
|
||||
"""
|
||||
Test `crud.Find.get_args` and `crud.Find.get_options` methods.
|
||||
"""
|
||||
api = get_api()
|
||||
class user_find(self.cls):
|
||||
pass
|
||||
api.register(user_find)
|
||||
api.finalize()
|
||||
assert list(api.Method.user_find.args) == ['uid']
|
||||
assert api.Method.user_find.args[0].required is True
|
||||
assert list(api.Method.user_find.options) == \
|
||||
['givenname', 'sn', 'initials']
|
||||
for param in api.Method.user_find.options():
|
||||
assert param.required is False
|
||||
@@ -1,274 +0,0 @@
|
||||
# Authors:
|
||||
# Jason Gerard DeRose <jderose@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2008 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; version 2 only
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
"""
|
||||
Unit tests for `ipalib.errors` module.
|
||||
"""
|
||||
|
||||
from tstutil import raises, ClassChecker
|
||||
from ipalib import errors
|
||||
|
||||
|
||||
type_format = '%s: need a %r; got %r'
|
||||
|
||||
|
||||
def check_TypeError(f, value, type_, name, **kw):
|
||||
e = raises(TypeError, f, value, type_, name, **kw)
|
||||
assert e.value is value
|
||||
assert e.type is type_
|
||||
assert e.name is name
|
||||
assert str(e) == type_format % (name, type_, value)
|
||||
|
||||
|
||||
def test_raise_TypeError():
|
||||
"""
|
||||
Tests the `errors.raise_TypeError` function.
|
||||
"""
|
||||
f = errors.raise_TypeError
|
||||
value = 'Hello.'
|
||||
type_ = unicode
|
||||
name = 'message'
|
||||
|
||||
check_TypeError(f, value, type_, name)
|
||||
|
||||
# name not an str
|
||||
fail_name = 42
|
||||
e = raises(AssertionError, f, value, type_, fail_name)
|
||||
assert str(e) == type_format % ('name', str, fail_name), str(e)
|
||||
|
||||
# type_ not a type:
|
||||
fail_type = unicode()
|
||||
e = raises(AssertionError, f, value, fail_type, name)
|
||||
assert str(e) == type_format % ('type_', type, fail_type)
|
||||
|
||||
# type(value) is type_:
|
||||
fail_value = u'How are you?'
|
||||
e = raises(AssertionError, f, fail_value, type_, name)
|
||||
assert str(e) == 'value: %r is a %r' % (fail_value, type_)
|
||||
|
||||
|
||||
def test_check_type():
|
||||
"""
|
||||
Tests the `errors.check_type` function.
|
||||
"""
|
||||
f = errors.check_type
|
||||
value = 'How are you?'
|
||||
type_ = str
|
||||
name = 'greeting'
|
||||
|
||||
# Should pass:
|
||||
assert value is f(value, type_, name)
|
||||
assert None is f(None, type_, name, allow_none=True)
|
||||
|
||||
# Should raise TypeError
|
||||
check_TypeError(f, None, type_, name)
|
||||
check_TypeError(f, value, basestring, name)
|
||||
check_TypeError(f, value, unicode, name)
|
||||
|
||||
# name not an str
|
||||
fail_name = unicode(name)
|
||||
e = raises(AssertionError, f, value, type_, fail_name)
|
||||
assert str(e) == type_format % ('name', str, fail_name)
|
||||
|
||||
# type_ not a type:
|
||||
fail_type = 42
|
||||
e = raises(AssertionError, f, value, fail_type, name)
|
||||
assert str(e) == type_format % ('type_', type, fail_type)
|
||||
|
||||
# allow_none not a bool:
|
||||
fail_bool = 0
|
||||
e = raises(AssertionError, f, value, type_, name, allow_none=fail_bool)
|
||||
assert str(e) == type_format % ('allow_none', bool, fail_bool)
|
||||
|
||||
|
||||
def test_check_isinstance():
|
||||
"""
|
||||
Tests the `errors.check_isinstance` function.
|
||||
"""
|
||||
f = errors.check_isinstance
|
||||
value = 'How are you?'
|
||||
type_ = str
|
||||
name = 'greeting'
|
||||
|
||||
# Should pass:
|
||||
assert value is f(value, type_, name)
|
||||
assert value is f(value, basestring, name)
|
||||
assert None is f(None, type_, name, allow_none=True)
|
||||
|
||||
# Should raise TypeError
|
||||
check_TypeError(f, None, type_, name)
|
||||
check_TypeError(f, value, unicode, name)
|
||||
|
||||
# name not an str
|
||||
fail_name = unicode(name)
|
||||
e = raises(AssertionError, f, value, type_, fail_name)
|
||||
assert str(e) == type_format % ('name', str, fail_name)
|
||||
|
||||
# type_ not a type:
|
||||
fail_type = 42
|
||||
e = raises(AssertionError, f, value, fail_type, name)
|
||||
assert str(e) == type_format % ('type_', type, fail_type)
|
||||
|
||||
# allow_none not a bool:
|
||||
fail_bool = 0
|
||||
e = raises(AssertionError, f, value, type_, name, allow_none=fail_bool)
|
||||
assert str(e) == type_format % ('allow_none', bool, fail_bool)
|
||||
|
||||
|
||||
class test_IPAError(ClassChecker):
|
||||
"""
|
||||
Tests the `errors.IPAError` exception.
|
||||
"""
|
||||
_cls = errors.IPAError
|
||||
|
||||
def test_class(self):
|
||||
assert self.cls.__bases__ == (Exception,)
|
||||
|
||||
def test_init(self):
|
||||
"""
|
||||
Tests the `errors.IPAError.__init__` method.
|
||||
"""
|
||||
args = ('one fish', 'two fish')
|
||||
e = self.cls(*args)
|
||||
assert e.args == args
|
||||
assert self.cls().args == tuple()
|
||||
|
||||
def test_str(self):
|
||||
"""
|
||||
Tests the `errors.IPAError.__str__` method.
|
||||
"""
|
||||
f = 'The %s color is %s.'
|
||||
class custom_error(self.cls):
|
||||
format = f
|
||||
for args in [('sexiest', 'red'), ('most-batman-like', 'black')]:
|
||||
e = custom_error(*args)
|
||||
assert e.args == args
|
||||
assert str(e) == f % args
|
||||
|
||||
|
||||
class test_ValidationError(ClassChecker):
|
||||
"""
|
||||
Tests the `errors.ValidationError` exception.
|
||||
"""
|
||||
_cls = errors.ValidationError
|
||||
|
||||
def test_class(self):
|
||||
assert self.cls.__bases__ == (errors.IPAError,)
|
||||
|
||||
def test_init(self):
|
||||
"""
|
||||
Tests the `errors.ValidationError.__init__` method.
|
||||
"""
|
||||
name = 'login'
|
||||
value = 'Whatever'
|
||||
error = 'Must be lowercase.'
|
||||
for index in (None, 3):
|
||||
e = self.cls(name, value, error, index=index)
|
||||
assert e.name is name
|
||||
assert e.value is value
|
||||
assert e.error is error
|
||||
assert e.index is index
|
||||
assert str(e) == 'invalid %r value %r: %s' % (name, value, error)
|
||||
# Check that index default is None:
|
||||
assert self.cls(name, value, error).index is None
|
||||
# Check non str name raises AssertionError:
|
||||
raises(AssertionError, self.cls, unicode(name), value, error)
|
||||
# Check non int index raises AssertionError:
|
||||
raises(AssertionError, self.cls, name, value, error, index=5.0)
|
||||
# Check negative index raises AssertionError:
|
||||
raises(AssertionError, self.cls, name, value, error, index=-2)
|
||||
|
||||
|
||||
class test_ConversionError(ClassChecker):
|
||||
"""
|
||||
Tests the `errors.ConversionError` exception.
|
||||
"""
|
||||
_cls = errors.ConversionError
|
||||
|
||||
def test_class(self):
|
||||
assert self.cls.__bases__ == (errors.ValidationError,)
|
||||
|
||||
def test_init(self):
|
||||
"""
|
||||
Tests the `errors.ConversionError.__init__` method.
|
||||
"""
|
||||
name = 'some_arg'
|
||||
value = '42.0'
|
||||
class type_(object):
|
||||
conversion_error = 'Not an integer'
|
||||
for index in (None, 7):
|
||||
e = self.cls(name, value, type_, index=index)
|
||||
assert e.name is name
|
||||
assert e.value is value
|
||||
assert e.type is type_
|
||||
assert e.error is type_.conversion_error
|
||||
assert e.index is index
|
||||
assert str(e) == 'invalid %r value %r: %s' % (name, value,
|
||||
type_.conversion_error)
|
||||
# Check that index default is None:
|
||||
assert self.cls(name, value, type_).index is None
|
||||
|
||||
|
||||
class test_RuleError(ClassChecker):
|
||||
"""
|
||||
Tests the `errors.RuleError` exception.
|
||||
"""
|
||||
_cls = errors.RuleError
|
||||
|
||||
def test_class(self):
|
||||
assert self.cls.__bases__ == (errors.ValidationError,)
|
||||
|
||||
def test_init(self):
|
||||
"""
|
||||
Tests the `errors.RuleError.__init__` method.
|
||||
"""
|
||||
name = 'whatever'
|
||||
value = 'The smallest weird number.'
|
||||
def my_rule(value):
|
||||
return 'Value is bad.'
|
||||
error = my_rule(value)
|
||||
for index in (None, 42):
|
||||
e = self.cls(name, value, error, my_rule, index=index)
|
||||
assert e.name is name
|
||||
assert e.value is value
|
||||
assert e.error is error
|
||||
assert e.rule is my_rule
|
||||
# Check that index default is None:
|
||||
assert self.cls(name, value, error, my_rule).index is None
|
||||
|
||||
|
||||
class test_RequirementError(ClassChecker):
|
||||
"""
|
||||
Tests the `errors.RequirementError` exception.
|
||||
"""
|
||||
_cls = errors.RequirementError
|
||||
|
||||
def test_class(self):
|
||||
assert self.cls.__bases__ == (errors.ValidationError,)
|
||||
|
||||
def test_init(self):
|
||||
"""
|
||||
Tests the `errors.RequirementError.__init__` method.
|
||||
"""
|
||||
name = 'givenname'
|
||||
e = self.cls(name)
|
||||
assert e.name is name
|
||||
assert e.value is None
|
||||
assert e.error == 'Required'
|
||||
assert e.index is None
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,371 +0,0 @@
|
||||
# Authors:
|
||||
# Jason Gerard DeRose <jderose@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2008 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; version 2 only
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
"""
|
||||
Unit tests for `ipalib.ipa_types` module.
|
||||
"""
|
||||
|
||||
from tstutil import raises, getitem, no_set, no_del, read_only, ClassChecker
|
||||
from ipalib import ipa_types, errors, plugable
|
||||
|
||||
|
||||
def test_check_min_max():
|
||||
"""
|
||||
Tests the `ipa_types.check_min_max` function.
|
||||
"""
|
||||
f = ipa_types.check_min_max
|
||||
okay = [
|
||||
(None, -5),
|
||||
(-20, None),
|
||||
(-20, -5),
|
||||
]
|
||||
for (l, h) in okay:
|
||||
assert f(l, h, 'low', 'high') is None
|
||||
fail_type = [
|
||||
'10',
|
||||
10.0,
|
||||
10L,
|
||||
True,
|
||||
False,
|
||||
object,
|
||||
]
|
||||
for value in fail_type:
|
||||
e = raises(TypeError, f, value, None, 'low', 'high')
|
||||
assert str(e) == 'low must be an int or None, got: %r' % value
|
||||
e = raises(TypeError, f, None, value, 'low', 'high')
|
||||
assert str(e) == 'high must be an int or None, got: %r' % value
|
||||
fail_value = [
|
||||
(10, 5),
|
||||
(-5, -10),
|
||||
(5, -10),
|
||||
]
|
||||
for (l, h) in fail_value:
|
||||
e = raises(ValueError, f, l, h, 'low', 'high')
|
||||
assert str(e) == 'low > high: low=%r, high=%r' % (l, h)
|
||||
|
||||
|
||||
class test_Type(ClassChecker):
|
||||
"""
|
||||
Tests the `ipa_types.Type` class.
|
||||
"""
|
||||
_cls = ipa_types.Type
|
||||
|
||||
def test_class(self):
|
||||
assert self.cls.__bases__ == (plugable.ReadOnly,)
|
||||
|
||||
def test_init(self):
|
||||
okay = (bool, int, float, unicode)
|
||||
for t in okay:
|
||||
o = self.cls(t)
|
||||
assert o.__islocked__() is True
|
||||
assert read_only(o, 'type') is t
|
||||
assert read_only(o, 'name') is 'Type'
|
||||
|
||||
type_errors = (None, True, 8, 8.0, u'hello')
|
||||
for t in type_errors:
|
||||
e = raises(TypeError, self.cls, t)
|
||||
assert str(e) == '%r is not %r' % (type(t), type)
|
||||
|
||||
value_errors = (long, complex, str, tuple, list, dict, set, frozenset)
|
||||
for t in value_errors:
|
||||
e = raises(ValueError, self.cls, t)
|
||||
assert str(e) == 'not an allowed type: %r' % t
|
||||
|
||||
def test_validate(self):
|
||||
o = self.cls(unicode)
|
||||
for value in (None, u'Hello', 'Hello', 42, False):
|
||||
assert o.validate(value) is None
|
||||
|
||||
|
||||
class test_Bool(ClassChecker):
|
||||
_cls = ipa_types.Bool
|
||||
|
||||
def test_class(self):
|
||||
assert self.cls.__bases__ == (ipa_types.Type,)
|
||||
|
||||
def test_init(self):
|
||||
o = self.cls()
|
||||
assert o.__islocked__() is True
|
||||
assert read_only(o, 'type') is bool
|
||||
assert read_only(o, 'name') == 'Bool'
|
||||
assert read_only(o, 'true') == 'Yes'
|
||||
assert read_only(o, 'false') == 'No'
|
||||
|
||||
keys = ('true', 'false')
|
||||
val = 'some value'
|
||||
for key in keys:
|
||||
# Check that kwarg sets appropriate attribute:
|
||||
o = self.cls(**{key: val})
|
||||
assert read_only(o, key) is val
|
||||
# Check that None raises TypeError:
|
||||
e = raises(TypeError, self.cls, **{key: None})
|
||||
assert str(e) == '`%s` cannot be None' % key
|
||||
|
||||
# Check that ValueError is raise if true == false:
|
||||
e = raises(ValueError, self.cls, true=1L, false=1.0)
|
||||
assert str(e) == 'cannot be equal: true=1L, false=1.0'
|
||||
|
||||
def test_call(self):
|
||||
o = self.cls()
|
||||
assert o(True) is True
|
||||
assert o('Yes') is True
|
||||
assert o(False) is False
|
||||
assert o('No') is False
|
||||
for value in (0, 1, 'True', 'False', 'yes', 'no'):
|
||||
# value is not be converted, so None is returned
|
||||
assert o(value) is None
|
||||
|
||||
|
||||
class test_Int(ClassChecker):
|
||||
_cls = ipa_types.Int
|
||||
|
||||
def test_class(self):
|
||||
assert self.cls.__bases__ == (ipa_types.Type,)
|
||||
|
||||
def test_init(self):
|
||||
o = self.cls()
|
||||
assert o.__islocked__() is True
|
||||
assert read_only(o, 'type') is int
|
||||
assert read_only(o, 'name') == 'Int'
|
||||
assert read_only(o, 'min_value') is None
|
||||
assert read_only(o, 'max_value') is None
|
||||
|
||||
okay = [
|
||||
(None, -5),
|
||||
(-20, None),
|
||||
(-20, -5),
|
||||
]
|
||||
for (l, h) in okay:
|
||||
o = self.cls(min_value=l, max_value=h)
|
||||
assert o.min_value is l
|
||||
assert o.max_value is h
|
||||
|
||||
fail_type = [
|
||||
'10',
|
||||
10.0,
|
||||
10L,
|
||||
True,
|
||||
False,
|
||||
object,
|
||||
]
|
||||
for value in fail_type:
|
||||
e = raises(TypeError, self.cls, min_value=value)
|
||||
assert str(e) == (
|
||||
'min_value must be an int or None, got: %r' % value
|
||||
)
|
||||
e = raises(TypeError, self.cls, max_value=value)
|
||||
assert str(e) == (
|
||||
'max_value must be an int or None, got: %r' % value
|
||||
)
|
||||
|
||||
fail_value = [
|
||||
(10, 5),
|
||||
(5, -5),
|
||||
(-5, -10),
|
||||
]
|
||||
for (l, h) in fail_value:
|
||||
e = raises(ValueError, self.cls, min_value=l, max_value=h)
|
||||
assert str(e) == (
|
||||
'min_value > max_value: min_value=%d, max_value=%d' % (l, h)
|
||||
)
|
||||
|
||||
def test_call(self):
|
||||
o = self.cls()
|
||||
|
||||
# Test calling with None
|
||||
e = raises(TypeError, o, None)
|
||||
assert str(e) == 'value cannot be None'
|
||||
|
||||
# Test with values that can be converted:
|
||||
okay = [
|
||||
3,
|
||||
'3',
|
||||
' 3 ',
|
||||
3L,
|
||||
3.0,
|
||||
]
|
||||
for value in okay:
|
||||
assert o(value) == 3
|
||||
|
||||
# Test with values that cannot be converted:
|
||||
fail = [
|
||||
object,
|
||||
'3.0',
|
||||
'3L',
|
||||
'whatever',
|
||||
]
|
||||
for value in fail:
|
||||
assert o(value) is None
|
||||
|
||||
|
||||
def test_validate(self):
|
||||
o = self.cls(min_value=2, max_value=7)
|
||||
assert o.validate(2) is None
|
||||
assert o.validate(5) is None
|
||||
assert o.validate(7) is None
|
||||
assert o.validate(1) == 'Cannot be smaller than 2'
|
||||
assert o.validate(8) == 'Cannot be larger than 7'
|
||||
for val in ['5', 5.0, 5L, None, True, False, object]:
|
||||
assert o.validate(val) == 'Must be an integer'
|
||||
|
||||
|
||||
class test_Unicode(ClassChecker):
|
||||
_cls = ipa_types.Unicode
|
||||
|
||||
def test_class(self):
|
||||
assert self.cls.__bases__ == (ipa_types.Type,)
|
||||
|
||||
def test_init(self):
|
||||
o = self.cls()
|
||||
assert o.__islocked__() is True
|
||||
assert read_only(o, 'type') is unicode
|
||||
assert read_only(o, 'name') == 'Unicode'
|
||||
assert read_only(o, 'min_length') is None
|
||||
assert read_only(o, 'max_length') is None
|
||||
assert read_only(o, 'pattern') is None
|
||||
assert read_only(o, 'regex') is None
|
||||
|
||||
# Test min_length, max_length:
|
||||
okay = (
|
||||
(0, 1),
|
||||
(8, 8),
|
||||
)
|
||||
for (l, h) in okay:
|
||||
o = self.cls(min_length=l, max_length=h)
|
||||
assert o.min_length == l
|
||||
assert o.max_length == h
|
||||
|
||||
fail_type = [
|
||||
'10',
|
||||
10.0,
|
||||
10L,
|
||||
True,
|
||||
False,
|
||||
object,
|
||||
]
|
||||
for value in fail_type:
|
||||
e = raises(TypeError, self.cls, min_length=value)
|
||||
assert str(e) == (
|
||||
'min_length must be an int or None, got: %r' % value
|
||||
)
|
||||
e = raises(TypeError, self.cls, max_length=value)
|
||||
assert str(e) == (
|
||||
'max_length must be an int or None, got: %r' % value
|
||||
)
|
||||
|
||||
fail_value = [
|
||||
(10, 5),
|
||||
(5, -5),
|
||||
(0, -10),
|
||||
]
|
||||
for (l, h) in fail_value:
|
||||
e = raises(ValueError, self.cls, min_length=l, max_length=h)
|
||||
assert str(e) == (
|
||||
'min_length > max_length: min_length=%d, max_length=%d' % (l, h)
|
||||
)
|
||||
|
||||
for (key, lower) in [('min_length', 0), ('max_length', 1)]:
|
||||
value = lower - 1
|
||||
kw = {key: value}
|
||||
e = raises(ValueError, self.cls, **kw)
|
||||
assert str(e) == '%s must be >= %d, got: %d' % (key, lower, value)
|
||||
|
||||
# Test pattern:
|
||||
okay = [
|
||||
'(hello|world)',
|
||||
u'(take the blue pill|take the red pill)',
|
||||
]
|
||||
for value in okay:
|
||||
o = self.cls(pattern=value)
|
||||
assert o.pattern is value
|
||||
assert o.regex is not None
|
||||
|
||||
fail = [
|
||||
42,
|
||||
True,
|
||||
False,
|
||||
object,
|
||||
]
|
||||
for value in fail:
|
||||
e = raises(TypeError, self.cls, pattern=value)
|
||||
assert str(e) == (
|
||||
'pattern must be a basestring or None, got: %r' % value
|
||||
)
|
||||
|
||||
# Test regex:
|
||||
pat = '^(hello|world)$'
|
||||
o = self.cls(pattern=pat)
|
||||
for value in ('hello', 'world'):
|
||||
m = o.regex.match(value)
|
||||
assert m.group(1) == value
|
||||
for value in ('hello beautiful', 'world!'):
|
||||
assert o.regex.match(value) is None
|
||||
|
||||
def test_validate(self):
|
||||
pat = '^a_*b$'
|
||||
o = self.cls(min_length=3, max_length=4, pattern=pat)
|
||||
assert o.validate(u'a_b') is None
|
||||
assert o.validate(u'a__b') is None
|
||||
assert o.validate('a_b') == 'Must be a string'
|
||||
assert o.validate(u'ab') == 'Must be at least 3 characters long'
|
||||
assert o.validate(u'a___b') == 'Can be at most 4 characters long'
|
||||
assert o.validate(u'a-b') == 'Must match %r' % pat
|
||||
assert o.validate(u'a--b') == 'Must match %r' % pat
|
||||
|
||||
|
||||
class test_Enum(ClassChecker):
|
||||
_cls = ipa_types.Enum
|
||||
|
||||
def test_class(self):
|
||||
assert self.cls.__bases__ == (ipa_types.Type,)
|
||||
|
||||
def test_init(self):
|
||||
for t in (unicode, int, float):
|
||||
values = (t(1), t(2), t(3))
|
||||
o = self.cls(*values)
|
||||
assert o.__islocked__() is True
|
||||
assert read_only(o, 'type') is t
|
||||
assert read_only(o, 'name') is 'Enum'
|
||||
assert read_only(o, 'values') == values
|
||||
assert read_only(o, 'frozenset') == frozenset(values)
|
||||
|
||||
# Check that ValueError is raised when no values are given:
|
||||
e = raises(ValueError, self.cls)
|
||||
assert str(e) == 'Enum requires at least one value'
|
||||
|
||||
# Check that TypeError is raised when type of first value is not
|
||||
# allowed:
|
||||
e = raises(TypeError, self.cls, 'hello')
|
||||
assert str(e) == '%r: %r not unicode, int, nor float' % ('hello', str)
|
||||
#self.cls('hello')
|
||||
|
||||
# Check that TypeError is raised when subsequent values aren't same
|
||||
# type as first:
|
||||
e = raises(TypeError, self.cls, u'hello', 'world')
|
||||
assert str(e) == '%r: %r is not %r' % ('world', str, unicode)
|
||||
|
||||
def test_validate(self):
|
||||
values = (u'hello', u'naughty', u'nurse')
|
||||
o = self.cls(*values)
|
||||
for value in values:
|
||||
assert o.validate(value) is None
|
||||
assert o.validate(str(value)) == 'Incorrect type'
|
||||
for value in (u'one fish', u'two fish'):
|
||||
assert o.validate(value) == 'Invalid value'
|
||||
assert o.validate(str(value)) == 'Incorrect type'
|
||||
@@ -1,896 +0,0 @@
|
||||
# Authors:
|
||||
# Jason Gerard DeRose <jderose@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2008 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; version 2 only
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
"""
|
||||
Unit tests for `ipalib.plugable` module.
|
||||
"""
|
||||
|
||||
from tstutil import raises, no_set, no_del, read_only
|
||||
from tstutil import getitem, setitem, delitem
|
||||
from tstutil import ClassChecker
|
||||
from ipalib import plugable, errors
|
||||
|
||||
|
||||
class test_ReadOnly(ClassChecker):
|
||||
"""
|
||||
Test the `plugable.ReadOnly` class
|
||||
"""
|
||||
_cls = plugable.ReadOnly
|
||||
|
||||
def test_class(self):
|
||||
assert self.cls.__bases__ == (object,)
|
||||
assert callable(self.cls.__lock__)
|
||||
assert callable(self.cls.__islocked__)
|
||||
|
||||
def test_lock(self):
|
||||
"""
|
||||
Test the `plugable.ReadOnly.__lock__` method.
|
||||
"""
|
||||
o = self.cls()
|
||||
assert o._ReadOnly__locked is False
|
||||
o.__lock__()
|
||||
assert o._ReadOnly__locked is True
|
||||
e = raises(AssertionError, o.__lock__) # Can only be locked once
|
||||
assert str(e) == '__lock__() can only be called once'
|
||||
assert o._ReadOnly__locked is True # This should still be True
|
||||
|
||||
def test_lock(self):
|
||||
"""
|
||||
Test the `plugable.ReadOnly.__islocked__` method.
|
||||
"""
|
||||
o = self.cls()
|
||||
assert o.__islocked__() is False
|
||||
o.__lock__()
|
||||
assert o.__islocked__() is True
|
||||
|
||||
def test_setattr(self):
|
||||
"""
|
||||
Test the `plugable.ReadOnly.__setattr__` method.
|
||||
"""
|
||||
o = self.cls()
|
||||
o.attr1 = 'Hello, world!'
|
||||
assert o.attr1 == 'Hello, world!'
|
||||
o.__lock__()
|
||||
for name in ('attr1', 'attr2'):
|
||||
e = raises(AttributeError, setattr, o, name, 'whatever')
|
||||
assert str(e) == 'read-only: cannot set ReadOnly.%s' % name
|
||||
assert o.attr1 == 'Hello, world!'
|
||||
|
||||
def test_delattr(self):
|
||||
"""
|
||||
Test the `plugable.ReadOnly.__delattr__` method.
|
||||
"""
|
||||
o = self.cls()
|
||||
o.attr1 = 'Hello, world!'
|
||||
o.attr2 = 'How are you?'
|
||||
assert o.attr1 == 'Hello, world!'
|
||||
assert o.attr2 == 'How are you?'
|
||||
del o.attr1
|
||||
assert not hasattr(o, 'attr1')
|
||||
o.__lock__()
|
||||
e = raises(AttributeError, delattr, o, 'attr2')
|
||||
assert str(e) == 'read-only: cannot del ReadOnly.attr2'
|
||||
assert o.attr2 == 'How are you?'
|
||||
|
||||
|
||||
def test_lock():
|
||||
"""
|
||||
Tests the `plugable.lock` function.
|
||||
"""
|
||||
f = plugable.lock
|
||||
|
||||
# Test on a ReadOnly instance:
|
||||
o = plugable.ReadOnly()
|
||||
assert not o.__islocked__()
|
||||
assert f(o) is o
|
||||
assert o.__islocked__()
|
||||
|
||||
# Test on something not subclassed from ReadOnly:
|
||||
class not_subclass(object):
|
||||
def __lock__(self):
|
||||
pass
|
||||
def __islocked__(self):
|
||||
return True
|
||||
o = not_subclass()
|
||||
raises(ValueError, f, o)
|
||||
|
||||
# Test that it checks __islocked__():
|
||||
class subclass(plugable.ReadOnly):
|
||||
def __islocked__(self):
|
||||
return False
|
||||
o = subclass()
|
||||
raises(AssertionError, f, o)
|
||||
|
||||
|
||||
class test_SetProxy(ClassChecker):
|
||||
"""
|
||||
Tests the `plugable.SetProxy` class.
|
||||
"""
|
||||
_cls = plugable.SetProxy
|
||||
|
||||
def test_class(self):
|
||||
assert self.cls.__bases__ == (plugable.ReadOnly,)
|
||||
|
||||
def test_init(self):
|
||||
okay = (set, frozenset, dict)
|
||||
fail = (list, tuple)
|
||||
for t in okay:
|
||||
self.cls(t())
|
||||
raises(TypeError, self.cls, t)
|
||||
for t in fail:
|
||||
raises(TypeError, self.cls, t())
|
||||
raises(TypeError, self.cls, t)
|
||||
|
||||
def test_SetProxy(self):
|
||||
def get_key(i):
|
||||
return 'key_%d' % i
|
||||
|
||||
cnt = 10
|
||||
target = set()
|
||||
proxy = self.cls(target)
|
||||
for i in xrange(cnt):
|
||||
key = get_key(i)
|
||||
|
||||
# Check initial state
|
||||
assert len(proxy) == len(target)
|
||||
assert list(proxy) == sorted(target)
|
||||
assert key not in proxy
|
||||
assert key not in target
|
||||
|
||||
# Add and test again
|
||||
target.add(key)
|
||||
assert len(proxy) == len(target)
|
||||
assert list(proxy) == sorted(target)
|
||||
assert key in proxy
|
||||
assert key in target
|
||||
|
||||
|
||||
class test_DictProxy(ClassChecker):
|
||||
"""
|
||||
Tests the `plugable.DictProxy` class.
|
||||
"""
|
||||
_cls = plugable.DictProxy
|
||||
|
||||
def test_class(self):
|
||||
assert self.cls.__bases__ == (plugable.SetProxy,)
|
||||
|
||||
def test_init(self):
|
||||
self.cls(dict())
|
||||
raises(TypeError, self.cls, dict)
|
||||
fail = (set, frozenset, list, tuple)
|
||||
for t in fail:
|
||||
raises(TypeError, self.cls, t())
|
||||
raises(TypeError, self.cls, t)
|
||||
|
||||
def test_DictProxy(self):
|
||||
def get_kv(i):
|
||||
return (
|
||||
'key_%d' % i,
|
||||
'val_%d' % i,
|
||||
)
|
||||
cnt = 10
|
||||
target = dict()
|
||||
proxy = self.cls(target)
|
||||
for i in xrange(cnt):
|
||||
(key, val) = get_kv(i)
|
||||
|
||||
# Check initial state
|
||||
assert len(proxy) == len(target)
|
||||
assert list(proxy) == sorted(target)
|
||||
assert list(proxy()) == [target[k] for k in sorted(target)]
|
||||
assert key not in proxy
|
||||
raises(KeyError, getitem, proxy, key)
|
||||
|
||||
# Add and test again
|
||||
target[key] = val
|
||||
assert len(proxy) == len(target)
|
||||
assert list(proxy) == sorted(target)
|
||||
assert list(proxy()) == [target[k] for k in sorted(target)]
|
||||
|
||||
# Verify TypeError is raised trying to set/del via proxy
|
||||
raises(TypeError, setitem, proxy, key, val)
|
||||
raises(TypeError, delitem, proxy, key)
|
||||
|
||||
|
||||
class test_MagicDict(ClassChecker):
|
||||
"""
|
||||
Tests the `plugable.MagicDict` class.
|
||||
"""
|
||||
_cls = plugable.MagicDict
|
||||
|
||||
def test_class(self):
|
||||
assert self.cls.__bases__ == (plugable.DictProxy,)
|
||||
for non_dict in ('hello', 69, object):
|
||||
raises(TypeError, self.cls, non_dict)
|
||||
|
||||
def test_MagicDict(self):
|
||||
cnt = 10
|
||||
keys = []
|
||||
d = dict()
|
||||
dictproxy = self.cls(d)
|
||||
for i in xrange(cnt):
|
||||
key = 'key_%d' % i
|
||||
val = 'val_%d' % i
|
||||
keys.append(key)
|
||||
|
||||
# Test thet key does not yet exist
|
||||
assert len(dictproxy) == i
|
||||
assert key not in dictproxy
|
||||
assert not hasattr(dictproxy, key)
|
||||
raises(KeyError, getitem, dictproxy, key)
|
||||
raises(AttributeError, getattr, dictproxy, key)
|
||||
|
||||
# Test that items/attributes cannot be set on dictproxy:
|
||||
raises(TypeError, setitem, dictproxy, key, val)
|
||||
raises(AttributeError, setattr, dictproxy, key, val)
|
||||
|
||||
# Test that additions in d are reflected in dictproxy:
|
||||
d[key] = val
|
||||
assert len(dictproxy) == i + 1
|
||||
assert key in dictproxy
|
||||
assert hasattr(dictproxy, key)
|
||||
assert dictproxy[key] is val
|
||||
assert read_only(dictproxy, key) is val
|
||||
|
||||
# Test __iter__
|
||||
assert list(dictproxy) == keys
|
||||
|
||||
for key in keys:
|
||||
# Test that items cannot be deleted through dictproxy:
|
||||
raises(TypeError, delitem, dictproxy, key)
|
||||
raises(AttributeError, delattr, dictproxy, key)
|
||||
|
||||
# Test that deletions in d are reflected in dictproxy
|
||||
del d[key]
|
||||
assert len(dictproxy) == len(d)
|
||||
assert key not in dictproxy
|
||||
raises(KeyError, getitem, dictproxy, key)
|
||||
raises(AttributeError, getattr, dictproxy, key)
|
||||
|
||||
|
||||
class test_Plugin(ClassChecker):
|
||||
"""
|
||||
Tests the `plugable.Plugin` class.
|
||||
"""
|
||||
_cls = plugable.Plugin
|
||||
|
||||
def test_class(self):
|
||||
assert self.cls.__bases__ == (plugable.ReadOnly,)
|
||||
assert self.cls.__public__ == frozenset()
|
||||
assert type(self.cls.name) is property
|
||||
assert type(self.cls.doc) is property
|
||||
assert type(self.cls.api) is property
|
||||
|
||||
def test_name(self):
|
||||
"""
|
||||
Tests the `plugable.Plugin.name` property.
|
||||
"""
|
||||
assert read_only(self.cls(), 'name') == 'Plugin'
|
||||
|
||||
class some_subclass(self.cls):
|
||||
pass
|
||||
assert read_only(some_subclass(), 'name') == 'some_subclass'
|
||||
|
||||
def test_doc(self):
|
||||
"""
|
||||
Tests the `plugable.Plugin.doc` property.
|
||||
"""
|
||||
class some_subclass(self.cls):
|
||||
'here is the doc string'
|
||||
assert read_only(some_subclass(), 'doc') == 'here is the doc string'
|
||||
|
||||
def test_implements(self):
|
||||
"""
|
||||
Tests the `plugable.Plugin.implements` classmethod.
|
||||
"""
|
||||
class example(self.cls):
|
||||
__public__ = frozenset((
|
||||
'some_method',
|
||||
'some_property',
|
||||
))
|
||||
class superset(self.cls):
|
||||
__public__ = frozenset((
|
||||
'some_method',
|
||||
'some_property',
|
||||
'another_property',
|
||||
))
|
||||
class subset(self.cls):
|
||||
__public__ = frozenset((
|
||||
'some_property',
|
||||
))
|
||||
class any_object(object):
|
||||
__public__ = frozenset((
|
||||
'some_method',
|
||||
'some_property',
|
||||
))
|
||||
|
||||
for ex in (example, example()):
|
||||
# Test using str:
|
||||
assert ex.implements('some_method')
|
||||
assert not ex.implements('another_method')
|
||||
|
||||
# Test using frozenset:
|
||||
assert ex.implements(frozenset(['some_method']))
|
||||
assert not ex.implements(
|
||||
frozenset(['some_method', 'another_method'])
|
||||
)
|
||||
|
||||
# Test using another object/class with __public__ frozenset:
|
||||
assert ex.implements(example)
|
||||
assert ex.implements(example())
|
||||
|
||||
assert ex.implements(subset)
|
||||
assert not subset.implements(ex)
|
||||
|
||||
assert not ex.implements(superset)
|
||||
assert superset.implements(ex)
|
||||
|
||||
assert ex.implements(any_object)
|
||||
assert ex.implements(any_object())
|
||||
|
||||
def test_implemented_by(self):
|
||||
"""
|
||||
Tests the `plugable.Plugin.implemented_by` classmethod.
|
||||
"""
|
||||
class base(self.cls):
|
||||
__public__ = frozenset((
|
||||
'attr0',
|
||||
'attr1',
|
||||
'attr2',
|
||||
))
|
||||
|
||||
class okay(base):
|
||||
def attr0(self):
|
||||
pass
|
||||
def __get_attr1(self):
|
||||
assert False # Make sure property isn't accesed on instance
|
||||
attr1 = property(__get_attr1)
|
||||
attr2 = 'hello world'
|
||||
another_attr = 'whatever'
|
||||
|
||||
class fail(base):
|
||||
def __init__(self):
|
||||
# Check that class, not instance is inspected:
|
||||
self.attr2 = 'hello world'
|
||||
def attr0(self):
|
||||
pass
|
||||
def __get_attr1(self):
|
||||
assert False # Make sure property isn't accesed on instance
|
||||
attr1 = property(__get_attr1)
|
||||
another_attr = 'whatever'
|
||||
|
||||
# Test that AssertionError is raised trying to pass something not
|
||||
# subclass nor instance of base:
|
||||
raises(AssertionError, base.implemented_by, object)
|
||||
|
||||
# Test on subclass with needed attributes:
|
||||
assert base.implemented_by(okay) is True
|
||||
assert base.implemented_by(okay()) is True
|
||||
|
||||
# Test on subclass *without* needed attributes:
|
||||
assert base.implemented_by(fail) is False
|
||||
assert base.implemented_by(fail()) is False
|
||||
|
||||
def test_set_api(self):
|
||||
"""
|
||||
Tests the `plugable.Plugin.set_api` method.
|
||||
"""
|
||||
api = 'the api instance'
|
||||
o = self.cls()
|
||||
assert o.api is None
|
||||
e = raises(AssertionError, o.set_api, None)
|
||||
assert str(e) == 'set_api() argument cannot be None'
|
||||
o.set_api(api)
|
||||
assert o.api is api
|
||||
e = raises(AssertionError, o.set_api, api)
|
||||
assert str(e) == 'set_api() can only be called once'
|
||||
|
||||
def test_finalize(self):
|
||||
"""
|
||||
Tests the `plugable.Plugin.finalize` method.
|
||||
"""
|
||||
o = self.cls()
|
||||
assert not o.__islocked__()
|
||||
o.finalize()
|
||||
assert o.__islocked__()
|
||||
|
||||
|
||||
class test_PluginProxy(ClassChecker):
|
||||
"""
|
||||
Tests the `plugable.PluginProxy` class.
|
||||
"""
|
||||
_cls = plugable.PluginProxy
|
||||
|
||||
def test_class(self):
|
||||
assert self.cls.__bases__ == (plugable.SetProxy,)
|
||||
|
||||
def test_proxy(self):
|
||||
# Setup:
|
||||
class base(object):
|
||||
__public__ = frozenset((
|
||||
'public_0',
|
||||
'public_1',
|
||||
'__call__',
|
||||
))
|
||||
|
||||
def public_0(self):
|
||||
return 'public_0'
|
||||
|
||||
def public_1(self):
|
||||
return 'public_1'
|
||||
|
||||
def __call__(self, caller):
|
||||
return 'ya called it, %s.' % caller
|
||||
|
||||
def private_0(self):
|
||||
return 'private_0'
|
||||
|
||||
def private_1(self):
|
||||
return 'private_1'
|
||||
|
||||
class plugin(base):
|
||||
name = 'user_add'
|
||||
attr_name = 'add'
|
||||
doc = 'add a new user'
|
||||
|
||||
# Test that TypeError is raised when base is not a class:
|
||||
raises(TypeError, self.cls, base(), None)
|
||||
|
||||
# Test that ValueError is raised when target is not instance of base:
|
||||
raises(ValueError, self.cls, base, object())
|
||||
|
||||
# Test with correct arguments:
|
||||
i = plugin()
|
||||
p = self.cls(base, i)
|
||||
assert read_only(p, 'name') is plugin.name
|
||||
assert read_only(p, 'doc') == plugin.doc
|
||||
assert list(p) == sorted(base.__public__)
|
||||
|
||||
# Test normal methods:
|
||||
for n in xrange(2):
|
||||
pub = 'public_%d' % n
|
||||
priv = 'private_%d' % n
|
||||
assert getattr(i, pub)() == pub
|
||||
assert getattr(p, pub)() == pub
|
||||
assert hasattr(p, pub)
|
||||
assert getattr(i, priv)() == priv
|
||||
assert not hasattr(p, priv)
|
||||
|
||||
# Test __call__:
|
||||
value = 'ya called it, dude.'
|
||||
assert i('dude') == value
|
||||
assert p('dude') == value
|
||||
assert callable(p)
|
||||
|
||||
# Test name_attr='name' kw arg
|
||||
i = plugin()
|
||||
p = self.cls(base, i, 'attr_name')
|
||||
assert read_only(p, 'name') == 'add'
|
||||
|
||||
def test_implements(self):
|
||||
"""
|
||||
Tests the `plugable.PluginProxy.implements` method.
|
||||
"""
|
||||
class base(object):
|
||||
__public__ = frozenset()
|
||||
name = 'base'
|
||||
doc = 'doc'
|
||||
@classmethod
|
||||
def implements(cls, arg):
|
||||
return arg + 7
|
||||
|
||||
class sub(base):
|
||||
@classmethod
|
||||
def implements(cls, arg):
|
||||
"""
|
||||
Defined to make sure base.implements() is called, not
|
||||
target.implements()
|
||||
"""
|
||||
return arg
|
||||
|
||||
o = sub()
|
||||
p = self.cls(base, o)
|
||||
assert p.implements(3) == 10
|
||||
|
||||
def test_clone(self):
|
||||
"""
|
||||
Tests the `plugable.PluginProxy.__clone__` method.
|
||||
"""
|
||||
class base(object):
|
||||
__public__ = frozenset()
|
||||
class sub(base):
|
||||
name = 'some_name'
|
||||
doc = 'doc'
|
||||
label = 'another_name'
|
||||
|
||||
p = self.cls(base, sub())
|
||||
assert read_only(p, 'name') == 'some_name'
|
||||
c = p.__clone__('label')
|
||||
assert isinstance(c, self.cls)
|
||||
assert c is not p
|
||||
assert read_only(c, 'name') == 'another_name'
|
||||
|
||||
|
||||
def test_check_name():
|
||||
"""
|
||||
Tests the `plugable.check_name` function.
|
||||
"""
|
||||
f = plugable.check_name
|
||||
okay = [
|
||||
'user_add',
|
||||
'stuff2junk',
|
||||
'sixty9',
|
||||
]
|
||||
nope = [
|
||||
'_user_add',
|
||||
'__user_add',
|
||||
'user_add_',
|
||||
'user_add__',
|
||||
'_user_add_',
|
||||
'__user_add__',
|
||||
'60nine',
|
||||
]
|
||||
for name in okay:
|
||||
assert name is f(name)
|
||||
e = raises(TypeError, f, unicode(name))
|
||||
assert str(e) == errors.TYPE_FORMAT % ('name', str, unicode(name))
|
||||
for name in nope:
|
||||
raises(errors.NameSpaceError, f, name)
|
||||
for name in okay:
|
||||
raises(errors.NameSpaceError, f, name.upper())
|
||||
|
||||
class DummyMember(object):
|
||||
def __init__(self, i):
|
||||
assert type(i) is int
|
||||
self.name = 'member_%02d' % i
|
||||
|
||||
|
||||
class test_NameSpace(ClassChecker):
|
||||
"""
|
||||
Tests the `plugable.NameSpace` class.
|
||||
"""
|
||||
_cls = plugable.NameSpace
|
||||
|
||||
def test_class(self):
|
||||
assert self.cls.__bases__ == (plugable.ReadOnly,)
|
||||
|
||||
def test_init(self):
|
||||
"""
|
||||
Tests the `plugable.NameSpace.__init__` method.
|
||||
"""
|
||||
o = self.cls(tuple())
|
||||
assert list(o) == []
|
||||
assert list(o()) == []
|
||||
for cnt in (10, 25):
|
||||
members = tuple(DummyMember(cnt - i) for i in xrange(cnt))
|
||||
for sort in (True, False):
|
||||
o = self.cls(members, sort=sort)
|
||||
if sort:
|
||||
ordered = tuple(sorted(members, key=lambda m: m.name))
|
||||
else:
|
||||
ordered = members
|
||||
names = tuple(m.name for m in ordered)
|
||||
assert o.__todict__() == dict((o.name, o) for o in ordered)
|
||||
|
||||
# Test __len__:
|
||||
assert len(o) == cnt
|
||||
|
||||
# Test __contains__:
|
||||
for name in names:
|
||||
assert name in o
|
||||
assert ('member_00') not in o
|
||||
|
||||
# Test __iter__, __call__:
|
||||
assert tuple(o) == names
|
||||
assert tuple(o()) == ordered
|
||||
|
||||
# Test __getitem__, getattr:
|
||||
for (i, member) in enumerate(ordered):
|
||||
assert o[i] is member
|
||||
name = member.name
|
||||
assert o[name] is member
|
||||
assert read_only(o, name) is member
|
||||
|
||||
# Test negative indexes:
|
||||
for i in xrange(1, cnt + 1):
|
||||
assert o[-i] is ordered[-i]
|
||||
|
||||
# Test slices:
|
||||
assert o[2:cnt-5] == ordered[2:cnt-5]
|
||||
assert o[::3] == ordered[::3]
|
||||
|
||||
# Test __repr__:
|
||||
assert repr(o) == \
|
||||
'NameSpace(<%d members>, sort=%r)' % (cnt, sort)
|
||||
|
||||
|
||||
def test_Environment():
|
||||
"""
|
||||
Tests the `plugable.Environment` class.
|
||||
"""
|
||||
# This has to be the same as iter_cnt
|
||||
control_cnt = 0
|
||||
class prop_class:
|
||||
def __init__(self, val):
|
||||
self._val = val
|
||||
def get_value(self):
|
||||
return self._val
|
||||
|
||||
class iter_class(prop_class):
|
||||
# Increment this for each time iter_class yields
|
||||
iter_cnt = 0
|
||||
def get_value(self):
|
||||
for item in self._val:
|
||||
self.__class__.iter_cnt += 1
|
||||
yield item
|
||||
|
||||
# Tests for basic functionality
|
||||
basic_tests = (
|
||||
('a', 1),
|
||||
('b', 'basic_foo'),
|
||||
('c', ('basic_bar', 'basic_baz')),
|
||||
)
|
||||
# Tests with prop classes
|
||||
prop_tests = (
|
||||
('d', prop_class(2), 2),
|
||||
('e', prop_class('prop_foo'), 'prop_foo'),
|
||||
('f', prop_class(('prop_bar', 'prop_baz')), ('prop_bar', 'prop_baz')),
|
||||
)
|
||||
# Tests with iter classes
|
||||
iter_tests = (
|
||||
('g', iter_class((3, 4, 5)), (3, 4, 5)),
|
||||
('h', iter_class(('iter_foo', 'iter_bar', 'iter_baz')),
|
||||
('iter_foo', 'iter_bar', 'iter_baz')
|
||||
),
|
||||
)
|
||||
|
||||
# Set all the values
|
||||
env = plugable.Environment()
|
||||
for name, val in basic_tests:
|
||||
env[name] = val
|
||||
for name, val, dummy in prop_tests:
|
||||
env[name] = val
|
||||
for name, val, dummy in iter_tests:
|
||||
env[name] = val
|
||||
|
||||
# Test if the values are correct
|
||||
for name, val in basic_tests:
|
||||
assert env[name] == val
|
||||
for name, dummy, val in prop_tests:
|
||||
assert env[name] == val
|
||||
# Test if the get_value() function is called only when needed
|
||||
for name, dummy, correct_values in iter_tests:
|
||||
values_in_env = []
|
||||
for val in env[name]:
|
||||
control_cnt += 1
|
||||
assert iter_class.iter_cnt == control_cnt
|
||||
values_in_env.append(val)
|
||||
assert tuple(values_in_env) == correct_values
|
||||
|
||||
# Test __setattr__()
|
||||
env.spam = 'ham'
|
||||
assert env.spam == 'ham'
|
||||
|
||||
# Test if we throw AttributeError exception when trying to overwrite
|
||||
# existing value, or delete it
|
||||
raises(AttributeError, setitem, env, 'a', 1)
|
||||
raises(AttributeError, setattr, env, 'a', 1)
|
||||
raises(AttributeError, delitem, env, 'a')
|
||||
raises(AttributeError, delattr, env, 'a')
|
||||
raises(AttributeError, plugable.Environment.update, env, dict(a=1000))
|
||||
# This should be silently ignored
|
||||
env.update(dict(a=1000), True)
|
||||
assert env.a != 1000
|
||||
|
||||
def test_Registrar():
|
||||
class Base1(object):
|
||||
pass
|
||||
class Base2(object):
|
||||
pass
|
||||
class Base3(object):
|
||||
pass
|
||||
class plugin1(Base1):
|
||||
pass
|
||||
class plugin2(Base2):
|
||||
pass
|
||||
class plugin3(Base3):
|
||||
pass
|
||||
|
||||
# Test creation of Registrar:
|
||||
r = plugable.Registrar(Base1, Base2)
|
||||
|
||||
# Test __iter__:
|
||||
assert list(r) == ['Base1', 'Base2']
|
||||
|
||||
# Test __hasitem__, __getitem__:
|
||||
for base in [Base1, Base2]:
|
||||
name = base.__name__
|
||||
assert name in r
|
||||
assert r[name] is base
|
||||
magic = getattr(r, name)
|
||||
assert type(magic) is plugable.MagicDict
|
||||
assert len(magic) == 0
|
||||
|
||||
# Check that TypeError is raised trying to register something that isn't
|
||||
# a class:
|
||||
raises(TypeError, r, plugin1())
|
||||
|
||||
# Check that SubclassError is raised trying to register a class that is
|
||||
# not a subclass of an allowed base:
|
||||
raises(errors.SubclassError, r, plugin3)
|
||||
|
||||
# Check that registration works
|
||||
r(plugin1)
|
||||
assert len(r.Base1) == 1
|
||||
assert r.Base1['plugin1'] is plugin1
|
||||
assert r.Base1.plugin1 is plugin1
|
||||
|
||||
# Check that DuplicateError is raised trying to register exact class
|
||||
# again:
|
||||
raises(errors.DuplicateError, r, plugin1)
|
||||
|
||||
# Check that OverrideError is raised trying to register class with same
|
||||
# name and same base:
|
||||
orig1 = plugin1
|
||||
class base1_extended(Base1):
|
||||
pass
|
||||
class plugin1(base1_extended):
|
||||
pass
|
||||
raises(errors.OverrideError, r, plugin1)
|
||||
|
||||
# Check that overriding works
|
||||
r(plugin1, override=True)
|
||||
assert len(r.Base1) == 1
|
||||
assert r.Base1.plugin1 is plugin1
|
||||
assert r.Base1.plugin1 is not orig1
|
||||
|
||||
# Check that MissingOverrideError is raised trying to override a name
|
||||
# not yet registerd:
|
||||
raises(errors.MissingOverrideError, r, plugin2, override=True)
|
||||
|
||||
# Test that another plugin can be registered:
|
||||
assert len(r.Base2) == 0
|
||||
r(plugin2)
|
||||
assert len(r.Base2) == 1
|
||||
assert r.Base2.plugin2 is plugin2
|
||||
|
||||
# Setup to test more registration:
|
||||
class plugin1a(Base1):
|
||||
pass
|
||||
r(plugin1a)
|
||||
|
||||
class plugin1b(Base1):
|
||||
pass
|
||||
r(plugin1b)
|
||||
|
||||
class plugin2a(Base2):
|
||||
pass
|
||||
r(plugin2a)
|
||||
|
||||
class plugin2b(Base2):
|
||||
pass
|
||||
r(plugin2b)
|
||||
|
||||
# Again test __hasitem__, __getitem__:
|
||||
for base in [Base1, Base2]:
|
||||
name = base.__name__
|
||||
assert name in r
|
||||
assert r[name] is base
|
||||
magic = getattr(r, name)
|
||||
assert len(magic) == 3
|
||||
for key in magic:
|
||||
klass = magic[key]
|
||||
assert getattr(magic, key) is klass
|
||||
assert issubclass(klass, base)
|
||||
|
||||
|
||||
|
||||
def test_API():
|
||||
assert issubclass(plugable.API, plugable.ReadOnly)
|
||||
|
||||
# Setup the test bases, create the API:
|
||||
class base0(plugable.Plugin):
|
||||
__public__ = frozenset((
|
||||
'method',
|
||||
))
|
||||
|
||||
def method(self, n):
|
||||
return n
|
||||
|
||||
class base1(plugable.Plugin):
|
||||
__public__ = frozenset((
|
||||
'method',
|
||||
))
|
||||
|
||||
def method(self, n):
|
||||
return n + 1
|
||||
|
||||
api = plugable.API(base0, base1)
|
||||
r = api.register
|
||||
assert isinstance(r, plugable.Registrar)
|
||||
assert read_only(api, 'register') is r
|
||||
|
||||
class base0_plugin0(base0):
|
||||
pass
|
||||
r(base0_plugin0)
|
||||
|
||||
class base0_plugin1(base0):
|
||||
pass
|
||||
r(base0_plugin1)
|
||||
|
||||
class base0_plugin2(base0):
|
||||
pass
|
||||
r(base0_plugin2)
|
||||
|
||||
class base1_plugin0(base1):
|
||||
pass
|
||||
r(base1_plugin0)
|
||||
|
||||
class base1_plugin1(base1):
|
||||
pass
|
||||
r(base1_plugin1)
|
||||
|
||||
class base1_plugin2(base1):
|
||||
pass
|
||||
r(base1_plugin2)
|
||||
|
||||
# Test API instance:
|
||||
api.finalize()
|
||||
|
||||
def get_base(b):
|
||||
return 'base%d' % b
|
||||
|
||||
def get_plugin(b, p):
|
||||
return 'base%d_plugin%d' % (b, p)
|
||||
|
||||
for b in xrange(2):
|
||||
base_name = get_base(b)
|
||||
ns = getattr(api, base_name)
|
||||
assert isinstance(ns, plugable.NameSpace)
|
||||
assert read_only(api, base_name) is ns
|
||||
assert len(ns) == 3
|
||||
for p in xrange(3):
|
||||
plugin_name = get_plugin(b, p)
|
||||
proxy = ns[plugin_name]
|
||||
assert isinstance(proxy, plugable.PluginProxy)
|
||||
assert proxy.name == plugin_name
|
||||
assert read_only(ns, plugin_name) is proxy
|
||||
assert read_only(proxy, 'method')(7) == 7 + b
|
||||
|
||||
# Test that calling finilize again raises AssertionError:
|
||||
raises(AssertionError, api.finalize)
|
||||
|
||||
# Test with base class that doesn't request a proxy
|
||||
class NoProxy(plugable.Plugin):
|
||||
__proxy__ = False
|
||||
api = plugable.API(NoProxy)
|
||||
class plugin0(NoProxy):
|
||||
pass
|
||||
api.register(plugin0)
|
||||
class plugin1(NoProxy):
|
||||
pass
|
||||
api.register(plugin1)
|
||||
api.finalize()
|
||||
names = ['plugin0', 'plugin1']
|
||||
assert list(api.NoProxy) == names
|
||||
for name in names:
|
||||
plugin = api.NoProxy[name]
|
||||
assert getattr(api.NoProxy, name) is plugin
|
||||
assert isinstance(plugin, plugable.Plugin)
|
||||
assert not isinstance(plugin, plugable.PluginProxy)
|
||||
@@ -1,148 +0,0 @@
|
||||
# Authors:
|
||||
# Jason Gerard DeRose <jderose@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2008 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; version 2 only
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
"""
|
||||
Unit tests for test-helper `tests.tstutil` module.
|
||||
"""
|
||||
|
||||
import tstutil
|
||||
|
||||
|
||||
class Prop(object):
|
||||
def __init__(self, *ops):
|
||||
self.__ops = frozenset(ops)
|
||||
self.__prop = 'prop value'
|
||||
|
||||
def __get_prop(self):
|
||||
if 'get' not in self.__ops:
|
||||
raise AttributeError('get prop')
|
||||
return self.__prop
|
||||
|
||||
def __set_prop(self, value):
|
||||
if 'set' not in self.__ops:
|
||||
raise AttributeError('set prop')
|
||||
self.__prop = value
|
||||
|
||||
def __del_prop(self):
|
||||
if 'del' not in self.__ops:
|
||||
raise AttributeError('del prop')
|
||||
self.__prop = None
|
||||
|
||||
prop = property(__get_prop, __set_prop, __del_prop)
|
||||
|
||||
|
||||
def test_yes_raised():
|
||||
f = tstutil.raises
|
||||
|
||||
class SomeError(Exception):
|
||||
pass
|
||||
|
||||
class AnotherError(Exception):
|
||||
pass
|
||||
|
||||
def callback1():
|
||||
'raises correct exception'
|
||||
raise SomeError()
|
||||
|
||||
def callback2():
|
||||
'raises wrong exception'
|
||||
raise AnotherError()
|
||||
|
||||
def callback3():
|
||||
'raises no exception'
|
||||
|
||||
f(SomeError, callback1)
|
||||
|
||||
raised = False
|
||||
try:
|
||||
f(SomeError, callback2)
|
||||
except AnotherError:
|
||||
raised = True
|
||||
assert raised
|
||||
|
||||
raised = False
|
||||
try:
|
||||
f(SomeError, callback3)
|
||||
except tstutil.ExceptionNotRaised:
|
||||
raised = True
|
||||
assert raised
|
||||
|
||||
|
||||
def test_no_set():
|
||||
# Tests that it works when prop cannot be set:
|
||||
tstutil.no_set(Prop('get', 'del'), 'prop')
|
||||
|
||||
# Tests that ExceptionNotRaised is raised when prop *can* be set:
|
||||
raised = False
|
||||
try:
|
||||
tstutil.no_set(Prop('set'), 'prop')
|
||||
except tstutil.ExceptionNotRaised:
|
||||
raised = True
|
||||
assert raised
|
||||
|
||||
|
||||
def test_no_del():
|
||||
# Tests that it works when prop cannot be deleted:
|
||||
tstutil.no_del(Prop('get', 'set'), 'prop')
|
||||
|
||||
# Tests that ExceptionNotRaised is raised when prop *can* be set:
|
||||
raised = False
|
||||
try:
|
||||
tstutil.no_del(Prop('del'), 'prop')
|
||||
except tstutil.ExceptionNotRaised:
|
||||
raised = True
|
||||
assert raised
|
||||
|
||||
|
||||
def test_read_only():
|
||||
# Test that it works when prop is read only:
|
||||
assert tstutil.read_only(Prop('get'), 'prop') == 'prop value'
|
||||
|
||||
# Test that ExceptionNotRaised is raised when prop can be set:
|
||||
raised = False
|
||||
try:
|
||||
tstutil.read_only(Prop('get', 'set'), 'prop')
|
||||
except tstutil.ExceptionNotRaised:
|
||||
raised = True
|
||||
assert raised
|
||||
|
||||
# Test that ExceptionNotRaised is raised when prop can be deleted:
|
||||
raised = False
|
||||
try:
|
||||
tstutil.read_only(Prop('get', 'del'), 'prop')
|
||||
except tstutil.ExceptionNotRaised:
|
||||
raised = True
|
||||
assert raised
|
||||
|
||||
# Test that ExceptionNotRaised is raised when prop can be both set and
|
||||
# deleted:
|
||||
raised = False
|
||||
try:
|
||||
tstutil.read_only(Prop('get', 'del'), 'prop')
|
||||
except tstutil.ExceptionNotRaised:
|
||||
raised = True
|
||||
assert raised
|
||||
|
||||
# Test that AttributeError is raised when prop can't be read:
|
||||
raised = False
|
||||
try:
|
||||
tstutil.read_only(Prop(), 'prop')
|
||||
except AttributeError:
|
||||
raised = True
|
||||
assert raised
|
||||
@@ -1,49 +0,0 @@
|
||||
# Authors:
|
||||
# Jason Gerard DeRose <jderose@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2008 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; version 2 only
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
"""
|
||||
Unit tests for `ipalib.util` module.
|
||||
"""
|
||||
|
||||
from tstutil import raises
|
||||
from ipalib import util
|
||||
|
||||
|
||||
def test_xmlrpc_marshal():
|
||||
"""
|
||||
Test the `util.xmlrpc_marshal` function.
|
||||
"""
|
||||
f = util.xmlrpc_marshal
|
||||
assert f() == ({},)
|
||||
assert f('one', 'two') == ({}, 'one', 'two')
|
||||
assert f(one=1, two=2) == (dict(one=1, two=2),)
|
||||
assert f('one', 'two', three=3, four=4) == \
|
||||
(dict(three=3, four=4), 'one', 'two')
|
||||
|
||||
|
||||
def test_xmlrpc_unmarshal():
|
||||
"""
|
||||
Test the `util.xmlrpc_unmarshal` function.
|
||||
"""
|
||||
f = util.xmlrpc_unmarshal
|
||||
assert f() == (tuple(), {})
|
||||
assert f({}, 'one', 'two') == (('one', 'two'), {})
|
||||
assert f(dict(one=1, two=2)) == (tuple(), dict(one=1, two=2))
|
||||
assert f(dict(three=3, four=4), 'one', 'two') == \
|
||||
(('one', 'two'), dict(three=3, four=4))
|
||||
@@ -1,147 +0,0 @@
|
||||
# Authors:
|
||||
# Jason Gerard DeRose <jderose@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2008 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; version 2 only
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
"""
|
||||
Utility functions for the unit tests.
|
||||
"""
|
||||
|
||||
import inspect
|
||||
from ipalib import errors
|
||||
|
||||
class ExceptionNotRaised(Exception):
|
||||
"""
|
||||
Exception raised when an *expected* exception is *not* raised during a
|
||||
unit test.
|
||||
"""
|
||||
msg = 'expected %s'
|
||||
|
||||
def __init__(self, expected):
|
||||
self.expected = expected
|
||||
|
||||
def __str__(self):
|
||||
return self.msg % self.expected.__name__
|
||||
|
||||
|
||||
def raises(exception, callback, *args, **kw):
|
||||
"""
|
||||
Tests that the expected exception is raised; raises ExceptionNotRaised
|
||||
if test fails.
|
||||
"""
|
||||
raised = False
|
||||
try:
|
||||
callback(*args, **kw)
|
||||
except exception, e:
|
||||
raised = True
|
||||
if not raised:
|
||||
raise ExceptionNotRaised(exception)
|
||||
return e
|
||||
|
||||
|
||||
def getitem(obj, key):
|
||||
"""
|
||||
Works like getattr but for dictionary interface. Use this in combination
|
||||
with raises() to test that, for example, KeyError is raised.
|
||||
"""
|
||||
return obj[key]
|
||||
|
||||
|
||||
def setitem(obj, key, value):
|
||||
"""
|
||||
Works like setattr but for dictionary interface. Use this in combination
|
||||
with raises() to test that, for example, TypeError is raised.
|
||||
"""
|
||||
obj[key] = value
|
||||
|
||||
|
||||
def delitem(obj, key):
|
||||
"""
|
||||
Works like delattr but for dictionary interface. Use this in combination
|
||||
with raises() to test that, for example, TypeError is raised.
|
||||
"""
|
||||
del obj[key]
|
||||
|
||||
|
||||
def no_set(obj, name, value='some_new_obj'):
|
||||
"""
|
||||
Tests that attribute cannot be set.
|
||||
"""
|
||||
raises(AttributeError, setattr, obj, name, value)
|
||||
|
||||
|
||||
def no_del(obj, name):
|
||||
"""
|
||||
Tests that attribute cannot be deleted.
|
||||
"""
|
||||
raises(AttributeError, delattr, obj, name)
|
||||
|
||||
|
||||
def read_only(obj, name, value='some_new_obj'):
|
||||
"""
|
||||
Tests that attribute is read-only. Returns attribute.
|
||||
"""
|
||||
# Test that it cannot be set:
|
||||
no_set(obj, name, value)
|
||||
|
||||
# Test that it cannot be deleted:
|
||||
no_del(obj, name)
|
||||
|
||||
# Return the attribute
|
||||
return getattr(obj, name)
|
||||
|
||||
|
||||
def is_prop(prop):
|
||||
return type(prop) is property
|
||||
|
||||
|
||||
class ClassChecker(object):
|
||||
__cls = None
|
||||
__subcls = None
|
||||
|
||||
def __get_cls(self):
|
||||
if self.__cls is None:
|
||||
self.__cls = self._cls
|
||||
assert inspect.isclass(self.__cls)
|
||||
return self.__cls
|
||||
cls = property(__get_cls)
|
||||
|
||||
def __get_subcls(self):
|
||||
if self.__subcls is None:
|
||||
self.__subcls = self.get_subcls()
|
||||
assert inspect.isclass(self.__subcls)
|
||||
return self.__subcls
|
||||
subcls = property(__get_subcls)
|
||||
|
||||
def get_subcls(self):
|
||||
raise NotImplementedError(
|
||||
self.__class__.__name__,
|
||||
'get_subcls()'
|
||||
)
|
||||
|
||||
|
||||
def check_TypeError(value, type_, name, callback, *args, **kw):
|
||||
"""
|
||||
Tests a standard TypeError raised with `errors.raise_TypeError`.
|
||||
"""
|
||||
e = raises(TypeError, callback, *args, **kw)
|
||||
assert e.value is value
|
||||
assert e.type is type_
|
||||
assert e.name == name
|
||||
assert type(e.name) is str
|
||||
assert str(e) == errors.TYPE_FORMAT % (name, type_, value)
|
||||
return e
|
||||
Reference in New Issue
Block a user