K2LL33D SHELL

 Apache/2.4.7 (Ubuntu)
 Linux sman1baleendah 3.13.0-24-generic #46-Ubuntu SMP Thu Apr 10 19:11:08 UTC 2014 x86_64
 uid=33(www-data) gid=33(www-data) groups=33(www-data)
 safemode : OFF
 MySQL: ON | Perl: ON | cURL: OFF | WGet: ON
  >  / usr / lib / python2.7 / dist-packages / twisted / python / test /
server ip : 172.67.156.115

your ip : 172.70.131.201

H O M E


Filename/usr/lib/python2.7/dist-packages/twisted/python/test/test_components.py
Size24.56 kb
Permissionrw-r--r--
Ownerroot : root
Create time27-Apr-2025 09:56
Last modified15-Sep-2012 01:20
Last accessed07-Jul-2025 06:55
Actionsedit | rename | delete | download (gzip)
Viewtext | code | image
# Copyright (c) Twisted Matrix Laboratories.
# See LICENSE for details.


"""
Test cases for Twisted component architecture.
"""

from __future__ import division, absolute_import

from zope.interface import Interface, implementer, Attribute
from zope.interface.adapter import AdapterRegistry

from twisted.python.compat import comparable, cmp
from twisted.trial import unittest
from twisted.python import components
from twisted.python.components import _addHook, _removeHook, proxyForInterface


class Compo(components.Componentized):
num = 0
def inc(self):
self.num = self.num + 1
return self.num

class IAdept(Interface):
def adaptorFunc():
raise NotImplementedError()

class IElapsed(Interface):
def elapsedFunc():
"""
1!
"""

@implementer(IAdept)
class Adept(components.Adapter):
def __init__(self, orig):
self.original = orig
self.num = 0
def adaptorFunc(self):
self.num = self.num + 1
return self.num, self.original.inc()

@implementer(IElapsed)
class Elapsed(components.Adapter):
def elapsedFunc(self):
return 1

class AComp(components.Componentized):
pass
class BComp(AComp):
pass
class CComp(BComp):
pass

class ITest(Interface):
pass


class ITest2(Interface):
pass


class ITest3(Interface):
pass


class ITest4(Interface):
pass


@implementer(ITest, ITest3, ITest4)
class Test(components.Adapter):
def __init__(self, orig):
pass


@implementer(ITest2)
class Test2:
temporaryAdapter = 1
def __init__(self, orig):
pass



class RegistryUsingMixin(object):
"""
Mixin for test cases which modify the global registry somehow.
"""
def setUp(self):
"""
Configure L{twisted.python.components.registerAdapter} to mutate an
alternate registry to improve test isolation.
"""
# Create a brand new, empty registry and put it onto the components
# module where registerAdapter will use it. Also ensure that it goes
# away at the end of the test.
scratchRegistry = AdapterRegistry()
self.patch(components, 'globalRegistry', scratchRegistry)
# Hook the new registry up to the adapter lookup system and ensure that
# association is also discarded after the test.
hook = _addHook(scratchRegistry)
self.addCleanup(_removeHook, hook)



class ComponentizedTestCase(unittest.SynchronousTestCase, RegistryUsingMixin):
"""
Simple test case for caching in Componentized.
"""
def setUp(self):
RegistryUsingMixin.setUp(self)

components.registerAdapter(Test, AComp, ITest)
components.registerAdapter(Test, AComp, ITest3)
components.registerAdapter(Test2, AComp, ITest2)


def testComponentized(self):
components.registerAdapter(Adept, Compo, IAdept)
components.registerAdapter(Elapsed, Compo, IElapsed)

c = Compo()
assert c.getComponent(IAdept).adaptorFunc() == (1, 1)
assert c.getComponent(IAdept).adaptorFunc() == (2, 2)
assert IElapsed(IAdept(c)).elapsedFunc() == 1

def testInheritanceAdaptation(self):
c = CComp()
co1 = c.getComponent(ITest)
co2 = c.getComponent(ITest)
co3 = c.getComponent(ITest2)
co4 = c.getComponent(ITest2)
assert co1 is co2
assert co3 is not co4
c.removeComponent(co1)
co5 = c.getComponent(ITest)
co6 = c.getComponent(ITest)
assert co5 is co6
assert co1 is not co5

def testMultiAdapter(self):
c = CComp()
co1 = c.getComponent(ITest)
co2 = c.getComponent(ITest2)
co3 = c.getComponent(ITest3)
co4 = c.getComponent(ITest4)
self.assertIdentical(None, co4)
self.assertIdentical(co1, co3)


