diff options
author | Jason Gerard DeRose <jderose@redhat.com> | 2008-08-09 01:06:42 +0000 |
---|---|---|
committer | Jason Gerard DeRose <jderose@redhat.com> | 2008-08-09 01:06:42 +0000 |
commit | cc5b0174949a4769876a892b210a9faa9683d81e (patch) | |
tree | 94ec47b1618161f1fd4d977b0d8ba1c322b99003 /ipalib | |
parent | 45201e31c1b7be7cb770d2e864c307c95e743751 (diff) | |
download | freeipa-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.py | 9 | ||||
-rw-r--r-- | ipalib/tests/test_plugable.py | 185 |
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) |