summaryrefslogtreecommitdiffstats
path: root/ipalib
diff options
context:
space:
mode:
authorJason Gerard DeRose <jderose@redhat.com>2008-08-09 01:06:42 +0000
committerJason Gerard DeRose <jderose@redhat.com>2008-08-09 01:06:42 +0000
commitcc5b0174949a4769876a892b210a9faa9683d81e (patch)
tree94ec47b1618161f1fd4d977b0d8ba1c322b99003 /ipalib
parent45201e31c1b7be7cb770d2e864c307c95e743751 (diff)
downloadfreeipa-cc5b0174949a4769876a892b210a9faa9683d81e.tar.gz
freeipa-cc5b0174949a4769876a892b210a9faa9683d81e.tar.xz
freeipa-cc5b0174949a4769876a892b210a9faa9683d81e.zip
93: Added Proxy.implements() method; addeded corresponding unit tests
Diffstat (limited to 'ipalib')
-rw-r--r--ipalib/plugable.py9
-rw-r--r--ipalib/tests/test_plugable.py185
2 files changed, 113 insertions, 81 deletions
diff --git a/ipalib/plugable.py b/ipalib/plugable.py
index c5ceeffe2..1e1f4a904 100644
--- a/ipalib/plugable.py
+++ b/ipalib/plugable.py
@@ -102,7 +102,7 @@ class Proxy(ReadOnly):
Allows access to only certain attributes on its target object (a
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,
which can be thought of as an agreement that "I will have at least these
attributes".
@@ -136,9 +136,13 @@ class Proxy(ReadOnly):
check_identifier(self.name)
self.__lock__()
+ def implements(self, arg):
+ return self.__base.implements(arg)
+
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__):
yield name
@@ -176,6 +180,7 @@ class Proxy(ReadOnly):
)
+
class Plugin(object):
"""
Base class for all plugins.
diff --git a/ipalib/tests/test_plugable.py b/ipalib/tests/test_plugable.py
index 25f520993..faf2fd92c 100644
--- a/ipalib/tests/test_plugable.py
+++ b/ipalib/tests/test_plugable.py
@@ -28,7 +28,7 @@ from ipalib import plugable, errors
def test_valid_identifier():
"""
- Test the plugable.valid_identifier function.
+ Test the `valid_identifier` function.
"""
f = plugable.check_identifier
okay = [
@@ -172,6 +172,111 @@ class test_ProxyTarget(ClassChecker):
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():
cls = plugable.Plugin
assert type(cls.name) is property
@@ -198,84 +303,6 @@ def test_Plugin():
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():
cls = plugable.NameSpace
assert issubclass(cls, plugable.ReadOnly)