def test_getComponentDefaults(self):
"""
Test that a default value specified to Componentized.getComponent if
there is no component for the requested interface.
"""
componentized = components.Componentized()
default = object()
self.assertIdentical(
componentized.getComponent(ITest, default),
default)
self.assertIdentical(
componentized.getComponent(ITest, default=default),
default)
self.assertIdentical(
componentized.getComponent(ITest),
None)


def test_setAdapter(self):
"""
C{Componentized.setAdapter} sets a component for an interface by
wrapping the instance with the given adapter class.
"""
componentized = components.Componentized()
componentized.setAdapter(IAdept, Adept)
component = componentized.getComponent(IAdept)
self.assertEqual(component.original, componentized)
self.assertIsInstance(component, Adept)


def test_addAdapter(self):
"""
C{Componentized.setAdapter} adapts the instance by wrapping it with
given adapter class, then stores it using C{addComponent}.
"""
componentized = components.Componentized()
componentized.addAdapter(Adept, ignoreClass=True)
component = componentized.getComponent(IAdept)
self.assertEqual(component.original, componentized)
self.assertIsInstance(component, Adept)


def test_setComponent(self):
"""
C{Componentized.setComponent} stores the given component using the
given interface as the key.
"""
componentized = components.Componentized()
obj = object()
componentized.setComponent(ITest, obj)
self.assertIdentical(componentized.getComponent(ITest), obj)


def test_unsetComponent(self):
"""
C{Componentized.setComponent} removes the cached component for the
given interface.
"""
componentized = components.Componentized()
obj = object()
componentized.setComponent(ITest, obj)
componentized.unsetComponent(ITest)
self.assertIdentical(componentized.getComponent(ITest), None)


def test_reprableComponentized(self):
"""
C{ReprableComponentized} has a C{__repr__} that lists its cache.
"""
rc = components.ReprableComponentized()
rc.setComponent(ITest, "hello")
result = repr(rc)
self.assertIn("ITest", result)
self.assertIn("hello", result)



class AdapterTestCase(unittest.SynchronousTestCase):
"""Test adapters."""

def testAdapterGetComponent(self):
o = object()
a = Adept(o)
self.assertRaises(components.CannotAdapt, ITest, a)
self.assertEqual(ITest(a, None), None)



class IMeta(Interface):
pass

@implementer(IMeta)
class MetaAdder(components.Adapter):
def add(self, num):
return self.original.num + num

@implementer(IMeta)
class BackwardsAdder(components.Adapter):
def add(self, num):
return self.original.num - num

class MetaNumber:
def __init__(self, num):
self.num = num

class FakeAdder:
def add(self, num):
return num + 5

class FakeNumber:
num = 3

class ComponentNumber(components.Componentized):
def __init__(self):
self.num = 0
components.Componentized.__init__(self)

implementer(IMeta)
class ComponentMeta(components.Adapter):
def __init__(self, original):
components.Adapter.__init__(self, original)
self.num = self.original.num

class ComponentAdder(ComponentMeta):
def add(self, num):
self.num += num
return self.num

class ComponentDoubler(ComponentMeta):
def add(self, num):
self.num += (num * 2)
return self.original.num

class IAttrX(Interface):
def x():
pass

class IAttrXX(Interface):
def xx():
pass

@implementer(IAttrX)
class Xcellent:
def x(self):
return 'x!'

@comparable
class DoubleXAdapter:
num = 42
def __init__(self, original):
self.original = original
def xx(self):
return (self.original.x(), self.original.x())
def __cmp__(self, other):
return cmp(self.num, other.num)


class TestMetaInterface(RegistryUsingMixin, unittest.SynchronousTestCase):
def testBasic(self):
components.registerAdapter(MetaAdder, MetaNumber, IMeta)
n = MetaNumber(1)
self.assertEqual(IMeta(n).add(1), 2)

def testComponentizedInteraction(self):
components.registerAdapter(ComponentAdder, ComponentNumber, IMeta)
c = ComponentNumber()
IMeta(c).add(1)
IMeta(c).add(1)
self.assertEqual(IMeta(c).add(1), 3)

def testAdapterWithCmp(self):
# Make sure that a __cmp__ on an adapter doesn't break anything
components.registerAdapter(DoubleXAdapter, IAttrX, IAttrXX)
xx = IAttrXX(Xcellent())
self.assertEqual(('x!', 'x!'), xx.xx())


