[Checkins] SVN: z3c.proxy/ - Implemented container location proxy
and proxy aware
Roger Ineichen
roger at projekt01.ch
Mon Jan 22 03:29:31 EST 2007
Log message for revision 72169:
- Implemented container location proxy and proxy aware
object mover, copier and item renamer
- Added unittests
Changed:
A z3c.proxy/branches/
A z3c.proxy/tags/
A z3c.proxy/trunk/
A z3c.proxy/trunk/src/
A z3c.proxy/trunk/src/z3c/
A z3c.proxy/trunk/src/z3c/proxy/
A z3c.proxy/trunk/src/z3c/proxy/README.txt
A z3c.proxy/trunk/src/z3c/proxy/SETUP.cfg
A z3c.proxy/trunk/src/z3c/proxy/__init__.py
A z3c.proxy/trunk/src/z3c/proxy/container.py
A z3c.proxy/trunk/src/z3c/proxy/interfaces.py
A z3c.proxy/trunk/src/z3c/proxy/overrides.zcml
A z3c.proxy/trunk/src/z3c/proxy/testing.py
A z3c.proxy/trunk/src/z3c/proxy/tests.py
A z3c.proxy/trunk/src/z3c/proxy/z3c.proxy-overrides.zcml
-=-
Added: z3c.proxy/trunk/src/z3c/proxy/README.txt
===================================================================
--- z3c.proxy/trunk/src/z3c/proxy/README.txt 2007-01-22 08:25:30 UTC (rev 72168)
+++ z3c.proxy/trunk/src/z3c/proxy/README.txt 2007-01-22 08:29:30 UTC (rev 72169)
@@ -0,0 +1,470 @@
+======
+README
+======
+
+We can proxy a regular container derived from zope's btree container for
+example:
+
+ >>> from zope.app.container.interfaces import IContainer
+ >>> from zope.app.container.btree import BTreeContainer
+ >>> container = BTreeContainer()
+ >>> container.__name__, container.__parent__ = u'c1', u'p1'
+
+ >>> from z3c.proxy import interfaces
+ >>> from z3c.proxy.container import LocationProxy
+ >>> from z3c.proxy.container import ContainerLocationProxy
+ >>> proxy = ContainerLocationProxy(container)
+
+The name and the parent of the proxy is None. The proxy provides
+IContainer:
+
+ >>> proxy.__name__ is None
+ True
+ >>> proxy.__parent__ is None
+ True
+ >>> IContainer.providedBy(proxy)
+ True
+ >>> interfaces.IContainerLocationProxy.providedBy(proxy)
+ True
+
+First we check the empty proxy:
+
+ >>> proxy['x']
+ Traceback (most recent call last):
+ ...
+ KeyError: 'x'
+
+ >>> 'x' in proxy
+ False
+
+ >>> proxy.has_key('x')
+ 0
+
+ >>> [key for key in proxy.keys()]
+ []
+
+ >>> [item for item in proxy.items()]
+ []
+
+ >>> proxy.get('x') is None
+ True
+
+ >>> iterator = iter(proxy)
+ >>> iterator.next()
+ Traceback (most recent call last):
+ ...
+ StopIteration
+
+ >>> proxy.values()
+ []
+
+ >>> len(proxy)
+ 0
+
+ >>> del proxy['x']
+ Traceback (most recent call last):
+ ...
+ KeyError: 'x'
+
+ >>> from zope.app.container.contained import Contained
+ >>> proxy['x'] = x = Contained()
+
+Now we added our first item. This item should be added to the container.
+Its name will be x and its parent is the container itself:
+
+ >>> x is container['x']
+ True
+
+ >>> x.__name__
+ u'x'
+
+ >>> x.__parent__ is container
+ True
+
+If we lookup 'x' within the proxy we do not get the blank 'x' but rather
+the proxied 'x'. The proxy is not 'x' but only equal to 'x':
+
+ >>> x is proxy['x']
+ False
+
+ >>> x == proxy['x']
+ True
+
+ >>> x1 = proxy['x']
+ >>> from zope.proxy import isProxy
+ >>> isProxy(x1)
+ True
+
+ >>> isinstance(x1, LocationProxy)
+ True
+
+The proxied 'x' has still the same name but not the same parent:
+
+ >>> x1.__name__
+ u'x'
+
+ >>> x1.__parent__ is container
+ False
+
+ >>> x1.__parent__ is proxy
+ True
+
+If we add a second item to the container, it should appear in the
+proxy, too. But this item is proxied as container location proxy:
+
+ >>> container['y'] = y = BTreeContainer()
+ >>> y1 = proxy['y']
+ >>> y1 is y
+ False
+
+ >>> y1 == y
+ True
+
+ >>> isinstance(y1, ContainerLocationProxy)
+ True
+
+The container location proxy is able to proxy the location of
+nested objects:
+
+ >>> proxy['y']['z'] = z = Contained()
+ >>> container['y']['z'] is z
+ True
+
+ >>> z1 = y1['z']
+ >>> z1 is z
+ False
+
+ >>> z1 == z
+ True
+
+ >>> isinstance(z1, LocationProxy)
+ True
+
+ >>> z1.__parent__ is y1
+ True
+
+Finaly we check all other methods of the proxy:
+
+ >>> 'x' in proxy
+ True
+
+ >>> proxy.has_key('x')
+ 1
+
+ >>> keys = [key for key in proxy.keys()]; keys.sort(); keys
+ [u'x', u'y']
+
+ >>> items = [item for item in proxy.items()]; items.sort()
+ >>> items == [(u'x', x), (u'y', y)]
+ True
+
+ >>> proxy.get('x') == x
+ True
+
+ >>> iterator = iter(proxy)
+ >>> iterator.next() in proxy
+ True
+
+ >>> iterator.next() in proxy
+ True
+
+ >>> iterator.next()
+ Traceback (most recent call last):
+ ...
+ StopIteration
+
+ >>> values = proxy.values(); values.sort();
+ >>> x in values, y in values
+ (True, True)
+
+ >>> len(proxy)
+ 2
+
+ >>> del proxy['x']
+ >>> 'x' in proxy
+ False
+
+
+ObjectMover
+-----------
+
+To use an object mover, pass a contained ``object`` to the class. The
+contained ``object`` should implement ``IContained``. It should be contained
+in a container that has an adapter to ``INameChooser``.
+
+Setup test container and proxies:
+
+ >>> from zope.interface import implements
+ >>> from zope.app.container.interfaces import INameChooser
+ >>> from zope.copypastemove import ExampleContainer
+ >>> from z3c.proxy.container import ProxyAwareObjectMover
+
+ >>> class ContainerLocationProxyStub(ContainerLocationProxy):
+ ...
+ ... implements(INameChooser)
+ ...
+ ... def chooseName(self, name, ob):
+ ... while name in self:
+ ... name += '_'
+ ... return name
+
+ >>> container = ExampleContainer()
+ >>> container2 = ExampleContainer()
+
+ >>> ob = Contained()
+ >>> proxy = ContainerLocationProxyStub(container)
+ >>> proxy[u'foo'] = ob
+ >>> ob = proxy[u'foo']
+ >>> mover = ProxyAwareObjectMover(ob)
+
+In addition to moving objects, object movers can tell you if the object is
+movable:
+
+ >>> mover.moveable()
+ 1
+
+which, at least for now, they always are. A better question to ask is whether
+we can move to a particular container. Right now, we can always move to a
+container of the same class:
+
+ >>> proxy2 = ContainerLocationProxyStub(container2)
+ >>> mover.moveableTo(proxy2)
+ 1
+
+ >>> mover.moveableTo({})
+ Traceback (most recent call last):
+ ...
+ TypeError: Container is not a valid Zope container.
+
+Of course, once we've decided we can move an object, we can use the mover to
+do so:
+
+ >>> mover.moveTo(proxy2)
+ u'foo'
+
+ >>> list(proxy)
+ []
+
+ >>> list(proxy2)
+ [u'foo']
+
+ >>> ob = proxy2[u'foo']
+ >>> ob.__parent__ is proxy2
+ True
+
+We can also specify a name:
+
+ >>> mover.moveTo(proxy2, u'bar')
+ u'bar'
+
+ >>> list(proxy2)
+ [u'bar']
+
+ >>> ob = proxy2[u'bar']
+ >>> ob.__parent__ is proxy2
+ True
+
+ >>> ob.__name__
+ u'bar'
+
+But we may not use the same name given, if the name is already in use:
+
+ >>> proxy2[u'splat'] = 1
+ >>> mover.moveTo(proxy2, u'splat')
+ u'splat_'
+
+ >>> l = list(proxy2)
+ >>> l.sort()
+ >>> l
+ [u'splat', u'splat_']
+
+ >>> ob = proxy2[u'splat_']
+ >>> ob.__name__
+ u'splat_'
+
+If we try to move to an invalid container, we'll get an error:
+
+ >>> mover.moveTo({})
+ Traceback (most recent call last):
+ ...
+ TypeError: Container is not a valid Zope container.
+
+
+ObjectCopier
+------------
+
+To use an object copier, pass a contained ``object`` to the class. The
+contained ``object`` should implement ``IContained``. It should be contained
+in a container that has an adapter to `INameChooser`.
+
+Setup test container and proxies:
+
+ >>> from z3c.proxy.container import ProxyAwareObjectCopier
+ >>> class ContainerLocationProxyStub(ContainerLocationProxy):
+ ...
+ ... implements(INameChooser)
+ ...
+ ... def chooseName(self, name, ob):
+ ... while name in self:
+ ... name += '_'
+ ... return name
+
+
+ >>> container = ExampleContainer()
+ >>> container2 = ExampleContainer()
+
+ >>> proxy = ContainerLocationProxyStub(container)
+ >>> proxy[u'foo'] = ob = Contained()
+ >>> ob = proxy[u'foo']
+ >>> copier = ProxyAwareObjectCopier(ob)
+
+In addition to moving objects, object copiers can tell you if the object is
+movable:
+
+ >>> copier.copyable()
+ 1
+
+which, at least for now, they always are. A better question to ask is whether
+we can copy to a particular container. Right now, we can always copy to a
+container of the same class:
+
+ >>> proxy2 = ContainerLocationProxyStub(container2)
+ >>> copier.copyableTo(proxy2)
+ 1
+
+ >>> copier.copyableTo({})
+ Traceback (most recent call last):
+ ...
+ TypeError: Container is not a valid Zope container.
+
+Of course, once we've decided we can copy an object, we can use the copier to
+do so:
+
+ >>> copier.copyTo(proxy2)
+ u'foo'
+
+ >>> list(proxy)
+ [u'foo']
+
+ >>> list(proxy2)
+ [u'foo']
+
+ >>> ob.__parent__ is proxy
+ 1
+
+ >>> proxy2[u'foo'] is ob
+ 0
+
+ >>> proxy2[u'foo'].__parent__ is proxy2
+ 1
+
+ >>> proxy2[u'foo'].__name__
+ u'foo'
+
+We can also specify a name:
+
+ >>> copier.copyTo(proxy2, u'bar')
+ u'bar'
+
+ >>> l = list(proxy2)
+ >>> l.sort()
+ >>> l
+ [u'bar', u'foo']
+
+ >>> ob.__parent__ is proxy
+ 1
+
+ >>> proxy2[u'bar'] is ob
+ 0
+
+ >>> proxy2[u'bar'].__parent__ is proxy2
+ 1
+
+ >>> proxy2[u'bar'].__name__
+ u'bar'
+
+But we may not use the same name given, if the name is already in use:
+
+ >>> copier.copyTo(proxy2, u'bar')
+ u'bar_'
+
+ >>> l = list(proxy2)
+ >>> l.sort()
+ >>> l
+ [u'bar', u'bar_', u'foo']
+
+ >>> proxy2[u'bar_'].__name__
+ u'bar_'
+
+
+If we try to copy to an invalid container, we'll get an error:
+
+ >>> copier.copyTo({})
+ Traceback (most recent call last):
+ ...
+ TypeError: Container is not a valid Zope container.
+
+
+ProxyAwareContainerItemRenamer
+------------------------------
+
+This adapter uses IObjectMover to move an item within the same container to
+a different name. We need to first setup an adapter for IObjectMover:
+
+Setup test container and proxies:
+
+ >>> from zope.app.container.sample import SampleContainer
+ >>> from zope.copypastemove import ContainerItemRenamer
+ >>> from zope.copypastemove import IObjectMover
+ >>> from z3c.proxy.container import ProxyAwareContainerItemRenamer
+
+ >>> import zope.component
+ >>> from zope.app.container.interfaces import IContained
+ >>> zope.component.provideAdapter(ProxyAwareObjectMover, [IContained],
+ ... IObjectMover)
+
+ >>> class ContainerLocationProxyStub(ContainerLocationProxy):
+ ...
+ ... implements(INameChooser)
+ ...
+ ... def chooseName(self, name, ob):
+ ... while name in self:
+ ... name += '_'
+ ... return name
+
+To rename an item in a container, instantiate a ContainerItemRenamer with the
+container:
+
+ >>> container = SampleContainer()
+ >>> proxy = ContainerLocationProxyStub(container)
+ >>> renamer = ProxyAwareContainerItemRenamer(container)
+
+For this example, we'll rename an item 'foo':
+
+ >>> from z3c.proxy.container import _unproxy
+ >>> foo = Contained()
+ >>> proxy['foo'] = foo
+ >>> proxy['foo'] == _unproxy(foo)
+ True
+
+to 'bar':
+
+ >>> renamer.renameItem('foo', 'bar')
+ >>> proxy['foo'] is foo
+ Traceback (most recent call last):
+ KeyError: 'foo'
+
+ >>> proxy['bar'] == _unproxy(foo)
+ True
+
+If the item being renamed isn't in the container, a NotFoundError is raised:
+
+ >>> renamer.renameItem('foo', 'bar') # doctest:+ELLIPSIS
+ Traceback (most recent call last):
+ ItemNotFoundError: (<...SampleContainer...>, 'foo')
+
+If the new item name already exists, a DuplicationError is raised:
+
+ >>> renamer.renameItem('bar', 'bar')
+ Traceback (most recent call last):
+ DuplicationError: bar is already in use
Property changes on: z3c.proxy/trunk/src/z3c/proxy/README.txt
___________________________________________________________________
Name: svn:eol-style
+ native
Added: z3c.proxy/trunk/src/z3c/proxy/SETUP.cfg
===================================================================
--- z3c.proxy/trunk/src/z3c/proxy/SETUP.cfg 2007-01-22 08:25:30 UTC (rev 72168)
+++ z3c.proxy/trunk/src/z3c/proxy/SETUP.cfg 2007-01-22 08:29:30 UTC (rev 72169)
@@ -0,0 +1,3 @@
+<data-files zopeskel/etc/package-includes>
+ z3c.proxy-*.zcml
+</data-files>
Property changes on: z3c.proxy/trunk/src/z3c/proxy/SETUP.cfg
___________________________________________________________________
Name: svn:eol-style
+ native
Added: z3c.proxy/trunk/src/z3c/proxy/__init__.py
===================================================================
--- z3c.proxy/trunk/src/z3c/proxy/__init__.py 2007-01-22 08:25:30 UTC (rev 72168)
+++ z3c.proxy/trunk/src/z3c/proxy/__init__.py 2007-01-22 08:29:30 UTC (rev 72169)
@@ -0,0 +1,16 @@
+###############################################################################
+#
+# Copyright (c) 2006 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+###############################################################################
+"""
+$Id$
+"""
Property changes on: z3c.proxy/trunk/src/z3c/proxy/__init__.py
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: z3c.proxy/trunk/src/z3c/proxy/container.py
===================================================================
--- z3c.proxy/trunk/src/z3c/proxy/container.py 2007-01-22 08:25:30 UTC (rev 72168)
+++ z3c.proxy/trunk/src/z3c/proxy/container.py 2007-01-22 08:29:30 UTC (rev 72169)
@@ -0,0 +1,125 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+$Id$
+"""
+__docformat__ = 'restructuredtext'
+
+from zope.interface import implements
+from zope.copypastemove import ObjectCopier
+from zope.copypastemove import ObjectMover
+from zope.copypastemove import ContainerItemRenamer
+from zope.location import LocationProxy
+from zope.proxy import getProxiedObject
+from zope.proxy import non_overridable
+from zope.proxy import isProxy
+
+from zope.app.container.interfaces import IContainer
+from z3c.proxy import interfaces
+
+
+def proxify(container, item):
+ if IContainer.providedBy(item):
+ proxy = ContainerLocationProxy(item)
+ else:
+ proxy = LocationProxy(item)
+ proxy.__name__ = item.__name__
+ proxy.__parent__ = container
+ return proxy
+
+
+def _unproxy(obj):
+ # precondition: treate only proxied objects
+ if not isProxy(obj):
+ return obj
+ # essential
+ return getProxiedObject(obj)
+
+
+class ContainerLocationProxy(LocationProxy):
+ """Proxy the location of a container an its items."""
+
+ implements(interfaces.IContainerLocationProxy)
+
+ # zope.app.conatiner.interfaces.IReadContainer
+ @non_overridable
+ def __getitem__(self, key):
+ return proxify(self, getProxiedObject(self).__getitem__(key))
+
+ @non_overridable
+ def __contains__(self, key):
+ return getProxiedObject(self).__contains__(key)
+
+ @non_overridable
+ def has_key(self, key):
+ return getProxiedObject(self).has_key(key)
+
+ @non_overridable
+ def keys(self):
+ return getProxiedObject(self).keys()
+
+ @non_overridable
+ def items(self):
+ return [(key, proxify(self, item)) for key, item in getProxiedObject(self).items()]
+
+ @non_overridable
+ def get(self, key, default=None):
+ item = getProxiedObject(self).get(key, default)
+
+ if item is not default:
+ return proxify(self, item)
+
+ else:
+ return default
+
+ @non_overridable
+ def __iter__(self):
+ return iter(getProxiedObject(self))
+
+ @non_overridable
+ def values(self):
+ return [proxify(self, value) for value in getProxiedObject(self).values()]
+
+ @non_overridable
+ def __len__(self):
+ return getProxiedObject(self).__len__()
+
+ # zope.app.conatiner.interfaces.IWriteContainer
+ @non_overridable
+ def __delitem__(self, key):
+ getProxiedObject(self).__delitem__(key)
+
+ @non_overridable
+ def __setitem__(self, key, value):
+ getProxiedObject(self).__setitem__(key, value)
+
+
+class ProxyAwareObjectMover(ObjectMover):
+ """Adapter for moving objects between containers that removes proxies."""
+ def __init__(self, object):
+ super(ProxyAwareObjectMover, self).__init__(_unproxy(object))
+
+
+class ProxyAwareObjectCopier(ObjectCopier):
+ """Adapter for copying objects between containers that removes proxies."""
+ def __init__(self, object):
+ super(ProxyAwareObjectCopier, self).__init__(_unproxy(object))
+
+
+class ProxyAwareContainerItemRenamer(ContainerItemRenamer):
+ """An IContainerItemRenamer adapter for containers."""
+ def __init__(self, container):
+ super(ProxyAwareContainerItemRenamer, self).__init__(
+ _unproxy(container))
+
Property changes on: z3c.proxy/trunk/src/z3c/proxy/container.py
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: z3c.proxy/trunk/src/z3c/proxy/interfaces.py
===================================================================
--- z3c.proxy/trunk/src/z3c/proxy/interfaces.py 2007-01-22 08:25:30 UTC (rev 72168)
+++ z3c.proxy/trunk/src/z3c/proxy/interfaces.py 2007-01-22 08:29:30 UTC (rev 72169)
@@ -0,0 +1,26 @@
+###############################################################################
+#
+# Copyright (c) 2006 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+###############################################################################
+"""
+$Id$
+"""
+__docformat__ = 'restructuredtext'
+
+
+from zope.location.interfaces import ILocation
+from zope.app.container.interfaces import IContainer
+
+
+
+class IContainerLocationProxy(ILocation, IContainer):
+ """Container proxy supporting a location."""
\ No newline at end of file
Property changes on: z3c.proxy/trunk/src/z3c/proxy/interfaces.py
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: z3c.proxy/trunk/src/z3c/proxy/overrides.zcml
===================================================================
--- z3c.proxy/trunk/src/z3c/proxy/overrides.zcml 2007-01-22 08:25:30 UTC (rev 72168)
+++ z3c.proxy/trunk/src/z3c/proxy/overrides.zcml 2007-01-22 08:29:30 UTC (rev 72169)
@@ -0,0 +1,38 @@
+<configure
+ xmlns="http://namespaces.zope.org/zope"
+ i18n_domain="z3c">
+
+ <!-- TODO: This adapter should be regsitred to the the LocationProxy class
+ and not use overrides.zcml. But this doesn't work. Find a way where we
+ can register this adapters without overrides.zcml. -->
+
+ <!-- support move for LocationProxy items -->
+ <adapter
+ factory="z3c.proxy.adapters.ProxyAwareObjectMover"
+ provides="zope.copypastemove.interfaces.IObjectMover"
+ permission="zope.ManageContent"
+ for="zope.app.container.interfaces.IContained"
+ trusted="True"
+ />
+
+
+ <!-- support copy/paste for LocationProxy items -->
+ <adapter
+ factory="z3c.proxy.adapters.ProxyAwareObjectCopier"
+ provides="zope.copypastemove.interfaces.IObjectCopier"
+ permission="zope.ManageContent"
+ for="zope.app.container.interfaces.IContained"
+ trusted="True"
+ />
+
+
+ <!-- support rename for ContainerLocationProxy items -->
+ <adapter
+ factory="z3c.proxy.adapters.ProxyAwareContainerItemRenamer"
+ provides="zope.copypastemove.interfaces.IContainerItemRenamer"
+ permission="zope.ManageContent"
+ for="zope.app.container.interfaces.IContainer"
+ trusted="True"
+ />
+
+</configure>
\ No newline at end of file
Property changes on: z3c.proxy/trunk/src/z3c/proxy/overrides.zcml
___________________________________________________________________
Name: svn:eol-style
+ native
Added: z3c.proxy/trunk/src/z3c/proxy/testing.py
===================================================================
--- z3c.proxy/trunk/src/z3c/proxy/testing.py 2007-01-22 08:25:30 UTC (rev 72168)
+++ z3c.proxy/trunk/src/z3c/proxy/testing.py 2007-01-22 08:29:30 UTC (rev 72169)
@@ -0,0 +1,56 @@
+###############################################################################
+#
+# Copyright (c) 2006 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+###############################################################################
+"""
+$Id$
+"""
+__docformat__ = 'restructuredtext'
+
+import zope.interface
+from zope.app.container.interfaces import IContainer
+from zope.app.container.tests.test_icontainer import BaseTestIContainer as BT
+from zope.app.container.tests.test_icontainer import DefaultTestData
+
+from z3c.testing.app import InterfaceBaseTest
+from z3c.proxy import interfaces
+from z3c.proxy import container
+
+
+# stub testing classes
+class ISampleContainerProxy(IContainer):
+ """Sample interface."""
+
+
+class SampleContainerProxy(container.ContainerLocationProxy):
+ """Sample implementation."""
+
+ zope.interface.implements(ISampleContainerProxy)
+
+
+class BaseTestIContainerLocationProxy(InterfaceBaseTest, BT):
+
+ def getTestInterface(self):
+ return interfaces.IContainerLocationProxy
+
+ def makeTestData(self):
+ return DefaultTestData()
+
+ def getUnknownKey(self):
+ return '10'
+
+ def getBadKeyTypes(self):
+ return [None, ['foo'], 1, '\xf3abc']
+
+ def test_IContainer(self):
+ proxy = self.makeTestObject()
+ self.assertEqual(IContainer.providedBy(proxy), True)
Property changes on: z3c.proxy/trunk/src/z3c/proxy/testing.py
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: z3c.proxy/trunk/src/z3c/proxy/tests.py
===================================================================
--- z3c.proxy/trunk/src/z3c/proxy/tests.py 2007-01-22 08:25:30 UTC (rev 72168)
+++ z3c.proxy/trunk/src/z3c/proxy/tests.py 2007-01-22 08:29:30 UTC (rev 72169)
@@ -0,0 +1,50 @@
+###############################################################################
+#
+# Copyright (c) 2006 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+###############################################################################
+"""
+$Id$
+"""
+__docformat__ = 'restructuredtext'
+
+import unittest
+from zope.testing.doctestunit import DocTestSuite
+from zope.testing.doctestunit import DocFileSuite
+from zope.app.container.sample import SampleContainer
+from zope.app.testing.placelesssetup import setUp
+from zope.app.testing.placelesssetup import tearDown
+
+from z3c.proxy import testing
+
+
+class SampleContainerTest(testing.BaseTestIContainerLocationProxy):
+ """Base container test sample."""
+
+ def getTestInterface(self):
+ return testing.ISampleContainerProxy
+
+ def getTestClass(self):
+ return testing.SampleContainerProxy
+
+ def makeTestObject(self):
+ obj = SampleContainer()
+ return testing.SampleContainerProxy(obj)
+
+
+def test_suite():
+ return unittest.TestSuite((
+ DocFileSuite('README.txt',
+ setUp=setUp, tearDown=tearDown),
+ unittest.makeSuite(SampleContainerTest),
+ ))
+
+if __name__ == '__main__': unittest.main(SampleContainerTest)
Property changes on: z3c.proxy/trunk/src/z3c/proxy/tests.py
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: z3c.proxy/trunk/src/z3c/proxy/z3c.proxy-overrides.zcml
===================================================================
--- z3c.proxy/trunk/src/z3c/proxy/z3c.proxy-overrides.zcml 2007-01-22 08:25:30 UTC (rev 72168)
+++ z3c.proxy/trunk/src/z3c/proxy/z3c.proxy-overrides.zcml 2007-01-22 08:29:30 UTC (rev 72169)
@@ -0,0 +1,5 @@
+<configure xmlns="http://namespaces.zope.org/zope">
+
+ <include package="z3c.proxy" file="overrides.zcml" />
+
+</configure>
\ No newline at end of file
Property changes on: z3c.proxy/trunk/src/z3c/proxy/z3c.proxy-overrides.zcml
___________________________________________________________________
Name: svn:eol-style
+ native
More information about the Checkins
mailing list