mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
93: Added Proxy.implements() method; addeded corresponding unit tests
This commit is contained in:
parent
45201e31c1
commit
cc5b017494
@ -102,7 +102,7 @@ class Proxy(ReadOnly):
|
|||||||
Allows access to only certain attributes on its target object (a
|
Allows access to only certain attributes on its target object (a
|
||||||
ProxyTarget).
|
ProxyTarget).
|
||||||
|
|
||||||
Think of a proxy as an argreement that "I will have at most these
|
Think of a proxy as an agreement that "I will have at most these
|
||||||
attributes". This is different from (although similar to) an interface,
|
attributes". This is different from (although similar to) an interface,
|
||||||
which can be thought of as an agreement that "I will have at least these
|
which can be thought of as an agreement that "I will have at least these
|
||||||
attributes".
|
attributes".
|
||||||
@ -136,9 +136,13 @@ class Proxy(ReadOnly):
|
|||||||
check_identifier(self.name)
|
check_identifier(self.name)
|
||||||
self.__lock__()
|
self.__lock__()
|
||||||
|
|
||||||
|
def implements(self, arg):
|
||||||
|
return self.__base.implements(arg)
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
"""
|
"""
|
||||||
Iterates though the attribute names this proxy is allowing access to.
|
Iterates (in ascending order) though the attribute names this proxy is
|
||||||
|
allowing access to.
|
||||||
"""
|
"""
|
||||||
for name in sorted(self.__public__):
|
for name in sorted(self.__public__):
|
||||||
yield name
|
yield name
|
||||||
@ -176,6 +180,7 @@ class Proxy(ReadOnly):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Plugin(object):
|
class Plugin(object):
|
||||||
"""
|
"""
|
||||||
Base class for all plugins.
|
Base class for all plugins.
|
||||||
|
@ -28,7 +28,7 @@ from ipalib import plugable, errors
|
|||||||
|
|
||||||
def test_valid_identifier():
|
def test_valid_identifier():
|
||||||
"""
|
"""
|
||||||
Test the plugable.valid_identifier function.
|
Test the `valid_identifier` function.
|
||||||
"""
|
"""
|
||||||
f = plugable.check_identifier
|
f = plugable.check_identifier
|
||||||
okay = [
|
okay = [
|
||||||
@ -172,6 +172,111 @@ class test_ProxyTarget(ClassChecker):
|
|||||||
assert ex.implements(any_object())
|
assert ex.implements(any_object())
|
||||||
|
|
||||||
|
|
||||||
|
class test_Proxy(ClassChecker):
|
||||||
|
"""
|
||||||
|
Test the `Proxy` class.
|
||||||
|
"""
|
||||||
|
_cls = plugable.Proxy
|
||||||
|
|
||||||
|
def test_class(self):
|
||||||
|
assert self.cls.__bases__ == (plugable.ReadOnly,)
|
||||||
|
|
||||||
|
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'
|
||||||
|
|
||||||
|
# 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') == 'user_add'
|
||||||
|
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'
|
||||||
|
|
||||||
|
# Test _clone():
|
||||||
|
i = plugin()
|
||||||
|
p = self.cls(base, i)
|
||||||
|
assert read_only(p, 'name') == 'user_add'
|
||||||
|
c = p._clone('attr_name')
|
||||||
|
assert isinstance(c, self.cls)
|
||||||
|
assert read_only(c, 'name') == 'add'
|
||||||
|
assert c is not p
|
||||||
|
assert c('whoever') == p('whoever')
|
||||||
|
|
||||||
|
def test_implements(self):
|
||||||
|
"""
|
||||||
|
Test the `implements` method.
|
||||||
|
"""
|
||||||
|
class base(object):
|
||||||
|
__public__ = frozenset()
|
||||||
|
name = 'base'
|
||||||
|
@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_Plugin():
|
def test_Plugin():
|
||||||
cls = plugable.Plugin
|
cls = plugable.Plugin
|
||||||
assert type(cls.name) is property
|
assert type(cls.name) is property
|
||||||
@ -198,84 +303,6 @@ def test_Plugin():
|
|||||||
raises(AssertionError, p.finalize, api)
|
raises(AssertionError, p.finalize, api)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def test_Proxy():
|
|
||||||
cls = plugable.Proxy
|
|
||||||
assert issubclass(cls, plugable.ReadOnly)
|
|
||||||
|
|
||||||
# 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'
|
|
||||||
|
|
||||||
# Test that TypeError is raised when base is not a class:
|
|
||||||
raises(TypeError, cls, base(), None)
|
|
||||||
|
|
||||||
# Test that ValueError is raised when target is not instance of base:
|
|
||||||
raises(ValueError, cls, base, object())
|
|
||||||
|
|
||||||
# Test with correct arguments:
|
|
||||||
i = plugin()
|
|
||||||
p = cls(base, i)
|
|
||||||
assert read_only(p, 'name') == 'user_add'
|
|
||||||
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 = cls(base, i, 'attr_name')
|
|
||||||
assert read_only(p, 'name') == 'add'
|
|
||||||
|
|
||||||
# Test _clone():
|
|
||||||
i = plugin()
|
|
||||||
p = cls(base, i)
|
|
||||||
assert read_only(p, 'name') == 'user_add'
|
|
||||||
c = p._clone('attr_name')
|
|
||||||
assert isinstance(c, cls)
|
|
||||||
assert read_only(c, 'name') == 'add'
|
|
||||||
assert c is not p
|
|
||||||
assert c('whoever') == p('whoever')
|
|
||||||
|
|
||||||
|
|
||||||
def test_NameSpace():
|
def test_NameSpace():
|
||||||
cls = plugable.NameSpace
|
cls = plugable.NameSpace
|
||||||
assert issubclass(cls, plugable.ReadOnly)
|
assert issubclass(cls, plugable.ReadOnly)
|
||||||
|
Loading…
Reference in New Issue
Block a user