class RegistrationTestCase(RegistryUsingMixin, unittest.SynchronousTestCase):
"""
Tests for adapter registration.
"""
def _registerAdapterForClassOrInterface(self, original):
"""
Register an adapter with L{components.registerAdapter} for the given
class or interface and verify that the adapter can be looked up with
L{components.getAdapterFactory}.
"""
adapter = lambda o: None
components.registerAdapter(adapter, original, ITest)
self.assertIdentical(
components.getAdapterFactory(original, ITest, None),
adapter)


def test_registerAdapterForClass(self):
"""
Test that an adapter from a class can be registered and then looked
up.
"""
class TheOriginal(object):
pass
return self._registerAdapterForClassOrInterface(TheOriginal)


def test_registerAdapterForInterface(self):
"""
Test that an adapter from an interface can be registered and then
looked up.
"""
return self._registerAdapterForClassOrInterface(ITest2)


def _duplicateAdapterForClassOrInterface(self, original):
"""
Verify that L{components.registerAdapter} raises L{ValueError} if the
from-type/interface and to-interface pair is not unique.
"""
firstAdapter = lambda o: False
secondAdapter = lambda o: True
components.registerAdapter(firstAdapter, original, ITest)
self.assertRaises(
ValueError,
components.registerAdapter,
secondAdapter, original, ITest)
# Make sure that the original adapter is still around as well
self.assertIdentical(
components.getAdapterFactory(original, ITest, None),
firstAdapter)


def test_duplicateAdapterForClass(self):
"""
Test that attempting to register a second adapter from a class
raises the appropriate exception.
"""
class TheOriginal(object):
pass
return self._duplicateAdapterForClassOrInterface(TheOriginal)


def test_duplicateAdapterForInterface(self):
"""
Test that attempting to register a second adapter from an interface
raises the appropriate exception.
"""
return self._duplicateAdapterForClassOrInterface(ITest2)


def _duplicateAdapterForClassOrInterfaceAllowed(self, original):
"""
Verify that when C{components.ALLOW_DUPLICATES} is set to C{True}, new
adapter registrations for a particular from-type/interface and
to-interface pair replace older registrations.
"""
firstAdapter = lambda o: False
secondAdapter = lambda o: True
class TheInterface(Interface):
pass
components.registerAdapter(firstAdapter, original, TheInterface)
components.ALLOW_DUPLICATES = True
try:
components.registerAdapter(secondAdapter, original, TheInterface)
self.assertIdentical(
components.getAdapterFactory(original, TheInterface, None),
secondAdapter)
finally:
components.ALLOW_DUPLICATES = False

# It should be rejected again at this point
self.assertRaises(
ValueError,
components.registerAdapter,
firstAdapter, original, TheInterface)

self.assertIdentical(
components.getAdapterFactory(original, TheInterface, None),
secondAdapter)


def test_duplicateAdapterForClassAllowed(self):
"""
Test that when L{components.ALLOW_DUPLICATES} is set to a true
value, duplicate registrations from classes are allowed to override
the original registration.
"""
class TheOriginal(object):
pass
return self._duplicateAdapterForClassOrInterfaceAllowed(TheOriginal)


def test_duplicateAdapterForInterfaceAllowed(self):
"""
Test that when L{components.ALLOW_DUPLICATES} is set to a true
value, duplicate registrations from interfaces are allowed to
override the original registration.
"""
class TheOriginal(Interface):
pass
return self._duplicateAdapterForClassOrInterfaceAllowed(TheOriginal)


def _multipleInterfacesForClassOrInterface(self, original):
"""
Verify that an adapter can be registered for multiple to-interfaces at a
time.
"""
adapter = lambda o: None
components.registerAdapter(adapter, original, ITest, ITest2)
self.assertIdentical(
components.getAdapterFactory(original, ITest, None), adapter)
self.assertIdentical(
components.getAdapterFactory(original, ITest2, None), adapter)


def test_multipleInterfacesForClass(self):
"""
Test the registration of an adapter from a class to several
interfaces at once.
"""
class TheOriginal(object):
pass
return self._multipleInterfacesForClassOrInterface(TheOriginal)


def test_multipleInterfacesForInterface(self):
"""
Test the registration of an adapter from an interface to several
interfaces at once.
"""
return self._multipleInterfacesForClassOrInterface(ITest3)


