[Zope3-checkins] CVS: Zope3/src/zope/proxy/context/tests - test_wrapper.py:1.2.12.2

Steve Alexander steve@cat-box.net
Mon, 7 Apr 2003 05:31:47 -0400


Update of /cvs-repository/Zope3/src/zope/proxy/context/tests
In directory cvs.zope.org:/tmp/cvs-serv8100/src/zope/proxy/context/tests

Modified Files:
      Tag: stevea-contextaware_in_c-branch
	test_wrapper.py 
Log Message:
Marius and Steve added property, getattr and setattr tests.
We consider the test suite for the context-aware rebinding wrappers in C
to be complete.


=== Zope3/src/zope/proxy/context/tests/test_wrapper.py 1.2.12.1 => 1.2.12.2 ===
--- Zope3/src/zope/proxy/context/tests/test_wrapper.py:1.2.12.1	Tue Apr  1 14:53:06 2003
+++ Zope3/src/zope/proxy/context/tests/test_wrapper.py	Mon Apr  7 05:31:46 2003
@@ -14,7 +14,8 @@
 import pickle
 import unittest
 
-from zope.proxy.context import wrapper, getcontext, ContextAware, ContextMethod
+from zope.proxy.context import wrapper, getcontext, getobject
+from zope.proxy.context import ContextMethod, ContextProperty, ContextAware
 from zope.proxy.tests.test_proxy import Comparable, Thing, ProxyTestCase
 
 
@@ -125,6 +126,141 @@
         proxy3 = self.new_proxy(ContextMethodObj(), context)
 
         return proxy1, proxy2, proxy3, context
+
+    def test_normal_getattr(self):
+        class X(object):
+            def __init__(self, retval):
+                self.args = None
+                self.retval = retval
+            def __getattr__(self, name):
+                self.__dict__['args'] = self, name
+                return self.__dict__['retval']
+            def getArgs(self):
+                return self.__dict__['args']
+
+        context = object()
+
+        x = X(23)
+        try:
+            p = self.new_proxy(x, context)
+            self.assertEquals(p.foo, 23)
+            # Nothing special happens; we don't rebind the self of __getattr__
+            self.assertEquals(p.getArgs(), (x, 'foo'))
+            self.assert_(p.getArgs()[0] is x)
+        finally:
+            # remove cycles
+            del x.args
+
+    def test_ContextAware_getattr(self):
+        class Y(ContextAware):
+            def __init__(self, retval):
+                self.args = None
+                self.retval = retval
+            def __getattr__(self, name):
+                self.args = self, name
+                return self.__dict__['retval']
+            def getArgs(self):
+                # Need to get __dict__ from the clean object, because it
+                # is a special descriptor and complains bitterly about
+                # being got from the wrong kind of object.
+                return getobject(self).__dict__['args']
+
+        y = Y(23)
+        try:
+            p = self.new_proxy(y, 23)
+            self.assertEquals(p.foo, 23)
+            # Nothing special happens; we don't rebind the self of __getattr__
+            self.assertEquals(p.getArgs(), (y, 'foo'))
+            self.assert_(p.getArgs()[0] is y)
+        finally:
+            # remove cycles
+            del y.args
+
+    def test_ContextMethod_getattr(self):
+        class Z(object):
+            def __getattr__(self, name):
+                return 23
+            __getattr__ = ContextMethod(__getattr__)
+
+        z = Z()
+        self.assertRaises(TypeError, getattr, z, 'foo')
+        p = self.new_proxy(z, 23)
+        self.assertRaises(TypeError, getattr, p, 'foo')
+
+        # This is the same behaviour that you get if you try to make
+        # __getattr__ a classmethod.
+        class ZZ(object):
+            def __getattr__(self, name):
+                return 23
+            __getattr__ = classmethod(__getattr__)
+
+        zz = ZZ()
+        self.assertRaises(TypeError, getattr, zz, 'foo')
+
+    def test_property(self):
+        class X(object):
+            def getFoo(self):
+                self.called_with = self
+                return 42
+            def setFoo(self, value):
+                self.called_with = self, value
+            foo = property(getFoo, setFoo)
+            context_foo = ContextProperty(getFoo, setFoo)
+        x = X()
+        p = self.new_proxy(x)
+        self.assertEquals(p.foo, 42)
+        self.assert_(x.called_with is x)
+        self.assertEquals(p.context_foo, 42)
+        self.assert_(x.called_with is p)
+        p.foo = 24
+        self.assertEquals(x.called_with, (x, 24))
+        self.assert_(x.called_with[0] is x)
+        p.context_foo = 24
+        self.assertEquals(x.called_with, (p, 24))
+        self.assert_(x.called_with[0] is p)
+
+    def test_ContextAware_property(self):
+        class Y(ContextAware):
+            def getFoo(self):
+                self.called_with = self
+                return 42
+            def setFoo(self, value):
+                self.called_with = self, value
+            foo = property(getFoo, setFoo)
+        y = Y()
+        p = self.new_proxy(y)
+        self.assertEquals(p.foo, 42)
+        self.assert_(y.called_with is p)
+        p.foo = 24
+        self.assertEquals(y.called_with, (p, 24))
+        self.assert_(y.called_with[0] is p)
+
+    def test_setattr(self):
+        value_called = [None]
+        class X(object):
+            def __setattr__(self, name, value):
+                value_called[0] = self, name, value
+
+        x = X()
+        p = self.new_proxy(x)
+        p.foo = 'bar'
+        self.assertEqual(value_called[0], (p, 'foo', 'bar'))
+        self.assert_(value_called[0][0] is x)
+
+        class ContextAwareX(X, ContextAware):
+            pass
+        cax = ContextAwareX()
+        p = self.new_proxy(cax)
+        p.foo = 'bar'
+        self.assertEqual(value_called[0], (p, 'foo', 'bar'))
+        self.assert_(value_called[0][0] is cax)
+
+        X.__setattr__ = ContextMethod(X.__setattr__)
+        x = X()
+        p = self.new_proxy(x)
+        p.foo = 'bar'
+        self.assertEqual(value_called[0], (p, 'foo', 'bar'))
+        self.assert_(value_called[0][0] is x)
 
     def test_getitem(self):
         p1, p2, p3, context = self.make_proxies('__getitem__')