[Checkins] SVN: Sandbox/malthe/zope.container/ Initial package
creation.
Malthe Borch
mborch at gmail.com
Tue Apr 22 08:37:09 EDT 2008
Log message for revision 85592:
Initial package creation.
Changed:
U Sandbox/malthe/zope.container/CHANGES.txt
U Sandbox/malthe/zope.container/README.txt
U Sandbox/malthe/zope.container/buildout.cfg
D Sandbox/malthe/zope.container/include/
U Sandbox/malthe/zope.container/setup.py
D Sandbox/malthe/zope.container/src/zope/app/
A Sandbox/malthe/zope.container/src/zope/container/
A Sandbox/malthe/zope.container/src/zope/container/__init__.py
A Sandbox/malthe/zope.container/src/zope/container/constraints.py
A Sandbox/malthe/zope.container/src/zope/container/constraints.txt
A Sandbox/malthe/zope.container/src/zope/container/find.py
A Sandbox/malthe/zope.container/src/zope/container/i18n.py
A Sandbox/malthe/zope.container/src/zope/container/interfaces.py
A Sandbox/malthe/zope.container/src/zope/container/property.py
A Sandbox/malthe/zope.container/src/zope/container/property.txt
A Sandbox/malthe/zope.container/src/zope/container/size.py
A Sandbox/malthe/zope.container/src/zope/container/tests/
D Sandbox/malthe/zope.container/src/zope/container/tests/placelesssetup.py
D Sandbox/malthe/zope.container/src/zope/container/tests/test_btree.py
U Sandbox/malthe/zope.container/src/zope/container/tests/test_constraints.py
D Sandbox/malthe/zope.container/src/zope/container/tests/test_contained.py
D Sandbox/malthe/zope.container/src/zope/container/tests/test_containertraversable.py
D Sandbox/malthe/zope.container/src/zope/container/tests/test_containertraverser.py
D Sandbox/malthe/zope.container/src/zope/container/tests/test_dependency.py
D Sandbox/malthe/zope.container/src/zope/container/tests/test_directory.py
U Sandbox/malthe/zope.container/src/zope/container/tests/test_find.py
D Sandbox/malthe/zope.container/src/zope/container/tests/test_icontainer.py
D Sandbox/malthe/zope.container/src/zope/container/tests/test_objectcopier.py
D Sandbox/malthe/zope.container/src/zope/container/tests/test_objectmover.py
D Sandbox/malthe/zope.container/src/zope/container/tests/test_ordered.py
A Sandbox/malthe/zope.container/src/zope/container/tests/test_property.py
U Sandbox/malthe/zope.container/src/zope/container/tests/test_size.py
D Sandbox/malthe/zope.container/src/zope/container/tests/test_view_permissions.py
-=-
Modified: Sandbox/malthe/zope.container/CHANGES.txt
===================================================================
--- Sandbox/malthe/zope.container/CHANGES.txt 2008-04-22 12:19:47 UTC (rev 85591)
+++ Sandbox/malthe/zope.container/CHANGES.txt 2008-04-22 12:37:09 UTC (rev 85592)
@@ -5,46 +5,5 @@
3.6.0 (unreleased)
------------------
-- Added an ``IBTreeContainer`` interface that allows an argument to the
- ``items``, ``keys``, and ``values`` methods with the same semantics as for
- a BTree object. The extended interface is implemented by the
- ``BTreeContainer`` class.
-
-3.5.3 (2007-11-09)
-------------------
-
-- Send ``IObjectModifiedEvent`` when changing the title through the
- ``@@contents.html`` view.
-
- This fixes https://bugs.edge.launchpad.net/zope3/+bug/98483.
-
-3.5.2 (2007-11-01)
-------------------
-
-- Reactivated functional tests.
-
-3.5.1 (2007-10-31)
-------------------
-
-- Resolve ``ZopeSecurityPolicy`` and ``IRolePermissionManager`` deprecation
- warning.
-
-3.5.0 (2007-10-11)
-------------------
-
-- Updated package meta-data.
-
-3.5.0a1 (2007-06-29)
---------------------
-
-* Updated bootstrap script to current version.
-
-* Store length of ``BTreeContainer`` in its own ``Length`` object for faster
- ``__len__`` implementation of huge containers.
-
-
-3.4.0a1 (2007-04-22)
---------------------
-
-- Initial release as a separate project, corresponds to ``zope.app.container``
- from Zope 3.4.0a1.
+- Initial creation of package based on parts in ``zope.app.container``
+ that do not depend on the ZODB.
Modified: Sandbox/malthe/zope.container/README.txt
===================================================================
--- Sandbox/malthe/zope.container/README.txt 2008-04-22 12:19:47 UTC (rev 85591)
+++ Sandbox/malthe/zope.container/README.txt 2008-04-22 12:37:09 UTC (rev 85592)
@@ -1,3 +1,2 @@
-This package define interfaces of container components, and provides
-sample container implementations such as a BTreeContainer and
-OrderedContainer.
+This package define interfaces of container components and implements
+container constraints and utilities.
Modified: Sandbox/malthe/zope.container/buildout.cfg
===================================================================
--- Sandbox/malthe/zope.container/buildout.cfg 2008-04-22 12:19:47 UTC (rev 85591)
+++ Sandbox/malthe/zope.container/buildout.cfg 2008-04-22 12:37:09 UTC (rev 85592)
@@ -4,5 +4,5 @@
[test]
recipe = zc.recipe.testrunner
-eggs = zope.app.container [test]
+eggs = zope.container
Modified: Sandbox/malthe/zope.container/setup.py
===================================================================
--- Sandbox/malthe/zope.container/setup.py 2008-04-22 12:19:47 UTC (rev 85591)
+++ Sandbox/malthe/zope.container/setup.py 2008-04-22 12:37:09 UTC (rev 85592)
@@ -1,6 +1,6 @@
##############################################################################
#
-# Copyright (c) 2006 Zope Corporation and Contributors.
+# Copyright (c) 2008 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
@@ -11,7 +11,7 @@
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
-"""Setup for zope.app.container package
+"""Setup for zope.container package
$Id$
"""
@@ -21,7 +21,7 @@
def read(*rnames):
return open(os.path.join(os.path.dirname(__file__), *rnames)).read()
-setup(name='zope.app.container',
+setup(name='zope.container',
version = '3.6.0',
author='Zope Corporation and Contributors',
author_email='zope3-dev at zope.org',
@@ -32,7 +32,7 @@
'Detailed Documentation\n'
'**********************\n'
+ '\n\n' +
- read('src', 'zope', 'app', 'container', 'constraints.txt')
+ read('src', 'zope', 'container', 'constraints.txt')
+ '\n\n' +
read('CHANGES.txt')
),
@@ -47,43 +47,19 @@
'Operating System :: OS Independent',
'Topic :: Internet :: WWW/HTTP',
'Framework :: Zope3'],
- url='http://cheeseshop.python.org/pypi/zope.app.container',
+ url='http://cheeseshop.python.org/pypi/zope.container',
license='ZPL 2.1',
packages=find_packages('src'),
package_dir = {'': 'src'},
- namespace_packages=['zope', 'zope.app'],
- ext_modules=[Extension("zope.app.container._zope_app_container_contained",
- [os.path.join("src", "zope", "app", "container",
- "_zope_app_container_contained.c")
- ], include_dirs=['include']),
- ],
-
- extras_require=dict(test=['zope.app.testing',
- 'zope.app.securitypolicy',
- 'zope.app.zcmlfiles',
- 'zope.app.file']),
+ namespace_packages=['zope', ],
install_requires=['setuptools',
'zope.interface',
- 'zope.deprecation',
- 'zope.app.publisher',
- 'zope.cachedescriptors',
- 'zope.dottedname',
- 'zope.schema',
'zope.component',
- 'zope.event',
+ 'zope.size',
+ 'zope.dottedname',
'zope.location',
- 'zope.exceptions',
- 'zope.security',
'zope.lifecycleevent',
- 'zope.i18nmessageid',
- 'zope.filerepresentation',
- 'zope.size',
- 'zope.traversing',
- 'zope.publisher',
- 'zope.dublincore',
- 'zope.app.broken',
- 'zope.copypastemove',
- 'ZODB3',
+ 'zope.deprecation',
],
include_package_data = True,
zip_safe = False,
Copied: Sandbox/malthe/zope.container/src/zope/container/__init__.py (from rev 85590, Sandbox/malthe/zope.container/src/zope/app/container/__init__.py)
===================================================================
--- Sandbox/malthe/zope.container/src/zope/container/__init__.py (rev 0)
+++ Sandbox/malthe/zope.container/src/zope/container/__init__.py 2008-04-22 12:37:09 UTC (rev 85592)
@@ -0,0 +1,2 @@
+#
+# This file is necessary to make this directory a package.
Copied: Sandbox/malthe/zope.container/src/zope/container/constraints.py (from rev 85590, Sandbox/malthe/zope.container/src/zope/app/container/constraints.py)
===================================================================
--- Sandbox/malthe/zope.container/src/zope/container/constraints.py (rev 0)
+++ Sandbox/malthe/zope.container/src/zope/container/constraints.py 2008-04-22 12:37:09 UTC (rev 85592)
@@ -0,0 +1,461 @@
+##############################################################################
+#
+# Copyright (c) 2008 Zope Corporation 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.
+#
+##############################################################################
+"""Support for containment constraints
+
+ Either a container or an object can provide constraints on the
+ containment relationship.
+
+ A container expresses constraints through a precondition on it's
+ `__setitem__` method in it's interface.
+
+ Preconditions can be simple callable objects, like functions. They
+ should raise a ``zope.interface.Invalid`` exception to indicate that a
+ constraint isn't satisfied:
+
+ >>> def preNoZ(container, name, ob):
+ ... "Silly precondition example"
+ ... if name.startswith("Z"):
+ ... raise zope.interface.Invalid("Names can not start with Z")
+
+ >>> class I1(zope.interface.Interface):
+ ... def __setitem__(name, on):
+ ... "Add an item"
+ ... __setitem__.precondition = preNoZ
+
+ >>> from zope.container.interfaces import IContainer
+ >>> class C1(object):
+ ... zope.interface.implements(I1, IContainer)
+ ... def __repr__(self):
+ ... return 'C1'
+
+ Given such a precondition, we can then check whether an object can be
+ added:
+
+ >>> c1 = C1()
+ >>> checkObject(c1, "bob", None)
+ >>> checkObject(c1, "Zbob", None)
+ Traceback (most recent call last):
+ ...
+ Invalid: Names can not start with Z
+
+ We can also express constaints on the containers an object can be
+ added to. We do this by setting a field constraint on an object's
+ `__parent__` attribute:
+
+ >>> import zope.schema
+
+ A field constraint is a callable object that returns a boolean value:
+
+ >>> def con1(container):
+ ... "silly container constraint"
+ ... if not hasattr(container, 'x'):
+ ... return False
+ ... return True
+
+ >>> class I2(zope.interface.Interface):
+ ... __parent__ = zope.schema.Field(constraint = con1)
+
+ >>> class O(object):
+ ... zope.interface.implements(I2)
+
+ If the constraint isn't satisfied, we'll get a validation error when we
+ check whether the object can be added:
+
+ >>> checkObject(c1, "bob", O())
+ Traceback (most recent call last):
+ ...
+ ConstraintNotSatisfied: C1
+
+ Note that the validation error isn't very informative. For that
+ reason, it's better for constraints to raise Invalid errors when they
+ aren't satisfied:
+
+ >>> def con1(container):
+ ... "silly container constraint"
+ ... if not hasattr(container, 'x'):
+ ... raise zope.interface.Invalid("What, no x?")
+ ... return True
+
+ >>> class I2(zope.interface.Interface):
+ ... __parent__ = zope.schema.Field(constraint = con1)
+
+ >>> class O(object):
+ ... zope.interface.implements(I2)
+
+ >>> checkObject(c1, "bob", O())
+ Traceback (most recent call last):
+ ...
+ Invalid: What, no x?
+
+ >>> c1.x = 1
+ >>> checkObject(c1, "bob", O())
+
+ The `checkObject` function is handy when checking whether we can add an
+ existing object to a container, but, sometimes, we want to check
+ whether an object produced by a factory can be added. To do this, we
+ use `checkFactory`:
+
+ >>> class Factory(object):
+ ... def __call__(self):
+ ... return O()
+ ... def getInterfaces(self):
+ ... return zope.interface.implementedBy(O)
+
+ >>> factory = Factory()
+
+ >>> checkFactory(c1, "bob", factory)
+ True
+
+ >>> del c1.x
+ >>> checkFactory(c1, "bob", factory)
+ False
+
+ Unlike `checkObject`, `checkFactory`:
+
+ - Returns a boolean value
+
+ - Takes a factory (e.g. a class) rather than an argument.
+
+ The container constraint we defined for C1 isn't actually used to
+ check the factory:
+
+ >>> c1.x = 1
+ >>> checkFactory(c1, "Zbob", factory)
+ True
+
+ To work with `checkFactory`, a container precondition has to
+ implement a factory method. This is because a factory, rather than
+ an object is passed. To illustrate this, we'll make preNoZ its own
+ factory method:
+
+ >>> preNoZ.factory = preNoZ
+
+ We can do this (silly thing) because preNoZ doesn't use the object
+ argument.
+
+ >>> checkFactory(c1, "Zbob", factory)
+ False
+
+ $Id$
+ """
+__docformat__ = 'restructuredtext'
+
+import sys
+
+from zope.container.property import readproperty
+from zope.dottedname.resolve import resolve
+import zope.schema
+from zope.interface import providedBy
+from zope.container.interfaces import InvalidItemType, InvalidContainerType
+from zope.container.i18n import ZopeMessageFactory as _
+from zope.container.interfaces import IContainer
+
+def checkObject(container, name, object):
+ """Check containement constraints for an object and container
+ """
+
+ # check __setitem__ precondition
+ containerProvided = providedBy(container)
+ __setitem__ = containerProvided.get('__setitem__')
+ if __setitem__ is not None:
+ precondition = __setitem__.queryTaggedValue('precondition')
+ if precondition is not None:
+ precondition(container, name, object)
+
+ # check the constraint on __parent__
+ __parent__ = providedBy(object).get('__parent__')
+ if __parent__ is not None:
+ try:
+ validate = __parent__.validate
+ except AttributeError:
+ pass
+ else:
+ validate(container)
+
+
+ if not containerProvided.extends(IContainer):
+ # If it doesn't implement IContainer, it can't contain stuff.
+ raise TypeError(
+ _('Container is not a valid Zope container.')
+ )
+
+def checkFactory(container, name, factory):
+ __setitem__ = providedBy(container).get('__setitem__')
+ if __setitem__ is not None:
+ precondition = __setitem__.queryTaggedValue('precondition')
+ if precondition is not None:
+ try:
+ precondition = precondition.factory
+ except AttributeError:
+ pass
+ else:
+ try:
+ precondition(container, name, factory)
+ except zope.interface.Invalid:
+ return False
+
+ # check the constraint on __parent__
+ __parent__ = factory.getInterfaces().get('__parent__')
+ if __parent__ is not None:
+ try:
+ validate = __parent__.validate
+ except AttributeError:
+ pass
+ else:
+ try:
+ validate(container)
+ except zope.interface.Invalid:
+ return False
+
+ return True
+
+class IItemTypePrecondition(zope.interface.Interface):
+
+ def __call__(container, name, object):
+ """Test whether container setitem arguments are valid.
+
+ Raise zope.interface.Invalid if the object is invalid.
+ """
+
+ def factory(container, name, factory):
+ """Test whether objects provided by the factory are acceptable
+
+ Return a boolean value.
+ """
+
+
+class _TypesBased(object):
+
+ @readproperty
+ def types(self):
+ raw_types, module = self.raw_types
+ types = []
+ for t in raw_types:
+ if isinstance(t, str):
+ t = resolve(t, module)
+ types.append(t)
+
+ self.types = types
+ return types
+
+ def __init__(self, *types, **kw):
+ if [t for t in types if isinstance(t, str)]:
+ # have dotted names
+ module = kw.get('module', sys._getframe(1).f_globals['__name__'])
+ self.raw_types = types, module
+ else:
+ self.types = types
+
+
+class ItemTypePrecondition(_TypesBased):
+ """Specify a `__setitem__` precondition that restricts item types
+
+ Items must be one of the given types.
+
+ >>> class I1(zope.interface.Interface):
+ ... pass
+ >>> class I2(zope.interface.Interface):
+ ... pass
+
+
+ >>> precondition = ItemTypePrecondition(I1, I2)
+
+ >>> class Ob(object):
+ ... pass
+ >>> ob = Ob()
+
+ >>> class Factory(object):
+ ... def __call__(self):
+ ... return Ob()
+ ... def getInterfaces(self):
+ ... return zope.interface.implementedBy(Ob)
+
+ >>> factory = Factory()
+
+ >>> try:
+ ... precondition(None, 'foo', ob)
+ ... except InvalidItemType, v:
+ ... print v[0], (v[1] is ob), (v[2] == (I1, I2))
+ ... else:
+ ... print 'Should have failed'
+ None True True
+
+ >>> try:
+ ... precondition.factory(None, 'foo', factory)
+ ... except InvalidItemType, v:
+ ... print v[0], (v[1] is factory), (v[2] == (I1, I2))
+ ... else:
+ ... print 'Should have failed'
+ None True True
+
+ >>> zope.interface.classImplements(Ob, I2)
+ >>> precondition(None, 'foo', ob)
+ >>> precondition.factory(None, 'foo', factory)
+
+ """
+
+ zope.interface.implements(IItemTypePrecondition)
+
+ def __call__(self, container, name, object):
+ for iface in self.types:
+ if iface.providedBy(object):
+ return
+ raise InvalidItemType(container, object, self.types)
+
+ def factory(self, container, name, factory):
+ implemented = factory.getInterfaces()
+
+ for iface in self.types:
+ if implemented.isOrExtends(iface):
+ return
+ raise InvalidItemType(container, factory, self.types)
+
+
+def contains(*types):
+ """Declare that a container type contains only the given types
+
+ This is used within a class suite defining an interface to create
+ a __setitem__ specification with a precondition allowing only the
+ given types:
+
+ >>> class IFoo(zope.interface.Interface):
+ ... pass
+ >>> class IBar(zope.interface.Interface):
+ ... pass
+ >>> class IFooBarContainer(IContainer):
+ ... contains(IFoo, IBar)
+
+ >>> __setitem__ = IFooBarContainer['__setitem__']
+ >>> __setitem__.getTaggedValue('precondition').types == (IFoo, IBar)
+ True
+
+ It is invalid to call contains outside a class suite:
+
+ >>> contains(IFoo, IBar)
+ Traceback (most recent call last):
+ ...
+ TypeError: contains not called from suite
+ """
+
+ frame = sys._getframe(1)
+ f_locals = frame.f_locals
+ f_globals = frame.f_globals
+
+ if not (f_locals is not f_globals
+ and f_locals.get('__module__')
+ and f_locals.get('__module__') == f_globals.get('__name__')
+ ):
+ raise TypeError("contains not called from suite")
+
+ def __setitem__(key, value):
+ pass
+ __setitem__.__doc__ = IContainer['__setitem__'].__doc__
+ __setitem__.precondition = ItemTypePrecondition(
+ *types,
+ **dict(module=f_globals['__name__'])
+ )
+ f_locals['__setitem__'] = __setitem__
+
+
+class IContainerTypesConstraint(zope.interface.Interface):
+
+ def __call__(object):
+ """Test whether object is valid.
+
+ Return True if valid.
+ Raise zope.interface.Invalid if the objet is invalid.
+ """
+
+
+class ContainerTypesConstraint(_TypesBased):
+ """Constrain a container to be one of a number of types
+
+ >>> class I1(zope.interface.Interface):
+ ... pass
+ >>> class I2(zope.interface.Interface):
+ ... pass
+ >>> class Ob(object):
+ ... pass
+ >>> ob = Ob()
+ >>> constraint = ContainerTypesConstraint(I1, I2)
+ >>> try:
+ ... constraint(ob)
+ ... except InvalidContainerType, v:
+ ... print (v[0] is ob), (v[1] == (I1, I2))
+ ... else:
+ ... print 'Should have failed'
+ True True
+
+ >>> zope.interface.classImplements(Ob, I2)
+ >>> constraint(Ob())
+ True
+
+ """
+
+ zope.interface.implements(IContainerTypesConstraint)
+
+ def __call__(self, object):
+ for iface in self.types:
+ if iface.providedBy(object):
+ return True
+ else:
+ raise InvalidContainerType(object, self.types)
+
+
+def containers(*types):
+ """Declare the container types a type can be contained in
+
+ This is used within a class suite defining an interface to create
+ a __parent__ specification with a constraint allowing only the
+ given types:
+
+ >>> class IFoo(IContainer):
+ ... pass
+ >>> class IBar(IContainer):
+ ... pass
+
+ >>> from zope.container.interfaces import IContained
+ >>> class IFooBarContained(IContained):
+ ... containers(IFoo, IBar)
+
+ >>> __parent__ = IFooBarContained['__parent__']
+ >>> __parent__.constraint.types == (IFoo, IBar)
+ True
+
+ It is invalid to call containers outside a class suite:
+
+ >>> containers(IFoo, IBar)
+ Traceback (most recent call last):
+ ...
+ TypeError: containers not called from suite
+ """
+
+ frame = sys._getframe(1)
+ f_locals = frame.f_locals
+ f_globals = frame.f_globals
+
+ if not (f_locals is not f_globals
+ and f_locals.get('__module__')
+ and f_locals.get('__module__') == f_globals.get('__name__')
+ ):
+ raise TypeError("containers not called from suite")
+
+ __parent__ = zope.schema.Field(
+ constraint = ContainerTypesConstraint(
+ *types,
+ **dict(module=f_globals['__name__'])
+ )
+ )
+ f_locals['__parent__'] = __parent__
+
Copied: Sandbox/malthe/zope.container/src/zope/container/constraints.txt (from rev 85590, Sandbox/malthe/zope.container/src/zope/app/container/constraints.txt)
===================================================================
--- Sandbox/malthe/zope.container/src/zope/container/constraints.txt (rev 0)
+++ Sandbox/malthe/zope.container/src/zope/container/constraints.txt 2008-04-22 12:37:09 UTC (rev 85592)
@@ -0,0 +1,97 @@
+Containment constraints
+=======================
+
+Containment constraints allow us to express restrictions on the types
+of items that can be placed in containers or on the types of
+containers an item can be placed in. We express these constraints in
+interfaces. Let's define some container and item interfaces:
+
+ >>> from zope.container.interfaces import IContainer, IContained
+ >>> from zope.container.constraints import containers, contains
+
+ >>> class IBuddyFolder(IContainer):
+ ... contains('.IBuddy')
+
+
+In this example, we used the contains function to declare that objects
+that provide IBuddyFolder can only contain items that provide IBuddy.
+Note that we used a string containing a dotted name for the IBuddy
+interface. This is because IBuddy hasn't been defined yet. When we
+define IBuddy, we can use IBuddyFolder directly:
+
+ >>> class IBuddy(IContained):
+ ... containers(IBuddyFolder)
+
+
+Now, with these interfaces in place, we can define Buddy and
+BuddyFolder classes and verify that we can put buddies in buddy
+folders:
+
+ >>> from zope import interface
+
+ >>> class Buddy:
+ ... interface.implements(IBuddy)
+
+ >>> class BuddyFolder:
+ ... interface.implements(IBuddyFolder)
+
+ >>> from zope.container.constraints import checkObject, checkFactory
+ >>> from zope.component.factory import Factory
+
+ >>> checkObject(BuddyFolder(), 'x', Buddy())
+ >>> checkFactory(BuddyFolder(), 'x', Factory(Buddy))
+ True
+
+If we try to use other containers or folders, we'll get errors:
+
+ >>> class Container:
+ ... interface.implements(IContainer)
+
+ >>> class Contained:
+ ... interface.implements(IContained)
+
+ >>> checkObject(Container(), 'x', Buddy())
+ ... # doctest: +ELLIPSIS
+ Traceback (most recent call last):
+ InvalidContainerType: ...
+
+ >>> checkFactory(Container(), 'x', Factory(Buddy))
+ False
+
+ >>> checkObject(BuddyFolder(), 'x', Contained())
+ ... # doctest: +ELLIPSIS
+ Traceback (most recent call last):
+ InvalidItemType: ...
+
+ >>> checkFactory(BuddyFolder(), 'x', Factory(Contained))
+ False
+
+In the example, we defined the container first and then the items. We
+could have defined these in the opposite order:
+
+ >>> class IContact(IContained):
+ ... containers('.IContacts')
+
+ >>> class IContacts(IContainer):
+ ... contains(IContact)
+
+ >>> class Contact:
+ ... interface.implements(IContact)
+
+ >>> class Contacts:
+ ... interface.implements(IContacts)
+
+ >>> checkObject(Contacts(), 'x', Contact())
+
+ >>> checkFactory(Contacts(), 'x', Factory(Contact))
+ True
+
+ >>> checkObject(Contacts(), 'x', Buddy())
+ ... # doctest: +ELLIPSIS
+ Traceback (most recent call last):
+ InvalidItemType: ...
+
+ >>> checkFactory(Contacts(), 'x', Factory(Buddy))
+ False
+
+
Copied: Sandbox/malthe/zope.container/src/zope/container/find.py (from rev 85590, Sandbox/malthe/zope.container/src/zope/app/container/find.py)
===================================================================
--- Sandbox/malthe/zope.container/src/zope/container/find.py (rev 0)
+++ Sandbox/malthe/zope.container/src/zope/container/find.py 2008-04-22 12:37:09 UTC (rev 85592)
@@ -0,0 +1,89 @@
+##############################################################################
+#
+# Copyright (c) 2008 Zope Corporation 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.
+#
+##############################################################################
+"""Find Support
+
+$Id$
+"""
+__docformat__ = 'restructuredtext'
+
+from zope.interface import implements
+from interfaces import IFind, IIdFindFilter, IObjectFindFilter
+from interfaces import IReadContainer
+
+class FindAdapter(object):
+
+ implements(IFind)
+
+ __used_for__ = IReadContainer
+
+ def __init__(self, context):
+ self._context = context
+
+ def find(self, id_filters=None, object_filters=None):
+ 'See IFind'
+ id_filters = id_filters or []
+ object_filters = object_filters or []
+ result = []
+ container = self._context
+ for id, object in container.items():
+ _find_helper(id, object, container,
+ id_filters, object_filters,
+ result)
+ return result
+
+
+def _find_helper(id, object, container, id_filters, object_filters, result):
+ for id_filter in id_filters:
+ if not id_filter.matches(id):
+ break
+ else:
+ # if we didn't break out of the loop, all name filters matched
+ # now check all object filters
+ for object_filter in object_filters:
+ if not object_filter.matches(object):
+ break
+ else:
+ # if we didn't break out of the loop, all filters matched
+ result.append(object)
+
+ if not IReadContainer.providedBy(object):
+ return
+
+ container = object
+ for id, object in container.items():
+ _find_helper(id, object, container, id_filters, object_filters, result)
+
+class SimpleIdFindFilter(object):
+
+ implements(IIdFindFilter)
+
+ def __init__(self, ids):
+ self._ids = ids
+
+ def matches(self, id):
+ 'See INameFindFilter'
+ return id in self._ids
+
+class SimpleInterfacesFindFilter(object):
+ """Filter objects on the provided interfaces"""
+ implements(IObjectFindFilter)
+
+ def __init__(self, *interfaces):
+ self.interfaces = interfaces
+
+ def matches(self, object):
+ for iface in self.interfaces:
+ if iface.providedBy(object):
+ return True
+ return False
Copied: Sandbox/malthe/zope.container/src/zope/container/i18n.py (from rev 85590, Sandbox/malthe/zope.container/src/zope/app/container/i18n.py)
===================================================================
--- Sandbox/malthe/zope.container/src/zope/container/i18n.py (rev 0)
+++ Sandbox/malthe/zope.container/src/zope/container/i18n.py 2008-04-22 12:37:09 UTC (rev 85592)
@@ -0,0 +1,22 @@
+##############################################################################
+#
+# Copyright (c) 2008 Zope Corporation 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.
+#
+##############################################################################
+"""Customization of zope.i18n for the Zope application server
+
+$Id$
+"""
+__docformat__ = 'restructuredtext'
+
+# import this as _ to create i18n messages in the zope domain
+from zope.i18nmessageid import MessageFactory
+ZopeMessageFactory = MessageFactory('zope')
Copied: Sandbox/malthe/zope.container/src/zope/container/interfaces.py (from rev 85590, Sandbox/malthe/zope.container/src/zope/app/container/interfaces.py)
===================================================================
--- Sandbox/malthe/zope.container/src/zope/container/interfaces.py (rev 0)
+++ Sandbox/malthe/zope.container/src/zope/container/interfaces.py 2008-04-22 12:37:09 UTC (rev 85592)
@@ -0,0 +1,341 @@
+##############################################################################
+#
+# Copyright (c) 2008 Zope Corporation 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.
+#
+##############################################################################
+"""Container-related interfaces
+
+$Id$
+"""
+__docformat__ = 'restructuredtext'
+
+from zope.deprecation import deprecated
+
+from zope.interface import Interface, Attribute, Invalid
+from zope.component.interfaces import IView, IObjectEvent
+from zope.interface.common.mapping import IItemMapping
+from zope.interface.common.mapping import IReadMapping, IEnumerableMapping
+from zope.location.interfaces import ILocation
+from zope.lifecycleevent.interfaces import IObjectModifiedEvent
+
+deprecated('IContentContainer',
+ 'This interface has been deprecated. '
+ 'Check the "containerViews" zcml directive. '
+ 'The reference will be gone in 3.3')
+
+class DuplicateIDError(KeyError):
+ pass
+
+class ContainerError(Exception):
+ """An error of a container with one of its components."""
+
+class InvalidContainerType(Invalid, TypeError):
+ """The type of a container is not valid."""
+
+class InvalidItemType(Invalid, TypeError):
+ """The type of an item is not valid."""
+
+class InvalidType(Invalid, TypeError):
+ """The type of an object is not valid."""
+
+
+
+class IContained(ILocation):
+ """Objects contained in containers."""
+
+
+class IItemContainer(IItemMapping):
+ """Minimal readable container."""
+
+
+class ISimpleReadContainer(IItemContainer, IReadMapping):
+ """Readable content containers."""
+
+
+class IReadContainer(ISimpleReadContainer, IEnumerableMapping):
+ """Readable containers that can be enumerated."""
+
+
+class IWriteContainer(Interface):
+ """An interface for the write aspects of a container."""
+
+ def __setitem__(name, object):
+ """Add the given `object` to the container under the given name.
+
+ Raises a ``TypeError`` if the key is not a unicode or ascii string.
+ Raises a ``ValueError`` if key is empty.
+
+ The container might choose to add a different object than the
+ one passed to this method.
+
+ If the object doesn't implement `IContained`, then one of two
+ things must be done:
+
+ 1. If the object implements `ILocation`, then the `IContained`
+ interface must be declared for the object.
+
+ 2. Otherwise, a `ContainedProxy` is created for the object and
+ stored.
+
+ The object's `__parent__` and `__name__` attributes are set to the
+ container and the given name.
+
+ If the old parent was ``None``, then an `IObjectAddedEvent` is
+ generated, otherwise, an `IObjectMovedEvent` is generated. An
+ `IContainerModifiedEvent` is generated for the container.
+
+ If the object replaces another object, then the old object is
+ deleted before the new object is added, unless the container
+ vetos the replacement by raising an exception.
+
+ If the object's `__parent__` and `__name__` were already set to
+ the container and the name, then no events are generated and
+ no hooks. This allows advanced clients to take over event
+ generation.
+
+ """
+
+ def __delitem__(name):
+ """Delete the named object from the container.
+
+ Raises a ``KeyError`` if the object is not found.
+
+ If the deleted object's `__parent__` and `__name__` match the
+ container and given name, then an `IObjectRemovedEvent` is
+ generated and the attributes are set to ``None``. If the object
+ can be adapted to `IObjectMovedEvent`, then the adapter's
+ `moveNotify` method is called with the event.
+
+ Unless the object's `__parent__` and `__name__` attributes were
+ initially ``None``, generate an `IContainerModifiedEvent` for the
+ container.
+
+ If the object's `__parent__` and `__name__` were already set to
+ ``None``, then no events are generated. This allows advanced
+ clients to take over event generation.
+
+ """
+
+
+class IItemWriteContainer(IWriteContainer, IItemContainer):
+ """A write container that also supports minimal reads."""
+
+
+class IContentContainer(IWriteContainer):
+ """Containers (like folders) that contain ordinary content."""
+
+
+class IContainer(IReadContainer, IWriteContainer):
+ """Readable and writable content container."""
+
+
+class IBTreeContainer(IContainer):
+ """Container that supports BTree semantics for some methods."""
+
+ def items(key=None):
+ """Return an iterator over the key-value pairs in the container.
+
+ If ``None`` is passed as `key`, this method behaves as if no argument
+ were passed; exactly as required for ``IContainer.items()``.
+
+ If `key` is in the container, the first item provided by the iterator
+ will correspond to that key. Otherwise, the first item will be for
+ the key that would come next if `key` were in the container.
+
+ """
+
+ def keys(key=None):
+ """Return an iterator over the keys in the container.
+
+ If ``None`` is passed as `key`, this method behaves as if no argument
+ were passed; exactly as required for ``IContainer.keys()``.
+
+ If `key` is in the container, the first key provided by the iterator
+ will be that key. Otherwise, the first key will be the one that would
+ come next if `key` were in the container.
+
+ """
+
+ def values(key=None):
+ """Return an iterator over the values in the container.
+
+ If ``None`` is passed as `key`, this method behaves as if no argument
+ were passed; exactly as required for ``IContainer.values()``.
+
+ If `key` is in the container, the first value provided by the iterator
+ will correspond to that key. Otherwise, the first value will be for
+ the key that would come next if `key` were in the container.
+
+ """
+
+
+class IOrderedContainer(IContainer):
+ """Containers whose contents are maintained in order."""
+
+ def updateOrder(order):
+ """Revise the order of keys, replacing the current ordering.
+
+ order is a list or a tuple containing the set of existing keys in
+ the new order. `order` must contain ``len(keys())`` items and cannot
+ contain duplicate keys.
+
+ Raises ``TypeError`` if order is not a tuple or a list.
+
+ Raises ``ValueError`` if order contains an invalid set of keys.
+ """
+
+
+class IContainerNamesContainer(IContainer):
+ """Containers that always choose names for their items."""
+
+
+##############################################################################
+# Moving Objects
+
+class IObjectMovedEvent(IObjectEvent):
+ """An object has been moved."""
+
+ oldParent = Attribute("The old location parent for the object.")
+ oldName = Attribute("The old location name for the object.")
+ newParent = Attribute("The new location parent for the object.")
+ newName = Attribute("The new location name for the object.")
+
+
+##############################################################################
+# Adding objects
+
+class UnaddableError(ContainerError):
+ """An object cannot be added to a container."""
+
+ def __init__(self, container, obj, message=""):
+ self.container = container
+ self.obj = obj
+ self.message = message and ": %s" % message
+
+ def __str__(self):
+ return ("%(obj)s cannot be added "
+ "to %(container)s%(message)s" % self.__dict__)
+
+
+class IObjectAddedEvent(IObjectMovedEvent):
+ """An object has been added to a container."""
+
+
+class IAdding(IView):
+
+ def add(content):
+ """Add content object to container.
+
+ Add using the name in `contentName`. Returns the added object
+ in the context of its container.
+
+ If `contentName` is already used in container, raises
+ ``DuplicateIDError``.
+ """
+
+ contentName = Attribute(
+ """The content name, as usually set by the Adder traverser.
+
+ If the content name hasn't been defined yet, returns ``None``.
+
+ Some creation views might use this to optionally display the
+ name on forms.
+ """
+ )
+
+ def nextURL():
+ """Return the URL that the creation view should redirect to.
+
+ This is called by the creation view after calling add.
+
+ It is the adder's responsibility, not the creation view's to
+ decide what page to display after content is added.
+ """
+
+ def nameAllowed():
+ """Return whether names can be input by the user."""
+
+ def addingInfo():
+ """Return add menu data as a sequence of mappings.
+
+ Each mapping contains 'action', 'title', and possibly other keys.
+
+ The result is sorted by title.
+ """
+
+ def isSingleMenuItem():
+ """Return whether there is single menu item or not."""
+
+ def hasCustomAddView():
+ "This should be called only if there is `singleMenuItem` else return 0"
+
+
+class INameChooser(Interface):
+
+ def checkName(name, object):
+ """Check whether an object name is valid.
+
+ Raises a user error if the name is not valid.
+ """
+
+ def chooseName(name, object):
+ """Choose a unique valid name for the object
+
+ The given name and object may be taken into account when
+ choosing the name.
+ """
+
+
+##############################################################################
+# Removing objects
+
+
+class IObjectRemovedEvent(IObjectMovedEvent):
+ """An object has been removed from a container."""
+
+
+##############################################################################
+# Modifying containers
+
+
+class IContainerModifiedEvent(IObjectModifiedEvent):
+ """The container has been modified.
+
+ This event is specific to "containerness" modifications, which means
+ addition, removal or reordering of sub-objects.
+ """
+
+
+##############################################################################
+# Finding objects
+
+class IFind(Interface):
+ """
+ Find support for containers.
+ """
+
+ def find(id_filters=None, object_filters=None):
+ """Find object that matches all filters in all sub-objects.
+
+ This container itself is not included.
+ """
+
+
+class IObjectFindFilter(Interface):
+
+ def matches(object):
+ """Return True if the object matches the filter criteria."""
+
+
+class IIdFindFilter(Interface):
+
+ def matches(id):
+ """Return True if the id matches the filter criteria."""
Copied: Sandbox/malthe/zope.container/src/zope/container/property.py (from rev 85591, zope.cachedescriptors/trunk/src/zope/cachedescriptors/property.py)
===================================================================
--- Sandbox/malthe/zope.container/src/zope/container/property.py (rev 0)
+++ Sandbox/malthe/zope.container/src/zope/container/property.py 2008-04-22 12:37:09 UTC (rev 85592)
@@ -0,0 +1,106 @@
+##############################################################################
+# Copyright (c) 2008 Zope Corporation 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.
+##############################################################################
+"""Cached properties
+
+See the CachedProperty class.
+
+$Id$
+"""
+
+ncaches = 0l
+
+
+class CachedProperty(object):
+ """Cached Properties.
+ """
+
+ def __init__(self, func, *names):
+ global ncaches
+ ncaches += 1
+ self.data = (func, names,
+ "_v_cached_property_key_%s" % ncaches,
+ "_v_cached_property_value_%s" % ncaches)
+
+ def __get__(self, inst, class_):
+ if inst is None:
+ return self
+
+ func, names, key_name, value_name = self.data
+
+ key = names and [getattr(inst, name) for name in names]
+ value = getattr(inst, value_name, self)
+
+ if value is not self:
+ # We have a cached value
+ if key == getattr(inst, key_name, self):
+ # Cache is still good!
+ return value
+
+ # We need to compute and cache the value
+
+ value = func(inst)
+ setattr(inst, key_name, key)
+ setattr(inst, value_name, value)
+
+ return value
+
+
+class Lazy(object):
+ """Lazy Attributes.
+ """
+
+ def __init__(self, func, name=None):
+ if name is None:
+ name = func.__name__
+ self.data = (func, name)
+
+ def __get__(self, inst, class_):
+ if inst is None:
+ return self
+
+ func, name = self.data
+ value = func(inst)
+ inst.__dict__[name] = value
+
+ return value
+
+
+class readproperty(object):
+
+ def __init__(self, func):
+ self.func = func
+
+ def __get__(self, inst, class_):
+ if inst is None:
+ return self
+
+ func = self.func
+ return func(inst)
+
+
+class cachedIn(object):
+ """Cached property with given cache attribute."""
+
+ def __init__(self, attribute_name):
+ self.attribute_name = attribute_name
+
+ def __call__(self, func):
+
+ def get(instance):
+ try:
+ value = getattr(instance, self.attribute_name)
+ except AttributeError:
+ value = func(instance)
+ setattr(instance, self.attribute_name, value)
+ return value
+
+ return property(get)
Copied: Sandbox/malthe/zope.container/src/zope/container/property.txt (from rev 85591, zope.cachedescriptors/trunk/src/zope/cachedescriptors/property.txt)
===================================================================
--- Sandbox/malthe/zope.container/src/zope/container/property.txt (rev 0)
+++ Sandbox/malthe/zope.container/src/zope/container/property.txt 2008-04-22 12:37:09 UTC (rev 85592)
@@ -0,0 +1,208 @@
+Cached Properties
+=================
+
+Cached properties are computed properties that cache their computed
+values. They take into account instance attributes that they depend
+on, so when the instance attributes change, the properties will change
+the values they return.
+
+Cached properties cache their data in _v_ attributes, so they are
+also useful for managing the computation of volatile attributes for
+persistent objects. Let's look at an example::
+
+ >>> from zope.container import property
+ >>> import math
+
+ >>> class Point:
+ ...
+ ... def __init__(self, x, y):
+ ... self.x, self.y = x, y
+ ...
+ ... def radius(self):
+ ... print 'computing radius'
+ ... return math.sqrt(self.x**2 + self.y**2)
+ ... radius = property.CachedProperty(radius, 'x', 'y')
+
+ >>> point = Point(1.0, 2.0)
+
+If we ask for the radius the first time::
+
+ >>> '%.2f' % point.radius
+ computing radius
+ '2.24'
+
+We see that the radius function is called, but if we ask for it again::
+
+ >>> '%.2f' % point.radius
+ '2.24'
+
+The function isn't called. If we change one of the attribute the
+radius depends on, it will be recomputed::
+
+ >>> point.x = 2.0
+ >>> '%.2f' % point.radius
+ computing radius
+ '2.83'
+
+But changing other attributes doesn't cause recomputation::
+
+ >>> point.q = 1
+ >>> '%.2f' % point.radius
+ '2.83'
+
+Note that we don't have any non-volitile attributes added::
+
+ >>> names = [name for name in point.__dict__ if not name.startswith('_v_')]
+ >>> names.sort()
+ >>> names
+ ['q', 'x', 'y']
+
+
+Lazy Computed Attributes
+------------------------
+
+The `property` module provides another descriptor that supports a
+slightly different caching model: lazy attributes. Like cached
+proprties, they are computed the first time they are used. however,
+they aren't stored in volatile attributes and they aren't
+automatically updated when other attributes change. Furthermore, the
+store their data using their attribute name, thus overriding
+themselves. This provides much faster attribute access after the
+attribute has been computed. Let's look at the previous example using
+lazy attributes::
+
+ >>> class Point:
+ ...
+ ... def __init__(self, x, y):
+ ... self.x, self.y = x, y
+ ...
+ ... def radius(self):
+ ... print 'computing radius'
+ ... return math.sqrt(self.x**2 + self.y**2)
+ ... radius = property.Lazy(radius)
+
+ >>> point = Point(1.0, 2.0)
+
+If we ask for the radius the first time::
+
+ >>> '%.2f' % point.radius
+ computing radius
+ '2.24'
+
+We see that the radius function is called, but if we ask for it again::
+
+ >>> '%.2f' % point.radius
+ '2.24'
+
+The function isn't called. If we change one of the attribute the
+radius depends on, it still isn't called::
+
+ >>> point.x = 2.0
+ >>> '%.2f' % point.radius
+ '2.24'
+
+If we want the radius to be recomputed, we have to manually delete it::
+
+ >>> del point.radius
+
+ >>> point.x = 2.0
+ >>> '%.2f' % point.radius
+ computing radius
+ '2.83'
+
+Note that the radius is stored in the instance dictionary::
+
+ >>> '%.2f' % point.__dict__['radius']
+ '2.83'
+
+The lazy attribute needs to know the attribute name. It normally
+deduces the attribute name from the name of the function passed. If we
+want to use a different name, we need to pass it::
+
+ >>> def d(point):
+ ... print 'computing diameter'
+ ... return 2*point.radius
+
+ >>> Point.diameter = property.Lazy(d, 'diameter')
+ >>> '%.2f' % point.diameter
+ computing diameter
+ '5.66'
+
+
+readproperties
+==============
+
+readproperties are like lazy computed attributes except that the
+attribute isn't set by the property::
+
+
+ >>> class Point:
+ ...
+ ... def __init__(self, x, y):
+ ... self.x, self.y = x, y
+ ...
+ ... def radius(self):
+ ... print 'computing radius'
+ ... return math.sqrt(self.x**2 + self.y**2)
+ ... radius = property.readproperty(radius)
+
+ >>> point = Point(1.0, 2.0)
+
+ >>> '%.2f' % point.radius
+ computing radius
+ '2.24'
+
+ >>> '%.2f' % point.radius
+ computing radius
+ '2.24'
+
+But you *can* replace the property by setting a value. This is the major
+difference to the builtin `property`::
+
+ >>> point.radius = 5
+ >>> point.radius
+ 5
+
+
+cachedIn
+========
+
+The `cachedIn` property allows to specify the attribute where to store the
+computed value::
+
+ >>> class Point:
+ ...
+ ... def __init__(self, x, y):
+ ... self.x, self.y = x, y
+ ...
+ ... @property.cachedIn('_radius_attribute')
+ ... def radius(self):
+ ... print 'computing radius'
+ ... return math.sqrt(self.x**2 + self.y**2)
+
+ >>> point = Point(1.0, 2.0)
+
+ >>> '%.2f' % point.radius
+ computing radius
+ '2.24'
+
+ >>> '%.2f' % point.radius
+ '2.24'
+
+The radius is cached in the attribute with the given name, `_radius_attribute`
+in this case::
+
+ >>> '%.2f' % point._radius_attribute
+ '2.24'
+
+When the attribute is removed the radius is re-calculated once. This allows
+invalidation::
+
+ >>> del point._radius_attribute
+
+ >>> '%.2f' % point.radius
+ computing radius
+ '2.24'
+
+ >>> '%.2f' % point.radius
+ '2.24'
Copied: Sandbox/malthe/zope.container/src/zope/container/size.py (from rev 85590, Sandbox/malthe/zope.container/src/zope/app/container/size.py)
===================================================================
--- Sandbox/malthe/zope.container/src/zope/container/size.py (rev 0)
+++ Sandbox/malthe/zope.container/src/zope/container/size.py 2008-04-22 12:37:09 UTC (rev 85592)
@@ -0,0 +1,40 @@
+##############################################################################
+#
+# Copyright (c) 2008 Zope Corporation 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.
+#
+##############################################################################
+"""Adapters that give the size of an object.
+
+$Id$
+"""
+__docformat__ = 'restructuredtext'
+
+from zope.container.i18n import ZopeMessageFactory as _
+from zope.size.interfaces import ISized
+from zope.interface import implements
+
+class ContainerSized(object):
+
+ implements(ISized)
+
+ def __init__(self, container):
+ self._container = container
+
+ def sizeForSorting(self):
+ """See `ISized`"""
+ return ('item', len(self._container))
+
+ def sizeForDisplay(self):
+ """See `ISized`"""
+ num_items = len(self._container)
+ if num_items == 1:
+ return _('1 item')
+ return _('${items} items', mapping={'items': str(num_items)})
Copied: Sandbox/malthe/zope.container/src/zope/container/tests (from rev 85590, Sandbox/malthe/zope.container/src/zope/app/container/tests)
Deleted: Sandbox/malthe/zope.container/src/zope/container/tests/placelesssetup.py
===================================================================
--- Sandbox/malthe/zope.container/src/zope/app/container/tests/placelesssetup.py 2008-04-22 12:11:58 UTC (rev 85590)
+++ Sandbox/malthe/zope.container/src/zope/container/tests/placelesssetup.py 2008-04-22 12:37:09 UTC (rev 85592)
@@ -1,25 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2002 Zope Corporation 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.
-#
-##############################################################################
-"""Unit test logic for setting up and tearing down basic infrastructure
-
-$Id$
-"""
-from zope.app.testing import ztapi
-from zope.app.container.interfaces import IWriteContainer, INameChooser
-from zope.app.container.contained import NameChooser
-
-class PlacelessSetup(object):
-
- def setUp(self):
- ztapi.provideAdapter(IWriteContainer, INameChooser, NameChooser)
Deleted: Sandbox/malthe/zope.container/src/zope/container/tests/test_btree.py
===================================================================
--- Sandbox/malthe/zope.container/src/zope/app/container/tests/test_btree.py 2008-04-22 12:11:58 UTC (rev 85590)
+++ Sandbox/malthe/zope.container/src/zope/container/tests/test_btree.py 2008-04-22 12:37:09 UTC (rev 85592)
@@ -1,165 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2004 Zope Corporation 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.
-#
-##############################################################################
-"""BTree Container Tests
-
-$Id$
-"""
-from unittest import TestCase, main, makeSuite, TestSuite
-from zope.interface.verify import verifyObject
-from zope.testing.doctestunit import DocTestSuite
-from zope.app.testing import placelesssetup
-from test_icontainer import TestSampleContainer
-from zope.app.container.btree import BTreeContainer
-from zope.app.container.interfaces import IBTreeContainer
-
-
-class TestBTreeContainer(TestSampleContainer, TestCase):
-
- def makeTestObject(self):
- return BTreeContainer()
-
-
-class TestBTreeSpecials(TestCase):
-
- def testStoredLength(self):
- # This is lazy for backward compatibility. If the len is not
- # stored already we set it to the length of the underlying
- # btree.
- bc = BTreeContainer()
- self.assertEqual(bc.__dict__['_BTreeContainer__len'](), 0)
- del bc.__dict__['_BTreeContainer__len']
- self.failIf(bc.__dict__.has_key('_BTreeContainer__len'))
- bc['1'] = 1
- self.assertEqual(len(bc), 1)
- self.assertEqual(bc.__dict__['_BTreeContainer__len'](), 1)
-
- # The tests which follow test the additional signatures and declarations
- # for the BTreeContainer that allow it to provide the IBTreeContainer
- # interface.
-
- def testBTreeContainerInterface(self):
- bc = BTreeContainer()
- self.assert_(verifyObject(IBTreeContainer, bc))
- self.checkIterable(bc.items())
- self.checkIterable(bc.keys())
- self.checkIterable(bc.values())
-
- def testEmptyItemsWithArg(self):
- bc = BTreeContainer()
- self.assertEqual(list(bc.items(None)), list(bc.items()))
- self.assertEqual(list(bc.items("")), [])
- self.assertEqual(list(bc.items("not-there")), [])
- self.checkIterable(bc.items(None))
- self.checkIterable(bc.items(""))
- self.checkIterable(bc.items("not-there"))
-
- def testEmptyKeysWithArg(self):
- bc = BTreeContainer()
- self.assertEqual(list(bc.keys(None)), list(bc.keys()))
- self.assertEqual(list(bc.keys("")), [])
- self.assertEqual(list(bc.keys("not-there")), [])
- self.checkIterable(bc.keys(None))
- self.checkIterable(bc.keys(""))
- self.checkIterable(bc.keys("not-there"))
-
- def testEmptyValuesWithArg(self):
- bc = BTreeContainer()
- self.assertEqual(list(bc.values(None)), list(bc.values()))
- self.assertEqual(list(bc.values("")), [])
- self.assertEqual(list(bc.values("not-there")), [])
- self.checkIterable(bc.values(None))
- self.checkIterable(bc.values(""))
- self.checkIterable(bc.values("not-there"))
-
- def testNonemptyItemsWithArg(self):
- bc = BTreeContainer()
- bc["0"] = 1
- bc["1"] = 2
- bc["2"] = 3
- self.assertEqual(list(bc.items(None)), list(bc.items()))
- self.assertEqual(list(bc.items("")), [("0", 1), ("1", 2), ("2", 3)])
- self.assertEqual(list(bc.items("3")), [])
- self.assertEqual(list(bc.items("2.")), [])
- self.assertEqual(list(bc.items("2")), [("2", 3)])
- self.assertEqual(list(bc.items("1.")), [("2", 3)])
- self.assertEqual(list(bc.items("1")), [("1", 2), ("2", 3)])
- self.assertEqual(list(bc.items("0.")), [("1", 2), ("2", 3)])
- self.assertEqual(list(bc.items("0")), [("0", 1), ("1", 2), ("2", 3)])
- self.checkIterable(bc.items(None))
- self.checkIterable(bc.items(""))
- self.checkIterable(bc.items("0."))
- self.checkIterable(bc.items("3"))
-
- def testNonemptyKeysWithArg(self):
- bc = BTreeContainer()
- bc["0"] = 1
- bc["1"] = 2
- bc["2"] = 3
- self.assertEqual(list(bc.keys(None)), list(bc.keys()))
- self.assertEqual(list(bc.keys("")), ["0", "1", "2"])
- self.assertEqual(list(bc.keys("3")), [])
- self.assertEqual(list(bc.keys("2.")), [])
- self.assertEqual(list(bc.keys("2")), ["2"])
- self.assertEqual(list(bc.keys("1.")), ["2"])
- self.assertEqual(list(bc.keys("1")), ["1", "2"])
- self.assertEqual(list(bc.keys("0.")), ["1", "2"])
- self.assertEqual(list(bc.keys("0")), ["0", "1", "2"])
- self.checkIterable(bc.keys(None))
- self.checkIterable(bc.keys(""))
- self.checkIterable(bc.keys("0."))
- self.checkIterable(bc.keys("3"))
-
- def testNonemptyValueWithArg(self):
- bc = BTreeContainer()
- bc["0"] = 1
- bc["1"] = 2
- bc["2"] = 3
- self.assertEqual(list(bc.values(None)), list(bc.values()))
- self.assertEqual(list(bc.values("")), [1, 2, 3])
- self.assertEqual(list(bc.values("3")), [])
- self.assertEqual(list(bc.values("2.")), [])
- self.assertEqual(list(bc.values("2")), [3])
- self.assertEqual(list(bc.values("1.")), [3])
- self.assertEqual(list(bc.values("1")), [2, 3])
- self.assertEqual(list(bc.values("0.")), [2, 3])
- self.assertEqual(list(bc.values("0")), [1, 2, 3])
- self.checkIterable(bc.values(None))
- self.checkIterable(bc.values(""))
- self.checkIterable(bc.values("0."))
- self.checkIterable(bc.values("3"))
-
- def checkIterable(self, iterable):
- it = iter(iterable)
- self.assert_(callable(it.next))
- self.assert_(callable(it.__iter__))
- self.assert_(iter(it) is it)
- # Exhaust the iterator:
- first_time = list(it)
- self.assertRaises(StopIteration, it.next)
- # Subsequent iterations will return the same values:
- self.assertEqual(list(iterable), first_time)
- self.assertEqual(list(iterable), first_time)
-
-
-def test_suite():
- return TestSuite((
- makeSuite(TestBTreeContainer),
- makeSuite(TestBTreeSpecials),
- DocTestSuite('zope.app.container.btree',
- setUp=placelesssetup.setUp,
- tearDown=placelesssetup.tearDown),
- ))
-
-if __name__=='__main__':
- main(defaultTest='test_suite')
Modified: Sandbox/malthe/zope.container/src/zope/container/tests/test_constraints.py
===================================================================
--- Sandbox/malthe/zope.container/src/zope/app/container/tests/test_constraints.py 2008-04-22 12:11:58 UTC (rev 85590)
+++ Sandbox/malthe/zope.container/src/zope/container/tests/test_constraints.py 2008-04-22 12:37:09 UTC (rev 85592)
@@ -1,6 +1,6 @@
##############################################################################
#
-# Copyright (c) 2003 Zope Corporation and Contributors.
+# Copyright (c) 2008 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
@@ -19,14 +19,14 @@
from zope.testing import doctest, module
def setUp(test):
- module.setUp(test, 'zope.app.container.constraints_txt')
+ module.setUp(test, 'zope.container.constraints_txt')
def tearDown(test):
- module.tearDown(test, 'zope.app.container.constraints_txt')
+ module.tearDown(test, 'zope.container.constraints_txt')
def test_suite():
return unittest.TestSuite((
- doctest.DocTestSuite('zope.app.container.constraints'),
+ doctest.DocTestSuite('zope.container.constraints'),
doctest.DocFileSuite('../constraints.txt',
setUp=setUp, tearDown=tearDown),
))
Deleted: Sandbox/malthe/zope.container/src/zope/container/tests/test_contained.py
===================================================================
--- Sandbox/malthe/zope.container/src/zope/app/container/tests/test_contained.py 2008-04-22 12:11:58 UTC (rev 85590)
+++ Sandbox/malthe/zope.container/src/zope/container/tests/test_contained.py 2008-04-22 12:37:09 UTC (rev 85592)
@@ -1,327 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2003 Zope Corporation 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.
-#
-##############################################################################
-"""Contained Tests
-
-$Id$
-"""
-import unittest
-import gc
-from ZODB.DemoStorage import DemoStorage
-from ZODB.DB import DB
-import transaction
-from persistent import Persistent
-
-import zope.interface
-from zope.testing import doctest
-
-from zope.app.container.contained import ContainedProxy
-from zope.app.testing import placelesssetup
-
-class MyOb(Persistent):
- pass
-
-def test_basic_proxy_attribute_management_and_picklability():
- """Contained-object proxy
-
- This is a picklable proxy that can be put around objects that
- don't implement IContained.
-
- >>> l = [1, 2, 3]
- >>> p = ContainedProxy(l)
- >>> p.__parent__ = 'Dad'
- >>> p.__name__ = 'p'
- >>> p
- [1, 2, 3]
- >>> p.__parent__
- 'Dad'
- >>> p.__name__
- 'p'
-
- >>> import pickle
- >>> p2 = pickle.loads(pickle.dumps(p))
- >>> p2
- [1, 2, 3]
- >>> p2.__parent__
- 'Dad'
- >>> p2.__name__
- 'p'
- """
-
-def test_basic_persistent_w_non_persistent_proxied():
- """
- >>> p = ContainedProxy([1])
- >>> p.__parent__ = 2
- >>> p.__name__ = 'test'
- >>> db = DB(DemoStorage('test_storage'))
- >>> c = db.open()
- >>> c.root()['p'] = p
- >>> transaction.commit()
-
- >>> c2 = db.open()
- >>> p2 = c2.root()['p']
- >>> p2
- [1]
- >>> p2.__parent__
- 2
- >>> p2.__name__
- 'test'
-
- >>> p2._p_changed
- 0
- >>> p2._p_deactivate()
- >>> p2._p_changed
- >>> p2.__name__
- 'test'
-
- >>> db.close()
- """
-
-def test_declarations_on_ContainedProxy():
- r"""
-
- It is possible to make declarations on ContainedProxy objects.
-
- >>> class I1(zope.interface.Interface):
- ... pass
- >>> class C(object):
- ... zope.interface.implements(I1)
-
- >>> c = C()
- >>> p = ContainedProxy(c)
-
- ContainedProxy provides no interfaces on it's own:
-
- >>> tuple(zope.interface.providedBy(ContainedProxy))
- ()
-
- It implements IContained and IPersistent:
-
- >>> tuple(zope.interface.implementedBy(ContainedProxy))
- (<InterfaceClass zope.app.container.interfaces.IContained>,
- <InterfaceClass persistent.interfaces.IPersistent>)
-
- A proxied object has IContainer, in addition to what the unproxied
- object has:
-
- >>> tuple(zope.interface.providedBy(p))
- (<InterfaceClass zope.app.container.tests.test_contained.I1>,
- <InterfaceClass zope.app.container.interfaces.IContained>,
- <InterfaceClass persistent.interfaces.IPersistent>)
-
- >>> class I2(zope.interface.Interface):
- ... pass
- >>> zope.interface.directlyProvides(c, I2)
- >>> tuple(zope.interface.providedBy(p))
- (<InterfaceClass zope.app.container.tests.test_contained.I2>,
- <InterfaceClass zope.app.container.tests.test_contained.I1>,
- <InterfaceClass zope.app.container.interfaces.IContained>,
- <InterfaceClass persistent.interfaces.IPersistent>)
-
- We can declare interfaces through the proxy:
-
- >>> class I3(zope.interface.Interface):
- ... pass
- >>> zope.interface.directlyProvides(p, I3)
- >>> tuple(zope.interface.providedBy(p))
- (<InterfaceClass zope.app.container.tests.test_contained.I3>,
- <InterfaceClass zope.app.container.tests.test_contained.I1>,
- <InterfaceClass zope.app.container.interfaces.IContained>,
- <InterfaceClass persistent.interfaces.IPersistent>)
-
- """
-
-def test_basic_persistent_w_persistent_proxied():
- """
-
- Here, we'll verify that shared references work and
- that updates to both the proxies and the proxied objects
- are made correctly.
-
- ----------------------
- | |
- parent other
- | /
- ob <--------------
-
- Here we have an object, parent, that contains ob. There is another
- object, other, that has a non-container reference to ob.
-
- >>> parent = MyOb()
- >>> parent.ob = ContainedProxy(MyOb())
- >>> parent.ob.__parent__ = parent
- >>> parent.ob.__name__ = 'test'
- >>> other = MyOb()
- >>> other.ob = parent.ob
-
- We can change ob through either parent or other
-
- >>> parent.ob.x = 1
- >>> other.ob.y = 2
-
- Now we'll save the data:
-
- >>> db = DB(DemoStorage('test_storage'))
- >>> c1 = db.open()
- >>> c1.root()['parent'] = parent
- >>> c1.root()['other'] = other
- >>> transaction.commit()
-
- We'll open a second connection and verify that we have the data we
- expect:
-
- >>> c2 = db.open()
- >>> p2 = c2.root()['parent']
- >>> p2.ob.__parent__ is p2
- 1
- >>> p2.ob.x
- 1
- >>> p2.ob.y
- 2
- >>> o2 = c2.root()['other']
- >>> o2.ob is p2.ob
- 1
- >>> o2.ob is p2.ob
- 1
- >>> o2.ob.__name__
- 'test'
-
- Now we'll change things around a bit. We'll move things around
- a bit. We'll also add an attribute to ob
-
- >>> o2.ob.__name__ = 'test 2'
- >>> o2.ob.__parent__ = o2
- >>> o2.ob.z = 3
-
- >>> p2.ob.__parent__ is p2
- 0
- >>> p2.ob.__parent__ is o2
- 1
-
- And save the changes:
-
- >>> transaction.commit()
-
- Now we'll reopen the first connection and verify that we can see
- the changes:
-
- >>> c1.close()
- >>> c1 = db.open()
- >>> p2 = c1.root()['parent']
- >>> p2.ob.__name__
- 'test 2'
- >>> p2.ob.z
- 3
- >>> p2.ob.__parent__ is c1.root()['other']
- 1
-
- >>> db.close()
- """
-
-def test_proxy_cache_interaction():
- """Test to make sure the proxy properly interacts with the object cache
-
- Persistent objects are their own weak refs. Thier deallocators
- need to notify their connection's cache that their object is being
- deallocated, so that it is removed from the cache.
-
- >>> from ZODB.tests.util import DB
- >>> db = DB()
- >>> db.setCacheSize(5)
- >>> conn = db.open()
- >>> conn.root()['p'] = ContainedProxy(None)
-
- We need to create some filler objects to push our proxy out of the cache:
-
- >>> for i in range(10):
- ... conn.root()[i] = MyOb()
-
- >>> transaction.commit()
-
- Let's get the oid of our proxy:
-
- >>> oid = conn.root()['p']._p_oid
-
- Now, we'll access the filler object's:
-
- >>> x = [getattr(conn.root()[i], 'x', 0) for i in range(10)]
-
- We've also accessed the root object. If we garbage-collect the
- cache:
-
- >>> conn._cache.incrgc()
-
- Then the root object will still be active, because it was accessed
- recently:
-
- >>> conn.root()._p_changed
- 0
-
- And the proxy will be in the cache, because it's refernced from
- the root object:
-
- >>> conn._cache.get(oid) is not None
- True
-
- But it's a ghost:
-
- >>> conn.root()['p']._p_changed
-
- If we deactivate the root object:
-
- >>> conn.root()._p_deactivate()
-
- Then we'll release the last reference to the proxy and it should
- no longer be in the cache. To be sure, we'll call gc:
-
- >>> x = gc.collect()
- >>> conn._cache.get(oid) is not None
- False
-
- """
-
-def test_ContainedProxy_instances_have_no_instance_dictionaries():
- """Make sure that proxies don't introduce extra instance dictionaries
-
- >>> from zope.app.container.contained import ContainedProxy
- >>> class C:
- ... pass
-
- >>> c = C()
- >>> c.x = 1
- >>> c.__dict__
- {'x': 1}
-
- >>> p = ContainedProxy(c)
- >>> p.__dict__
- {'x': 1}
- >>> p.y = 3
- >>> p.__dict__
- {'y': 3, 'x': 1}
- >>> c.__dict__
- {'y': 3, 'x': 1}
-
- >>> p.__dict__ is c.__dict__
- True
-
- """
-
-def test_suite():
- return unittest.TestSuite((
- doctest.DocTestSuite('zope.app.container.contained',
- setUp=placelesssetup.setUp,
- tearDown=placelesssetup.tearDown),
- doctest.DocTestSuite(optionflags=doctest.NORMALIZE_WHITESPACE),
- ))
-
-if __name__ == '__main__': unittest.main()
Deleted: Sandbox/malthe/zope.container/src/zope/container/tests/test_containertraversable.py
===================================================================
--- Sandbox/malthe/zope.container/src/zope/app/container/tests/test_containertraversable.py 2008-04-22 12:11:58 UTC (rev 85590)
+++ Sandbox/malthe/zope.container/src/zope/container/tests/test_containertraversable.py 2008-04-22 12:37:09 UTC (rev 85592)
@@ -1,70 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2001, 2002 Zope Corporation 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.
-#
-##############################################################################
-"""Container Traverser tests.
-
-$Id$
-"""
-import unittest
-from zope.testing.cleanup import CleanUp
-from zope.interface import implements
-from zope.traversing.interfaces import TraversalError
-
-from zope.app.container.traversal import ContainerTraversable
-from zope.app.container.interfaces import IContainer
-
-class Container(object):
-
- implements(IContainer)
-
- def __init__(self, attrs={}, objs={}):
- for attr,value in attrs.iteritems():
- setattr(self, attr, value)
-
- self.__objs = {}
- for name,value in objs.iteritems():
- self.__objs[name] = value
-
-
- def __getitem__(self, name):
- return self.__objs[name]
-
- def get(self, name, default=None):
- return self.__objs.get(name, default)
-
- def __contains__(self, name):
- return self.__objs.has_key(name)
-
-
-class Test(CleanUp, unittest.TestCase):
- def testAttr(self):
- # test container path traversal
- foo = Container()
- bar = Container()
- baz = Container()
- c = Container({'foo': foo}, {'bar': bar, 'foo': baz})
-
- T = ContainerTraversable(c)
- self.failUnless(T.traverse('foo', []) is baz)
- self.failUnless(T.traverse('bar', []) is bar)
-
- self.assertRaises(TraversalError , T.traverse, 'morebar', [])
-
-
-def test_suite():
- loader = unittest.TestLoader()
- return loader.loadTestsFromTestCase(Test)
-
-
-if __name__ == '__main__':
- unittest.TextTestRunner().run(test_suite())
Deleted: Sandbox/malthe/zope.container/src/zope/container/tests/test_containertraverser.py
===================================================================
--- Sandbox/malthe/zope.container/src/zope/app/container/tests/test_containertraverser.py 2008-04-22 12:11:58 UTC (rev 85590)
+++ Sandbox/malthe/zope.container/src/zope/container/tests/test_containertraverser.py 2008-04-22 12:37:09 UTC (rev 85592)
@@ -1,94 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2001, 2002 Zope Corporation 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.
-#
-##############################################################################
-"""Container Traverser Tests
-
-$Id$
-"""
-import unittest
-from zope.app.container.traversal import ContainerTraverser
-from zope.app.container.interfaces import IReadContainer
-from zope.app.testing import ztapi, placelesssetup
-from zope.publisher.interfaces import NotFound
-from zope.publisher.browser import TestRequest
-from zope.interface import implements
-
-class TestContainer(object):
- implements(IReadContainer)
-
- def __init__(self, **kw):
- for name, value in kw.items():
- setattr(self, name , value)
-
- def get(self, name, default=None):
- return getattr(self, name, default)
-
-
-class View(object):
- def __init__(self, context, request):
- self.context = context
- self.request = request
-
-
-class TraverserTest(placelesssetup.PlacelessSetup, unittest.TestCase):
-
- # The following two methods exist, so that other container traversers can
- # use these tests as a base.
- def _getTraverser(self, context, request):
- return ContainerTraverser(context, request)
-
- def _getContainer(self, **kw):
- return TestContainer(**kw)
-
- def setUp(self):
- super(TraverserTest, self).setUp()
- # Create a small object tree
- self.foo = self._getContainer()
- foo2 = self._getContainer(Foo=self.foo)
- # Initiate a request
- self.request = TestRequest()
- # Create the traverser
- self.traverser = self._getTraverser(foo2, self.request)
- # Define a simple view for the container
- ztapi.browserView(IReadContainer, 'viewfoo', View)
-
- def test_itemTraversal(self):
- self.assertEqual(
- self.traverser.publishTraverse(self.request, 'Foo'),
- self.foo)
- self.assertRaises(
- NotFound,
- self.traverser.publishTraverse, self.request, 'morebar')
-
- def test_viewTraversal(self):
- self.assertEquals(
- self.traverser.publishTraverse(self.request, 'viewfoo').__class__,
- View)
- self.assertEquals(
- self.traverser.publishTraverse(self.request, 'Foo'),
- self.foo)
- self.assertRaises(
- NotFound,
- self.traverser.publishTraverse, self.request, 'morebar')
- self.assertRaises(
- NotFound,
- self.traverser.publishTraverse, self.request, '@@morebar')
-
-
-def test_suite():
- return unittest.TestSuite((
- unittest.makeSuite(TraverserTest),
- ))
-
-if __name__ == '__main__':
- unittest.main(defaultTest='test_suite')
Deleted: Sandbox/malthe/zope.container/src/zope/container/tests/test_dependency.py
===================================================================
--- Sandbox/malthe/zope.container/src/zope/app/container/tests/test_dependency.py 2008-04-22 12:11:58 UTC (rev 85590)
+++ Sandbox/malthe/zope.container/src/zope/container/tests/test_dependency.py 2008-04-22 12:37:09 UTC (rev 85592)
@@ -1,52 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2008 Zope Corporation 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.
-#
-##############################################################################
-"""Test the CheckDependency event subscriber.
-
-$Id$
-"""
-import unittest
-
-from zope.interface import implements
-from zope.app.dependable.interfaces import IDependable, DependencyError
-from zope.app.container.contained import ObjectRemovedEvent
-from zope.app.container.dependency import CheckDependency
-from zope.traversing.interfaces import IPhysicallyLocatable
-
-class DummyObject(object):
-
- implements(IDependable, IPhysicallyLocatable)
-
- def dependents(self):
- return ['dependency1', 'dependency2']
-
- def getPath(self):
- return '/dummy-object'
-
-
-class Test(unittest.TestCase):
-
- def testCheckDependency(self):
- obj = DummyObject()
- parent = object()
- event = ObjectRemovedEvent(obj, parent, 'oldName')
- self.assertRaises(DependencyError, CheckDependency, event)
-
-
-def test_suite():
- return unittest.TestSuite((
- unittest.makeSuite(Test),
- ))
-
-if __name__=='__main__':
- unittest.main()
Deleted: Sandbox/malthe/zope.container/src/zope/container/tests/test_directory.py
===================================================================
--- Sandbox/malthe/zope.container/src/zope/app/container/tests/test_directory.py 2008-04-22 12:11:58 UTC (rev 85590)
+++ Sandbox/malthe/zope.container/src/zope/container/tests/test_directory.py 2008-04-22 12:37:09 UTC (rev 85592)
@@ -1,39 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2003 Zope Corporation 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.
-#
-##############################################################################
-"""FS-based directory implementation tests for containers
-
-$Id$
-"""
-from unittest import TestCase, TestSuite, main, makeSuite
-import zope.app.container.directory
-
-class Directory(object):
- pass
-
-class Test(TestCase):
-
- def test_Cloner(self):
- d = Directory()
- d.a = 1
- clone = zope.app.container.directory.Cloner(d)('foo')
- self.assert_(clone != d)
- self.assertEqual(clone.__class__, d.__class__)
-
-def test_suite():
- return TestSuite((
- makeSuite(Test),
- ))
-
-if __name__=='__main__':
- main(defaultTest='test_suite')
Modified: Sandbox/malthe/zope.container/src/zope/container/tests/test_find.py
===================================================================
--- Sandbox/malthe/zope.container/src/zope/app/container/tests/test_find.py 2008-04-22 12:11:58 UTC (rev 85590)
+++ Sandbox/malthe/zope.container/src/zope/container/tests/test_find.py 2008-04-22 12:37:09 UTC (rev 85592)
@@ -1,6 +1,6 @@
##############################################################################
#
-# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# Copyright (c) 2008 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
@@ -16,10 +16,10 @@
$Id$
"""
from unittest import TestCase, main, makeSuite
-from zope.app.container.interfaces import IReadContainer
-from zope.app.container.interfaces import IObjectFindFilter
-from zope.app.container.find import FindAdapter, SimpleIdFindFilter
-from zope.app.container.find import SimpleInterfacesFindFilter
+from zope.container.interfaces import IReadContainer
+from zope.container.interfaces import IObjectFindFilter
+from zope.container.find import FindAdapter, SimpleIdFindFilter
+from zope.container.find import SimpleInterfacesFindFilter
from zope.interface import implements, Interface, directlyProvides
class FakeContainer(object):
Deleted: Sandbox/malthe/zope.container/src/zope/container/tests/test_icontainer.py
===================================================================
--- Sandbox/malthe/zope.container/src/zope/app/container/tests/test_icontainer.py 2008-04-22 12:11:58 UTC (rev 85590)
+++ Sandbox/malthe/zope.container/src/zope/container/tests/test_icontainer.py 2008-04-22 12:37:09 UTC (rev 85592)
@@ -1,319 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2001, 2002 Zope Corporation 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.
-#
-##############################################################################
-"""Test the IContainer interface.
-
-$Id$
-"""
-from unittest import TestCase, main, makeSuite
-
-from zope.interface.verify import verifyObject
-from zope.app.container.interfaces import IContainer
-from zope.app.testing import placelesssetup
-
-
-def DefaultTestData():
- return [('3', '0'), ('2', '1'), ('4', '2'), ('6', '3'), ('0', '4'),
- ('5', '5'), ('1', '6'), ('8', '7'), ('7', '8'), ('9', '9')]
-
-class BaseTestIContainer(placelesssetup.PlacelessSetup):
- """Base test cases for containers.
-
- Subclasses must define a makeTestObject that takes no
- arguments and that returns a new empty test container,
- and a makeTestData that also takes no arguments and returns
- a sequence of (key, value) pairs that may be stored in
- the test container. The list must be at least ten items long.
- 'NoSuchKey' may not be used as a key value in the returned list.
- """
-
- def __setUp(self):
- self.__container = container = self.makeTestObject()
- self.__data = data = self.makeTestData()
- for k, v in data:
- container[k] = v
- return container, data
-
- ############################################################
- # Interface-driven tests:
-
- def testIContainerVerify(self):
- verifyObject(IContainer, self.makeTestObject())
-
- def test_keys(self):
- # See interface IReadContainer
- container = self.makeTestObject()
- keys = container.keys()
- self.assertEqual(list(keys), [])
-
- container, data = self.__setUp()
- keys = container.keys()
- keys = list(keys); keys.sort() # convert to sorted list
- ikeys = [ k for k, v in data ]; ikeys.sort() # sort input keys
- self.assertEqual(keys, ikeys)
-
- def test_get(self):
- # See interface IReadContainer
- default = object()
- data = self.makeTestData()
- container = self.makeTestObject()
- self.assertRaises(KeyError, container.__getitem__, data[0][0])
- self.assertEqual(container.get(data[0][0], default), default)
-
- container, data = self.__setUp()
- self.assertRaises(KeyError, container.__getitem__,
- self.getUnknownKey())
- self.assertEqual(container.get(self.getUnknownKey(), default), default)
- for i in (1, 8, 7, 3, 4):
- self.assertEqual(container.get(data[i][0], default), data[i][1])
- self.assertEqual(container.get(data[i][0]), data[i][1])
-
- def test_values(self):
- # See interface IReadContainer
- container = self.makeTestObject()
- values = container.values()
- self.assertEqual(list(values), [])
-
- container, data = self.__setUp()
- values = list(container.values())
- for k, v in data:
- try:
- values.remove(v)
- except ValueError:
- self.fail('Value not in list')
-
- self.assertEqual(values, [])
-
- def test_len(self):
- # See interface IReadContainer
- container = self.makeTestObject()
- self.assertEqual(len(container), 0)
-
- container, data = self.__setUp()
- self.assertEqual(len(container), len(data))
-
- def test_items(self):
- # See interface IReadContainer
- container = self.makeTestObject()
- items = container.items()
- self.assertEqual(list(items), [])
-
- container, data = self.__setUp()
- items = container.items()
- items = list(items); items.sort() # convert to sorted list
- data.sort() # sort input data
- self.assertEqual(items, data)
-
- def test___contains__(self):
- # See interface IReadContainer
- container = self.makeTestObject()
- data = self.makeTestData()
- self.assertEqual(not not (data[6][0] in container), False)
-
- container, data = self.__setUp()
- self.assertEqual(not not (data[6][0] in container), True)
- for i in (1, 8, 7, 3, 4):
- self.assertEqual(not not (data[i][0] in container), 1)
-
- def test_delObject(self):
- # See interface IWriteContainer
- default = object()
- data = self.makeTestData()
- container = self.makeTestObject()
- self.assertRaises(KeyError, container.__delitem__, data[0][0])
-
- container, data = self.__setUp()
- self.assertRaises(KeyError, container.__delitem__,
- self.getUnknownKey())
- for i in (1, 8, 7, 3, 4):
- del container[data[i][0]]
- for i in (1, 8, 7, 3, 4):
- self.assertRaises(KeyError, container.__getitem__, data[i][0])
- self.assertEqual(container.get(data[i][0], default), default)
- for i in (0, 2, 9, 6, 5):
- self.assertEqual(container[data[i][0]], data[i][1])
-
- ############################################################
- # Tests from Folder
-
- def testEmpty(self):
- folder = self.makeTestObject()
- data = self.makeTestData()
- self.failIf(folder.keys())
- self.failIf(folder.values())
- self.failIf(folder.items())
- self.failIf(len(folder))
- self.failIf(data[6][0] in folder)
-
- self.assertEquals(folder.get(data[6][0], None), None)
- self.assertRaises(KeyError, folder.__getitem__, data[6][0])
-
- self.assertRaises(KeyError, folder.__delitem__, data[6][0])
-
- def testBadKeyTypes(self):
- folder = self.makeTestObject()
- data = self.makeTestData()
- value = data[1][1]
- for name in self.getBadKeyTypes():
- self.assertRaises(TypeError, folder.__setitem__, name, value)
-
- def testOneItem(self):
- folder = self.makeTestObject()
- data = self.makeTestData()
-
- foo = data[0][1]
- name = data[0][0]
- folder[name] = foo
-
- self.assertEquals(len(folder.keys()), 1)
- self.assertEquals(folder.keys()[0], name)
- self.assertEquals(len(folder.values()), 1)
- self.assertEquals(folder.values()[0], foo)
- self.assertEquals(len(folder.items()), 1)
- self.assertEquals(folder.items()[0], (name, foo))
- self.assertEquals(len(folder), 1)
-
- self.failUnless(name in folder)
- # Use an arbitrary id frpm the data set; don;t just use any id, since
- # there might be restrictions on their form
- self.failIf(data[6][0] in folder)
-
- self.assertEquals(folder.get(name, None), foo)
- self.assertEquals(folder[name], foo)
-
- self.assertRaises(KeyError, folder.__getitem__, data[6][0])
-
- foo2 = data[1][1]
-
- name2 = data[1][0]
- folder[name2] = foo2
-
- self.assertEquals(len(folder.keys()), 2)
- self.assertEquals(not not name2 in folder.keys(), True)
- self.assertEquals(len(folder.values()), 2)
- self.assertEquals(not not foo2 in folder.values(), True)
- self.assertEquals(len(folder.items()), 2)
- self.assertEquals(not not (name2, foo2) in folder.items(), True)
- self.assertEquals(len(folder), 2)
-
- del folder[name]
- del folder[name2]
-
- self.failIf(folder.keys())
- self.failIf(folder.values())
- self.failIf(folder.items())
- self.failIf(len(folder))
- self.failIf(name in folder)
-
- self.assertRaises(KeyError, folder.__getitem__, name)
- self.assertEquals(folder.get(name, None), None)
- self.assertRaises(KeyError, folder.__delitem__, name)
-
- def testManyItems(self):
- folder = self.makeTestObject()
- data = self.makeTestData()
- objects = [ data[i][1] for i in range(4) ]
- name0 = data[0][0]
- name1 = data[1][0]
- name2 = data[2][0]
- name3 = data[3][0]
- folder[name0] = objects[0]
- folder[name1] = objects[1]
- folder[name2] = objects[2]
- folder[name3] = objects[3]
-
- self.assertEquals(len(folder.keys()), len(objects))
- self.failUnless(name0 in folder.keys())
- self.failUnless(name1 in folder.keys())
- self.failUnless(name2 in folder.keys())
- self.failUnless(name3 in folder.keys())
-
- self.assertEquals(len(folder.values()), len(objects))
- self.failUnless(objects[0] in folder.values())
- self.failUnless(objects[1] in folder.values())
- self.failUnless(objects[2] in folder.values())
- self.failUnless(objects[3] in folder.values())
-
- self.assertEquals(len(folder.items()), len(objects))
- self.failUnless((name0, objects[0]) in folder.items())
- self.failUnless((name1, objects[1]) in folder.items())
- self.failUnless((name2, objects[2]) in folder.items())
- self.failUnless((name3, objects[3]) in folder.items())
-
- self.assertEquals(len(folder), len(objects))
-
- self.failUnless(name0 in folder)
- self.failUnless(name1 in folder)
- self.failUnless(name2 in folder)
- self.failUnless(name3 in folder)
- self.failIf(data[5][0] in folder)
-
- self.assertEquals(folder.get(name0, None), objects[0])
- self.assertEquals(folder[name0], objects[0])
- self.assertEquals(folder.get(name1, None), objects[1])
- self.assertEquals(folder[name1], objects[1])
- self.assertEquals(folder.get(name2, None), objects[2])
- self.assertEquals(folder[name2], objects[2])
- self.assertEquals(folder.get(name3, None), objects[3])
- self.assertEquals(folder[name3], objects[3])
-
- self.assertEquals(folder.get(data[5][0], None), None)
- self.assertRaises(KeyError, folder.__getitem__, data[5][0])
-
- del folder[name0]
- self.assertEquals(len(folder), len(objects) - 1)
- self.failIf(name0 in folder)
- self.failIf(name0 in folder.keys())
-
- self.failIf(objects[0] in folder.values())
- self.failIf((name0, objects[0]) in folder.items())
-
- self.assertEquals(folder.get(name0, None), None)
- self.assertRaises(KeyError, folder.__getitem__, name0)
-
- self.assertRaises(KeyError, folder.__delitem__, name0)
-
- del folder[name1]
- del folder[name2]
- del folder[name3]
-
- self.failIf(folder.keys())
- self.failIf(folder.values())
- self.failIf(folder.items())
- self.failIf(len(folder))
- self.failIf(name0 in folder)
- self.failIf(name1 in folder)
- self.failIf(name2 in folder)
- self.failIf(name3 in folder)
-
-
-class TestSampleContainer(BaseTestIContainer, TestCase):
-
- def makeTestObject(self):
- from zope.app.container.sample import SampleContainer
- return SampleContainer()
-
- def makeTestData(self):
- return DefaultTestData()
-
- def getUnknownKey(self):
- return '10'
-
- def getBadKeyTypes(self):
- return [None, ['foo'], 1, '\xf3abc']
-
-def test_suite():
- return makeSuite(TestSampleContainer)
-
-if __name__=='__main__':
- main(defaultTest='test_suite')
Deleted: Sandbox/malthe/zope.container/src/zope/container/tests/test_objectcopier.py
===================================================================
--- Sandbox/malthe/zope.container/src/zope/app/container/tests/test_objectcopier.py 2008-04-22 12:11:58 UTC (rev 85590)
+++ Sandbox/malthe/zope.container/src/zope/container/tests/test_objectcopier.py 2008-04-22 12:37:09 UTC (rev 85592)
@@ -1,211 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2001, 2002 Zope Corporation 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.
-#
-##############################################################################
-"""Object Copier Tests
-
-$Id$
-"""
-from unittest import TestCase, TestSuite, main, makeSuite
-
-import zope.component
-from zope.testing import doctest
-from zope.traversing.api import traverse
-from zope.component.eventtesting import getEvents, clearEvents
-from zope.copypastemove import ObjectCopier
-from zope.copypastemove.interfaces import IObjectCopier
-
-from zope.app.component.testing import PlacefulSetup
-from zope.app.testing import setup
-from zope.app.folder import Folder
-
-class File(object):
- pass
-
-def test_copy_events():
- """
- Prepare the setup::
-
- >>> root = setup.placefulSetUp(site=True)
- >>> zope.component.provideAdapter(ObjectCopier, (None,), IObjectCopier)
-
- Prepare some objects::
-
- >>> folder = Folder()
- >>> root[u'foo'] = File()
- >>> root[u'folder'] = folder
- >>> list(folder.keys())
- []
- >>> foo = traverse(root, 'foo') # wrap in ContainedProxy
-
- Now make a copy::
-
- >>> clearEvents()
- >>> copier = IObjectCopier(foo)
- >>> copier.copyTo(folder, u'bar')
- u'bar'
-
- Check that the copy has been done::
-
- >>> list(folder.keys())
- [u'bar']
-
- Check what events have been sent::
-
- >>> events = getEvents()
- >>> [event.__class__.__name__ for event in events]
- ['ObjectCopiedEvent', 'ObjectAddedEvent', 'ContainerModifiedEvent']
-
- Check that the ObjectCopiedEvent includes the correct data::
-
- >>> events[0].object is folder[u'bar']
- True
- >>> events[0].original is root[u'foo']
- True
-
- Finally, tear down::
-
- >>> setup.placefulTearDown()
- """
-
-
-class ObjectCopierTest(PlacefulSetup, TestCase):
-
- def setUp(self):
- PlacefulSetup.setUp(self)
- PlacefulSetup.buildFolders(self)
- zope.component.provideAdapter(ObjectCopier, (None,), IObjectCopier)
-
- def test_copytosame(self):
- root = self.rootFolder
- container = traverse(root, 'folder1')
- container['file1'] = File()
- file = traverse(root, 'folder1/file1')
- copier = IObjectCopier(file)
- copier.copyTo(container, 'file1')
- self.failUnless('file1' in container)
- self.failUnless('file1-2' in container)
-
- def test_copytosamewithnewname(self):
- root = self.rootFolder
- container = traverse(root, 'folder1')
- container['file1'] = File()
- file = traverse(root, 'folder1/file1')
- copier = IObjectCopier(file)
- copier.copyTo(container, 'file2')
- self.failUnless('file1' in container)
- self.failUnless('file2' in container)
-
- def test_copytoother(self):
- root = self.rootFolder
- container = traverse(root, 'folder1')
- container['file1'] = File()
- target = traverse(root, 'folder2')
- file = traverse(root, 'folder1/file1')
- copier = IObjectCopier(file)
- copier.copyTo(target, 'file1')
- self.failUnless('file1' in container)
- self.failUnless('file1' in target)
-
- def test_copytootherwithnewname(self):
- root = self.rootFolder
- container = traverse(root, 'folder1')
- container['file1'] = File()
- target = traverse(root, 'folder2')
- file = traverse(root, 'folder1/file1')
- copier = IObjectCopier(file)
- copier.copyTo(target, 'file2')
- self.failUnless('file1' in container)
- self.failUnless('file2' in target)
-
- def test_copytootherwithnamecollision(self):
- root = self.rootFolder
- container = traverse(root, 'folder1')
- container['file1'] = File()
- target = traverse(root, 'folder2')
- target['file1'] = File()
- file = traverse(root, 'folder1/file1')
- copier = IObjectCopier(file)
- copier.copyTo(target, 'file1')
- # we do it twice, just to test auto-name generation
- copier.copyTo(target, 'file1')
- self.failUnless('file1' in container)
- self.failUnless('file1' in target)
- self.failUnless('file1-2' in target)
- self.failUnless('file1-3' in target)
-
- def test_copyable(self):
- root = self.rootFolder
- container = traverse(root, 'folder1')
- container['file1'] = File()
- file = traverse(root, 'folder1/file1')
- copier = IObjectCopier(file)
- self.failUnless(copier.copyable())
-
- def test_copyableTo(self):
- # A file should be copyable to a folder that has an
- # object with the same id.
- root = self.rootFolder
- container = traverse(root, 'folder1')
- container['file1'] = File()
- file = traverse(root, 'folder1/file1')
- copier = IObjectCopier(file)
- self.failUnless(copier.copyableTo(container, 'file1'))
-
- def test_copyfoldertosibling(self):
- root = self.rootFolder
- target = traverse(root, '/folder2')
- source = traverse(root, '/folder1/folder1_1')
- copier = IObjectCopier(source)
- copier.copyTo(target)
- self.failUnless('folder1_1' in target)
-
- def test_copyfoldertosame(self):
- root = self.rootFolder
- target = traverse(root, '/folder1')
- source = traverse(root, '/folder1/folder1_1')
- copier = IObjectCopier(source)
- copier.copyTo(target)
- self.failUnless('folder1_1' in target)
-
- def test_copyfoldertosame2(self):
- root = self.rootFolder
- target = traverse(root, '/folder1/folder1_1')
- source = traverse(root, '/folder1/folder1_1/folder1_1_1')
- copier = IObjectCopier(source)
- copier.copyTo(target)
- self.failUnless('folder1_1_1' in target)
-
- def test_copyfolderfromroot(self):
- root = self.rootFolder
- target = traverse(root, '/folder2')
- source = traverse(root, '/folder1')
- copier = IObjectCopier(source)
- copier.copyTo(target)
- self.failUnless('folder1' in target)
-
- def test_copyfolderfromroot2(self):
- root = self.rootFolder
- target = traverse(root, '/folder2/folder2_1/folder2_1_1')
- source = traverse(root, '/folder1')
- copier = IObjectCopier(source)
- copier.copyTo(target)
- self.failUnless('folder1' in target)
-
-def test_suite():
- return TestSuite((
- makeSuite(ObjectCopierTest),
- doctest.DocTestSuite(),
- ))
-
-if __name__=='__main__':
- main(defaultTest='test_suite')
Deleted: Sandbox/malthe/zope.container/src/zope/container/tests/test_objectmover.py
===================================================================
--- Sandbox/malthe/zope.container/src/zope/app/container/tests/test_objectmover.py 2008-04-22 12:11:58 UTC (rev 85590)
+++ Sandbox/malthe/zope.container/src/zope/container/tests/test_objectmover.py 2008-04-22 12:37:09 UTC (rev 85592)
@@ -1,227 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2001, 2002 Zope Corporation 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.
-#
-##############################################################################
-"""Object Mover Tests
-
-$Id$
-"""
-from unittest import TestCase, TestSuite, main, makeSuite
-
-import zope.component
-from zope.testing import doctest
-from zope.traversing.api import traverse
-from zope.component.eventtesting import getEvents, clearEvents
-from zope.copypastemove import ObjectMover
-from zope.copypastemove.interfaces import IObjectMover
-
-from zope.app.component.testing import PlacefulSetup
-from zope.app.testing import setup
-from zope.app.folder import Folder
-
-class File(object):
- pass
-
-def test_move_events():
- """
- Prepare the setup::
-
- >>> root = setup.placefulSetUp(site=True)
- >>> zope.component.provideAdapter(ObjectMover, (None,), IObjectMover)
-
- Prepare some objects::
-
- >>> folder = Folder()
- >>> root[u'foo'] = File()
- >>> root[u'folder'] = folder
- >>> list(folder.keys())
- []
- >>> foo = traverse(root, 'foo') # wrap in ContainedProxy
-
- Now move it::
-
- >>> clearEvents()
- >>> mover = IObjectMover(foo)
- >>> mover.moveableTo(folder)
- True
- >>> mover.moveTo(folder, u'bar')
- u'bar'
-
- Check that the move has been done::
-
- >>> list(root.keys())
- [u'folder']
- >>> list(folder.keys())
- [u'bar']
-
- Check what events have been sent::
-
- >>> events = getEvents()
- >>> [event.__class__.__name__ for event in events]
- ['ObjectMovedEvent', 'ContainerModifiedEvent', 'ContainerModifiedEvent']
-
- Verify that the ObjectMovedEvent includes the correct data::
-
- >>> events[0].oldName, events[0].newName
- (u'foo', u'bar')
- >>> events[0].oldParent is root
- True
- >>> events[0].newParent is folder
- True
-
- Let's look the other events:
-
- >>> events[1].object is folder
- True
- >>> events[2].object is root
- True
-
- Finally, tear down::
-
- >>> setup.placefulTearDown()
- """
-
-
-class ObjectMoverTest(PlacefulSetup, TestCase):
-
- def setUp(self):
- PlacefulSetup.setUp(self)
- PlacefulSetup.buildFolders(self)
- zope.component.provideAdapter(ObjectMover, (None,), )
-
- def test_movetosame(self):
- # Should be a noop, because "moving" to same location
- root = self.rootFolder
- container = traverse(root, 'folder1')
- container['file1'] = File()
- file = traverse(root, 'folder1/file1')
- mover = IObjectMover(file)
- mover.moveTo(container, 'file1')
- self.failUnless('file1' in container)
- self.assertEquals(len(container), 3)
-
- def test_movetosamewithnewname(self):
- root = self.rootFolder
- container = traverse(root, 'folder1')
- container['file1'] = File()
- file = traverse(root, 'folder1/file1')
- mover = IObjectMover(file)
- mover.moveTo(container, 'file2')
- self.failIf('file1' in container)
- self.failUnless('file2' in container)
-
- def test_movetoother(self):
- root = self.rootFolder
- container = traverse(root, 'folder1')
- container['file1'] = File()
- target = traverse(root, 'folder2')
- file = traverse(root, 'folder1/file1')
- mover = IObjectMover(file)
- mover.moveTo(target, 'file1')
- self.failIf('file1' in container)
- self.failUnless('file1' in target)
-
- def test_movetootherwithnewname(self):
- root = self.rootFolder
- container = traverse(root, 'folder1')
- container['file1'] = File()
- target = traverse(root, 'folder2')
- file = traverse(root, 'folder1/file1')
- mover = IObjectMover(file)
- mover.moveTo(target, 'file2')
- self.failIf('file1' in container)
- self.failUnless('file2' in target)
-
- def test_movetootherwithnamecollision(self):
- root = self.rootFolder
- container = traverse(root, 'folder1')
- container['file1'] = File()
- target = traverse(root, 'folder2')
- target['file1'] = File()
- file = traverse(root, 'folder1/file1')
- mover = IObjectMover(file)
- mover.moveTo(target, 'file1')
- self.failIf('file1' in container)
- self.failUnless('file1' in target)
- self.failUnless('file1-2' in target)
-
- def test_moveable(self):
- root = self.rootFolder
- container = traverse(root, 'folder1')
- container['file1'] = File()
- file = traverse(root, 'folder1/file1')
- mover = IObjectMover(file)
- self.failUnless(mover.moveable())
-
- def test_moveableTo(self):
- # A file should be moveable to a folder that has an
- # object with the same id.
- root = self.rootFolder
- container = traverse(root, 'folder1')
- container['file1'] = File()
- file = traverse(root, 'folder1/file1')
- mover = IObjectMover(file)
- self.failUnless(mover.moveableTo(container, 'file1'))
-
- def test_movefoldertosibling(self):
- root = self.rootFolder
- target = traverse(root, '/folder2')
- source = traverse(root, '/folder1/folder1_1')
- mover = IObjectMover(source)
- mover.moveTo(target)
- self.failUnless('folder1_1' in target)
-
- def test_movefoldertosame(self):
- # Should be a noop, because "moving" to same location
- root = self.rootFolder
- target = traverse(root, '/folder1')
- source = traverse(root, '/folder1/folder1_1')
- mover = IObjectMover(source)
- mover.moveTo(target)
- self.failUnless('folder1_1' in target)
- self.assertEquals(len(target), 2)
-
- def test_movefoldertosame2(self):
- # Should be a noop, because "moving" to same location
- root = self.rootFolder
- target = traverse(root, '/folder1/folder1_1')
- source = traverse(root, '/folder1/folder1_1/folder1_1_1')
- mover = IObjectMover(source)
- mover.moveTo(target)
- self.failUnless('folder1_1_1' in target)
- self.assertEquals(len(target), 2)
-
- def test_movefolderfromroot(self):
- root = self.rootFolder
- target = traverse(root, '/folder2')
- source = traverse(root, '/folder1')
- mover = IObjectMover(source)
- mover.moveTo(target)
- self.failUnless('folder1' in target)
-
- def test_movefolderfromroot2(self):
- root = self.rootFolder
- target = traverse(root, '/folder2/folder2_1/folder2_1_1')
- source = traverse(root, '/folder1')
- mover = IObjectMover(source)
- mover.moveTo(target)
- self.failUnless('folder1' in target)
-
-
-def test_suite():
- return TestSuite((
- makeSuite(ObjectMoverTest),
- doctest.DocTestSuite(),
- ))
-
-if __name__=='__main__':
- main(defaultTest='test_suite')
Deleted: Sandbox/malthe/zope.container/src/zope/container/tests/test_ordered.py
===================================================================
--- Sandbox/malthe/zope.container/src/zope/app/container/tests/test_ordered.py 2008-04-22 12:11:58 UTC (rev 85590)
+++ Sandbox/malthe/zope.container/src/zope/container/tests/test_ordered.py 2008-04-22 12:37:09 UTC (rev 85592)
@@ -1,101 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2003 Zope Corporation 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.
-#
-##############################################################################
-"""Test the OrderedContainer.
-
-$Id$
-"""
-import unittest
-from zope.testing.doctestunit import DocTestSuite
-from zope.component.eventtesting import getEvents, clearEvents
-from zope.app.testing import placelesssetup, setup
-
-def test_order_events():
- """
- Prepare the setup::
-
- >>> root = setup.placefulSetUp(site=True)
-
- Prepare some objects::
-
- >>> from zope.app.container.ordered import OrderedContainer
- >>> oc = OrderedContainer()
- >>> oc['foo'] = 'bar'
- >>> oc['baz'] = 'quux'
- >>> oc['zork'] = 'grue'
- >>> oc.keys()
- ['foo', 'baz', 'zork']
-
- Now change the order::
-
- >>> clearEvents()
- >>> oc.updateOrder(['baz', 'foo', 'zork'])
- >>> oc.keys()
- ['baz', 'foo', 'zork']
-
- Check what events have been sent::
-
- >>> events = getEvents()
- >>> [event.__class__.__name__ for event in events]
- ['ContainerModifiedEvent']
-
- This is in fact a specialized modification event::
-
- >>> from zope.lifecycleevent.interfaces import IObjectModifiedEvent
- >>> IObjectModifiedEvent.providedBy(events[0])
- True
-
- Finally, tear down::
-
- >>> setup.placefulTearDown()
- """
-
-def test_all_items_available_at_object_added_event():
- """
- Prepare the setup::
-
- >>> root = setup.placefulSetUp(site=True)
-
- Now register an event subscriber to object added events.
-
- >>> import zope.component
- >>> from zope.app.container import interfaces
-
- >>> @zope.component.adapter(interfaces.IObjectAddedEvent)
- ... def printContainerKeys(event):
- ... print event.newParent.keys()
-
- >>> zope.component.provideHandler(printContainerKeys)
-
- Now we are adding an object to the container.
-
- >>> from zope.app.container.ordered import OrderedContainer
- >>> oc = OrderedContainer()
- >>> oc['foo'] = 'FOO'
- ['foo']
-
- Finally, tear down::
-
- >>> setup.placefulTearDown()
- """
-
-def test_suite():
- suite = unittest.TestSuite()
- suite.addTest(DocTestSuite("zope.app.container.ordered",
- setUp=placelesssetup.setUp,
- tearDown=placelesssetup.tearDown))
- suite.addTest(DocTestSuite())
- return suite
-
-if __name__ == '__main__':
- unittest.main()
Added: Sandbox/malthe/zope.container/src/zope/container/tests/test_property.py
===================================================================
--- Sandbox/malthe/zope.container/src/zope/container/tests/test_property.py (rev 0)
+++ Sandbox/malthe/zope.container/src/zope/container/tests/test_property.py 2008-04-22 12:37:09 UTC (rev 85592)
@@ -0,0 +1,33 @@
+##############################################################################
+#
+# Copyright (c) 2008 Zope Corporation 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.
+#
+##############################################################################
+"""Container constraint tests
+
+$Id: test_constraints.py 40495 2005-12-02 17:51:22Z efge $
+"""
+import unittest
+from zope.testing import doctest, module
+
+def setUp(test):
+ module.setUp(test, 'zope.container.property_txt')
+
+def tearDown(test):
+ module.tearDown(test, 'zope.container.property_txt')
+
+def test_suite():
+ return unittest.TestSuite((
+ doctest.DocFileSuite('../property.txt',
+ setUp=setUp, tearDown=tearDown),
+ ))
+
+if __name__ == '__main__': unittest.main()
Modified: Sandbox/malthe/zope.container/src/zope/container/tests/test_size.py
===================================================================
--- Sandbox/malthe/zope.container/src/zope/app/container/tests/test_size.py 2008-04-22 12:11:58 UTC (rev 85590)
+++ Sandbox/malthe/zope.container/src/zope/container/tests/test_size.py 2008-04-22 12:37:09 UTC (rev 85592)
@@ -1,6 +1,6 @@
##############################################################################
#
-# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# Copyright (c) 2008 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
@@ -19,7 +19,7 @@
from zope.interface import implements
from zope.size.interfaces import ISized
-from zope.app.container.interfaces import IContainer
+from zope.container.interfaces import IContainer
class DummyContainer(object):
@@ -35,12 +35,12 @@
class Test(unittest.TestCase):
def testImplementsISized(self):
- from zope.app.container.size import ContainerSized
+ from zope.container.size import ContainerSized
sized = ContainerSized(DummyContainer(23))
self.assert_(ISized.providedBy(sized))
def testEmptyContainer(self):
- from zope.app.container.size import ContainerSized
+ from zope.container.size import ContainerSized
obj = DummyContainer(0)
sized = ContainerSized(obj)
self.assertEqual(sized.sizeForSorting(), ('item', 0))
@@ -48,14 +48,14 @@
self.assertEqual(sized.sizeForDisplay().mapping['items'], '0')
def testOneItem(self):
- from zope.app.container.size import ContainerSized
+ from zope.container.size import ContainerSized
obj = DummyContainer(1)
sized = ContainerSized(obj)
self.assertEqual(sized.sizeForSorting(), ('item', 1))
self.assertEqual(sized.sizeForDisplay(), u'1 item')
def testSeveralItems(self):
- from zope.app.container.size import ContainerSized
+ from zope.container.size import ContainerSized
obj = DummyContainer(2)
sized = ContainerSized(obj)
self.assertEqual(sized.sizeForSorting(), ('item', 2))
Deleted: Sandbox/malthe/zope.container/src/zope/container/tests/test_view_permissions.py
===================================================================
--- Sandbox/malthe/zope.container/src/zope/app/container/tests/test_view_permissions.py 2008-04-22 12:11:58 UTC (rev 85590)
+++ Sandbox/malthe/zope.container/src/zope/container/tests/test_view_permissions.py 2008-04-22 12:37:09 UTC (rev 85592)
@@ -1,103 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2004 Zope Corporation 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.
-#
-##############################################################################
-"""Container View Permissions Tests
-
-$Id$
-"""
-import unittest
-import transaction
-
-from zope.security.interfaces import Unauthorized
-
-from zope.app.testing.functional import BrowserTestCase
-from zope.app.file import File
-from zope.dublincore.interfaces import IZopeDublinCore
-from zope.securitypolicy.interfaces import IRolePermissionManager
-from zope.app.container.testing import AppContainerLayer
-
-class Tests(BrowserTestCase):
-
- def test_default_view_permissions(self):
- """Tests the default view permissions.
-
- See zope/app/securitypolicy/configure.zcml for the grants of
- zope.View and zope.app.dublincore.view to zope.Anonymous. These
- ensure that, by default, anonymous users can view container contents.
- """
- # add an item that can be viewed from the root folder
- file = File()
- self.getRootFolder()['file'] = file
- IZopeDublinCore(file).title = u'My File'
- transaction.commit()
-
- response = self.publish('/')
- self.assertEquals(response.getStatus(), 200)
- body = response.getBody()
-
- # confirm we can see the file name
- self.assert_(body.find('<a href="file">file</a>') != -1)
-
- # confirm we can see the metadata title
- self.assert_(body.find('<td><span>My File</span></td>') != -1)
-
- def test_deny_view(self):
- """Tests the denial of view permissions to anonymous.
-
- This test uses the ZMI interface to deny anonymous zope.View permission
- to the root folder.
- """
- # deny zope.View to zope.Anonymous
- prm = IRolePermissionManager(self.getRootFolder())
- prm.denyPermissionToRole('zope.View', 'zope.Anonymous')
- transaction.commit()
-
- # confirm Unauthorized when viewing root folder
- self.assertRaises(Unauthorized, self.publish, '/')
-
- def test_deny_dublincore_view(self):
- """Tests the denial of dublincore view permissions to anonymous.
-
- Users who can view a folder contents page but cannot view dublin core
- should still be able to see the folder items' names, but not their
- title, modified, and created info.
- """
- # add an item that can be viewed from the root folder
- file = File()
- self.getRootFolder()['file'] = file
- IZopeDublinCore(file).title = u'My File'
-
- # deny zope.app.dublincore.view to zope.Anonymous
- prm = IRolePermissionManager(self.getRootFolder())
- prm.denyPermissionToRole('zope.app.dublincore.view', 'zope.Anonymous')
- transaction.commit()
-
- response = self.publish('/')
- self.assertEquals(response.getStatus(), 200)
- body = response.getBody()
-
- # confirm we can see the file name
- self.assert_(body.find('<a href="file">file</a>') != -1)
-
- # confirm we *cannot* see the metadata title
- self.assert_(body.find('My File') == -1)
-
-
-def test_suite():
- suite = unittest.TestSuite()
- Tests.layer = AppContainerLayer
- suite.addTest(unittest.makeSuite(Tests))
- return suite
-
-if __name__=='__main__':
- unittest.main(defaultTest='test_suite')
More information about the Checkins
mailing list