def _subclassAdapterRegistrationForClassOrInterface(self, original):
"""
Verify that a new adapter can be registered for a particular
to-interface from a subclass of a type or interface which already has an
adapter registered to that interface and that the subclass adapter takes
precedence over the base class adapter.
"""
firstAdapter = lambda o: True
secondAdapter = lambda o: False
class TheSubclass(original):
pass
components.registerAdapter(firstAdapter, original, ITest)
components.registerAdapter(secondAdapter, TheSubclass, ITest)
self.assertIdentical(
components.getAdapterFactory(original, ITest, None),
firstAdapter)
self.assertIdentical(
components.getAdapterFactory(TheSubclass, ITest, None),
secondAdapter)


def test_subclassAdapterRegistrationForClass(self):
"""
Test that an adapter to a particular interface can be registered
from both a class and its subclass.
"""
class TheOriginal(object):
pass
return self._subclassAdapterRegistrationForClassOrInterface(TheOriginal)


def test_subclassAdapterRegistrationForInterface(self):
"""
Test that an adapter to a particular interface can be registered
from both an interface and its subclass.
"""
return self._subclassAdapterRegistrationForClassOrInterface(ITest2)



class IProxiedInterface(Interface):
"""
An interface class for use by L{proxyForInterface}.
"""

ifaceAttribute = Attribute("""
An example declared attribute, which should be proxied.""")

def yay(*a, **kw):
"""
A sample method which should be proxied.
"""

class IProxiedSubInterface(IProxiedInterface):
"""
An interface that derives from another for use with L{proxyForInterface}.
"""

def boo(self):
"""
A different sample method which should be proxied.
"""


@implementer(IProxiedInterface)
class Yayable(object):
"""
A provider of L{IProxiedInterface} which increments a counter for
every call to C{yay}.

@ivar yays: The number of times C{yay} has been called.
"""

def __init__(self):
self.yays = 0
self.yayArgs = []

def yay(self, *a, **kw):
"""
Increment C{self.yays}.
"""
self.yays += 1
self.yayArgs.append((a, kw))
return self.yays



@implementer(IProxiedSubInterface)
class Booable(object):
"""
An implementation of IProxiedSubInterface
"""
yayed = False
booed = False
def yay(self):
"""
Mark the fact that 'yay' has been called.
"""
self.yayed = True


def boo(self):
"""
Mark the fact that 'boo' has been called.1
"""
self.booed = True



class IMultipleMethods(Interface):
"""
An interface with multiple methods.
"""

def methodOne():
"""
The first method. Should return 1.
"""

def methodTwo():
"""
The second method. Should return 2.
"""



class MultipleMethodImplementor(object):
"""
A precise implementation of L{IMultipleMethods}.
"""

def methodOne(self):
"""
@return: 1
"""
return 1


def methodTwo(self):
"""
@return: 2
"""
return 2



class ProxyForInterfaceTests(unittest.SynchronousTestCase):
"""
Tests for L{proxyForInterface}.
"""

def test_original(self):
"""
Proxy objects should have an C{original} attribute which refers to the
original object passed to the constructor.
"""
original = object()
proxy = proxyForInterface(IProxiedInterface)(original)
self.assertIdentical(proxy.original, original)


def test_proxyMethod(self):
"""
The class created from L{proxyForInterface} passes methods on an
interface to the object which is passed to its constructor.
"""
klass = proxyForInterface(IProxiedInterface)
yayable = Yayable()
proxy = klass(yayable)
proxy.yay()
self.assertEqual(proxy.yay(), 2)
self.assertEqual(yayable.yays, 2)


def test_proxyAttribute(self):
"""
Proxy objects should proxy declared attributes, but not other
attributes.
"""
yayable = Yayable()
yayable.ifaceAttribute = object()
proxy = proxyForInterface(IProxiedInterface)(yayable)
self.assertIdentical(proxy.ifaceAttribute, yayable.ifaceAttribute)
self.assertRaises(AttributeError, lambda: proxy.yays)


def test_proxySetAttribute(self):
"""
The attributes that proxy objects proxy should be assignable and affect
the original object.
"""
yayable = Yayable()
proxy = proxyForInterface(IProxiedInterface)(yayable)
thingy = object()
proxy.ifaceAttribute = thingy
self.assertIdentical(yayable.ifaceAttribute, thingy)


def test_proxyDeleteAttribute(self):
"""
The attributes that proxy objects proxy should be deletable and affect
the original object.
"""
yayable = Yayable()
yayable.ifaceAttribute = None
proxy = proxyForInterface(IProxiedInterface)(yayable)
del proxy.ifaceAttribute
self.assertFalse(hasattr(yayable, 'ifaceAttribute'))


def test_multipleMethods(self):
"""
[Regression test] The proxy should send its method calls to the correct
method, not the incorrect one.
"""
multi = MultipleMethodImplementor()
proxy = proxyForInterface(IMultipleMethods)(multi)
self.assertEqual(proxy.methodOne(), 1)
self.assertEqual(proxy.methodTwo(), 2)


def test_subclassing(self):
"""
It is possible to subclass the result of L{proxyForInterface}.
"""

class SpecializedProxy(proxyForInterface(IProxiedInterface)):
"""
A specialized proxy which can decrement the number of yays.
"""
def boo(self):
"""
Decrement the number of yays.
"""
self.original.yays -= 1

yayable = Yayable()
special = SpecializedProxy(yayable)
self.assertEqual(yayable.yays, 0)
special.boo()
self.assertEqual(yayable.yays, -1)


def test_proxyName(self):
"""
The name of a proxy class indicates which interface it proxies.
"""
proxy = proxyForInterface(IProxiedInterface)
self.assertEqual(
proxy.__name__,
"(Proxy for "
"twisted.python.test.test_components.IProxiedInterface)")


def test_implements(self):
"""
The resulting proxy implements the interface that it proxies.
"""
proxy = proxyForInterface(IProxiedInterface)
self.assertTrue(IProxiedInterface.implementedBy(proxy))


def test_proxyDescriptorGet(self):
"""
_ProxyDescriptor's __get__ method should return the appropriate
attribute of its argument's 'original' attribute if it is invoked with
an object. If it is invoked with None, it should return a false
class-method emulator instead.

For some reason, Python's documentation recommends to define
descriptors' __get__ methods with the 'type' parameter as optional,
despite the fact that Python itself never actually calls the descriptor
that way. This is probably do to support 'foo.__get__(bar)' as an
idiom. Let's make sure that the behavior is correct. Since we don't
actually use the 'type' argument at all, this test calls it the
idiomatic way to ensure that signature works; test_proxyInheritance
verifies the how-Python-actually-calls-it signature.
"""
class Sample:
called = False
def hello(self):
self.called = True
fakeProxy = Sample()
testObject = Sample()
fakeProxy.original = testObject
pd = components._ProxyDescriptor("hello", "original")
self.assertEqual(pd.__get__(fakeProxy), testObject.hello)
fakeClassMethod = pd.__get__(None)
fakeClassMethod(fakeProxy)
self.failUnless(testObject.called)


def test_proxyInheritance(self):
"""
Subclasses of the class returned from L{proxyForInterface} should be
able to upcall methods by reference to their superclass, as any normal
Python class can.
"""
class YayableWrapper(proxyForInterface(IProxiedInterface)):
"""
This class does not override any functionality.
"""

class EnhancedWrapper(YayableWrapper):
"""
This class overrides the 'yay' method.
"""
wrappedYays = 1
def yay(self, *a, **k):
self.wrappedYays += 1
return YayableWrapper.yay(self, *a, **k) + 7

yayable = Yayable()
wrapper = EnhancedWrapper(yayable)
self.assertEqual(wrapper.yay(3, 4, x=5, y=6), 8)
self.assertEqual(yayable.yayArgs,
[((3, 4), dict(x=5, y=6))])


def test_interfaceInheritance(self):
"""
Proxies of subinterfaces generated with proxyForInterface should allow
access to attributes of both the child and the base interfaces.
"""
proxyClass = proxyForInterface(IProxiedSubInterface)
booable = Booable()
proxy = proxyClass(booable)
proxy.yay()
proxy.boo()
self.failUnless(booable.yayed)
self.failUnless(booable.booed)


def test_attributeCustomization(self):
"""
The original attribute name can be customized via the
C{originalAttribute} argument of L{proxyForInterface}: the attribute
should change, but the methods of the original object should still be
callable, and the attributes still accessible.
"""
yayable = Yayable()
yayable.ifaceAttribute = object()
proxy = proxyForInterface(
IProxiedInterface, originalAttribute='foo')(yayable)
self.assertIdentical(proxy.foo, yayable)

# Check the behavior
self.assertEqual(proxy.yay(), 1)
self.assertIdentical(proxy.ifaceAttribute, yayable.ifaceAttribute)
thingy = object()
proxy.ifaceAttribute = thingy
self.assertIdentical(yayable.ifaceAttribute, thingy)
del proxy.ifaceAttribute
self.assertFalse(hasattr(yayable, 'ifaceAttribute'))