[Zope-Checkins]
SVN: Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/
preparing to merge
david whitfield Morriss
whit at longnow.org
Fri Aug 18 22:36:54 EDT 2006
Log message for revision 69679:
preparing to merge
Changed:
A Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/
A Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/PortalTestCase.py
A Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/ZopeLite.py
A Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/ZopeTestCase.py
A Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/__init__.py
A Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/base.py
A Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/connections.py
A Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/doc/
A Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/doc/API.stx
A Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/doc/CHANGES.txt
A Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/doc/ClassDiagram.pdf
A Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/doc/ENVIRONMENT.txt
A Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/doc/FunctionalTesting.stx
A Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/doc/HOWTO.stx
A Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/doc/PROFILER.stx
A Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/doc/PortalTestCase.stx
A Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/doc/README.stx
A Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/doc/SECURITY.stx
A Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/doc/TIMELINES.txt
A Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/doc/VERSION.txt
A Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/framework.py
A Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/functional.py
A Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/interfaces.py
A Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/layer.py
A Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/placeless.py
A Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/profiler.py
A Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/sandbox.py
A Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/testBaseTestCase.py
A Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/testFunctional.py
A Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/testInterfaces.py
A Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/testPlaceless.py
A Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/testPortalTestCase.py
A Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/testPythonScript.py
A Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/testShoppingCart.py
A Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/testSkeleton.py
A Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/testWebserver.py
A Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/testZODBCompat.py
A Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/testZopeTestCase.py
A Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/testing.log
A Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/tests.py
A Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/threadutils.py
A Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/utils.py
A Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/zopedoctest/
A Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/zopedoctest/FunctionalDocTest.txt
A Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/zopedoctest/README.txt
A Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/zopedoctest/WarningsTest.txt
A Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/zopedoctest/ZopeDocTest.txt
A Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/zopedoctest/__init__.py
A Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/zopedoctest/framework.py
A Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/zopedoctest/functional.py
A Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/zopedoctest/testAuthHeaderTest.py
A Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/zopedoctest/testFunctionalDocTest.py
A Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/zopedoctest/testWarningsTest.py
A Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/zopedoctest/testZopeDocTest.py
A Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/zopedoctest/tests.py
A Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/ztc_common.py
-=-
Added: Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/PortalTestCase.py
===================================================================
--- Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/PortalTestCase.py 2006-08-19 02:33:50 UTC (rev 69678)
+++ Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/PortalTestCase.py 2006-08-19 02:36:49 UTC (rev 69679)
@@ -0,0 +1,151 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+"""Abstract base test case for working with CMF-style portals
+
+This class maintains a fixture consisting of:
+
+ - a portal object (self.portal)
+ - a user folder inside the portal
+ - a default user with role 'Member' inside the user folder
+ - the default user's memberarea (self.folder)
+ - the default user is logged in
+
+The twist is that the portal object itself is *not* created
+by the PortalTestCase class! Subclasses must make sure
+getPortal() returns a usable portal object to the setup code.
+
+$Id: PortalTestCase.py 30565 2005-05-30 22:07:11Z shh $
+"""
+
+import base
+import interfaces
+import utils
+
+from AccessControl import getSecurityManager
+from AccessControl.SecurityManagement import newSecurityManager
+from AccessControl.SecurityManagement import noSecurityManager
+from Acquisition import aq_base
+
+portal_name = 'portal'
+from ZopeTestCase import user_name
+from ZopeTestCase import user_password
+
+
+class PortalTestCase(base.TestCase):
+ '''Base test case for testing CMF-style portals'''
+
+ __implements__ = (interfaces.IPortalTestCase,
+ interfaces.IPortalSecurity,
+ base.TestCase.__implements__)
+
+ _configure_portal = 1
+
+ def setUp(self):
+ '''Sets up the fixture. Do not override,
+ use the hooks instead.
+ '''
+ try:
+ self.beforeSetUp()
+ self.app = self._app()
+ self.portal = self._portal()
+ self._setup()
+ self.afterSetUp()
+ except:
+ self._clear()
+ raise
+
+ def _portal(self):
+ '''Returns the portal object for a test.'''
+ return self.getPortal()
+
+ def _setup(self):
+ '''Configures the portal. Framework authors may
+ override.
+ '''
+ if self._configure_portal:
+ self._setupUserFolder()
+ self._setupUser()
+ self.login()
+ self._setupHomeFolder()
+
+ def _setupUserFolder(self):
+ '''Creates the user folder if missing.'''
+ if not hasattr(aq_base(self.portal), 'acl_users'):
+ self.portal.manage_addUserFolder()
+
+ def _setupUser(self):
+ '''Creates the default user.'''
+ uf = self.portal.acl_users
+ uf.userFolderAddUser(user_name, user_password, ['Member'], [])
+
+ def _setupHomeFolder(self):
+ '''Creates the default user's home folder.'''
+ self.createMemberarea(user_name)
+ pm = self.portal.portal_membership
+ self.folder = pm.getHomeFolder(user_name)
+
+ def _refreshSkinData(self):
+ '''Refreshes the skin cache.'''
+ if hasattr(aq_base(self.portal), 'clearCurrentSkin'):
+ self.portal.clearCurrentSkin()
+ else: # CMF 1.4
+ self.portal._v_skindata = None
+ self.portal.setupCurrentSkin()
+
+ # Portal interface
+
+ def getPortal(self):
+ '''Returns the portal object to the setup code.
+ Will typically be overridden by subclasses
+ to return the object serving as the "portal".
+
+ Note: This method should not be called by tests!
+ '''
+ return getattr(self.app, portal_name)
+
+ def createMemberarea(self, name):
+ '''Creates a memberarea for the specified user.
+ Subclasses may override to provide a customized
+ or more lightweight version of the memberarea.
+ '''
+ pm = self.portal.portal_membership
+ if hasattr(aq_base(pm), 'createMemberArea'):
+ pm.createMemberArea(name)
+ else: # CMF 1.4
+ pm.createMemberarea(name)
+
+ # Security interface
+
+ def setRoles(self, roles, name=user_name):
+ '''Changes the user's roles.'''
+ uf = self.portal.acl_users
+ uf.userFolderEditUser(name, None, utils.makelist(roles), [])
+ if name == getSecurityManager().getUser().getId():
+ self.login(name)
+
+ def setPermissions(self, permissions, role='Member'):
+ '''Changes the permissions assigned to role.'''
+ self.portal.manage_role(role, utils.makelist(permissions))
+
+ def login(self, name=user_name):
+ '''Logs in.'''
+ uf = self.portal.acl_users
+ user = uf.getUserById(name)
+ if not hasattr(user, 'aq_base'):
+ user = user.__of__(uf)
+ newSecurityManager(None, user)
+
+ def logout(self):
+ '''Logs out.'''
+ noSecurityManager()
+
Added: Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/ZopeLite.py
===================================================================
--- Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/ZopeLite.py 2006-08-19 02:33:50 UTC (rev 69678)
+++ Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/ZopeLite.py 2006-08-19 02:36:49 UTC (rev 69679)
@@ -0,0 +1,201 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+"""Lightweight Zope startup
+
+Fast Zope startup is achieved by not installing (m)any
+products. If your tests require a product you must
+install it yourself using installProduct().
+
+Typically used as in
+
+ import ZopeLite as Zope2
+ Zope2.installProduct('SomeProduct')
+ app = Zope2.app()
+
+$Id: ZopeLite.py 66172 2006-03-26 15:15:41Z shh $
+"""
+
+import os, sys, time
+from utils import hasProduct, _print
+
+# Allow code to tell it is run by the test framework
+os.environ['ZOPETESTCASE'] = '1'
+
+# Increase performance on MP hardware
+sys.setcheckinterval(2500)
+
+# Shut up if we are not in control of the import process
+_quiet = sys.modules.has_key('Zope2')
+
+def _write(msg):
+ '''Writes 'msg' to stderr if not _quiet.'''
+ if not _quiet:
+ _print(msg)
+
+def _exec(cmd):
+ '''Prints the time it takes to execute 'cmd'.'''
+ if os.environ.get('X', None):
+ start = time.time()
+ exec cmd
+ _print('(%.3fs)' % (time.time() - start))
+
+_write('Loading Zope, please stand by ')
+_start = time.time()
+
+def _configure_logging():
+ # Initialize the logging module
+ import logging
+ root = logging.getLogger()
+ if not root.handlers:
+ class NullHandler(logging.Handler):
+ def emit(self, record): pass
+ root.addHandler(NullHandler())
+ logging.basicConfig()
+
+def _configure_debug_mode():
+ # Switch off debug mode
+ import App.config
+ config = App.config.getConfiguration()
+ config.debug_mode = 0
+ App.config.setConfiguration(config)
+
+def _configure_client_cache():
+ # Make sure we use a temporary client cache
+ import App.config
+ config = App.config.getConfiguration()
+ config.zeo_client_name = None
+ App.config.setConfiguration(config)
+
+_configure_logging()
+_configure_debug_mode()
+_configure_client_cache()
+
+_exec('import Zope2')
+import Zope2
+_exec('import ZODB')
+import ZODB
+_write('.')
+
+_exec('import Globals')
+import Globals
+_exec('import OFS.SimpleItem')
+import OFS.SimpleItem
+_exec('import OFS.ObjectManager')
+import OFS.ObjectManager
+_write('.')
+
+_exec('import OFS.Application')
+import OFS.Application
+import App.ProductContext
+_write('.')
+
+_patched = False
+
+def _apply_patches():
+ # Avoid expensive product import
+ def null_import_products(): pass
+ OFS.Application.import_products = null_import_products
+
+ # Avoid expensive product installation
+ def null_initialize(app): pass
+ OFS.Application.initialize = null_initialize
+
+ # Avoid expensive help registration
+ def null_register_topic(self,id,topic): pass
+ App.ProductContext.ProductContext.registerHelpTopic = null_register_topic
+ def null_register_title(self,title): pass
+ App.ProductContext.ProductContext.registerHelpTitle = null_register_title
+ def null_register_help(self,directory='',clear=1,title_re=None): pass
+ App.ProductContext.ProductContext.registerHelp = null_register_help
+
+ # Note that we applied the monkey patches
+ global _patched
+ _patched = True
+
+# Do not patch a running Zope
+if not Zope2._began_startup:
+ _apply_patches()
+
+# Allow test authors to install Zope products into the test environment. Note
+# that installProduct() must be called at module level -- never from tests.
+from OFS.Application import get_folder_permissions, get_products, install_product
+from OFS.Folder import Folder
+import Products
+
+_theApp = Zope2.app()
+_installedProducts = {}
+
+def installProduct(name, quiet=0):
+ '''Installs a Zope product.'''
+ start = time.time()
+ meta_types = []
+ if _patched and not _installedProducts.has_key(name):
+ for priority, product_name, index, product_dir in get_products():
+ if product_name == name:
+ if not quiet: _print('Installing %s ... ' % product_name)
+ # We want to fail immediately if a product throws an exception
+ # during install, so we set the raise_exc flag.
+ install_product(_theApp, product_dir, product_name, meta_types,
+ get_folder_permissions(), raise_exc=1)
+ _installedProducts[product_name] = 1
+ Products.meta_types = Products.meta_types + tuple(meta_types)
+ Globals.default__class_init__(Folder)
+ if not quiet: _print('done (%.3fs)\n' % (time.time() - start))
+ break
+ else:
+ if name != 'SomeProduct': # Ignore the skeleton tests :-P
+ if not quiet: _print('Installing %s ... NOT FOUND\n' % name)
+
+def _load_control_panel():
+ # Loading the Control_Panel of an existing ZODB may take
+ # a while; print another dot if it does.
+ start = time.time()
+ max = (start - _start) / 4
+ _exec('_theApp.Control_Panel')
+ _theApp.Control_Panel
+ if (time.time() - start) > max:
+ _write('.')
+
+def _install_products():
+ installProduct('PluginIndexes', 1) # Must install first
+ installProduct('OFSP', 1)
+ #installProduct('ExternalMethod', 1)
+ #installProduct('ZSQLMethods', 1)
+ #installProduct('ZGadflyDA', 1)
+ #installProduct('MIMETools', 1)
+ #installProduct('MailHost', 1)
+
+_load_control_panel()
+_install_products()
+
+# So people can use ZopeLite.app()
+app = Zope2.app
+debug = Zope2.debug
+DB = Zope2.DB
+configure = Zope2.configure
+def startup(): pass
+Zope = Zope2
+
+# ZODB sandbox factory
+from ZODB.DemoStorage import DemoStorage
+
+def sandbox(base=None):
+ '''Returns a sandbox copy of the base ZODB.'''
+ if base is None: base = Zope2.DB
+ base_storage = base._storage
+ quota = getattr(base_storage, '_quota', None)
+ storage = DemoStorage(base=base_storage, quota=quota)
+ return ZODB.DB(storage)
+
+_write(' done (%.3fs)\n' % (time.time() - _start))
+
Added: Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/ZopeTestCase.py
===================================================================
--- Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/ZopeTestCase.py 2006-08-19 02:33:50 UTC (rev 69678)
+++ Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/ZopeTestCase.py 2006-08-19 02:36:49 UTC (rev 69679)
@@ -0,0 +1,132 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+"""Default test case & fixture for Zope testing
+
+The fixture consists of:
+
+ - a folder (self.folder)
+ - a user folder inside that folder
+ - a default user inside the user folder
+
+The default user is logged in and has the 'Access contents information'
+and 'View' permissions given to his role.
+
+$Id: ZopeTestCase.py 30326 2005-05-11 16:03:21Z shh $
+"""
+
+import base
+import functional
+import interfaces
+import utils
+import connections
+import layer
+
+from AccessControl import getSecurityManager
+from AccessControl.SecurityManagement import newSecurityManager
+from AccessControl.SecurityManagement import noSecurityManager
+from AccessControl.Permissions import access_contents_information
+from AccessControl.Permissions import view
+
+folder_name = 'test_folder_1_'
+user_name = 'test_user_1_'
+user_password = 'secret'
+user_role = 'test_role_1_'
+standard_permissions = [access_contents_information, view]
+
+
+class ZopeTestCase(base.TestCase):
+ '''Base test case for Zope testing'''
+
+ __implements__ = (interfaces.IZopeSecurity,
+ base.TestCase.__implements__)
+
+ _setup_fixture = 1
+
+ layer = layer.Zope2Layer
+
+ def _setup(self):
+ '''Sets up the fixture. Framework authors may
+ override.
+ '''
+ if self._setup_fixture:
+ self._setupFolder()
+ self._setupUserFolder()
+ self._setupUser()
+ self.login()
+
+ def _setupFolder(self):
+ '''Creates and configures the folder.'''
+ self.app.manage_addFolder(folder_name)
+ self.folder = getattr(self.app, folder_name)
+ self.folder._addRole(user_role)
+ self.folder.manage_role(user_role, standard_permissions)
+
+ def _setupUserFolder(self):
+ '''Creates the user folder.'''
+ self.folder.manage_addUserFolder()
+
+ def _setupUser(self):
+ '''Creates the default user.'''
+ uf = self.folder.acl_users
+ uf.userFolderAddUser(user_name, user_password, [user_role], [])
+
+ def _clear(self, call_close_hook=0):
+ '''Clears the fixture.'''
+ # This code is a wart from the olden days.
+ try:
+ if connections.contains(self.app):
+ self.app._delObject(folder_name)
+ except:
+ pass
+ base.TestCase._clear(self, call_close_hook)
+
+ # Security interface
+
+ def setRoles(self, roles, name=user_name):
+ '''Changes the user's roles.'''
+ uf = self.folder.acl_users
+ uf.userFolderEditUser(name, None, utils.makelist(roles), [])
+ if name == getSecurityManager().getUser().getId():
+ self.login(name)
+
+ def setPermissions(self, permissions, role=user_role):
+ '''Changes the user's permissions.'''
+ self.folder.manage_role(role, utils.makelist(permissions))
+
+ def login(self, name=user_name):
+ '''Logs in.'''
+ uf = self.folder.acl_users
+ user = uf.getUserById(name)
+ if not hasattr(user, 'aq_base'):
+ user = user.__of__(uf)
+ newSecurityManager(None, user)
+
+ def logout(self):
+ '''Logs out.'''
+ noSecurityManager()
+
+
+class FunctionalTestCase(functional.Functional, ZopeTestCase):
+ '''Convenience base class for functional Zope tests
+
+ You can mix-in Functional with every xTestCase
+ to turn it into a functional test case.
+ '''
+
+ __implements__ = (functional.Functional.__implements__,
+ ZopeTestCase.__implements__)
+
+
+from base import app
+from base import close
+
Added: Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/__init__.py
===================================================================
--- Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/__init__.py 2006-08-19 02:33:50 UTC (rev 69678)
+++ Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/__init__.py 2006-08-19 02:36:49 UTC (rev 69679)
@@ -0,0 +1,58 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+"""Names exported by the ZopeTestCase package
+
+$Id: __init__.py 66218 2006-03-27 01:29:02Z shh $
+"""
+
+import utils
+
+from utils import hasProduct
+from layer import installProduct
+from utils import _print
+from utils import setAllLayers
+
+from ZopeTestCase import folder_name
+from ZopeTestCase import user_name
+from ZopeTestCase import user_password
+from ZopeTestCase import user_role
+from ZopeTestCase import standard_permissions
+from ZopeTestCase import ZopeTestCase
+from ZopeTestCase import FunctionalTestCase
+
+from PortalTestCase import portal_name
+from PortalTestCase import PortalTestCase
+
+from profiler import Profiled
+from sandbox import Sandboxed
+from functional import Functional
+
+from base import TestCase
+from base import app
+from base import close
+
+from ZODB.tests.warnhook import WarningsHook
+from unittest import main
+
+from zopedoctest import ZopeDocTestSuite
+from zopedoctest import ZopeDocFileSuite
+from zopedoctest import FunctionalDocTestSuite
+from zopedoctest import FunctionalDocFileSuite
+
+from layer import ZopeLiteLayer
+from layer import Zope2Layer
+
+import zopedoctest as doctest
+import transaction
+import placeless
+
Added: Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/base.py
===================================================================
--- Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/base.py 2006-08-19 02:33:50 UTC (rev 69678)
+++ Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/base.py 2006-08-19 02:36:49 UTC (rev 69679)
@@ -0,0 +1,132 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+"""TestCase for Zope testing
+
+$Id: base.py 66218 2006-03-27 01:29:02Z shh $
+"""
+
+import unittest
+import transaction
+import profiler
+import utils
+import interfaces
+import connections
+
+from AccessControl.SecurityManagement import noSecurityManager
+
+def app():
+ '''Opens a ZODB connection and returns the app object.'''
+ import ZopeLite as Zope2
+ app = Zope2.app()
+ app = utils.makerequest(app)
+ connections.register(app)
+ return app
+
+def close(app):
+ '''Closes the app's ZODB connection.'''
+ connections.close(app)
+
+
+
+class TestCase(profiler.Profiled, unittest.TestCase, object):
+ '''Base test case for Zope testing
+ '''
+
+ __implements__ = (interfaces.IZopeTestCase,
+ profiler.Profiled.__implements__)
+
+ def afterSetUp(self):
+ '''Called after setUp() has completed. This is
+ far and away the most useful hook.
+ '''
+ pass
+
+ def beforeTearDown(self):
+ '''Called before tearDown() is executed.
+ Note that tearDown() is not called if
+ setUp() fails.
+ '''
+ pass
+
+ def afterClear(self):
+ '''Called after the fixture has been cleared.
+ Note that this may occur during setUp() *and*
+ tearDown().
+ '''
+ pass
+
+ def beforeSetUp(self):
+ '''Called before the ZODB connection is opened,
+ at the start of setUp(). By default begins
+ a new transaction.
+ '''
+ transaction.begin()
+
+ def beforeClose(self):
+ '''Called before the ZODB connection is closed,
+ at the end of tearDown(). By default aborts
+ the transaction.
+ '''
+ transaction.abort()
+
+ def setUp(self):
+ '''Sets up the fixture. Do not override,
+ use the hooks instead.
+ '''
+ try:
+ self.beforeSetUp()
+ self.app = self._app()
+ self._setup()
+ self.afterSetUp()
+ except:
+ self._clear()
+ raise
+
+ def tearDown(self):
+ '''Tears down the fixture. Do not override,
+ use the hooks instead.
+ '''
+ try:
+ self.beforeTearDown()
+ self._clear(1)
+ except:
+ self._clear()
+ raise
+
+ def _app(self):
+ '''Returns the app object for a test.'''
+ return app()
+
+ def _setup(self):
+ '''Sets up the fixture. Framework authors may
+ override.
+ '''
+ pass
+
+ def _clear(self, call_close_hook=0):
+ '''Clears the fixture.'''
+ if call_close_hook:
+ self.beforeClose()
+ self._close()
+ self.logout()
+ self.afterClear()
+
+ def _close(self):
+ '''Closes the ZODB connection.'''
+ transaction.abort()
+ connections.closeAll()
+
+ def logout(self):
+ '''Logs out.'''
+ noSecurityManager()
+
Added: Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/connections.py
===================================================================
--- Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/connections.py 2006-08-19 02:33:50 UTC (rev 69678)
+++ Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/connections.py 2006-08-19 02:36:49 UTC (rev 69679)
@@ -0,0 +1,65 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+"""ZODB connection registry
+
+$Id: connections.py 30326 2005-05-11 16:03:21Z shh $
+"""
+
+class ConnectionRegistry:
+ '''ZODB connection registry
+
+ This registry can hold either ZODB.Connection objects or OFS.Application
+ objects. In the latter case, a close operation will close the REQUEST as
+ well as the Connection referenced by the Application's _p_jar attribute.
+ '''
+
+ def __init__(self):
+ self._conns = []
+
+ def register(self, conn):
+ self._conns.append(conn)
+
+ def contains(self, conn):
+ return conn in self._conns
+
+ def __len__(self):
+ return len(self._conns)
+
+ def count(self):
+ return len(self)
+
+ def close(self, conn):
+ if self.contains(conn):
+ self._conns.remove(conn)
+ self._do_close(conn)
+
+ def closeAll(self):
+ for conn in self._conns:
+ self._do_close(conn)
+ self._conns = []
+
+ def _do_close(self, conn):
+ if hasattr(conn, 'close'):
+ conn.close()
+ else:
+ conn.REQUEST.close()
+ conn._p_jar.close()
+
+
+registry = ConnectionRegistry()
+register = registry.register
+contains = registry.contains
+count = registry.count
+close = registry.close
+closeAll = registry.closeAll
+
Added: Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/doc/API.stx
===================================================================
--- Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/doc/API.stx 2006-08-19 02:33:50 UTC (rev 69678)
+++ Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/doc/API.stx 2006-08-19 02:36:49 UTC (rev 69679)
@@ -0,0 +1,332 @@
+<style type="text/css"> <!-- li { margin: 1em } --> </style>
+
+ZopeTestCase API Reference
+
+ A nicely rendered version of this document can be found at
+ http://zope.org/Members/shh/ZopeTestCaseWiki/ApiReference
+
+
+
+Module Testing.ZopeTestCase
+
+ Top-level package exposing names from contained modules
+
+ Constants
+
+ folder_name
+
+ user_name
+
+ user_password
+
+ user_role
+
+ standard_permissions
+
+ portal_name
+
+ Functions
+
+ hasProduct(name)
+
+ installProduct(name, quiet=0)
+
+ app()
+
+ close(app)
+
+ main()
+
+ _print(msg)
+
+ ZopeDocTestSuite(module=None, **kw)
+
+ ZopeDocFileSuite(*paths, **kw)
+
+ FunctionalDocTestSuite(module=None, **kw)
+
+ FunctionalDocFileSuite(*paths, **kw)
+
+ Classes
+
+ TestCase
+
+ ZopeTestCase
+
+ FunctionalTestCase
+
+ PortalTestCase
+
+ Profiled
+
+ Sandboxed
+
+ Functional
+
+ WarningsHook
+
+ Modules
+
+ ZopeLite as Zope
+
+ utils
+
+ doctest
+
+ transaction
+
+
+
+Module ZopeLite
+
+ Lightweight replacement for the Zope module
+
+ Constants
+
+ DB
+
+ Functions
+
+ hasProduct(name)
+
+ installProduct(name, quiet=0)
+
+ app(connection=None)
+
+ sandbox(base=None)
+
+ startup()
+
+ _print(msg)
+
+
+
+Module base
+
+ Basic infrastructure for Zope testing
+
+ Functions
+
+ app()
+
+ close(app)
+
+ Classes
+
+ TestCase
+
+
+
+Class TestCase
+
+ Base test case for Zope testing
+ (derived from unittest.TestCase)
+
+ __implements__ = (IZopeTestCase,
+ Profiled.__implements__)
+
+ Methods
+
+ afterSetUp()
+
+ beforeTearDown()
+
+ afterClear()
+
+ beforeSetUp()
+
+ beforeClose()
+
+
+
+Module ZopeTestCase
+
+ Test case and fixture for Zope testing
+
+ Constants
+
+ folder_name
+
+ user_name
+
+ user_password
+
+ user_role
+
+ standard_permissions
+
+ Classes
+
+ ZopeTestCase
+
+ FunctionalTestCase
+
+
+
+Class ZopeTestCase
+
+ Base test case for Zope testing
+ (derived from base.TestCase)
+
+ __implements__ = (IZopeSecurity,
+ TestCase.__implements__)
+
+ Methods
+
+ setRoles(roles, name=user_name)
+
+ setPermissions(permissions, role=user_role)
+
+ login(name=user_name)
+
+ logout()
+
+
+
+Class FunctionalTestCase
+
+ Convenience class for functional unit testing
+ (derived from Functional and ZopeTestCase)
+
+ __implements__ = (Functional.__implements__,
+ ZopeTestCase.__implements__)
+
+ Methods
+
+ *See base classes*
+
+
+
+Module PortalTestCase
+
+ Test case and fixture for testing CMF-based applications
+
+ Constants
+
+ portal_name
+
+ user_name
+
+ user_password
+
+ Classes
+
+ PortalTestCase
+
+
+
+Class PortalTestCase
+
+ Base test case for CMF testing
+ (derived from base.TestCase)
+
+ __implements__ = (IPortalTestCase,
+ IPortalSecurity,
+ TestCase.__implements__)
+
+ Methods
+
+ getPortal()
+
+ createMemberarea(name)
+
+ setRoles(roles, name=user_name)
+
+ setPermissions(permissions, role='Member')
+
+ login(name=user_name)
+
+ logout()
+
+
+
+Module profiler
+
+ Profiling support
+
+ Functions
+
+ runcall(func, *args, **kw)
+
+ print_stats()
+
+ dump_stats(filename)
+
+ Classes
+
+ Profiled
+
+
+
+Class Profiled
+
+ Profiling support mix-in for xTestCases
+
+ __implements__ = (IProfiled,)
+
+ Methods
+
+ runcall(func, *args, **kw)
+
+
+
+Module sandbox
+
+ ZODB sandbox support
+
+ Classes
+
+ Sandboxed
+
+
+
+Class Sandboxed
+
+ Sandbox support mix-in for xTestCases
+
+ Methods
+
+ *No public methods*
+
+
+
+Module functional
+
+ Functional testing support
+
+ Classes
+
+ Functional
+
+
+
+Class Functional
+
+ Functional testing mix-in for xTestCases
+
+ __implements__ = (IFunctional,)
+
+ Methods
+
+ publish(path, basic=None, env=None, extra=None, request_method='GET', stdin=None)
+
+
+
+Module utils
+
+ Utility functions to extend the test environment
+
+ Functions
+
+ setupCoreSessions(app=None)
+
+ setupZGlobals(app=None)
+
+ setupSiteErrorLog(app=None)
+
+ startZServer(number_of_threads=1, log=None)
+
+ importObjectFromFile(container, filename, quiet=0)
+
+ appcall(func, *args, **kw)
+
Added: Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/doc/CHANGES.txt
===================================================================
--- Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/doc/CHANGES.txt 2006-08-19 02:33:50 UTC (rev 69678)
+++ Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/doc/CHANGES.txt 2006-08-19 02:36:49 UTC (rev 69679)
@@ -0,0 +1,184 @@
+2.9-layer support
+- removed all direct imports of ZopeLite
+
+2.9 edition
+- transaction.commit(1) is deprecated in favor of transaction.savepoint().
+- Don't break if Python distros ship without profile support (Debian, Ubuntu).
+- Functional.publish() would hang if it got a request_method argument other
+ than GET or HEAD while omitting the stdin argument.
+- installProduct() now becomes a noop if ZopeTestCase did not apply its
+ patches.
+- Made functional doctests set cookie related headers.
+- Made functional doctests set the Www-Authenticate header.
+- Made sure logging is configured. Read $INSTANCE_HOME/log.ini if it exists.
+- Made base.TestCase a new-style class.
+- Added placeless.py for Z3-style setup. Thanks to Whit Morriss.
+
+0.9.8 (Zope 2.8 edition)
+- Renamed 'doctest' package to 'zopedoctest' because of name-shadowing
+ issues discovered during integration into Zope 2.8. Tests may still use
+ 'from Testing.ZopeTestCase import doctest' as the name is aliased there.
+- Greatly improved the doctest story. ZopeTestCase now implements four test
+ suite factories: ZopeDocTestSuite, ZopeDocFileSuite, FunctionalDocTestSuite,
+ and FunctionalDocFileSuite.
+- Removed warnhook.py, we now use the one from ZODB.tests.
+- Removed doctest.py, we now use the one from zope.testing.
+- Removed dochttp.py + test, we now use the one from zope.app.tests.
+- ZopeLite now takes care not to monkey patch an already started Zope.
+- PortalTestCase.setUp() no longer calls _refreshSkinData() as CMF is smart
+ enough now.
+- Fixed PortalTestCase._refreshSkinData() helper to work with CMF >= 1.5.
+- Made PortalTestCase.createMemberarea() work better with CMF >= 1.5.
+- Fixed a bug where using sessions in sandboxed (functional) tests would cause
+ connection pool depletion and subsequent hangs. Thanks to Balazs Ree.
+- Encapsulated the ConnectionRegistry in its own module, connections.py.
+ Reusing the registry from other modules becomes a lot cleaner as a result.
+- Made sure to close the REQUEST so as not to leak REQUEST._held. Thanks
+ to Sidnei da Silva.
+- Modified runalltests.py so it imports modules more like test.py, i.e.
+ without touching sys.path and without the help of imp.
+- The standalone version of ZopeTestCase gained a Zope 2.8-style transaction
+ module. Tests may now use 'from Testing.ZopeTestCase import transaction'
+ which is guaranteed to work across Zope versions.
+- The REQUEST now contains the ACTUAL_URL variable introduced in Zope 2.7.4.
+
+0.9.6
+- Dropped support for Zope 2.5 as it lacks the setSecurityManager() API.
+- Moved interfaces from doc section to interfaces.py module.
+- Test classes now assert their interfaces.
+- Refactored security interfaces to IZopeSecurity and IPortalSecurity.
+- Added a class diagram to the doc section.
+- setRoles() and setPermissions() no longer insist on ListType arguments
+ but now accept lists, tuples, and strings.
+- getRoles() and getPermissions() are no longer part of the security API
+ because of YAGNI.
+- Added getHeader() and getCookie() accessors to the response wrapper
+ used in functional tests.
+- publish() now accepts an optional 'stdin' argument, allowing to pass
+ the input stream for POST and PUT requests.
+- runalltests.py now supports a '-R' (recursive) command line option.
+
+0.9.4 (not released)
+- Backported functional doc tests from Zope 3.
+- Included a copy of doctest.py from Zope 3 (which is copied from
+ Python2.4 CVS). It will be removed when we start requiring Python2.4.
+- Added dochttp.py script from Zope 3, which is used to convert
+ tcpwatch.py output to functional doc tests.
+- Added warnhook.py from ZODB. It is used to capture the output of
+ warnings.warn() calls.
+- Added missing 'user_password' constant.
+- Many thanks to Sidnei da Silva!
+
+0.9.2
+- Introduced new base.TestCase class which contains the bare-
+ bones framework code and serves as baseclass for ZTC and PTC.
+- ZopeLite now configures the logging module in Zope >= 2.7.
+- Teardown sequence is now compatible with Zope trunk (again).
+- Added getRoles() and getPermissions() methods to security API.
+- setRoles() now asserts 'roles' argument is ListType.
+- setPermissions() now asserts 'permissions' argument is ListType.
+
+0.9.0
+- No longer support Zope 2.4 as its DemoStorage is broken.
+- Made PortalTestCase derive from ZopeTestCase (again).
+- Made all xTestCases profiler aware by default.
+- Renamed the Profiler module to profiler.py (lowercase).
+- Added support for ZODB sandboxes, sandbox.py.
+- Added support for functional unit testing, functional.py.
+- The profiler module now provides a dump_stats() method to write
+ profiler statistics to a file for manual inspection.
+- The REQUEST now fakes a published object to make the URL1
+ request variable available to tests. Thanks to Alan Runyan.
+- startZServer() now accepts a log argument, allowing to pass
+ a stream which the ZServer access log (Z2.log) will be written to.
+- The 'app' argument of utility functions is now optional.
+- Fixed custom_zodb.py support for Zope 2.7.
+- Most mercilessly refactored ztc_common.py.
+- ZopeLite now loads silently if it does not control the import process.
+
+0.8.6
+- Revised and amended much of the existing documentation.
+- Added an API reference (skeleton), API.stx.
+- Documented what's going on when tests are run in TIMELINES.txt.
+- Fixed issues with testZODBCompat.py and Zope < 2.6.
+- setupZGlobals() now uses a new-style BTrees.OOBTree.
+- Profiling can now be activated from the command line.
+
+0.8.4
+- framework.py now flushes stdout to not mess up the output in batch mode.
+- framework.py no longer adds os.pardir to the sys.path. Thanks to
+ Yoshinori Okuji.
+- Made sure user objects are not inadvertently wrapped twice by login().
+- Made sure "renegade" transactions are aborted if something goes wrong
+ during the setup phase.
+- initialize_cache() is no longer called for Zope 2.7.
+
+0.8.2
+- Removed the leading underscores from all constant names. They proved
+ non-private in "real life" anyway. The old names are still available
+ for backward compatibility, but are deprecated.
+- Removed NO_PRODUCT_LOAD for reasons of obscureness and YAGNI.
+- Added a test for ZODB behavior in ZTC, testZODBCompat.py.
+
+0.8.0
+- Added a PortalTestCase base class to aid testing of CMF-style portals.
+- Added simple profiling support using the Python profile library.
+- Got rid of the ill-conceived FX interface (don't even ask).
+- ZopeLite now supports Zope 2.7.
+
+0.7.2 (not released)
+- ZopeLite gained a do-nothing startup() method for API compliance.
+- The ZopeTestCase module now has a main() method like unittest has.
+- Made sure the test user's 'roles' attribute is a list because CMF
+ role-mapping assumes it can append to it. :-/
+
+0.7.0
+- Fixed a bug that caused setRoles() to only work with the
+ default user folder. Refactored the fixture code in the process.
+- Reworked the connection registry and wrote tests for it.
+- Made afterClear() largely redundant because it turned out to be just that.
+- Added close() method to be able to close ZODB connections individually.
+- Added ISimpleSecurity and IExtensibleSecurity interfaces.
+
+0.6.4
+- installProduct() now immediately fails if a product throws an
+ exception during installation. Thanks to Tom Jenkins.
+- The REQUEST no longer contains the entire shell environment.
+- Moved all documentation files to the 'doc' subdirectory.
+- Added IZopeTestCase and IZopeTestCaseFX interfaces.
+
+0.6.2
+- The effects of setting INSTANCE_HOME have been changed to something
+ less surprising. Please see ENVIRONMENT.txt for details.
+- Now uses the environment variable ZEO_INSTANCE_HOME to enable ZEO
+ support.
+
+0.6.0
+- Use a module-level database connection registry to avoid freezing
+ after too many errors.
+- All tests are now transactional by default.
+- Added beforeSetUp() and beforeClose() hooks to the ZopeTestCase class.
+- Added utility method importObjectFromFile()
+- Added utility method setupSiteErrorLog().
+- Added utility method startZServer().
+- Added accompanying test, testWebserver.py.
+- Added first incarnation of a How-To.
+- Revised the example tests.
+
+0.5.3
+- Zope 2.6 compatibility adjustments.
+- Hardening in the face of incomplete Zope installations.
+
+0.5.2
+- Delete ZEO_CLIENT environment variable to enforce a temporary client
+ cache. Repair Zope 2.4 Testing package issue in the process.
+- Provide NO_PRODUCT_LOAD environment variable for completeness.
+- Added hasProduct() method to allow testing for product availability.
+- Added new utility method setupZGlobals().
+- Added a skeleton test suite, testSkeleton.py.
+- Added runalltests.py script.
+- Added CHANGES, INSTALL, and VERSION documents.
+
+0.5.0
+- Unit and regression testing framework for Zope. Initial release.
+
Added: Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/doc/ClassDiagram.pdf
===================================================================
(Binary files differ)
Property changes on: Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/doc/ClassDiagram.pdf
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/doc/ENVIRONMENT.txt
===================================================================
--- Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/doc/ENVIRONMENT.txt 2006-08-19 02:33:50 UTC (rev 69678)
+++ Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/doc/ENVIRONMENT.txt 2006-08-19 02:36:49 UTC (rev 69679)
@@ -0,0 +1,48 @@
+
+ZTC makes the following assumptions about its environment:
+
+a) The 'ZopeTestCase' package is installed in the Zope "trunk" inside the
+ 'Testing' module, which means: SOFTWARE_HOME/Testing/ZopeTestCase.
+
+b) A 'Products' directory exists inside SOFTWARE_HOME and INSTANCE_HOME.
+
+c) The tests (the 'tests' subdirectories) are located either below a
+ SOFTWARE_HOME or INSTANCE_HOME, typically in Products/MyCoolProduct/tests.
+
+d) The somewhat weak assumption is that ZTC can walk up the directory tree from
+ 'tests', and find a 'Products' directory. This is how INSTANCE_HOME
+ detection works. It regrettably fails on some filesystems when symbolic
+ links are involved (a solution is detailed below, so hang on).
+
+
+The non-trivial part is that INSTANCE_HOME has two distinct purposes:
+
+ 1) INSTANCE_HOME/lib/python must be added to sys.path and
+ INSTANCE_HOME/Products to Products.__path__.
+
+ 2) INSTANCE_HOME/custom_zodb.py must be used to set up a ZODB.
+
+
+ZTC attempts to resolve this by detecting an INSTANCE_HOME for 1) but leaving
+the actual environment variable untouched so 2) works by still pointing into
+SOFTWARE_HOME/Testing.
+
+As soon as I allow you to set INSTANCE_HOME yourself, I lose the ability to
+distinguish whether you mean 1) or 2) or both.
+
+Before ZTC 0.6.2 the code assumed "both" and did the magic ZEO dance. This was
+clearly too surprising.
+
+The behaviour has now been changed to 1).
+
+That way, if your setup does not fit c) or you run into the symbolic link
+problem d), you can solve it by setting INSTANCE_HOME prior to running the
+tests.
+
+ZEO support ("both") is handled separately, through the new environment
+variable ZEO_INSTANCE_HOME.
+
+
+You may want to consider using a testrunner to run your tests. You can find one
+here: http://zope.org/Members/shh/TestRunner
+
Added: Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/doc/FunctionalTesting.stx
===================================================================
--- Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/doc/FunctionalTesting.stx 2006-08-19 02:33:50 UTC (rev 69678)
+++ Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/doc/FunctionalTesting.stx 2006-08-19 02:36:49 UTC (rev 69679)
@@ -0,0 +1,47 @@
+<style type="text/css"> <!-- li { margin: 1em } --> </style>
+
+Functional Testing Readme
+
+ The functional testing support of ZopeTestCase was inspired by
+ Marius Gedminas' work for Zope 3.
+
+ Deriving from the 'Functional' mix-in (and an xTestCase) adds a
+ 'publish' method to your test case class. Tests can call
+ 'self.publish(path, basic=None, env=None, extra=None, request_method='GET', stdin=None)',
+ passing a path and, optionally, basic-auth info and form data.
+ The path may contain a query string.
+
+ 'publish' returns an enhanced Response object, that can be queried
+ for status, response body, headers, etc.
+
+ 'publish' invokes the ZPublisher machinery just as if the request
+ had come in through ZServer. This allows for high-level testing
+ of things like argument marshalling, form validation, and traversal.
+
+ Note that the tests have *full access to the ZODB*. This means you
+ can easily prepare a fixture for 'publish' and/or check the impact
+ of a publication on the database. This represents a major advantage
+ over purely URL-based test environments!
+
+ Please see the 'testFunctional.py' example test for more.
+
+ While the modules are called 'functional.py' in both Zope 3 and
+ ZopeTestCase, it is current wisdom that such tests are not truly
+ "functional tests", but rather "integration tests".
+
+ True functional tests, in their most-helpful guise as "acceptance
+ tests", must be able to test the end-user experience. For web
+ applications this means: browser simulation.
+
+ Plone 2 comes with an 'ftests' package combining the functional
+ testing support of ZopeTestCase with the "mechanize" browser
+ simulator library: http://wwwsearch.sourceforge.net/mechanize/
+ (For some version of 2, currently only available from the Plone
+ CVS HEAD.)
+
+Read the Source
+
+ Amen. Read 'functional.py' and 'sandbox.py' if you want to know
+ what's going on behind the scenes.
+
+
Added: Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/doc/HOWTO.stx
===================================================================
--- Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/doc/HOWTO.stx 2006-08-19 02:33:50 UTC (rev 69678)
+++ Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/doc/HOWTO.stx 2006-08-19 02:36:49 UTC (rev 69679)
@@ -0,0 +1,238 @@
+<style type="text/css"> <!-- li { margin: 1em } --> </style>
+
+ZopeTestCase Mini How-To
+
+ (Still-terse-but-the-Wiki-has-more Version 0.3)
+
+Introduction
+
+ *ZopeTestCase* is an attempt to make writing unit and regression tests
+ in Zope a more rewarding experience. The package deals with all the plumbing
+ required, and leaves the programmer with writing the tests - and the tests only.
+ It is built on PyUnit and the Testing package coming with Zope.
+
+ ZopeTestCase provides a Zope sandbox to every test. This sandbox comes fully
+ equipped with ZODB connection, root application object, and REQUEST.
+ When writing tests you have complete control over Zope, the way you have from a Python
+ product. The framework is easily customized and can be adapted to virtually every
+ conceivable test situation.
+
+ What you can test with ZTC
+
+ - Basically everything. Including security, transactions, sessions, web access, ...
+
+ What you cannot test with ZTC
+
+ - Web forms and user interaction. This should be left to FunctionalTests.
+
+Prereqs
+
+ For an excellent introduction to unit testing read chapter 11 of Mark Pilgrim's
+ "Dive Into Python.":http://diveintopython.org/unit_testing/index.html
+
+ Read about what unit tests are and what they are not in Chris McDonough's
+ "Unit Testing Zope.":http://zope.org/Members/mcdonc/PDG/UnitTesting
+
+ Download and install "ZopeTestCase.":http://zope.org/Members/shh/ZopeTestCase
+ Be prepared to read the source files, especially the example tests. And the README of course.
+
+What You Get
+
+ The ZopeTestCase package consists of the following components:
+
+ framework.py
+
+ This file must be copied into the individual 'tests' directories (See the README for more).
+ It locates the Testing and ZopeTestCase packages, detects INSTANCE_HOME installations,
+ and determines the 'custom_zodb.py' file used to set up the test ZODB. 'framework.py' is
+ included first thing in every test module.
+
+ ZopeLite.py
+
+ This module is designed to work like the 'Zope' module, but to load a lot faster.
+ The speed-up is achieved by not installing Zope products and help files. If your
+ tests require a product to be installed (most don't actually), you must install
+ it yourself using the 'installProduct' method. 'ZopeLite' also provides a
+ 'hasProduct' method, that allows to test whether a product can be found along the
+ products path, i.e. whether it is available to the test instance.
+
+ ZopeTestCase.py
+
+ This module provides the 'ZopeTestCase' class, which is used as a base class for
+ all test cases.
+
+ A ZopeTestCase sets up a default fixture in the newly started Zope instance.
+ This fixture consist of a folder, a userfolder inside that folder, and a
+ user created in that userfolder. The user's role is configured at folder level
+ and populated with default permissions. Finally, the user is logged in.
+
+ This way, once a test runs, a complete and sane Zope "toy" environment is
+ already in place.
+
+ The fixture is destroyed during the tearDown phase and can be switched off
+ entirely by setting '_setup_fixture=0' in your test case.
+
+ The ZopeTestCase class provides a number of hooks that allow you to
+ adapt the fixture to your needs:
+
+ - **'afterSetUp'** is called after the default fixture has been set up. Override this
+ method to add the objects you intend to test.
+
+ *This is clearly the most useful hook. You may ignore the remaining hooks until you
+ really need them, if ever.*
+
+ - **'beforeTearDown'** is called at the start of the tearDown phase. The fixture
+ is still in place at this point.
+
+ - **'afterClear'** is called after the fixture has been destroyed. Note that this
+ may occur during setUp *and* tearDown. This method must not throw an exception
+ even when called repeatedly.
+
+ Hooks for controlling transactions:
+
+ - **'beforeSetUp'** is called before the ZODB connection is opened, at the start of setUp.
+ The default behaviour of this hook is to call 'transaction.begin()'.
+ You will rarely want to override this.
+
+ - **'beforeClose'** is called before the ZODB connection is closed, at the end of
+ tearDown. By default this method calls 'transaction.abort()' to discard
+ any changes made by the test. In some situations you may need to override
+ this hook and commit the transaction instead. Make sure you really know what
+ you are doing though.
+
+ utils.py
+
+ Provides utility methods to extend the test environment:
+
+ - **'setupCoreSessions'** creates the Zope sessioning objects in the test ZODB.
+
+ - **'setupZGlobals'** creates the ZGlobals BTree required by ZClasses.
+
+ - **'setupSiteErrorLog'** creates the error_log object required by ZPublisher.
+
+ - **'startZServer'** starts a ZServer thread on the local host. Use this if the
+ objects you test require URL access to Zope.
+
+ - **'importObjectFromFile'** imports a (.zexp) file into a specified container.
+ Handy for adding "prerolled" components to the sandbox.
+
+ These methods must be run at module level. Do not call them from 'afterSetUp' or from tests!
+
+Writing Tests
+
+ Generally, writing tests with ZTC is no different from writing "ordinary" Zope code. A complete
+ Zope environment is made available to every test. The only real difference is that it is not
+ driven by ZServer + ZPublisher but by the PyUnit TestRunner.
+
+ Inside a ZopeTestCase the root application object can be accessed as 'self.app'.
+ The folder serving as the fixture is available as 'self.folder'. The REQUEST is
+ reachable as 'self.app.REQUEST'.
+
+ 1. In your test module create a test case derived from 'ZopeTestCase'.
+
+ 2. Override 'afterSetUp' to add your own objects to 'self.folder'.
+
+ 3. Write one or more tests exercising these objects.
+
+ How to setup and run your tests is covered in detail by the
+ "README":http://zope.org/Members/shh/ZopeTestCase/README
+
+ The easiest way to start with your own tests is to copy the skeleton test
+ 'testSkeleton.py', and take it from there.
+
+ Note that tests are written in unrestricted Python and are not affected by Zope's
+ security policy. To test the security of individual methods or objects, you must invoke
+ 'restrictedTraverse' or 'validateValue' explicitly!
+
+ A simple test may look like::
+
+ from Testing import ZopeTestCase
+ from AccessControl import Unauthorized
+
+ class ExampleTest(ZopeTestCase.ZopeTestCase):
+
+ def afterSetUp(self):
+ # Add objects to the workarea
+ self.folder.addDTMLMethod('doc', file='foo')
+
+ def testDocument(self):
+ self.assertEqual(self.folder.doc(), 'foo')
+
+ def testEditDocument(self):
+ self.folder.doc.manage_edit('bar', '')
+ self.assertEqual(self.folder.doc(), 'bar')
+
+ def testAccessDocument(self):
+ self.folder.doc.manage_permission('View', ['Manager'])
+ self.assertRaises(Unauthorized,
+ self.folder.restrictedTraverse, 'doc')
+
+ Read the Examples
+
+ Please study the example tests for more:
+
+ - **'testSkeleton.py'** represents the simplest possible ZopeTestCase. The module contains all
+ the plumbing required. It is recommended that you copy this file to start your own tests.
+
+ - **'testPythonScript.py'** tests a PythonScript object in the default fixture.
+ It demonstrates how to manipulate the test user's roles and permissions and how
+ security is validated.
+
+ - **'testShoppingCart.py'** tests the ShoppingCart example. This test
+ uses Sessions and shows how to test a TTW Zope application.
+
+ - **'testFunctional.py'** demonstrates the new functional testing features.
+ Tests may call 'self.publish()' to simulate URL calls to the ZPublisher.
+
+ - **'testWebserver.py'** starts up an HTTP ZServer thread and tests URL access to it. This
+ test is an example for explicit transaction handling and shows how to use ZODB
+ sandboxes to further increase isolation between individual tests.
+
+ - **'testZopeTestCase.py'** tests the ZopeTestCase class itself. May be of interest to the
+ investigative types.
+
+ - **'testPortalTestCase.py'** contains an equivalent test suite for the PortalTestCase
+ base class.
+
+ - **'testZODBCompat.py'** tests various aspects of ZODB behavior in a ZopeTestCase environment.
+ Shows things like cut/paste, import/export, and that _v_ and _p_ variables survive
+ transaction boundaries.
+
+ Read the Source
+
+ The source files are well documented and an overall worthy read <wink>:
+
+ - The ZopeTestCase class is defined in file 'ZopeTestCase.py'.
+
+ - The interfaces implemented by this class are documented in 'interfaces.py'.
+
+ - All names exported by the ZopeTestCase package are listed in '__init__.py'.
+
+Resources
+
+ A Wiki with all the documentation:
+ "ZopeTestCaseWiki":http://zope.org/Members/shh/ZopeTestCaseWiki
+
+ Slides of my talk at EuroPython 2003:
+ "UnitTestingZope":http://zope.org/Members/shh/UnitTestingZope.pdf
+
+ A testrunner with INSTANCE_HOME support:
+ "TestRunner":http://zope.org/Members/shh/TestRunner
+
+Related
+
+ "PyUnit":http://pyunit.sf.net (Steve Purcell)
+
+ "WebUnit":http://mechanicalcat.net/tech/webunit (Richard Jones) and
+ "WebUnit":http://webunit.sf.net (Steve Purcell)
+
+ "ZUnit":http://zope.org/Members/lalo/ZUnit (Lalo Martins)
+
+ "FunctionalTests":http://zope.org/Members/tseaver/FunctionalTests (Tres Seaver)
+
+ "WebsiteLoadTest":http://zope.org/Members/ajung/WebsiteLoadTest (Andreas Jung)
+
+Contact
+
+ Feel free to send bug reports, feature requests, etc to stefan at epy.co.at.
+
Added: Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/doc/PROFILER.stx
===================================================================
--- Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/doc/PROFILER.stx 2006-08-19 02:33:50 UTC (rev 69678)
+++ Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/doc/PROFILER.stx 2006-08-19 02:36:49 UTC (rev 69679)
@@ -0,0 +1,19 @@
+<style type="text/css"> <!-- li { margin: 1em } --> </style>
+
+Profiler Readme
+
+ Since version 0.9.0 all xTestCases are profiler aware by default.
+
+ You can run your tests under profiler control like this::
+
+ python testSomething.py profile
+
+ If you want to profile fixture creation or destruction type one of::
+
+ python testSomething.py profile-setup
+ python testSomething.py profile-teardown
+
+ Profiler statistics will be printed after the test results.
+
+ See the API reference for more on the 'profiler' module.
+
Added: Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/doc/PortalTestCase.stx
===================================================================
--- Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/doc/PortalTestCase.stx 2006-08-19 02:33:50 UTC (rev 69678)
+++ Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/doc/PortalTestCase.stx 2006-08-19 02:36:49 UTC (rev 69679)
@@ -0,0 +1,93 @@
+<style type="text/css"> <!-- li { margin: 1em } --> </style>
+
+PortalTestCase Readme
+
+ The PortalTestCase class is a close relative of the ZopeTestCase
+ class. It was devised at the Plone Castle Sprint to form the base of an
+ integration testing framework for Plone 2.0. Thanks to Gidon Friedman
+ and Godefroid Chapelle for their collaboration.
+
+
+Much of what is true for ZopeTestCase is true for PortalTestCase as well:
+
+ * PortalTestCase handles the ZODB connection, transaction, and
+ application object; and it provides a REQUEST.
+
+ * PortalTestCase sets up a user folder and a user.
+
+ * PortalTestCase provides the same hooks as ZopeTestCase.
+
+ * PortalTestCase implements the same security interfaces as
+ ZopeTestCase.
+
+
+What's different?
+
+ * PortalTestCase is designed for testing CMF-based applications.
+
+ * The fixture is slightly more complex, consisting of a portal object,
+ a userfolder + user, and the user's memberarea.
+
+ * For flexibility, the portal is *not* created by the base class but
+ must be provided by the user (typically a derived xTestCase) of the
+ PortalTestCase base class.
+
+ * Subclasses will have to override 'getPortal' to return the object
+ serving as the portal.
+
+ * The portal will however be configured by the machinery which means
+ creating a user and a fresh memberarea for every test.
+
+ * Subclasses may override 'createMemberarea' to provide customized
+ and/or more lightweight memberareas to the tests. This can improve
+ performance quite significantly.
+
+
+Feature Comparison:
+
+ ZopeTestCase
+
+ * 1 user + 1 role
+
+ * Folder contains user folder and role definition
+
+ * Folder also serves as workarea
+
+ * User is logged in
+
+ * Provides attributes::
+
+ self.app
+ self.app.REQUEST
+ self.folder
+ self.folder.acl_users
+
+ PortalTestCase
+
+ * 1 user + 'Member' role
+
+ * Portal contains user folder and role definition
+
+ * User's home folder serves as workarea
+
+ * User is logged in
+
+ * Provides attributes::
+
+ self.app
+ self.app.REQUEST
+ self.portal
+ self.portal.acl_users
+ self.folder
+
+
+Read the Source
+
+ As always, I recommend to look at the source code of both
+ 'ZopeTestCase.py' and 'PortalTestCase.py' for all the details you may need.
+ Interface documentation can be found in 'interfaces.py'.
+
+ The test framework shipping with Plone 2.0 is a good example of how the
+ PortalTestCase class can be put to use.
+
+
Added: Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/doc/README.stx
===================================================================
--- Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/doc/README.stx 2006-08-19 02:33:50 UTC (rev 69678)
+++ Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/doc/README.stx 2006-08-19 02:36:49 UTC (rev 69679)
@@ -0,0 +1,89 @@
+<style type="text/css"> <!-- li { margin: 1em } --> </style>
+
+ZopeTestCase Readme
+
+ The ZopeTestCase package has been developed in the hope that it will make
+ testing Zope packages more convenient. It has features to support various
+ scenarios from unit-testing individual components inside a "toy" environment
+ to running regression tests against live ZEO servers.
+
+ To add a test suite to a Zope package:
+
+ 1. Make a 'tests' subdirectory.
+
+ 2. Create an (empty) '__init__.py' in 'tests' to make it a package.
+
+ 3. Copy 'framework.py' from the 'ZopeTestCase' package into 'tests'.
+
+ Once a test suite has been set up, you can add test modules:
+
+ 1. Create a file with a name matching 'test*.py'.
+
+ 2. Import the 'ZopeTestCase' package as in 'from Testing import ZopeTestCase'
+ and define one or more subclasses of 'ZopeTestCase.ZopeTestCase'.
+
+ 3. Define methods for the test classes. Each method's name must start
+ with 'test'. It should test one small case, preferably using a PyUnit
+ assertion method. Here's a minimal example::
+
+ class ExampleTest(ZopeTestCase.ZopeTestCase):
+ def testAddition(self):
+ self.assertEqual(1+1, 2)
+
+ 4. You can add 'afterSetUp' and 'beforeTearDown' methods that are automatically
+ called after the fixture has been set up and before the fixture is destroyed
+ respectively.
+
+ 5. Follow the instructions in 'framework.py' about adding lines to the
+ top and bottom of the file.
+
+ Now you can run the test as 'python path/to/tests/testName.py', or
+ simply go to the 'tests' directory and type 'python testName.py'.
+
+ Note that there is a skeleton test suite named 'testSkeleton.py' that you
+ may copy into your 'tests' directory and take it from there.
+
+ Note also that when the tests are run in an INSTANCE_HOME installation of
+ Zope, you must set the SOFTWARE_HOME environment variable for the 'Testing'
+ and 'ZopeTestCase' packages to be found.
+
+ See the sample tests in the 'ZopeTestCase' directory for details on writing
+ your own tests.
+
+framework.py
+
+ 1. Uses SOFTWARE_HOME (if set) to locate the Testing package.
+
+ 2. Detects and handles INSTANCE_HOME installations of Zope. Please
+ see ENVIRONMENT.txt for the assumptions ZTC makes about its
+ environment.
+
+ 3. Supports setting up a ZODB from a 'custom_zodb.py' file in
+ the 'tests' directory.
+
+ 4. Allows to connect to a running ZEO server by setting the
+ ZEO_INSTANCE_HOME environment variable.
+
+testrunner.py
+
+ Alternatively, you may use Zope's testrunner utility to run your tests
+ ('testrunner.py' can be found in the 'utilities' directory of your Zope
+ installation). If you do so, you will have to define a 'test_suite' method
+ in your modules (see examples).
+
+ There is no need to set SOFTWARE_HOME when using the testrunner but you may
+ have to provide the -i flag when testing in an INSTANCE_HOME setup.
+
+ Example: 'python /path/to/Zope/utilities/testrunner.py -q -i -a'
+
+ If your testrunner does not appear to support the -i flag get the one from
+ 'http://zope.org/Members/shh/TestRunner'
+
+ Note that the 'custom_zodb.py' magic (3. + 4.) is not available when using
+ the testrunner.
+
+ If you have tests that should not be picked up by the testrunner, make a
+ 'test_suite' method that returns an empty TestSuite.
+
+ Note that in Zope 2.7 the testrunner lives in '/path/to/Zope/bin'.
+
Added: Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/doc/SECURITY.stx
===================================================================
--- Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/doc/SECURITY.stx 2006-08-19 02:33:50 UTC (rev 69678)
+++ Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/doc/SECURITY.stx 2006-08-19 02:36:49 UTC (rev 69679)
@@ -0,0 +1,58 @@
+<style type="text/css"> <!-- li { margin: 1em } --> </style>
+
+Default Fixture
+
+ - **'self.app'** is the root application object of the test ZODB (contains Control_Panel, ...)
+
+ Note that a ZODB connections has already been opened and a transaction begun at this point.
+
+ - **'self.app.REQUEST'** is the request object. Note that the REQUEST is rather minimal because
+ ZPublisher is not involved when running tests, and as such many REQUEST variables are never
+ set. Feel free to add to the REQUEST whatever your tests require.
+
+ - **'self.folder'** is the work area. This folder will be created anew for each test and thrown
+ away once the test has finished. The name of the folder is 'test_folder_1_'. You should
+ use the 'ZopeTestCase.folder_name' constant when you need the folder's name. 'self.folder' is a
+ reference to the object at 'self.app[folder_name]'.
+
+ A default role definition ('ZopeTestCase.user_role') is added to the folder, and a list of
+ permissions ('ZopeTestCase.standard_permissions') is assigned to the role.
+
+ - **'self.folder.acl_users'** is the user folder providing a security context to the work area.
+
+ A default user account is added to the user folder with name 'test_user_1_' and password 'secret'.
+ You should use the 'ZopeTestCase.user_name' constant when you need the user's name, the
+ 'ZopeTestCase.user_password' constant when you need the user's password.
+
+ The default user has a single role, 'ZopeTestCase.user_role'.
+
+ At the end of the setup process the default user is logged in, and the 'afterSetUp' hook is called.
+
+Security API
+
+ - **'self.setRoles(roles, name=user_name)'** allows to change the roles assigned to a user.
+ If the 'name' argument is omitted, changes the roles of the default user.
+
+ - **'self.setPermissions(permissions, role=user_role)'** allows to change the permissions
+ assigned to a role. If the 'role' argument is omitted, changes the permissions of the
+ default role.
+
+ - **'self.login(name=user_name)'** allows to log in as a specified user.
+ If the 'name' argument is omitted, logs in as the default user.
+
+ - **'self.logout()'** allows to log out and become 'Anonymous User'.
+
+Testing Security
+
+ - **'ob.restrictedTraverse("attr")'** is a simple way to check whether the currently logged in user is
+ allowed to access attribute 'attr' of object 'ob'.
+
+ - **'getSecurityManager().validate(None, ob, "attr", ob.attr)'** uses the security manager to do the same.
+ The convenience method 'getSecurityManager().validateValue(ob.attr)' will no longer work
+ in Zope 2.8.
+
+ Also see the 'testPythonScript.py' example test.
+
+ Note that you have the entire Zope security API at your disposal to further refine your fixture.
+ E.g. to add another user call 'self.folder.acl_users.userFolderAddUser("user2", "secret", ["role2"], [])'.
+
Added: Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/doc/TIMELINES.txt
===================================================================
--- Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/doc/TIMELINES.txt 2006-08-19 02:33:50 UTC (rev 69678)
+++ Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/doc/TIMELINES.txt 2006-08-19 02:36:49 UTC (rev 69679)
@@ -0,0 +1,85 @@
+Timelines
+
+When the skeleton test is run by typing 'python testSkeleton.py', it
+
+ 1. includes file framework.py
+
+ 1.1 locates and imports the Testing package by means of
+ - SOFTWARE_HOME environment variable
+ - auto-detection
+
+ 1.2 locates and includes file ztc_common.py
+
+ 1.2.1 sets up the instance environment by means of
+ - ZEO_INSTANCE_HOME environment variable
+ - INSTANCE_HOME environment variable
+ - auto-detection
+ - optional custom_zodb.py
+
+ 2. imports module Testing.ZopeTestCase
+
+ 2.1 imports module Testing.ZopeTestCase.ZopeLite
+
+ 2.1.1 imports module ZODB
+ 2.1.2 imports module Globals
+ 2.1.3 patches OFS.Application to not auto-install all products
+ 2.1.4 patches App.ProductContext to not auto-install all help files
+ 2.1.5 imports module Zope
+ 2.1.6 starts Zope
+ 2.1.7 installs product PluginIndexes
+ 2.1.8 installs product OFSP
+
+ 2.2 imports module Testing.ZopeTestCase.ZopeTestCase
+
+ 2.2.1 creates the connection registry
+ 2.2.2 defines class ZopeTestCase(unittest.TestCase)
+
+ 3. installs product SomeProduct
+
+ 4. defines class TestSomeProduct(ZopeTestCase.ZopeTestCase)
+
+ 5. executes method framework()
+
+ 5.1 collects all TestCase-derived classes in a test suite
+ 5.2 runs the test suite using the TextTestRunner
+
+
+When a ZopeTestCase test method is run, it
+
+ 1. executes setUp()
+
+ 1.1 calls the beforeSetUp() hook
+
+ 1.1.1 by default begins a new transaction
+
+ 1.2 opens a ZODB connection and retrieves the root application object
+
+ 1.3 sets up the default fixture
+
+ 1.3.1 creates a Folder object in the root
+ 1.3.2 creates a UserFolder object in the folder
+ 1.3.3 creates a default user in the user folder
+ 1.3.4 logs in as the default user
+
+ 1.4 calls the afterSetUp() hook
+
+ 2. executes the test method
+
+ 3. executes tearDown()
+
+ 3.1 calls the beforeTearDown() hook
+
+ 3.2 calls the beforeClose() hook
+
+ 3.2.1 by default aborts the transaction
+
+ 3.3 clears the fixture *)
+
+ 3.1.1 aborts all transactions
+ 3.1.2 closes all ZODB connections
+ 3.1.3 logs out
+ 3.1.4 calls the afterClear() hook
+
+
+*) Note: The fixture is also cleared if an error occurs during setUp()
+
Added: Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/doc/VERSION.txt
===================================================================
--- Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/doc/VERSION.txt 2006-08-19 02:33:50 UTC (rev 69678)
+++ Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/doc/VERSION.txt 2006-08-19 02:36:49 UTC (rev 69679)
@@ -0,0 +1 @@
+ZopeTestCase 0.9.8
Added: Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/framework.py
===================================================================
--- Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/framework.py 2006-08-19 02:33:50 UTC (rev 69678)
+++ Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/framework.py 2006-08-19 02:36:49 UTC (rev 69679)
@@ -0,0 +1,116 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+"""ZopeTestCase framework
+
+COPY THIS FILE TO YOUR 'tests' DIRECTORY.
+
+This version of framework.py will use the SOFTWARE_HOME
+environment variable to locate Zope and the Testing package.
+
+If the tests are run in an INSTANCE_HOME installation of Zope,
+Products.__path__ and sys.path with be adjusted to include the
+instance's Products and lib/python directories respectively.
+
+If you explicitly set INSTANCE_HOME prior to running the tests,
+auto-detection is disabled and the specified path will be used
+instead.
+
+If the 'tests' directory contains a custom_zodb.py file, INSTANCE_HOME
+will be adjusted to use it.
+
+If you set the ZEO_INSTANCE_HOME environment variable a ZEO setup
+is assumed, and you can attach to a running ZEO server (via the
+instance's custom_zodb.py).
+
+The following code should be at the top of every test module:
+
+ import os, sys
+ if __name__ == '__main__':
+ execfile(os.path.join(sys.path[0], 'framework.py'))
+
+...and the following at the bottom:
+
+ if __name__ == '__main__':
+ framework()
+
+$Id: framework.py 40219 2005-11-18 15:05:47Z andreasjung $
+"""
+
+__version__ = '0.2.4'
+
+# Save start state
+#
+__SOFTWARE_HOME = os.environ.get('SOFTWARE_HOME', '')
+__INSTANCE_HOME = os.environ.get('INSTANCE_HOME', '')
+
+if __SOFTWARE_HOME.endswith(os.sep):
+ __SOFTWARE_HOME = os.path.dirname(__SOFTWARE_HOME)
+
+if __INSTANCE_HOME.endswith(os.sep):
+ __INSTANCE_HOME = os.path.dirname(__INSTANCE_HOME)
+
+# Find and import the Testing package
+#
+if not sys.modules.has_key('Testing'):
+ p0 = sys.path[0]
+ if p0 and __name__ == '__main__':
+ os.chdir(p0)
+ p0 = ''
+ s = __SOFTWARE_HOME
+ p = d = s and s or os.getcwd()
+ while d:
+ if os.path.isdir(os.path.join(p, 'Testing')):
+ zope_home = os.path.dirname(os.path.dirname(p))
+ sys.path[:1] = [p0, p, zope_home]
+ break
+ p, d = s and ('','') or os.path.split(p)
+ else:
+ print 'Unable to locate Testing package.',
+ print 'You might need to set SOFTWARE_HOME.'
+ sys.exit(1)
+
+import Testing, unittest
+execfile(os.path.join(os.path.dirname(Testing.__file__), 'common.py'))
+
+# Include ZopeTestCase support
+#
+if 1: # Create a new scope
+
+ p = os.path.join(os.path.dirname(Testing.__file__), 'ZopeTestCase')
+
+ if not os.path.isdir(p):
+ print 'Unable to locate ZopeTestCase package.',
+ print 'You might need to install ZopeTestCase.'
+ sys.exit(1)
+
+ ztc_common = 'ztc_common.py'
+ ztc_common_global = os.path.join(p, ztc_common)
+
+ f = 0
+ if os.path.exists(ztc_common_global):
+ execfile(ztc_common_global)
+ f = 1
+ if os.path.exists(ztc_common):
+ execfile(ztc_common)
+ f = 1
+
+ if not f:
+ print 'Unable to locate %s.' % ztc_common
+ sys.exit(1)
+
+# Debug
+#
+print 'SOFTWARE_HOME: %s' % os.environ.get('SOFTWARE_HOME', 'Not set')
+print 'INSTANCE_HOME: %s' % os.environ.get('INSTANCE_HOME', 'Not set')
+sys.stdout.flush()
+
Added: Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/functional.py
===================================================================
--- Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/functional.py 2006-08-19 02:33:50 UTC (rev 69678)
+++ Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/functional.py 2006-08-19 02:36:49 UTC (rev 69679)
@@ -0,0 +1,130 @@
+##############################################################################
+#
+# Copyright (c) 2005 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 functional unit testing in ZTC
+
+After Marius Gedminas' functional.py module for Zope3.
+
+$Id: functional.py 38608 2005-09-25 08:44:20Z tseaver $
+"""
+
+import sys, re, base64
+import transaction
+import sandbox
+import interfaces
+
+
+class Functional(sandbox.Sandboxed):
+ '''Derive from this class and an xTestCase to get functional
+ testing support::
+
+ class MyTest(Functional, ZopeTestCase):
+ ...
+ '''
+
+ __implements__ = (interfaces.IFunctional,)
+
+ def publish(self, path, basic=None, env=None, extra=None,
+ request_method='GET', stdin=None, handle_errors=True):
+ '''Publishes the object at 'path' returning a response object.'''
+
+ from StringIO import StringIO
+ from ZPublisher.Response import Response
+ from ZPublisher.Test import publish_module
+
+ from AccessControl.SecurityManagement import getSecurityManager
+ from AccessControl.SecurityManagement import setSecurityManager
+
+ # Save current security manager
+ sm = getSecurityManager()
+
+ # Commit the sandbox for good measure
+ transaction.commit()
+
+ if env is None:
+ env = {}
+ if extra is None:
+ extra = {}
+
+ request = self.app.REQUEST
+
+ env['SERVER_NAME'] = request['SERVER_NAME']
+ env['SERVER_PORT'] = request['SERVER_PORT']
+ env['REQUEST_METHOD'] = request_method
+
+ p = path.split('?')
+ if len(p) == 1:
+ env['PATH_INFO'] = p[0]
+ elif len(p) == 2:
+ [env['PATH_INFO'], env['QUERY_STRING']] = p
+ else:
+ raise TypeError, ''
+
+ if basic:
+ env['HTTP_AUTHORIZATION'] = "Basic %s" % base64.encodestring(basic)
+
+ if stdin is None:
+ stdin = StringIO()
+
+ outstream = StringIO()
+ response = Response(stdout=outstream, stderr=sys.stderr)
+
+ publish_module('Zope2',
+ response=response,
+ stdin=stdin,
+ environ=env,
+ extra=extra,
+ debug=not handle_errors,
+ )
+
+ # Restore security manager
+ setSecurityManager(sm)
+
+ return ResponseWrapper(response, outstream, path)
+
+
+class ResponseWrapper:
+ '''Decorates a response object with additional introspective methods.'''
+
+ _bodyre = re.compile('^$^\n(.*)', re.MULTILINE | re.DOTALL)
+
+ def __init__(self, response, outstream, path):
+ self._response = response
+ self._outstream = outstream
+ self._path = path
+
+ def __getattr__(self, name):
+ return getattr(self._response, name)
+
+ def getOutput(self):
+ '''Returns the complete output, headers and all.'''
+ return self._outstream.getvalue()
+
+ def getBody(self):
+ '''Returns the page body, i.e. the output par headers.'''
+ body = self._bodyre.search(self.getOutput())
+ if body is not None:
+ body = body.group(1)
+ return body
+
+ def getPath(self):
+ '''Returns the path used by the request.'''
+ return self._path
+
+ def getHeader(self, name):
+ '''Returns the value of a response header.'''
+ return self.headers.get(name.lower())
+
+ def getCookie(self, name):
+ '''Returns a response cookie.'''
+ return self.cookies.get(name)
+
Added: Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/interfaces.py
===================================================================
--- Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/interfaces.py 2006-08-19 02:33:50 UTC (rev 69678)
+++ Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/interfaces.py 2006-08-19 02:36:49 UTC (rev 69679)
@@ -0,0 +1,114 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+"""ZopeTestCase interfaces
+
+$Id: interfaces.py 30300 2005-05-08 08:15:23Z shh $
+"""
+
+from Interface import Interface
+
+
+class IZopeTestCase(Interface):
+
+ def afterSetUp():
+ '''Called after setUp() has completed. This is
+ far and away the most useful hook.
+ '''
+
+ def beforeTearDown():
+ '''Called before tearDown() is executed.
+ Note that tearDown() is not called if
+ setUp() fails.
+ '''
+
+ def afterClear():
+ '''Called after the fixture has been cleared.
+ Note that this may occur during setUp() *and*
+ tearDown().
+ '''
+
+ def beforeSetUp():
+ '''Called before the ZODB connection is opened,
+ at the start of setUp(). By default begins a
+ new transaction.
+ '''
+
+ def beforeClose():
+ '''Called before the ZODB connection is closed,
+ at the end of tearDown(). By default aborts
+ the transaction.
+ '''
+
+
+class IZopeSecurity(Interface):
+
+ def setRoles(roles, name=None):
+ '''Changes the roles assigned to a user.
+ If the 'name' argument is omitted, changes the
+ roles of the default user.
+ '''
+
+ def setPermissions(permissions, role=None):
+ '''Changes the permissions assigned to a role.
+ If the 'role' argument is omitted, changes the
+ permissions assigned to the default role.
+ '''
+
+ def login(name=None):
+ '''Logs in as the specified user.
+ If the 'name' argument is omitted, logs in
+ as the default user.
+ '''
+
+ def logout():
+ '''Logs out.'''
+
+
+class IPortalTestCase(IZopeTestCase):
+
+ def getPortal():
+ '''Returns the portal object to the setup code.
+ Will typically be overridden by subclasses
+ to return the object serving as the "portal".
+
+ Note: This method should not be called by tests!
+ '''
+
+ def createMemberarea(name):
+ '''Creates a memberarea for the specified user.
+ Subclasses may override to provide a customized
+ or more lightweight version of the memberarea.
+ '''
+
+
+class IPortalSecurity(IZopeSecurity):
+ '''This is currently the same as IZopeSecurity'''
+
+
+class IProfiled(Interface):
+
+ def runcall(func, *args, **kw):
+ '''Allows to run a function under profiler control
+ adding to the accumulated profiler statistics.
+ '''
+
+
+class IFunctional(Interface):
+
+ def publish(path, basic=None, env=None, extra=None, request_method='GET', stdin=None):
+ '''Publishes the object at 'path' returning an
+ extended response object. The path may contain
+ a query string.
+ '''
+
+
Added: Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/layer.py
===================================================================
--- Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/layer.py 2006-08-19 02:33:50 UTC (rev 69678)
+++ Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/layer.py 2006-08-19 02:36:49 UTC (rev 69679)
@@ -0,0 +1,54 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+"""
+layer support for ZopeTestCase
+
+$Id: $
+"""
+import os
+from utils import setDebugMode
+
+class ZopeLiteLayer:
+ @classmethod
+ def setUp(cls):
+ import ZopeLite
+
+ @classmethod
+ def tearDown(cls):
+ raise NotImplementedError
+
+# products to install
+_products=[]
+
+# setup functions
+_z2_callables=[]
+class Zope2Layer(ZopeLiteLayer):
+ """ stacks upon ZopeLiteLayer and handles products installs """
+ @classmethod
+ def setUp(cls):
+ import ZopeLite as Zope2
+ install = Zope2.installProduct
+
+ [install(name, quiet=quiet) \
+ for name, quiet in _products]
+
+ [func(*args, **kw) for func, args, kw in _z2_callables]
+
+ @classmethod
+ def tearDown(cls):
+ raise NotImplementedError
+
+
+def installProduct(name, quiet=0):
+ if not (name, quiet) in _products:
+ _products.append((name, quiet))
Added: Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/placeless.py
===================================================================
--- Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/placeless.py 2006-08-19 02:33:50 UTC (rev 69678)
+++ Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/placeless.py 2006-08-19 02:36:49 UTC (rev 69679)
@@ -0,0 +1,60 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+"""Placeless setup
+
+$Id: placeless.py 66218M 2006-08-01 03:30:55Z (local) $
+"""
+
+from zope.app.testing.placelesssetup import setUp, tearDown
+
+# For convenience
+from Products.Five import zcml
+
+
+def callZCML(zcml_callback):
+ if callable(zcml_callback):
+ zcml_callback()
+ else:
+ for func in zcml_callback:
+ func()
+
+
+def temporaryPlacelessSetUp(orig_func, placeless_available=True, required_zcml=[]):
+ '''A wrapper for test functions that require CA to be available and/or
+ some ZCML to be run during test fixture creation.
+ '''
+ if not placeless_available:
+ return orig_func
+
+ def wrapper(*args, **kw):
+ __doc__ = '''%s ::
+
+ @param required_zcml callback or iterable of callbacks
+ required for setup of configuration needed by fixture
+ creation.
+ ''' % orig_func.__doc__
+
+ # Call any necessary callbacks for setting up ZCML
+ callZCML(required_zcml)
+ if kw.has_key('required_zcml'):
+ zcml = kw.pop('required_zcml')
+ callZCML(zcml)
+
+ value = orig_func(*args, **kw)
+
+ # And tear it down
+ tearDown()
+ return value
+
+ return wrapper
+
Added: Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/profiler.py
===================================================================
--- Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/profiler.py 2006-08-19 02:33:50 UTC (rev 69678)
+++ Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/profiler.py 2006-08-19 02:36:49 UTC (rev 69679)
@@ -0,0 +1,120 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+"""Profiling support for ZTC
+
+$Id: profiler.py 37344 2005-07-20 07:35:36Z shh $
+"""
+
+import os, sys
+import interfaces
+
+# Some distros ship without profile
+try:
+ from profile import Profile
+ from pstats import Stats
+except ImportError:
+ def Profile(): pass
+
+_profile = Profile()
+_have_stats = 0
+
+limit = ('.py:', 200)
+sort = ('cumulative', 'time', 'pcalls')
+strip_dirs = 1
+
+
+def runcall(*args, **kw):
+ if _profile is None:
+ return apply(args[0], args[1:], kw)
+ else:
+ global _have_stats
+ _have_stats = 1
+ return apply(_profile.runcall, args, kw)
+
+
+def print_stats(limit=limit, sort=sort, strip_dirs=strip_dirs):
+ if _have_stats:
+ stats = Stats(_profile)
+ if strip_dirs:
+ stats.strip_dirs()
+ apply(stats.sort_stats, sort)
+ apply(stats.print_stats, limit)
+
+
+def dump_stats(filename):
+ if _have_stats:
+ _profile.dump_stats(filename)
+
+
+class Profiled:
+ '''Derive from this class and an xTestCase to get profiling support::
+
+ class MyTest(Profiled, ZopeTestCase):
+ ...
+
+ Then run the test module by typing::
+
+ $ python testSomething.py profile
+
+ Profiler statistics will be printed after the test results.
+ '''
+
+ __implements__ = (interfaces.IProfiled,)
+
+ def runcall(self, *args, **kw):
+ return apply(runcall, args, kw)
+
+ def __call__(self, result=None):
+ if result is None: result = self.defaultTestResult()
+ result.startTest(self)
+ testMethod = getattr(self, self._TestCase__testMethodName)
+ try:
+ try:
+ if int(os.environ.get('PROFILE_SETUP', 0)):
+ self.runcall(self.setUp)
+ else:
+ self.setUp()
+ except KeyboardInterrupt:
+ raise
+ except:
+ result.addError(self, self._TestCase__exc_info())
+ return
+
+ ok = 0
+ try:
+ if int(os.environ.get('PROFILE_TESTS', 0)):
+ self.runcall(testMethod)
+ else:
+ testMethod()
+ ok = 1
+ except self.failureException:
+ result.addFailure(self, self._TestCase__exc_info())
+ except KeyboardInterrupt:
+ raise
+ except:
+ result.addError(self, self._TestCase__exc_info())
+
+ try:
+ if int(os.environ.get('PROFILE_TEARDOWN', 0)):
+ self.runcall(self.tearDown)
+ else:
+ self.tearDown()
+ except KeyboardInterrupt:
+ raise
+ except:
+ result.addError(self, self._TestCase__exc_info())
+ ok = 0
+ if ok: result.addSuccess(self)
+ finally:
+ result.stopTest(self)
+
Added: Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/sandbox.py
===================================================================
--- Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/sandbox.py 2006-08-19 02:33:50 UTC (rev 69678)
+++ Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/sandbox.py 2006-08-19 02:36:49 UTC (rev 69679)
@@ -0,0 +1,77 @@
+##############################################################################
+#
+# Copyright (c) 2005 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 ZODB sandboxes in ZTC
+
+$Id: sandbox.py 30326 2005-05-11 16:03:21Z shh $
+"""
+import transaction
+import base
+import utils
+import connections
+
+class Sandboxed:
+ '''Derive from this class and an xTestCase to make each test
+ run in its own ZODB sandbox::
+
+ class MyTest(Sandboxed, ZopeTestCase):
+ ...
+ '''
+
+ def _app(self):
+ '''Returns the app object for a test.'''
+ import ZopeLite as Zope2
+ app = Zope2.app(Zope2.sandbox().open())
+ AppZapper().set(app)
+ app = utils.makerequest(app)
+ connections.register(app)
+ return app
+
+ def _close(self):
+ '''Clears the transaction and the AppZapper.'''
+ AppZapper().clear()
+ transaction.abort()
+ connections.closeAll()
+
+
+class AppZapper:
+ '''Application object share point'''
+
+ __shared_state = {'_app': None}
+
+ def __init__(self):
+ self.__dict__ = self.__shared_state
+
+ def set(self, app):
+ self._app = app
+
+ def clear(self):
+ self._app = None
+
+ def app(self):
+ return self._app
+
+
+def __bobo_traverse__(self, REQUEST=None, name=None):
+ '''Makes ZPublisher.publish() use the current app object.'''
+ app = AppZapper().app()
+ if app is not None:
+ return app
+ return self.__old_bobo_traverse__(REQUEST, name)
+
+
+from App.ZApplication import ZApplicationWrapper
+if not hasattr(ZApplicationWrapper, '__old_bobo_traverse__'):
+ ZApplicationWrapper.__old_bobo_traverse__ = (
+ ZApplicationWrapper.__bobo_traverse__)
+ ZApplicationWrapper.__bobo_traverse__ = __bobo_traverse__
+
Added: Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/testBaseTestCase.py
===================================================================
--- Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/testBaseTestCase.py 2006-08-19 02:33:50 UTC (rev 69678)
+++ Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/testBaseTestCase.py 2006-08-19 02:36:49 UTC (rev 69679)
@@ -0,0 +1,466 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+"""Tests the base.TestCase class
+
+NOTE: This is *not* an example TestCase. Do not
+use this file as a blueprint for your own tests!
+
+See testPythonScript.py and testShoppingCart.py for
+example test cases. See testSkeleton.py for a quick
+way of getting started.
+
+$Id: testBaseTestCase.py 30565 2005-05-30 22:07:11Z shh $
+"""
+
+import os, sys
+if __name__ == '__main__':
+ execfile(os.path.join(sys.path[0], 'framework.py'))
+
+import transaction
+
+from Testing.ZopeTestCase import base
+from Testing.ZopeTestCase import utils
+from Testing.ZopeTestCase import connections
+from Testing.ZopeTestCase import sandbox
+
+from Acquisition import aq_base
+from AccessControl import getSecurityManager
+from AccessControl.SecurityManagement import newSecurityManager
+
+
+class HookTest(base.TestCase):
+
+ def setUp(self):
+ self._called = []
+ base.TestCase.setUp(self)
+
+ def beforeSetUp(self):
+ self._called.append('beforeSetUp')
+ base.TestCase.beforeSetUp(self)
+
+ def _setup(self):
+ self._called.append('_setup')
+ base.TestCase._setup(self)
+
+ def afterSetUp(self):
+ self._called.append('afterSetUp')
+ base.TestCase.afterSetUp(self)
+
+ def beforeTearDown(self):
+ self._called.append('beforeTearDown')
+ base.TestCase.beforeTearDown(self)
+
+ def beforeClose(self):
+ self._called.append('beforeClose')
+ base.TestCase.beforeClose(self)
+
+ def afterClear(self):
+ self._called.append('afterClear')
+ base.TestCase.afterClear(self)
+
+ def assertHooks(self, sequence):
+ self.assertEqual(self._called, sequence)
+
+
+class TestTestCase(HookTest):
+
+ def testSetUp(self):
+ self.assertHooks(['beforeSetUp', '_setup', 'afterSetUp'])
+
+ def testTearDown(self):
+ self._called = []
+ self.tearDown()
+ self.assertHooks(['beforeTearDown', 'beforeClose', 'afterClear'])
+
+ def testAppOpensConnection(self):
+ self.assertEqual(connections.count(), 1)
+ self._app()
+ self.assertEqual(connections.count(), 2)
+
+ def testClearCallsCloseHook(self):
+ self._called = []
+ self._clear(1)
+ self.assertHooks(['beforeClose', 'afterClear'])
+
+ def testClearSkipsCloseHook(self):
+ self._called = []
+ self._clear()
+ self.assertHooks(['afterClear'])
+
+ def testClearAbortsTransaction(self):
+ self.assertEqual(len(self.getObjectsInTransaction()), 0)
+ self.app.foo = 1
+ self.assertEqual(len(self.getObjectsInTransaction()), 1)
+ self._clear()
+ self.assertEqual(len(self.getObjectsInTransaction()), 0)
+
+ def testClearClosesConnection(self):
+ self.assertEqual(connections.count(), 1)
+ self._clear()
+ self.assertEqual(connections.count(), 0)
+
+ def testClearClosesAllConnections(self):
+ self._app()
+ self.assertEqual(connections.count(), 2)
+ self._clear()
+ self.assertEqual(connections.count(), 0)
+
+ def testClearLogsOut(self):
+ uf = self.app.acl_users
+ uf.userFolderAddUser('user_1', '', [], [])
+ newSecurityManager(None, uf.getUserById('user_1').__of__(uf))
+ self.assertEqual(getSecurityManager().getUser().getUserName(), 'user_1')
+ self._clear()
+ self.assertEqual(getSecurityManager().getUser().getUserName(), 'Anonymous User')
+
+ def testClearSurvivesDoubleCall(self):
+ self._called = []
+ self._clear()
+ self._clear()
+ self.assertHooks(['afterClear', 'afterClear'])
+
+ def testClearSurvivesClosedConnection(self):
+ self._called = []
+ self._close()
+ self._clear()
+ self.assertHooks(['afterClear'])
+
+ def testClearSurvivesBrokenApp(self):
+ self._called = []
+ self.app = None
+ self._clear()
+ self.assertHooks(['afterClear'])
+
+ def testClearSurvivesMissingApp(self):
+ self._called = []
+ delattr(self, 'app')
+ self._clear()
+ self.assertHooks(['afterClear'])
+
+ def testClearSurvivesMissingRequest(self):
+ self._called = []
+ self.app = aq_base(self.app)
+ self._clear()
+ self.assertHooks(['afterClear'])
+
+ def testCloseAbortsTransaction(self):
+ self.assertEqual(len(self.getObjectsInTransaction()), 0)
+ self.app.foo = 1
+ self.assertEqual(len(self.getObjectsInTransaction()), 1)
+ self._close()
+ self.assertEqual(len(self.getObjectsInTransaction()), 0)
+
+ def testCloseClosesConnection(self):
+ self.assertEqual(connections.count(), 1)
+ self._close()
+ self.assertEqual(connections.count(), 0)
+
+ def testCloseClosesAllConnections(self):
+ self._app()
+ self.assertEqual(connections.count(), 2)
+ self._close()
+ self.assertEqual(connections.count(), 0)
+
+ def testLogoutLogsOut(self):
+ uf = self.app.acl_users
+ uf.userFolderAddUser('user_1', '', [], [])
+ newSecurityManager(None, uf.getUserById('user_1').__of__(uf))
+ self.assertEqual(getSecurityManager().getUser().getUserName(), 'user_1')
+ self.logout()
+ self.assertEqual(getSecurityManager().getUser().getUserName(), 'Anonymous User')
+
+ def getObjectsInTransaction(self):
+ # Lets us spy into the transaction
+ t = transaction.get()
+ if hasattr(t, '_objects'): # Zope < 2.8
+ return t._objects
+ elif hasattr(t, '_resources'): # Zope >= 2.8
+ return t._resources
+ else:
+ raise Exception, 'Unknown version'
+
+
+class TestSetUpRaises(HookTest):
+
+ class Error:
+ pass
+
+ def setUp(self):
+ try:
+ HookTest.setUp(self)
+ except self.Error:
+ self.assertHooks(['beforeSetUp', '_setup', 'afterClear'])
+ # Connection has been closed
+ self.assertEqual(connections.count(), 0)
+
+ def _setup(self):
+ HookTest._setup(self)
+ raise self.Error
+
+ def testTrigger(self):
+ pass
+
+
+class TestTearDownRaises(HookTest):
+
+ class Error:
+ pass
+
+ def tearDown(self):
+ self._called = []
+ try:
+ HookTest.tearDown(self)
+ except self.Error:
+ self.assertHooks(['beforeTearDown', 'beforeClose', 'afterClear'])
+ # Connection has been closed
+ self.assertEqual(connections.count(), 0)
+
+ def beforeClose(self):
+ HookTest.beforeClose(self)
+ raise self.Error
+
+ def testTrigger(self):
+ pass
+
+
+class TestConnectionRegistry(base.TestCase):
+ '''Test the registry with Connection-like objects'''
+
+ class Conn:
+ _closed = 0
+ def close(self):
+ self._closed = 1
+ def closed(self):
+ return self._closed
+
+ Klass = Conn
+
+ def afterSetUp(self):
+ self.reg = connections.ConnectionRegistry()
+ self.conns = [self.Klass(), self.Klass(), self.Klass()]
+ for conn in self.conns:
+ self.reg.register(conn)
+
+ def testRegister(self):
+ # Should be able to register connections
+ assert len(self.reg) == 3
+ assert self.reg.count() == 3
+
+ def testCloseConnection(self):
+ # Should be able to close a single registered connection
+ assert len(self.reg) == 3
+ self.reg.close(self.conns[0])
+ assert len(self.reg) == 2
+ assert self.conns[0].closed() == 1
+ assert self.conns[1].closed() == 0
+ assert self.conns[2].closed() == 0
+
+ def testCloseSeveralConnections(self):
+ # Should be able to close all registered connections one-by-one
+ assert len(self.reg) == 3
+ self.reg.close(self.conns[0])
+ assert len(self.reg) == 2
+ assert self.conns[0].closed() == 1
+ assert self.conns[1].closed() == 0
+ assert self.conns[2].closed() == 0
+ self.reg.close(self.conns[2])
+ assert len(self.reg) == 1
+ assert self.conns[0].closed() == 1
+ assert self.conns[1].closed() == 0
+ assert self.conns[2].closed() == 1
+ self.reg.close(self.conns[1])
+ assert len(self.reg) == 0
+ assert self.conns[0].closed() == 1
+ assert self.conns[1].closed() == 1
+ assert self.conns[2].closed() == 1
+
+ def testCloseForeignConnection(self):
+ # Should be able to close a connection that has not been registered
+ assert len(self.reg) == 3
+ conn = self.Klass()
+ self.reg.close(conn)
+ assert len(self.reg) == 3
+ assert self.conns[0].closed() == 0
+ assert self.conns[1].closed() == 0
+ assert self.conns[2].closed() == 0
+ assert conn.closed() == 1
+
+ def testCloseAllConnections(self):
+ # Should be able to close all registered connections at once
+ assert len(self.reg) == 3
+ self.reg.closeAll()
+ assert len(self.reg) == 0
+ assert self.conns[0].closed() == 1
+ assert self.conns[1].closed() == 1
+ assert self.conns[2].closed() == 1
+
+ def testContains(self):
+ # Should be able to check if a connection is registered
+ assert len(self.reg) == 3
+ assert self.reg.contains(self.conns[0])
+ assert self.reg.contains(self.conns[1])
+ assert self.reg.contains(self.conns[2])
+
+
+class TestApplicationRegistry(TestConnectionRegistry):
+ '''Test the registry with Application-like objects'''
+
+ class App:
+ class Conn:
+ _closed = 0
+ def close(self):
+ self._closed = 1
+ def closed(self):
+ return self._closed
+
+ def __init__(self):
+ self.REQUEST = self.Conn()
+ self._p_jar = self.Conn()
+
+ def closed(self):
+ if self.REQUEST.closed() and self._p_jar.closed():
+ return 1
+ return 0
+
+ Klass = App
+
+
+class TestListConverter(base.TestCase):
+ '''Test utils.makelist'''
+
+ def testList0(self):
+ self.assertEqual(utils.makelist([]), [])
+
+ def testList1(self):
+ self.assertEqual(utils.makelist(['foo']), ['foo'])
+
+ def testList2(self):
+ self.assertEqual(utils.makelist(['foo', 'bar']), ['foo', 'bar'])
+
+ def testTuple0(self):
+ self.assertEqual(utils.makelist(()), [])
+
+ def testTuple1(self):
+ self.assertEqual(utils.makelist(('foo',)), ['foo'])
+
+ def testTuple2(self):
+ self.assertEqual(utils.makelist(('foo', 'bar')), ['foo', 'bar'])
+
+ def testString0(self):
+ self.assertEqual(utils.makelist(''), [])
+
+ def testString1(self):
+ self.assertEqual(utils.makelist('foo'), ['foo'])
+
+ def testString2(self):
+ self.assertEqual(utils.makelist('foo, bar'), ['foo, bar'])
+
+ def testInteger(self):
+ self.assertRaises(ValueError, utils.makelist, 0)
+
+ def testObject(self):
+ class dummy: pass
+ self.assertRaises(ValueError, utils.makelist, dummy())
+
+
+class TestRequestVariables(base.TestCase):
+ '''Makes sure the REQUEST contains required variables'''
+
+ def testRequestVariables(self):
+ request = self.app.REQUEST
+ self.failIfEqual(request.get('SERVER_NAME', ''), '')
+ self.failIfEqual(request.get('SERVER_PORT', ''), '')
+ self.failIfEqual(request.get('REQUEST_METHOD', ''), '')
+ self.failIfEqual(request.get('URL', ''), '')
+ self.failIfEqual(request.get('SERVER_URL', ''), '')
+ self.failIfEqual(request.get('URL0', ''), '')
+ self.failIfEqual(request.get('URL1', ''), '')
+ self.failIfEqual(request.get('BASE0', ''), '')
+ self.failIfEqual(request.get('BASE1', ''), '')
+ self.failIfEqual(request.get('BASE2', ''), '')
+ self.failIfEqual(request.get('ACTUAL_URL', ''), '')
+
+
+import gc
+_sentinel1 = []
+_sentinel2 = []
+_sentinel3 = []
+
+
+class TestRequestGarbage1(base.TestCase):
+ '''Make sure base.app + base.close does not leak REQUEST._held'''
+
+ class Held:
+ def __del__(self):
+ _sentinel1.append('__del__')
+
+ def afterSetUp(self):
+ self.anApp = base.app()
+ self.anApp.REQUEST._hold(self.Held())
+
+ def testBaseCloseClosesRequest(self):
+ base.close(self.anApp)
+ gc.collect()
+ self.assertEqual(_sentinel1, ['__del__'])
+
+
+class TestRequestGarbage2(base.TestCase):
+ '''Make sure self._app + self._clear does not leak REQUEST._held'''
+
+ class Held:
+ def __del__(self):
+ _sentinel2.append('__del__')
+
+ def afterSetUp(self):
+ self.app.REQUEST._hold(self.Held())
+
+ def testClearClosesRequest(self):
+ self._clear()
+ gc.collect()
+ self.assertEqual(_sentinel2, ['__del__'])
+
+
+class TestRequestGarbage3(sandbox.Sandboxed, base.TestCase):
+ '''Make sure self._app + self._clear does not leak REQUEST._held'''
+
+ class Held:
+ def __del__(self):
+ _sentinel3.append('__del__')
+
+ def afterSetUp(self):
+ self.app.REQUEST._hold(self.Held())
+
+ def testClearClosesRequest(self):
+ self._clear()
+ gc.collect()
+ self.assertEqual(_sentinel3, ['__del__'])
+
+
+def test_suite():
+ from unittest import TestSuite, makeSuite
+ suite = TestSuite()
+ suite.addTest(makeSuite(TestTestCase))
+ suite.addTest(makeSuite(TestSetUpRaises))
+ suite.addTest(makeSuite(TestTearDownRaises))
+ suite.addTest(makeSuite(TestConnectionRegistry))
+ suite.addTest(makeSuite(TestApplicationRegistry))
+ suite.addTest(makeSuite(TestListConverter))
+ suite.addTest(makeSuite(TestRequestVariables))
+ suite.addTest(makeSuite(TestRequestGarbage1))
+ suite.addTest(makeSuite(TestRequestGarbage2))
+ suite.addTest(makeSuite(TestRequestGarbage3))
+ return suite
+
+if __name__ == '__main__':
+ framework()
+
Added: Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/testFunctional.py
===================================================================
--- Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/testFunctional.py 2006-08-19 02:33:50 UTC (rev 69678)
+++ Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/testFunctional.py 2006-08-19 02:36:49 UTC (rev 69679)
@@ -0,0 +1,211 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+"""Example functional ZopeTestCase
+
+Demonstrates how to use the publish() API to execute GET, POST, PUT, etc.
+requests against the ZPublisher and how to examine the response.
+
+$Id: testFunctional.py 30628 2005-06-03 17:42:57Z shh $
+"""
+
+import os, sys
+if __name__ == '__main__':
+ execfile(os.path.join(sys.path[0], 'framework.py'))
+
+from Testing import ZopeTestCase
+
+ZopeTestCase.installProduct('PythonScripts')
+
+from Testing.ZopeTestCase import user_name
+from Testing.ZopeTestCase import user_password
+
+from AccessControl import getSecurityManager
+from AccessControl.Permissions import view
+from AccessControl.Permissions import manage_properties
+from AccessControl.Permissions import add_documents_images_and_files
+from AccessControl.Permissions import change_dtml_documents
+
+from StringIO import StringIO
+from urllib import urlencode
+
+
+class TestFunctional(ZopeTestCase.FunctionalTestCase):
+
+ def afterSetUp(self):
+ self.folder_path = '/'+self.folder.absolute_url(1)
+ self.basic_auth = '%s:%s' % (user_name, user_password)
+
+ # A simple document
+ self.folder.addDTMLDocument('index_html', file='index')
+
+ # A document accessible only to its owner
+ self.folder.addDTMLDocument('secret_html', file='secret')
+ self.folder.secret_html.manage_permission(view, ['Owner'])
+
+ # A Python Script performing integer computation
+ self.folder.manage_addProduct['PythonScripts'].manage_addPythonScript('script')
+ self.folder.script.ZPythonScript_edit(params='a=0', body='return a+1')
+
+ # A method redirecting to the Zope root
+ redirect = '''<dtml-call "RESPONSE.redirect('%s')">''' % self.app.absolute_url()
+ self.folder.addDTMLMethod('redirect', file=redirect)
+
+ # A method setting a cookie
+ set_cookie = '''<dtml-call "RESPONSE.setCookie('foo', 'Bar', path='/')">'''
+ self.folder.addDTMLMethod('set_cookie', file=set_cookie)
+
+ # A method changing the title property of an object
+ change_title = '''<dtml-call "manage_changeProperties(title=REQUEST.get('title'))">'''
+ self.folder.addDTMLMethod('change_title', file=change_title)
+
+ def testPublishFolder(self):
+ response = self.publish(self.folder_path)
+ self.assertEqual(response.getStatus(), 200)
+ self.assertEqual(response.getBody(), 'index')
+
+ def testPublishDocument(self):
+ response = self.publish(self.folder_path+'/index_html')
+ self.assertEqual(response.getStatus(), 200)
+ self.assertEqual(response.getBody(), 'index')
+
+ def testPublishScript(self):
+ response = self.publish(self.folder_path+'/script')
+ self.assertEqual(response.getStatus(), 200)
+ self.assertEqual(response.getBody(), '1')
+
+ def testPublishScriptWithArgument(self):
+ response = self.publish(self.folder_path+'/script?a:int=2')
+ self.assertEqual(response.getStatus(), 200)
+ self.assertEqual(response.getBody(), '3')
+
+ def testServerError(self):
+ response = self.publish(self.folder_path+'/script?a=2')
+ self.assertEqual(response.getStatus(), 500)
+
+ def testUnauthorized(self):
+ response = self.publish(self.folder_path+'/secret_html')
+ self.assertEqual(response.getStatus(), 401)
+
+ def testBasicAuth(self):
+ response = self.publish(self.folder_path+'/secret_html', self.basic_auth)
+ self.assertEqual(response.getStatus(), 200)
+ self.assertEqual(response.getBody(), 'secret')
+
+ def testRedirect(self):
+ response = self.publish(self.folder_path+'/redirect')
+ self.assertEqual(response.getStatus(), 302)
+ self.assertEqual(response.getHeader('Location'), self.app.absolute_url())
+
+ def testCookie(self):
+ response = self.publish(self.folder_path+'/set_cookie')
+ self.assertEqual(response.getStatus(), 200)
+ self.assertEqual(response.getCookie('foo').get('value'), 'Bar')
+ self.assertEqual(response.getCookie('foo').get('path'), '/')
+
+ def testChangeTitle(self):
+ # Change the title of a document
+ self.setPermissions([manage_properties])
+
+ # Note that we must pass basic auth info
+ response = self.publish(self.folder_path+'/index_html/change_title?title=Foo',
+ self.basic_auth)
+
+ self.assertEqual(response.getStatus(), 200)
+ self.assertEqual(self.folder.index_html.title_or_id(), 'Foo')
+
+ def testPOST(self):
+ # Change the title in a POST request
+ self.setPermissions([manage_properties])
+
+ form = {'title': 'Foo'}
+ post_data = StringIO(urlencode(form))
+
+ response = self.publish(self.folder_path+'/index_html/change_title',
+ request_method='POST', stdin=post_data,
+ basic=self.basic_auth)
+
+ self.assertEqual(response.getStatus(), 200)
+ self.assertEqual(self.folder.index_html.title_or_id(), 'Foo')
+
+ def testPUTExisting(self):
+ # FTP new data into an existing object
+ self.setPermissions([change_dtml_documents])
+
+ put_data = StringIO('foo')
+ response = self.publish(self.folder_path+'/index_html',
+ request_method='PUT', stdin=put_data,
+ basic=self.basic_auth)
+
+ self.assertEqual(response.getStatus(), 204)
+ self.assertEqual(self.folder.index_html(), 'foo')
+
+ def testPUTNew(self):
+ # Create a new object via FTP or WebDAV
+ self.setPermissions([add_documents_images_and_files])
+
+ put_data = StringIO('foo')
+ response = self.publish(self.folder_path+'/new_document',
+ env={'CONTENT_TYPE': 'text/html'},
+ request_method='PUT', stdin=put_data,
+ basic=self.basic_auth)
+
+ self.assertEqual(response.getStatus(), 201)
+ self.failUnless('new_document' in self.folder.objectIds())
+ self.assertEqual(self.folder.new_document.meta_type, 'DTML Document')
+ self.assertEqual(self.folder.new_document(), 'foo')
+
+ def testPUTEmpty(self):
+ # PUT operation without passing stdin should result in empty content
+ self.setPermissions([change_dtml_documents])
+
+ response = self.publish(self.folder_path+'/index_html',
+ request_method='PUT',
+ basic=self.basic_auth)
+
+ self.assertEqual(response.getStatus(), 204)
+ self.assertEqual(self.folder.index_html(), '')
+
+ def testPROPFIND(self):
+ # PROPFIND should work without passing stdin
+ response = self.publish(self.folder_path+'/index_html',
+ request_method='PROPFIND',
+ basic=self.basic_auth)
+
+ self.assertEqual(response.getStatus(), 207)
+
+ def testHEAD(self):
+ # HEAD should work without passing stdin
+ response = self.publish(self.folder_path+'/index_html',
+ request_method='HEAD')
+
+ self.assertEqual(response.getStatus(), 200)
+
+ def testSecurityContext(self):
+ # The authenticated user should not change as a result of publish
+ self.assertEqual(getSecurityManager().getUser().getId(), user_name)
+
+ self.folder.acl_users.userFolderAddUser('barney', 'secret', [], [])
+ response = self.publish(self.folder_path, basic='barney:secret')
+
+ self.assertEqual(getSecurityManager().getUser().getId(), user_name)
+
+
+def test_suite():
+ from unittest import TestSuite, makeSuite
+ suite = TestSuite()
+ suite.addTest(makeSuite(TestFunctional))
+ return suite
+
+if __name__ == '__main__':
+ framework()
+
Added: Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/testInterfaces.py
===================================================================
--- Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/testInterfaces.py 2006-08-19 02:33:50 UTC (rev 69678)
+++ Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/testInterfaces.py 2006-08-19 02:36:49 UTC (rev 69679)
@@ -0,0 +1,123 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+"""Interface tests
+
+$Id: testInterfaces.py 30297 2005-05-07 00:44:45Z shh $
+"""
+
+import os, sys
+if __name__ == '__main__':
+ execfile(os.path.join(sys.path[0], 'framework.py'))
+
+from Testing.ZopeTestCase import *
+from Testing.ZopeTestCase.interfaces import *
+
+from Interface.Verify import verifyClass
+from Interface.Verify import verifyObject
+
+
+class TestAbstractClasses(TestCase):
+
+ def testIProfiled(self):
+ self.failUnless(verifyClass(IProfiled, Profiled))
+
+ def testIFunctional(self):
+ self.failUnless(verifyClass(IFunctional, Functional))
+
+
+class TestBaseTestCase(TestCase):
+
+ def testIProfiled(self):
+ self.failUnless(verifyClass(IProfiled, TestCase))
+ self.failUnless(verifyObject(IProfiled, self))
+
+ def testIZopeTestCase(self):
+ self.failUnless(verifyClass(IZopeTestCase, TestCase))
+ self.failUnless(verifyObject(IZopeTestCase, self))
+
+
+class TestZopeTestCase(ZopeTestCase):
+
+ _setup_fixture = 0
+
+ def testIProfiled(self):
+ self.failUnless(verifyClass(IProfiled, ZopeTestCase))
+ self.failUnless(verifyObject(IProfiled, self))
+
+ def testIZopeTestCase(self):
+ self.failUnless(verifyClass(IZopeTestCase, ZopeTestCase))
+ self.failUnless(verifyObject(IZopeTestCase, self))
+
+ def testIZopeSecurity(self):
+ self.failUnless(verifyClass(IZopeSecurity, ZopeTestCase))
+ self.failUnless(verifyObject(IZopeSecurity, self))
+
+
+class TestFunctionalTestCase(FunctionalTestCase):
+
+ _setup_fixture = 0
+
+ def testIFunctional(self):
+ self.failUnless(verifyClass(IFunctional, FunctionalTestCase))
+ self.failUnless(verifyObject(IFunctional, self))
+
+ def testIProfiled(self):
+ self.failUnless(verifyClass(IProfiled, FunctionalTestCase))
+ self.failUnless(verifyObject(IProfiled, self))
+
+ def testIZopeTestCase(self):
+ self.failUnless(verifyClass(IZopeTestCase, FunctionalTestCase))
+ self.failUnless(verifyObject(IZopeTestCase, self))
+
+ def testIZopeSecurity(self):
+ self.failUnless(verifyClass(IZopeSecurity, FunctionalTestCase))
+ self.failUnless(verifyObject(IZopeSecurity, self))
+
+
+class TestPortalTestCase(PortalTestCase):
+
+ _configure_portal = 0
+
+ def _portal(self):
+ return None
+
+ def testIProfiled(self):
+ self.failUnless(verifyClass(IProfiled, PortalTestCase))
+ self.failUnless(verifyObject(IProfiled, self))
+
+ def testIZopeTestCase(self):
+ self.failUnless(verifyClass(IZopeTestCase, PortalTestCase))
+ self.failUnless(verifyObject(IZopeTestCase, self))
+
+ def testIPortalTestCase(self):
+ self.failUnless(verifyClass(IPortalTestCase, PortalTestCase))
+ self.failUnless(verifyObject(IPortalTestCase, self))
+
+ def testIPortalSecurity(self):
+ self.failUnless(verifyClass(IPortalSecurity, PortalTestCase))
+ self.failUnless(verifyObject(IPortalSecurity, self))
+
+
+def test_suite():
+ from unittest import TestSuite, makeSuite
+ suite = TestSuite()
+ suite.addTest(makeSuite(TestAbstractClasses))
+ suite.addTest(makeSuite(TestBaseTestCase))
+ suite.addTest(makeSuite(TestZopeTestCase))
+ suite.addTest(makeSuite(TestFunctionalTestCase))
+ suite.addTest(makeSuite(TestPortalTestCase))
+ return suite
+
+if __name__ == '__main__':
+ framework()
+
Added: Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/testPlaceless.py
===================================================================
--- Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/testPlaceless.py 2006-08-19 02:33:50 UTC (rev 69678)
+++ Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/testPlaceless.py 2006-08-19 02:36:49 UTC (rev 69679)
@@ -0,0 +1,97 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+"""Placeless setup tests
+
+$Id: testPlaceless.py 66218 2006-03-27 01:29:02Z shh $
+"""
+
+import os, sys
+if __name__ == '__main__':
+ execfile(os.path.join(sys.path[0], 'framework.py'))
+
+from Testing import ZopeTestCase
+
+from Testing.ZopeTestCase.placeless import setUp, tearDown
+from Testing.ZopeTestCase.placeless import zcml
+from Testing.ZopeTestCase.placeless import temporaryPlacelessSetUp
+
+import Products.Five.tests
+from Products.Five.tests.adapters import IAdapted
+from Products.Five.tests.adapters import Adaptable
+
+
+def setupZCML():
+ zcml.load_config('meta.zcml', Products.Five)
+ zcml.load_config('permissions.zcml', Products.Five)
+ zcml.load_config('directives.zcml', Products.Five.tests)
+
+
+class TestPlacelessSetUp(ZopeTestCase.ZopeTestCase):
+ '''Tests ZopeTestCase with placeless setup'''
+
+ def afterSetUp(self):
+ tearDown()
+
+ def beforeTearDown(self):
+ tearDown()
+
+ def testSimple(self):
+ # SetUp according to Five's adapter test
+ setUp()
+ setupZCML()
+ # Now we have a fixture that should work for adaptation
+ adapted = IAdapted(Adaptable())
+ self.assertEqual(adapted.adaptedMethod(), 'Adapted: The method')
+
+ def func(self, *args):
+ adapted = IAdapted(Adaptable())
+ return True
+
+ def testNoCA(self):
+ self.assertRaises(TypeError, self.func)
+
+ def testAvailableCA(self):
+ setUp()
+ setupZCML()
+ self.assertEqual(self.func(), True)
+
+ def testDecoratorLoadsZCMLCallable(self):
+ f = temporaryPlacelessSetUp(self.func, required_zcml=setupZCML)
+ self.assertEqual(f(), True)
+
+ def testDecoratorLoadsZCMLIterable(self):
+ f = temporaryPlacelessSetUp(self.func, required_zcml=(setupZCML,))
+ self.assertEqual(f(), True)
+
+ def testPlacelessFlagDisablesDecoration(self):
+ f = temporaryPlacelessSetUp(self.func, placeless_available=False, required_zcml=setupZCML)
+ self.assertRaises(TypeError, f)
+
+ def testDecoratedFuncLoadsZCMLCallable(self):
+ f = temporaryPlacelessSetUp(self.func)
+ self.assertEqual(f(required_zcml=setupZCML), True)
+
+ def testDecoratedFuncLoadsZCMLIterable(self):
+ f = temporaryPlacelessSetUp(self.func)
+ self.assertEqual(f(required_zcml=(setupZCML,)), True)
+
+
+def test_suite():
+ from unittest import TestSuite, makeSuite
+ suite = TestSuite()
+ suite.addTest(makeSuite(TestPlacelessSetUp))
+ return suite
+
+if __name__ == '__main__':
+ framework()
+
Added: Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/testPortalTestCase.py
===================================================================
--- Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/testPortalTestCase.py 2006-08-19 02:33:50 UTC (rev 69678)
+++ Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/testPortalTestCase.py 2006-08-19 02:36:49 UTC (rev 69679)
@@ -0,0 +1,529 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+"""Tests the PortalTestCase
+
+NOTE: This is *not* an example TestCase. Do not
+use this file as a blueprint for your own tests!
+
+See testPythonScript.py and testShoppingCart.py for
+example test cases. See testSkeleton.py for a quick
+way of getting started.
+
+$Id: testPortalTestCase.py 30565 2005-05-30 22:07:11Z shh $
+"""
+
+import os, sys
+if __name__ == '__main__':
+ execfile(os.path.join(sys.path[0], 'framework.py'))
+
+from Testing import ZopeTestCase
+
+from Acquisition import aq_base
+from AccessControl import getSecurityManager
+from types import ListType
+
+import transaction
+
+portal_name = 'dummy_1_'
+user_name = ZopeTestCase.user_name
+
+
+def hasattr_(ob, attr):
+ return hasattr(aq_base(ob), attr)
+
+
+# A dummy portal
+
+from OFS.SimpleItem import SimpleItem
+from OFS.Folder import Folder
+
+class DummyPortal(Folder):
+ def __init__(self, id):
+ self.id = id
+ self._addRole('Member')
+ self._setObject('portal_membership', DummyMembershipTool())
+ self.manage_addFolder('Members')
+ self._called = []
+ def clearCurrentSkin(self):
+ self._called.append('clearCurrentSkin')
+ def setupCurrentSkin(self):
+ self._called.append('setupCurrentSkin')
+
+class DummyMembershipTool(SimpleItem):
+ id = 'portal_membership'
+ def __init__(self):
+ self._called = []
+ def createMemberarea(self, member_id):
+ self._called.append('createMemberarea')
+ portal = self.aq_inner.aq_parent
+ portal.Members.manage_addFolder(member_id)
+ def getHomeFolder(self, member_id):
+ portal = self.aq_inner.aq_parent
+ return getattr(portal.Members, member_id)
+
+class NewMembershipTool(DummyMembershipTool):
+ def createMemberArea(self, member_id):
+ self._called.append('createMemberArea')
+ portal = self.aq_inner.aq_parent
+ portal.Members.manage_addFolder(member_id)
+
+
+class TestPortalTestCase(ZopeTestCase.PortalTestCase):
+ '''Incrementally exercise the PortalTestCase API.'''
+
+ _setUp = ZopeTestCase.PortalTestCase.setUp
+ _tearDown = ZopeTestCase.PortalTestCase.tearDown
+
+ def getPortal(self):
+ # Must make sure we return a portal object
+ self.app._setObject(portal_name, DummyPortal(portal_name))
+ return getattr(self.app, portal_name)
+
+ def setUp(self):
+ # For this test case we *want* to start
+ # with an empty fixture.
+ self._called = []
+ # Implicitly aborts previous transaction
+ transaction.begin()
+
+ def beforeSetUp(self):
+ self._called.append('beforeSetUp')
+
+ def afterSetUp(self):
+ self._called.append('afterSetUp')
+
+ def beforeTearDown(self):
+ self._called.append('beforeTearDown')
+
+ def beforeClose(self):
+ self._called.append('beforeClose')
+
+ def afterClear(self):
+ self._called.append('afterClear')
+
+ def test_getPortal(self):
+ # Portal should be set up
+ self.app = self._app()
+ self.portal = self._portal()
+ self.failUnless(hasattr_(self.app, portal_name))
+ self.failUnless(hasattr_(self.portal, 'Members'))
+ self.failUnless(hasattr_(self.portal, 'portal_membership'))
+ self.failUnless('Member' in self.portal.userdefined_roles())
+
+ def test_setupUserFolder(self):
+ # User folder should be set up.
+ self.app = self._app()
+ self.portal = self._portal()
+ self.failIf(hasattr_(self.portal, 'acl_users'))
+ self._setupUserFolder()
+ self.failUnless(hasattr_(self.portal, 'acl_users'))
+ # Must not complain if UF already exists
+ self._setupUserFolder()
+
+ def test_setupUser(self):
+ # User should be set up
+ self.app = self._app()
+ self.portal = self._portal()
+ self._setupUserFolder()
+ self._setupUser()
+ acl_user = self.portal.acl_users.getUserById(user_name)
+ self.failUnless(acl_user)
+ self.assertEqual(acl_user.getRoles(), ('Member', 'Authenticated'))
+ self.assertEqual(type(acl_user.roles), ListType)
+
+ def test_setupHomeFolder(self):
+ # User's home folder should be set up
+ self.app = self._app()
+ self.portal = self._portal()
+ self._setupUserFolder()
+ self._setupUser()
+ self.login()
+ self._setupHomeFolder()
+ self.failUnless(hasattr_(self.portal.Members, user_name))
+ self.failIf(self.folder is None)
+ # Shut up deprecation warnings
+ try: owner_info = self.folder.getOwnerTuple()
+ except AttributeError:
+ owner_info = self.folder.getOwner(info=1)
+ self.assertEqual(owner_info, ([portal_name, 'acl_users'], user_name))
+
+ def test_refreshSkinData(self):
+ # The skin cache should be refreshed
+ self.app = self._app()
+ self.portal = self._portal()
+ self._refreshSkinData()
+ self.assertEqual(self.portal._called, ['clearCurrentSkin', 'setupCurrentSkin'])
+
+ def test_setRoles(self):
+ # Roles should be set for user
+ self.app = self._app()
+ self.portal = self._portal()
+ self._setupUserFolder()
+ self._setupUser()
+ test_roles = ['Manager', 'Member']
+ self.setRoles(test_roles)
+ acl_user = self.portal.acl_users.getUserById(user_name)
+ self.assertRolesOfUser(test_roles, acl_user)
+
+ def test_setRoles_2(self):
+ # Roles should be set for logged in user
+ self.app = self._app()
+ self.portal = self._portal()
+ self._setupUserFolder()
+ self._setupUser()
+ self.login()
+ test_roles = ['Manager', 'Member']
+ self.setRoles(test_roles)
+ auth_user = getSecurityManager().getUser()
+ self.assertRolesOfUser(test_roles, auth_user)
+
+ def test_setRoles_3(self):
+ # Roles should be set for a specified user
+ self.app = self._app()
+ self.portal = self._portal()
+ self._setupUserFolder()
+ self.portal.acl_users.userFolderAddUser('user_2', 'secret', [], [])
+ test_roles = ['Manager', 'Member']
+ self.setRoles(test_roles, 'user_2')
+ acl_user = self.portal.acl_users.getUserById('user_2')
+ self.assertRolesOfUser(test_roles, acl_user)
+
+ def test_setRoles_4(self):
+ # Roles should be set from a tuple
+ self.app = self._app()
+ self.portal = self._portal()
+ self._setupUserFolder()
+ self._setupUser()
+ test_roles = ['Manager', 'Member']
+ self.setRoles(tuple(test_roles))
+ acl_user = self.portal.acl_users.getUserById(user_name)
+ self.assertRolesOfUser(test_roles, acl_user)
+
+ def test_setRoles_5(self):
+ # Roles should be set from a string
+ self.app = self._app()
+ self.portal = self._portal()
+ self._setupUserFolder()
+ self._setupUser()
+ test_roles = ['Manager']
+ self.setRoles('Manager')
+ acl_user = self.portal.acl_users.getUserById(user_name)
+ self.assertRolesOfUser(test_roles, acl_user)
+
+ def test_setPermissions(self):
+ # Permissions should be set for user
+ self.app = self._app()
+ self.portal = self._portal()
+ test_perms = ['Add Folders', 'Delete objects']
+ self.setPermissions(test_perms)
+ self.assertPermissionsOfRole(test_perms, 'Member')
+
+ def test_setPermissions_2(self):
+ # Permissions should be set for specified role
+ self.app = self._app()
+ self.portal = self._portal()
+ self.portal._addRole('role_2')
+ test_perms = ['Add Folders', 'Delete objects']
+ self.assertPermissionsOfRole([], 'role_2')
+ self.setPermissions(test_perms, 'role_2')
+ self.assertPermissionsOfRole(test_perms, 'role_2')
+
+ def test_setPermissions_3(self):
+ # Permissions should be set from a tuple
+ self.app = self._app()
+ self.portal = self._portal()
+ test_perms = ['Add Folders', 'Delete objects']
+ self.setPermissions(tuple(test_perms))
+ self.assertPermissionsOfRole(test_perms, 'Member')
+
+ def test_setPermissions_4(self):
+ # Permissions should be set from a string
+ self.app = self._app()
+ self.portal = self._portal()
+ test_perms = ['Add Folders']
+ self.setPermissions('Add Folders')
+ self.assertPermissionsOfRole(test_perms, 'Member')
+
+ def test_login(self):
+ # User should be able to log in
+ self.app = self._app()
+ self.portal = self._portal()
+ self._setupUserFolder()
+ self._setupUser()
+ auth_name = getSecurityManager().getUser().getUserName()
+ self.assertEqual(auth_name, 'Anonymous User')
+ self.login()
+ auth_name = getSecurityManager().getUser().getId()
+ self.assertEqual(auth_name, user_name)
+
+ def test_login_2(self):
+ # A specified user should be logged in
+ self.app = self._app()
+ self.portal = self._portal()
+ self._setupUserFolder()
+ self.portal.acl_users.userFolderAddUser('user_2', 'secret', [], [])
+ auth_name = getSecurityManager().getUser().getUserName()
+ self.assertEqual(auth_name, 'Anonymous User')
+ self.login('user_2')
+ auth_name = getSecurityManager().getUser().getId()
+ self.assertEqual(auth_name, 'user_2')
+
+ def test_login_3(self):
+ # Unknown user should raise AttributeError
+ self.app = self._app()
+ self.portal = self._portal()
+ self._setupUserFolder()
+ self.assertRaises(AttributeError, self.login, 'user_3')
+
+ def test_logout(self):
+ # User should be able to log out
+ self.app = self._app()
+ self.portal = self._portal()
+ self._setupUserFolder()
+ self._setupUser()
+ self.login()
+ self.logout()
+ auth_name = getSecurityManager().getUser().getUserName()
+ self.assertEqual(auth_name, 'Anonymous User')
+
+ def test_clear(self):
+ # Everything should be removed
+ self.app = self._app()
+ self.portal = self._portal()
+ self._setupUserFolder()
+ self._setupUser()
+ self._setupHomeFolder()
+ self._clear(1)
+ self.failIf(self.app.__dict__.has_key(portal_name))
+ auth_name = getSecurityManager().getUser().getUserName()
+ self.assertEqual(auth_name, 'Anonymous User')
+ self.assertEqual(self._called, ['beforeClose', 'afterClear'])
+ # clear must not fail when called repeatedly
+ self._clear()
+
+ def test_setUp(self):
+ # Everything should be set up
+ self._setUp()
+ self.failUnless(hasattr_(self.app, portal_name))
+ self.failUnless(hasattr_(self.portal, 'acl_users'))
+ self.failUnless(hasattr_(self.portal, 'Members'))
+ self.failUnless(hasattr_(self.portal, 'portal_membership'))
+ self.failUnless('Member' in self.portal.userdefined_roles())
+ self.failUnless(hasattr_(self.portal.Members, user_name))
+ acl_user = self.portal.acl_users.getUserById(user_name)
+ self.failUnless(acl_user)
+ self.assertEqual(acl_user.getRoles(), ('Member', 'Authenticated'))
+ self.assertEqual(type(acl_user.roles), ListType)
+ auth_name = getSecurityManager().getUser().getId()
+ self.assertEqual(auth_name, user_name)
+ # XXX: Changed in 0.9.0
+ #self.assertEqual(self._called, ['afterClear', 'beforeSetUp', 'afterSetUp'])
+ self.assertEqual(self._called, ['beforeSetUp', 'afterSetUp'])
+
+ def test_tearDown(self):
+ # Everything should be removed
+ self._setUp()
+ self._called = []
+ self._tearDown()
+ self.failIf(self.app.__dict__.has_key(portal_name))
+ auth_name = getSecurityManager().getUser().getUserName()
+ self.assertEqual(auth_name, 'Anonymous User')
+ self.assertEqual(self._called, ['beforeTearDown', 'beforeClose', 'afterClear'])
+
+ def test_configureFlag(self):
+ # Nothing should be configured
+ self._configure_portal = 0
+ self._setUp()
+ self.assertEqual(self.portal.acl_users.getUserById(user_name), None)
+ self.failIf(hasattr_(self.portal.Members, user_name))
+ auth_name = getSecurityManager().getUser().getUserName()
+ self.assertEqual(auth_name, 'Anonymous User')
+ # XXX: Changed in 0.9.0
+ #self.assertEqual(self._called, ['afterClear', 'beforeSetUp', 'afterSetUp'])
+ self.assertEqual(self._called, ['beforeSetUp', 'afterSetUp'])
+
+ def test_createMemberarea(self):
+ # Should call the membership tool's createMemberarea
+ self.app = self._app()
+ self.portal = self._portal()
+ self._setupUserFolder()
+ self._setupUser()
+ self.login()
+ self.createMemberarea(user_name)
+ self.assertEqual(self.portal.portal_membership._called, ['createMemberarea'])
+ self.failUnless(hasattr_(self.portal.Members, user_name))
+
+ def test_createMemberarea_NewTool(self):
+ # Should call the membership tool's createMemberArea
+ self.app = self._app()
+ self.portal = self._portal()
+ self._setupUserFolder()
+ self._setupUser()
+ self.portal._delObject('portal_membership')
+ self.portal._setObject('portal_membership', NewMembershipTool())
+ self.login()
+ self.createMemberarea(user_name)
+ self.assertEqual(self.portal.portal_membership._called, ['createMemberArea'])
+ self.failUnless(hasattr_(self.portal.Members, user_name))
+
+ # Helpers
+
+ def getPermissionsOfRole(self, role, context=None):
+ '''Returns sorted list of permission names of the
+ given role in the given context.
+ '''
+ if context is None:
+ context = self.portal
+ perms = context.permissionsOfRole(role)
+ return [p['name'] for p in perms if p['selected']]
+
+ def assertPermissionsOfRole(self, permissions, role, context=None):
+ '''Compares list of permission names to permissions of the
+ given role in the given context. Fails if the lists are not
+ found equal.
+ '''
+ lhs = list(permissions)[:]
+ lhs.sort()
+ rhs = self.getPermissionsOfRole(role, context)
+ rhs.sort()
+ self.assertEqual(lhs, rhs)
+
+ def assertRolesOfUser(self, roles, user):
+ '''Compares list of role names to roles of user. Fails if the
+ lists are not found equal.
+ '''
+ lhs = list(roles)[:]
+ lhs.sort()
+ rhs = list(user.getRoles())[:]
+ rhs.remove('Authenticated')
+ rhs.sort()
+ self.assertEqual(lhs, rhs)
+
+
+from AccessControl.User import UserFolder
+
+class WrappingUserFolder(UserFolder):
+ '''User folder returning wrapped user objects'''
+
+ def getUser(self, name):
+ return UserFolder.getUser(self, name).__of__(self)
+
+
+class TestPlainUserFolder(ZopeTestCase.PortalTestCase):
+ '''Tests whether user objects are properly wrapped'''
+
+ def getPortal(self):
+ self.app._setObject(portal_name, DummyPortal(portal_name))
+ return getattr(self.app, portal_name)
+
+ def testGetUserDoesNotWrapUser(self):
+ user = self.portal.acl_users.getUserById(user_name)
+ self.failIf(hasattr(user, 'aq_base'))
+ self.failUnless(user is aq_base(user))
+
+ def testLoggedInUserIsWrapped(self):
+ user = getSecurityManager().getUser()
+ self.assertEqual(user.getId(), user_name)
+ self.failUnless(hasattr(user, 'aq_base'))
+ self.failUnless(user.__class__.__name__, 'User')
+ self.failUnless(user.aq_parent.__class__.__name__, 'UserFolder')
+ self.failUnless(user.aq_parent.aq_parent.__class__.__name__, 'Folder')
+
+
+class TestWrappingUserFolder(ZopeTestCase.PortalTestCase):
+ '''Tests whether user objects are properly wrapped'''
+
+ def getPortal(self):
+ self.app._setObject(portal_name, DummyPortal(portal_name))
+ return getattr(self.app, portal_name)
+
+ def _setupUserFolder(self):
+ self.portal._setObject('acl_users', WrappingUserFolder())
+
+ def testGetUserWrapsUser(self):
+ user = self.portal.acl_users.getUserById(user_name)
+ self.failUnless(hasattr(user, 'aq_base'))
+ self.failIf(user is aq_base(user))
+ self.failUnless(user.aq_parent.__class__.__name__, 'WrappingUserFolder')
+
+ def testLoggedInUserIsWrapped(self):
+ user = getSecurityManager().getUser()
+ self.assertEqual(user.getId(), user_name)
+ self.failUnless(hasattr(user, 'aq_base'))
+ self.failUnless(user.__class__.__name__, 'User')
+ self.failUnless(user.aq_parent.__class__.__name__, 'WrappingUserFolder')
+ self.failUnless(user.aq_parent.aq_parent.__class__.__name__, 'Folder')
+
+
+# Because we override setUp we need to test again
+
+class HookTest(ZopeTestCase.PortalTestCase):
+
+ def setUp(self):
+ self._called = []
+ ZopeTestCase.PortalTestCase.setUp(self)
+
+ def beforeSetUp(self):
+ self._called.append('beforeSetUp')
+ ZopeTestCase.PortalTestCase.beforeSetUp(self)
+
+ def _setup(self):
+ self._called.append('_setup')
+ ZopeTestCase.PortalTestCase._setup(self)
+
+ def afterClear(self):
+ self._called.append('afterClear')
+ ZopeTestCase.PortalTestCase.afterClear(self)
+
+ def assertHooks(self, sequence):
+ self.assertEqual(self._called, sequence)
+
+
+class TestSetUpRaises(HookTest):
+
+ class Error:
+ pass
+
+ def getPortal(self):
+ self.app._setObject(portal_name, DummyPortal(portal_name))
+ return getattr(self.app, portal_name)
+
+ def setUp(self):
+ try:
+ HookTest.setUp(self)
+ except self.Error:
+ self.assertHooks(['beforeSetUp', '_setup', 'afterClear'])
+ # Connection has been closed
+ from Testing.ZopeTestCase import connections
+ self.assertEqual(connections.count(), 0)
+
+ def _setup(self):
+ HookTest._setup(self)
+ raise self.Error
+
+ def testTrigger(self):
+ pass
+
+
+def test_suite():
+ from unittest import TestSuite, makeSuite
+ suite = TestSuite()
+ suite.addTest(makeSuite(TestPortalTestCase))
+ suite.addTest(makeSuite(TestPlainUserFolder))
+ suite.addTest(makeSuite(TestWrappingUserFolder))
+ suite.addTest(makeSuite(TestSetUpRaises))
+ return suite
+
+if __name__ == '__main__':
+ framework()
+
Added: Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/testPythonScript.py
===================================================================
--- Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/testPythonScript.py 2006-08-19 02:33:50 UTC (rev 69678)
+++ Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/testPythonScript.py 2006-08-19 02:36:49 UTC (rev 69679)
@@ -0,0 +1,202 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+"""Example ZopeTestCase testing a PythonScript in the default fixture
+
+This test module demonstrates the security API of ZopeTestCase.
+
+Note that you are encouraged to call any of the following methods to
+modify the test user's security credentials:
+
+ setRoles()
+ setPermissions()
+ login()
+ logout()
+
+$Id: testPythonScript.py 66140 2006-03-23 18:57:54Z shh $
+"""
+
+import os, sys
+if __name__ == '__main__':
+ execfile(os.path.join(sys.path[0], 'framework.py'))
+
+from Testing import ZopeTestCase
+
+ZopeTestCase.installProduct('PythonScripts')
+
+from AccessControl import Unauthorized
+from AccessControl import getSecurityManager
+
+access_permissions = ['View management screens']
+change_permissions = ['Change Python Scripts']
+
+ps_params1 = 'a=1'
+ps_body1 = 'return a'
+ps_params2 = 'a'
+ps_body2 = 'return a+1'
+
+
+class TestPythonScript(ZopeTestCase.ZopeTestCase):
+ '''Tries various things allowed by the ZopeTestCase API.'''
+
+ def afterSetUp(self):
+ '''Adds a PythonScript object to the default fixture'''
+ dispatcher = self.folder.manage_addProduct['PythonScripts']
+ dispatcher.manage_addPythonScript('ps')
+ self.ps = self.folder['ps']
+ self.ps.ZPythonScript_edit(ps_params1, ps_body1)
+
+ # Test the setup
+
+ def testSetup(self):
+ # The PythonScript should exist and be properly set up
+ self.failUnless(hasattr(self.folder, 'ps'))
+ self.assertEqual(self.ps.body(), ps_body1+'\n')
+ self.assertEqual(self.ps.params(), ps_params1)
+ owner = self.ps.getOwner()
+ self.assertEqual(owner.getUserName(), ZopeTestCase.user_name)
+
+ # Test the script(s)
+
+ def testCanCallScript1WithArgument(self):
+ # PythonScript should return 2
+ self.assertEqual(self.ps(2), 2)
+
+ def testCanCallScript1WithoutArgument(self):
+ # PythonScript should return 1
+ self.assertEqual(self.ps(), 1)
+
+ def testCanCallScript2WithArgument(self):
+ # PythonScript should return 2
+ self.ps.ZPythonScript_edit(ps_params2, ps_body2)
+ self.assertEqual(self.ps(1), 2)
+
+ def testCannotCallScript2WithoutArgument(self):
+ # PythonScript should raise a TypeError if called without arguments
+ self.ps.ZPythonScript_edit(ps_params2, ps_body2)
+ self.assertRaises(TypeError, self.ps, ())
+
+ # Test access protection with restrictedTraverse
+
+ def testCannotAccessWithoutAccessPermission(self):
+ # manage_main should be protected
+ self.assertRaises(Unauthorized, self.ps.restrictedTraverse, 'manage_main')
+
+ def testCanAccessWithAccessPermission(self):
+ # manage_main should be accessible if we have the necessary permissions
+ self.setPermissions(access_permissions)
+ try:
+ self.ps.restrictedTraverse('manage_main')
+ except Unauthorized:
+ self.fail('Access to manage_main was denied')
+
+ def testCannotAccessIfAnonymous(self):
+ # manage_main should be protected from Anonymous
+ self.logout()
+ self.assertRaises(Unauthorized, self.ps.restrictedTraverse, 'manage_main')
+
+ def testCanAccessIfManager(self):
+ # manage_main should be accessible to Manager
+ self.setRoles(['Manager'])
+ try:
+ self.ps.restrictedTraverse('manage_main')
+ except Unauthorized:
+ self.fail('Access to manage_main was denied to Manager')
+
+ # Test access protection with SecurityManager
+
+ def testCannotAccessWithoutAccessPermissionSecurityManager(self):
+ # manage_main should be protected
+ self.assertRaises(Unauthorized, getSecurityManager().validate,
+ self.ps, self.ps, 'manage_main', self.ps.manage_main)
+
+ def testCanAccessWithAccessPermissionSecurityManager(self):
+ # manage_main should be accessible if we have the necessary permissions
+ self.setPermissions(access_permissions)
+ try:
+ getSecurityManager().validate(self.ps, self.ps, 'manage_main', self.ps.manage_main)
+ except Unauthorized:
+ self.fail('Access to manage_main was denied')
+
+ def testCannotAccessIfAnonymousSecurityManager(self):
+ # manage_main should be protected from Anonymous
+ self.logout()
+ self.assertRaises(Unauthorized, getSecurityManager().validate,
+ self.ps, self.ps, 'manage_main', self.ps.manage_main)
+
+ def testCanAccessIfManagerSecurityManager(self):
+ # manage_main should be accessible to Manager
+ self.setRoles(['Manager'])
+ try:
+ getSecurityManager().validate(self.ps, self.ps, 'manage_main', self.ps.manage_main)
+ except Unauthorized:
+ self.fail('Access to manage_main was denied to Manager')
+
+ # Test edit protection with restrictedTraverse
+
+ def testCannotEditWithoutChangePermission(self):
+ # PythonScript should not be editable
+ try:
+ self.ps.restrictedTraverse('ZPythonScript_edit')(ps_params2, ps_body2)
+ except Unauthorized:
+ pass # Test passed
+ else:
+ self.assertEqual(self.ps.body(), ps_body2+'\n',
+ 'ZPythonScript_edit was not protected')
+ self.assertEqual(self.ps.body(), ps_body1+'\n',
+ 'ZPythonScript_edit was protected but no exception was raised')
+
+ def testCanEditWithChangePermission(self):
+ # PythonScript should be editable if we have the necessary permissions
+ self.setPermissions(change_permissions)
+ try:
+ self.ps.restrictedTraverse('ZPythonScript_edit')(ps_params2, ps_body2)
+ except Unauthorized:
+ self.fail('Access to ZPythonScript_edit was denied')
+ else:
+ self.assertEqual(self.ps.body(), ps_body2+'\n')
+ self.assertEqual(self.ps.params(), ps_params2)
+
+ def testCannotEditIfAnonymous(self):
+ # PythonScript should not be editable by Anonymous
+ self.logout()
+ try:
+ self.ps.restrictedTraverse('ZPythonScript_edit')(ps_params2, ps_body2)
+ except Unauthorized:
+ pass # Test passed
+ else:
+ self.assertEqual(self.ps.body(), ps_body2+'\n',
+ 'ZPythonScript_edit was not protected')
+ self.assertEqual(self.ps.body(), ps_body1+'\n',
+ 'ZPythonScript_edit was protected but no exception was raised')
+
+ def testCanEditIfManager(self):
+ # PythonScript should be editable by Manager
+ self.setRoles(['Manager'])
+ try:
+ self.ps.restrictedTraverse('ZPythonScript_edit')(ps_params2, ps_body2)
+ except Unauthorized:
+ self.fail('Access to ZPythonScript_edit was denied to Manager')
+ else:
+ self.assertEqual(self.ps.body(), ps_body2+'\n')
+ self.assertEqual(self.ps.params(), ps_params2)
+
+
+def test_suite():
+ from unittest import TestSuite, makeSuite
+ suite = TestSuite()
+ suite.addTest(makeSuite(TestPythonScript))
+ return suite
+
+if __name__ == '__main__':
+ framework()
+
Added: Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/testShoppingCart.py
===================================================================
--- Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/testShoppingCart.py 2006-08-19 02:33:50 UTC (rev 69678)
+++ Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/testShoppingCart.py 2006-08-19 02:36:49 UTC (rev 69679)
@@ -0,0 +1,133 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+"""Example ZopeTestCase testing the ShoppingCart example application
+
+Note the use of sessions and how the SESSION object is added to
+the REQUEST in afterSetUp().
+
+You can use zLOG.LOG() if you set up the event log variables first.
+Handy for debugging and tracing your tests.
+
+$Id: testShoppingCart.py 40258 2005-11-19 20:37:06Z shh $
+"""
+
+import os, sys
+if __name__ == '__main__':
+ execfile(os.path.join(sys.path[0], 'framework.py'))
+
+#os.environ['STUPID_LOG_FILE'] = os.path.join(os.getcwd(), 'zLOG.log')
+#os.environ['STUPID_LOG_SEVERITY'] = '0'
+
+from Testing import ZopeTestCase
+
+from Globals import SOFTWARE_HOME
+examples_path = os.path.join(SOFTWARE_HOME, '..', '..', 'skel', 'import', 'Examples.zexp')
+examples_path = os.path.abspath(examples_path)
+
+
+# Open ZODB connection
+app = ZopeTestCase.app()
+
+# Set up sessioning objects
+ZopeTestCase.utils.setupCoreSessions(app)
+
+# Set up example applications
+if not hasattr(app, 'Examples'):
+ ZopeTestCase.utils.importObjectFromFile(app, examples_path)
+
+# Close ZODB connection
+ZopeTestCase.close(app)
+
+
+class DummyOrder:
+ '''Construct an order we can add to the cart'''
+ __allow_access_to_unprotected_subobjects__ = 1
+
+ def __init__(self, id, quantity):
+ self.id = id
+ self.quantity = quantity
+
+
+class TestShoppingCart(ZopeTestCase.ZopeTestCase):
+ '''Test the ShoppingCart example application'''
+
+ _setup_fixture = 0 # No default fixture
+
+ def afterSetUp(self):
+ self.cart = self.app.Examples.ShoppingCart
+ # Put SESSION object into REQUEST
+ request = self.app.REQUEST
+ sdm = self.app.session_data_manager
+ request.set('SESSION', sdm.getSessionData())
+ self.session = request.SESSION
+
+ def testSession(self):
+ # Session should work
+ self.session.set('boring', 'boring')
+ self.assertEqual(self.session.get('boring'), 'boring')
+
+ def testCartIsEmpty(self):
+ # Cart should be empty
+ self.assertEqual(len(self.cart.currentItems()), 0)
+
+ def testAddItems(self):
+ # Adding to the cart should work
+ self.cart.addItems([DummyOrder('510-115', 1),])
+ self.assertEqual(len(self.cart.currentItems()), 1)
+
+ def testDeleteItems(self):
+ # Deleting from the cart should work
+ self.cart.addItems([DummyOrder('510-115', 1),])
+ self.cart.deleteItems(['510-115'])
+ self.assertEqual(len(self.cart.currentItems()), 0)
+
+ def testAddQuantity(self):
+ # Adding to quantity should work
+ self.cart.addItems([DummyOrder('510-115', 1),])
+ self.cart.addItems([DummyOrder('510-115', 2),])
+ self.cart.addItems([DummyOrder('510-115', 3),])
+ self.assertEqual(self.cart.currentItems()[0]['quantity'], 6)
+
+ def testGetTotal(self):
+ # Totals should be computed correctly
+ self.cart.addItems([DummyOrder('510-115', 1),])
+ self.cart.addItems([DummyOrder('510-122', 2),])
+ self.cart.addItems([DummyOrder('510-007', 2),])
+ self.assertEqual(self.cart.getTotal(), 149.95)
+
+ def testGetItem(self):
+ # Getting an item from the "database" should work
+ item = self.cart.getItem('510-115')
+ self.assertEqual(item['id'], '510-115')
+ self.assertEqual(item['title'], 'Econo Feeder')
+ self.assertEqual(item['price'], 7.95)
+
+ def testEight(self):
+ # Additional test to trigger connection pool depletion bug
+ pass
+
+
+class TestSandboxedShoppingCart(ZopeTestCase.Sandboxed, TestShoppingCart):
+ '''Demonstrate that sessions work in sandboxes'''
+
+
+def test_suite():
+ from unittest import TestSuite, makeSuite
+ suite = TestSuite()
+ suite.addTest(makeSuite(TestShoppingCart))
+ suite.addTest(makeSuite(TestSandboxedShoppingCart))
+ return suite
+
+if __name__ == '__main__':
+ framework()
+
Added: Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/testSkeleton.py
===================================================================
--- Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/testSkeleton.py 2006-08-19 02:33:50 UTC (rev 69678)
+++ Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/testSkeleton.py 2006-08-19 02:36:49 UTC (rev 69679)
@@ -0,0 +1,45 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+"""Skeleton ZopeTestCase
+
+$Id: testSkeleton.py 40219 2005-11-18 15:05:47Z andreasjung $
+"""
+
+import os, sys
+if __name__ == '__main__':
+ execfile(os.path.join(sys.path[0], 'framework.py'))
+
+from Testing import ZopeTestCase
+
+ZopeTestCase.installProduct('SomeProduct')
+
+
+class TestSomeProduct(ZopeTestCase.ZopeTestCase):
+
+ def afterSetUp(self):
+ pass
+
+ def testSomething(self):
+ # Test something
+ self.assertEqual(1+1, 2)
+
+
+def test_suite():
+ from unittest import TestSuite, makeSuite
+ suite = TestSuite()
+ suite.addTest(makeSuite(TestSomeProduct))
+ return suite
+
+if __name__ == '__main__':
+ framework()
+
Added: Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/testWebserver.py
===================================================================
--- Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/testWebserver.py 2006-08-19 02:33:50 UTC (rev 69678)
+++ Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/testWebserver.py 2006-08-19 02:36:49 UTC (rev 69679)
@@ -0,0 +1,206 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+"""Example ZopeTestCase testing web access to a freshly started ZServer
+
+Note that we need to set up the error_log before starting the ZServer.
+
+Note further that the test thread needs to explicitly commit its
+transactions, so the ZServer threads can see modifications made to
+the ZODB.
+
+IF YOU THINK YOU NEED THE WEBSERVER STARTED YOU ARE PROBABLY WRONG!
+This is only required in very special cases, like when testing
+ZopeXMLMethods where XSLT processing is done by external tools that
+need to URL-call back into the Zope server.
+
+If you want to write functional unit tests, see the testFunctional.py
+example instead.
+
+$Id: testWebserver.py 30565 2005-05-30 22:07:11Z shh $
+"""
+
+import os, sys
+if __name__ == '__main__':
+ execfile(os.path.join(sys.path[0], 'framework.py'))
+
+#os.environ['STUPID_LOG_FILE'] = os.path.join(os.getcwd(), 'zLOG.log')
+#os.environ['STUPID_LOG_SEVERITY'] = '0'
+
+from Testing import ZopeTestCase
+
+from Testing.ZopeTestCase import transaction
+from AccessControl import Unauthorized
+import urllib
+
+# Create the error_log object
+ZopeTestCase.utils.setupSiteErrorLog()
+
+# Start the web server
+host, port = ZopeTestCase.utils.startZServer(4)
+folder_url = 'http://%s:%d/%s' %(host, port, ZopeTestCase.folder_name)
+
+
+class ManagementOpener(urllib.FancyURLopener):
+ '''Logs on as manager when prompted'''
+ def prompt_user_passwd(self, host, realm):
+ return ('manager', 'secret')
+
+class UnauthorizedOpener(urllib.FancyURLopener):
+ '''Raises Unauthorized when prompted'''
+ def prompt_user_passwd(self, host, realm):
+ raise Unauthorized, 'The URLopener was asked for authentication'
+
+
+class TestWebserver(ZopeTestCase.ZopeTestCase):
+
+ def afterSetUp(self):
+ uf = self.folder.acl_users
+ uf.userFolderAddUser('manager', 'secret', ['Manager'], [])
+
+ # A simple document
+ self.folder.addDTMLDocument('index_html', file='index_html called')
+
+ # A document only accessible to manager
+ self.folder.addDTMLDocument('secret_html', file='secret_html called')
+
+ for p in ZopeTestCase.standard_permissions:
+ self.folder.secret_html.manage_permission(p, ['Manager'])
+
+ # A method to change the title property of an object
+ self.folder.addDTMLMethod('change_title',
+ file='''<dtml-call "manage_changeProperties(title=REQUEST.get('title'))">'''
+ '''<dtml-var title_or_id>''')
+
+ manager = uf.getUserById('manager').__of__(uf)
+ self.folder.change_title.changeOwnership(manager)
+
+ # Commit so the ZServer threads can see the changes
+ transaction.commit()
+
+ def beforeClose(self):
+ # Commit after cleanup
+ transaction.commit()
+
+ def testAccessPublicObject(self):
+ # Test access to a public resource
+ page = self.folder.index_html(self.folder)
+ self.assertEqual(page, 'index_html called')
+
+ def testURLAccessPublicObject(self):
+ # Test web access to a public resource
+ urllib._urlopener = ManagementOpener()
+ page = urllib.urlopen(folder_url+'/index_html').read()
+ self.assertEqual(page, 'index_html called')
+
+ def testAccessProtectedObject(self):
+ # Test access to a protected resource
+ page = self.folder.secret_html(self.folder)
+ self.assertEqual(page, 'secret_html called')
+
+ def testURLAccessProtectedObject(self):
+ # Test web access to a protected resource
+ urllib._urlopener = ManagementOpener()
+ page = urllib.urlopen(folder_url+'/secret_html').read()
+ self.assertEqual(page, 'secret_html called')
+
+ def testSecurityOfPublicObject(self):
+ # Test security of a public resource
+ try:
+ self.folder.restrictedTraverse('index_html')
+ except Unauthorized:
+ # Convert error to failure
+ self.fail('Unauthorized')
+
+ def testURLSecurityOfPublicObject(self):
+ # Test web security of a public resource
+ urllib._urlopener = UnauthorizedOpener()
+ try:
+ urllib.urlopen(folder_url+'/index_html')
+ except Unauthorized:
+ # Convert error to failure
+ self.fail('Unauthorized')
+
+ def testSecurityOfProtectedObject(self):
+ # Test security of a protected resource
+ try:
+ self.folder.restrictedTraverse('secret_html')
+ except Unauthorized:
+ pass # Test passed
+ else:
+ self.fail('Resource not protected')
+
+ def testURLSecurityOfProtectedObject(self):
+ # Test web security of a protected resource
+ urllib._urlopener = UnauthorizedOpener()
+ try:
+ urllib.urlopen(folder_url+'/secret_html')
+ except Unauthorized:
+ pass # Test passed
+ else:
+ self.fail('Resource not protected')
+
+ def testModifyObject(self):
+ # Test a script that modifies the ZODB
+ self.setRoles(['Manager'])
+ self.app.REQUEST.set('title', 'Foo')
+ page = self.folder.index_html.change_title(self.folder.index_html,
+ self.app.REQUEST)
+ self.assertEqual(page, 'Foo')
+ self.assertEqual(self.folder.index_html.title, 'Foo')
+
+ def testURLModifyObject(self):
+ # Test a transaction that actually commits something
+ urllib._urlopener = ManagementOpener()
+ page = urllib.urlopen(folder_url+'/index_html/change_title?title=Foo').read()
+ self.assertEqual(page, 'Foo')
+
+ def testAbsoluteURL(self):
+ # Test absolute_url
+ self.assertEqual(self.folder.absolute_url(), folder_url)
+
+
+class TestSandboxedWebserver(ZopeTestCase.Sandboxed, TestWebserver):
+ '''Demonstrates that tests involving ZServer threads can also be
+ run from sandboxes. In fact, it may be preferable to do so.
+ '''
+
+ # Note: By inheriting from TestWebserver we run the same
+ # test methods as above!
+
+ def testConnectionIsShared(self):
+ # Due to sandboxing the ZServer thread operates on the
+ # same connection as the main thread, allowing us to
+ # see changes made to 'index_html' right away.
+ urllib._urlopener = ManagementOpener()
+ urllib.urlopen(folder_url+'/index_html/change_title?title=Foo')
+ self.assertEqual(self.folder.index_html.title, 'Foo')
+
+ def testCanCommit(self):
+ # Additionally, it allows us to commit transactions without
+ # harming the test ZODB.
+ self.folder.foo = 1
+ transaction.commit()
+ self.folder.foo = 2
+ transaction.commit()
+
+
+def test_suite():
+ from unittest import TestSuite, makeSuite
+ suite = TestSuite()
+ suite.addTest(makeSuite(TestWebserver))
+ suite.addTest(makeSuite(TestSandboxedWebserver))
+ return suite
+
+if __name__ == '__main__':
+ framework()
+
Added: Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/testZODBCompat.py
===================================================================
--- Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/testZODBCompat.py 2006-08-19 02:33:50 UTC (rev 69678)
+++ Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/testZODBCompat.py 2006-08-19 02:36:49 UTC (rev 69679)
@@ -0,0 +1,366 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+"""Tests ZODB behavior in ZopeTestCase
+
+Demonstrates that cut/copy/paste/clone/rename and import/export
+work if a subtransaction is committed before performing the respective
+operation.
+
+$Id: testZODBCompat.py 39884 2005-11-04 10:24:10Z shh $
+"""
+
+import os, sys
+if __name__ == '__main__':
+ execfile(os.path.join(sys.path[0], 'framework.py'))
+
+from Testing import ZopeTestCase
+
+import transaction
+
+from AccessControl.Permissions import add_documents_images_and_files
+from AccessControl.Permissions import delete_objects
+import tempfile
+
+folder_name = ZopeTestCase.folder_name
+cutpaste_permissions = [add_documents_images_and_files, delete_objects]
+
+
+class TestCopyPaste(ZopeTestCase.ZopeTestCase):
+
+ def afterSetUp(self):
+ self.setPermissions(cutpaste_permissions)
+ self.folder.addDTMLMethod('doc', file='foo')
+ # _p_oids are None until we commit a subtransaction
+ self.assertEqual(self.folder._p_oid, None)
+ transaction.savepoint(optimistic=True)
+ self.failIfEqual(self.folder._p_oid, None)
+
+ def testCutPaste(self):
+ cb = self.folder.manage_cutObjects(['doc'])
+ self.folder.manage_pasteObjects(cb)
+ self.failUnless(hasattr(self.folder, 'doc'))
+ self.failIf(hasattr(self.folder, 'copy_of_doc'))
+
+ def testCopyPaste(self):
+ cb = self.folder.manage_copyObjects(['doc'])
+ self.folder.manage_pasteObjects(cb)
+ self.failUnless(hasattr(self.folder, 'doc'))
+ self.failUnless(hasattr(self.folder, 'copy_of_doc'))
+
+ def testClone(self):
+ self.folder.manage_clone(self.folder.doc, 'new_doc')
+ self.failUnless(hasattr(self.folder, 'doc'))
+ self.failUnless(hasattr(self.folder, 'new_doc'))
+
+ def testRename(self):
+ self.folder.manage_renameObjects(['doc'], ['new_doc'])
+ self.failIf(hasattr(self.folder, 'doc'))
+ self.failUnless(hasattr(self.folder, 'new_doc'))
+
+ def testCOPY(self):
+ # WebDAV COPY
+ request = self.app.REQUEST
+ request.environ['HTTP_DEPTH'] = 'infinity'
+ request.environ['HTTP_DESTINATION'] = 'http://foo.com/%s/new_doc' % folder_name
+ self.folder.doc.COPY(request, request.RESPONSE)
+ self.failUnless(hasattr(self.folder, 'doc'))
+ self.failUnless(hasattr(self.folder, 'new_doc'))
+
+ def testMOVE(self):
+ # WebDAV MOVE
+ request = self.app.REQUEST
+ request.environ['HTTP_DEPTH'] = 'infinity'
+ request.environ['HTTP_DESTINATION'] = 'http://foo.com/%s/new_doc' % folder_name
+ self.folder.doc.MOVE(request, request.RESPONSE)
+ self.failIf(hasattr(self.folder, 'doc'))
+ self.failUnless(hasattr(self.folder, 'new_doc'))
+
+
+class TestImportExport(ZopeTestCase.ZopeTestCase):
+
+ def afterSetUp(self):
+ self.setupLocalEnvironment()
+ self.folder.addDTMLMethod('doc', file='foo')
+ # _p_oids are None until we commit a subtransaction
+ self.assertEqual(self.folder._p_oid, None)
+ transaction.savepoint(optimistic=True)
+ self.failIfEqual(self.folder._p_oid, None)
+
+ def testExport(self):
+ self.folder.manage_exportObject('doc')
+ self.failUnless(os.path.exists(self.zexp_file))
+
+ def testImport(self):
+ self.folder.manage_exportObject('doc')
+ self.folder._delObject('doc')
+ self.folder.manage_importObject('doc.zexp')
+ self.failUnless(hasattr(self.folder, 'doc'))
+
+ # To make export and import happy, we have to provide a file-
+ # system 'import' directory and adapt the configuration a bit:
+
+ local_home = tempfile.gettempdir()
+ import_dir = os.path.join(local_home, 'import')
+ zexp_file = os.path.join(import_dir, 'doc.zexp')
+
+ def setupLocalEnvironment(self):
+ # Create the 'import' directory
+ os.mkdir(self.import_dir)
+ try:
+ import App.config
+ except ImportError:
+ # Modify builtins
+ builtins = getattr(__builtins__, '__dict__', __builtins__)
+ self._ih = INSTANCE_HOME
+ builtins['INSTANCE_HOME'] = self.local_home
+ self._ch = CLIENT_HOME
+ builtins['CLIENT_HOME'] = self.import_dir
+ else:
+ # Zope >= 2.7
+ config = App.config.getConfiguration()
+ self._ih = config.instancehome
+ config.instancehome = self.local_home
+ self._ch = config.clienthome
+ config.clienthome = self.import_dir
+ App.config.setConfiguration(config)
+
+ def afterClear(self):
+ # Remove external resources
+ try: os.remove(self.zexp_file)
+ except OSError: pass
+ try: os.rmdir(self.import_dir)
+ except OSError: pass
+ try:
+ import App.config
+ except ImportError:
+ # Restore builtins
+ builtins = getattr(__builtins__, '__dict__', __builtins__)
+ if hasattr(self, '_ih'):
+ builtins['INSTANCE_HOME'] = self._ih
+ if hasattr(self, '_ch'):
+ builtins['CLIENT_HOME'] = self._ch
+ else:
+ # Zope >= 2.7
+ config = App.config.getConfiguration()
+ if hasattr(self, '_ih'):
+ config.instancehome = self._ih
+ if hasattr(self, '_ch'):
+ config.clienthome = self._ch
+ App.config.setConfiguration(config)
+
+
+# Dummy object
+from OFS.SimpleItem import SimpleItem
+
+class DummyObject(SimpleItem):
+ id = 'dummy'
+ foo = None
+ _v_foo = None
+ _p_foo = None
+
+app = ZopeTestCase.app()
+app._setObject('dummy1', DummyObject())
+app._setObject('dummy2', DummyObject())
+transaction.commit()
+ZopeTestCase.close(app)
+
+
+class TestAttributesOfCleanObjects(ZopeTestCase.ZopeTestCase):
+ '''This testcase shows that _v_ and _p_ attributes are NOT bothered
+ by transaction boundaries, if the respective object is otherwise
+ left untouched (clean). This means that such variables will keep
+ their values across tests.
+
+ The only use case yet encountered in the wild is portal_memberdata's
+ _v_temps attribute. Test authors are cautioned to watch out for
+ occurrences of _v_ and _p_ attributes of objects that are not recreated
+ for every test method execution, but preexist in the test ZODB.
+
+ It is therefore deemed essential to initialize any _v_ and _p_
+ attributes of such objects in afterSetup(), as otherwise test results
+ will be distorted!
+
+ Note that _v_ attributes used to be transactional in Zope < 2.6.
+
+ This testcase exploits the fact that test methods are sorted by name.
+ '''
+
+ def afterSetUp(self):
+ self.dummy = self.app.dummy1 # See above
+
+ def testNormal_01(self):
+ # foo is always None
+ self.assertEqual(self.dummy.foo, None)
+ self.dummy.foo = 'foo'
+
+ def testNormal_02(self):
+ # foo is always None
+ self.assertEqual(self.dummy.foo, None)
+ self.dummy.foo = 'bar'
+
+ def testNormal_03(self):
+ # foo is always None
+ self.assertEqual(self.dummy.foo, None)
+
+ def testPersistent_01(self):
+ # _p_foo is initially None
+ self.assertEqual(self.dummy._p_foo, None)
+ self.dummy._p_foo = 'foo'
+
+ def testPersistent_02(self):
+ # _p_foo retains value assigned by previous test
+ self.assertEqual(self.dummy._p_foo, 'foo')
+ self.dummy._p_foo = 'bar'
+
+ def testPersistent_03(self):
+ # _p_foo retains value assigned by previous test
+ self.assertEqual(self.dummy._p_foo, 'bar')
+
+ def testVolatile_01(self):
+ # _v_foo is initially None
+ self.assertEqual(self.dummy._v_foo, None)
+ self.dummy._v_foo = 'foo'
+
+ def testVolatile_02(self):
+ if hasattr(self.app._p_jar, 'register'):
+ # _v_foo retains value assigned by previous test
+ self.assertEqual(self.dummy._v_foo, 'foo')
+ else:
+ # XXX: _v_foo is transactional in Zope < 2.6
+ self.assertEqual(self.dummy._v_foo, None)
+ self.dummy._v_foo = 'bar'
+
+ def testVolatile_03(self):
+ if hasattr(self.app._p_jar, 'register'):
+ # _v_foo retains value assigned by previous test
+ self.assertEqual(self.dummy._v_foo, 'bar')
+ else:
+ # XXX: _v_foo is transactional in Zope < 2.6
+ self.assertEqual(self.dummy._v_foo, None)
+
+
+class TestAttributesOfDirtyObjects(ZopeTestCase.ZopeTestCase):
+ '''This testcase shows that _v_ and _p_ attributes of dirty objects
+ ARE removed on abort.
+
+ This testcase exploits the fact that test methods are sorted by name.
+ '''
+
+ def afterSetUp(self):
+ self.dummy = self.app.dummy2 # See above
+ self.dummy.touchme = 1 # Tag, you're dirty
+
+ def testDirtyNormal_01(self):
+ # foo is always None
+ self.assertEqual(self.dummy.foo, None)
+ self.dummy.foo = 'foo'
+
+ def testDirtyNormal_02(self):
+ # foo is always None
+ self.assertEqual(self.dummy.foo, None)
+ self.dummy.foo = 'bar'
+
+ def testDirtyNormal_03(self):
+ # foo is always None
+ self.assertEqual(self.dummy.foo, None)
+
+ def testDirtyPersistent_01(self):
+ # _p_foo is alwas None
+ self.assertEqual(self.dummy._p_foo, None)
+ self.dummy._p_foo = 'foo'
+
+ def testDirtyPersistent_02(self):
+ # _p_foo is alwas None
+ self.assertEqual(self.dummy._p_foo, None)
+ self.dummy._p_foo = 'bar'
+
+ def testDirtyPersistent_03(self):
+ # _p_foo is alwas None
+ self.assertEqual(self.dummy._p_foo, None)
+
+ def testDirtyVolatile_01(self):
+ # _v_foo is always None
+ self.assertEqual(self.dummy._v_foo, None)
+ self.dummy._v_foo = 'foo'
+
+ def testDirtyVolatile_02(self):
+ # _v_foo is always None
+ self.assertEqual(self.dummy._v_foo, None)
+ self.dummy._v_foo = 'bar'
+
+ def testDirtyVolatile_03(self):
+ # _v_foo is always None
+ self.assertEqual(self.dummy._v_foo, None)
+
+
+class TestTransactionAbort(ZopeTestCase.ZopeTestCase):
+
+ def testTransactionAbort(self):
+ self.folder.foo = 1
+ self.failUnless(hasattr(self.folder, 'foo'))
+ transaction.abort()
+ # The foo attribute is still present
+ self.failUnless(hasattr(self.folder, 'foo'))
+
+ def testSubTransactionAbort(self):
+ self.folder.foo = 1
+ self.failUnless(hasattr(self.folder, 'foo'))
+ transaction.savepoint(optimistic=True)
+ transaction.abort()
+ # This time the abort nukes the foo attribute...
+ self.failIf(hasattr(self.folder, 'foo'))
+
+ def testTransactionAbortPersistent(self):
+ self.folder._p_foo = 1
+ self.failUnless(hasattr(self.folder, '_p_foo'))
+ transaction.abort()
+ # The _p_foo attribute is still present
+ self.failUnless(hasattr(self.folder, '_p_foo'))
+
+ def testSubTransactionAbortPersistent(self):
+ self.folder._p_foo = 1
+ self.failUnless(hasattr(self.folder, '_p_foo'))
+ transaction.savepoint(optimistic=True)
+ transaction.abort()
+ # This time the abort nukes the _p_foo attribute...
+ self.failIf(hasattr(self.folder, '_p_foo'))
+
+ def testTransactionAbortVolatile(self):
+ self.folder._v_foo = 1
+ self.failUnless(hasattr(self.folder, '_v_foo'))
+ transaction.abort()
+ # The _v_foo attribute is still present
+ self.failUnless(hasattr(self.folder, '_v_foo'))
+
+ def testSubTransactionAbortVolatile(self):
+ self.folder._v_foo = 1
+ self.failUnless(hasattr(self.folder, '_v_foo'))
+ transaction.savepoint(optimistic=True)
+ transaction.abort()
+ # This time the abort nukes the _v_foo attribute...
+ self.failIf(hasattr(self.folder, '_v_foo'))
+
+
+def test_suite():
+ from unittest import TestSuite, makeSuite
+ suite = TestSuite()
+ suite.addTest(makeSuite(TestCopyPaste))
+ suite.addTest(makeSuite(TestImportExport))
+ suite.addTest(makeSuite(TestAttributesOfCleanObjects))
+ suite.addTest(makeSuite(TestAttributesOfDirtyObjects))
+ suite.addTest(makeSuite(TestTransactionAbort))
+ return suite
+
+if __name__ == '__main__':
+ framework()
+
Added: Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/testZopeTestCase.py
===================================================================
--- Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/testZopeTestCase.py 2006-08-19 02:33:50 UTC (rev 69678)
+++ Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/testZopeTestCase.py 2006-08-19 02:36:49 UTC (rev 69679)
@@ -0,0 +1,414 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+"""Tests the ZopeTestCase, eating its own dogfood
+
+NOTE: This is *not* an example TestCase. Do not
+use this file as a blueprint for your own tests!
+
+See testPythonScript.py and testShoppingCart.py for
+example test cases. See testSkeleton.py for a quick
+way of getting started.
+
+$Id: testZopeTestCase.py 30565 2005-05-30 22:07:11Z shh $
+"""
+
+import os, sys
+if __name__ == '__main__':
+ execfile(os.path.join(sys.path[0], 'framework.py'))
+
+from Testing import ZopeTestCase
+
+from Testing.ZopeTestCase import folder_name
+from Testing.ZopeTestCase import user_name
+from Testing.ZopeTestCase import user_role
+from Testing.ZopeTestCase import standard_permissions
+
+from Acquisition import aq_base
+from AccessControl import getSecurityManager
+from types import ListType
+
+import transaction
+
+
+def hasattr_(ob, attr):
+ return hasattr(aq_base(ob), attr)
+
+
+class TestZopeTestCase(ZopeTestCase.ZopeTestCase):
+ '''Incrementally exercise the ZopeTestCase API.'''
+
+ _setUp = ZopeTestCase.ZopeTestCase.setUp
+ _tearDown = ZopeTestCase.ZopeTestCase.tearDown
+
+ def setUp(self):
+ # For this test case we *want* to start
+ # with an empty fixture.
+ self._called = []
+ # Implicitly aborts previous transaction
+ transaction.begin()
+
+ def beforeSetUp(self):
+ self._called.append('beforeSetUp')
+
+ def afterSetUp(self):
+ self._called.append('afterSetUp')
+
+ def beforeTearDown(self):
+ self._called.append('beforeTearDown')
+
+ def beforeClose(self):
+ self._called.append('beforeClose')
+
+ def afterClear(self):
+ self._called.append('afterClear')
+
+ def test_setupFolder(self):
+ # Folder should be set up
+ self.app = self._app()
+ self._setupFolder()
+ self.failUnless(hasattr_(self.app, folder_name))
+ self.failUnless(hasattr_(self, 'folder'))
+ self.failUnless(user_role in self.folder.userdefined_roles())
+ self.assertPermissionsOfRole(standard_permissions, user_role)
+
+ def test_setupUserFolder(self):
+ # User folder should be set up
+ self.app = self._app()
+ self._setupFolder()
+ self._setupUserFolder()
+ self.failUnless(hasattr_(self.folder, 'acl_users'))
+
+ def test_setupUser(self):
+ # User should be set up
+ self.app = self._app()
+ self._setupFolder()
+ self._setupUserFolder()
+ self._setupUser()
+ acl_user = self.folder.acl_users.getUserById(user_name)
+ self.failUnless(acl_user)
+ self.assertEqual(acl_user.getRoles(), (user_role, 'Authenticated'))
+ self.assertEqual(type(acl_user.roles), ListType)
+
+ def test_setRoles(self):
+ # Roles should be set for user
+ self.app = self._app()
+ self._setupFolder()
+ self._setupUserFolder()
+ self._setupUser()
+ test_roles = ['Manager', user_role]
+ self.setRoles(test_roles)
+ acl_user = self.folder.acl_users.getUserById(user_name)
+ self.assertRolesOfUser(test_roles, acl_user)
+
+ def test_setRoles_2(self):
+ # Roles of logged in user should be updated
+ self.app = self._app()
+ self._setupFolder()
+ self._setupUserFolder()
+ self._setupUser()
+ self.login()
+ test_roles = ['Manager', user_role]
+ self.setRoles(test_roles)
+ auth_user = getSecurityManager().getUser()
+ self.assertRolesOfUser(test_roles, auth_user)
+
+ def test_setRoles_3(self):
+ # Roles should be set for a specified user
+ self.app = self._app()
+ self._setupFolder()
+ self._setupUserFolder()
+ self.folder.acl_users.userFolderAddUser('user_2', 'secret', [], [])
+ test_roles = ['Manager', user_role]
+ self.setRoles(test_roles, 'user_2')
+ acl_user = self.folder.acl_users.getUserById('user_2')
+ self.assertRolesOfUser(test_roles, acl_user)
+
+ def test_setRoles_4(self):
+ # Roles should be set from a tuple
+ self.app = self._app()
+ self._setupFolder()
+ self._setupUserFolder()
+ self._setupUser()
+ test_roles = ['Manager', user_role]
+ self.setRoles(tuple(test_roles))
+ acl_user = self.folder.acl_users.getUserById(user_name)
+ self.assertRolesOfUser(test_roles, acl_user)
+
+ def test_setRoles_5(self):
+ # Roles should be set from a string
+ self.app = self._app()
+ self._setupFolder()
+ self._setupUserFolder()
+ self._setupUser()
+ test_roles = ['Manager']
+ self.setRoles('Manager')
+ acl_user = self.folder.acl_users.getUserById(user_name)
+ self.assertRolesOfUser(test_roles, acl_user)
+
+ def test_setPermissions(self):
+ # Permissions should be set for user
+ self.app = self._app()
+ self._setupFolder()
+ test_perms = ['Add Folders', 'Delete objects']
+ self.assertPermissionsOfRole(standard_permissions, user_role)
+ self.setPermissions(test_perms)
+ self.assertPermissionsOfRole(test_perms, user_role)
+
+ def test_setPermissions_2(self):
+ # Permissions should be set for specified role
+ self.app = self._app()
+ self._setupFolder()
+ self.folder._addRole('role_2')
+ self.assertPermissionsOfRole([], 'role_2')
+ self.setPermissions(standard_permissions, 'role_2')
+ self.assertPermissionsOfRole(standard_permissions, 'role_2')
+
+ def test_setPermissions_3(self):
+ # Permissions should be set from a tuple
+ self.app = self._app()
+ self._setupFolder()
+ test_perms = ['Add Folders', 'Delete objects']
+ self.assertPermissionsOfRole(standard_permissions, user_role)
+ self.setPermissions(tuple(test_perms))
+ self.assertPermissionsOfRole(test_perms, user_role)
+
+ def test_setPermissions_4(self):
+ # Permissions should be set from a comma separated string
+ self.app = self._app()
+ self._setupFolder()
+ test_perms = ['Add Folders']
+ self.assertPermissionsOfRole(standard_permissions, user_role)
+ self.setPermissions('Add Folders')
+ self.assertPermissionsOfRole(test_perms, user_role)
+
+ def test_login(self):
+ # User should be able to log in
+ self.app = self._app()
+ self._setupFolder()
+ self._setupUserFolder()
+ self._setupUser()
+ auth_name = getSecurityManager().getUser().getUserName()
+ self.assertEqual(auth_name, 'Anonymous User')
+ self.login()
+ auth_name = getSecurityManager().getUser().getId()
+ self.assertEqual(auth_name, user_name)
+
+ def test_login_2(self):
+ # A specified user should be logged in
+ self.app = self._app()
+ self._setupFolder()
+ self._setupUserFolder()
+ self.folder.acl_users.userFolderAddUser('user_2', 'secret', [], [])
+ auth_name = getSecurityManager().getUser().getUserName()
+ self.assertEqual(auth_name, 'Anonymous User')
+ self.login('user_2')
+ auth_name = getSecurityManager().getUser().getId()
+ self.assertEqual(auth_name, 'user_2')
+
+ def test_login_3(self):
+ # Unknown user should raise AttributeError
+ self.app = self._app()
+ self._setupFolder()
+ self._setupUserFolder()
+ self.assertRaises(AttributeError, self.login, 'user_3')
+
+ def test_logout(self):
+ # User should be able to log out
+ self.app = self._app()
+ self._setupFolder()
+ self._setupUserFolder()
+ self._setupUser()
+ self.login()
+ self.logout()
+ auth_name = getSecurityManager().getUser().getUserName()
+ self.assertEqual(auth_name, 'Anonymous User')
+
+ def test_clear(self):
+ # Everything should be removed
+ self.app = self._app()
+ self._setupFolder()
+ self._setupUserFolder()
+ self._setupUser()
+ self.login()
+ self._clear(1)
+ self.failIf(self.app.__dict__.has_key(folder_name))
+ auth_name = getSecurityManager().getUser().getUserName()
+ self.assertEqual(auth_name, 'Anonymous User')
+ self.assertEqual(self._called, ['beforeClose', 'afterClear'])
+ # _clear must not fail when called repeatedly
+ self._clear()
+
+ def test_setUp(self):
+ # Everything should be set up
+ self._setUp()
+ self.failUnless(hasattr_(self.app, folder_name))
+ self.failUnless(hasattr_(self, 'folder'))
+ self.failUnless(user_role in self.folder.userdefined_roles())
+ self.assertPermissionsOfRole(standard_permissions, user_role)
+ self.failUnless(hasattr_(self.folder, 'acl_users'))
+ acl_user = self.folder.acl_users.getUserById(user_name)
+ self.failUnless(acl_user)
+ self.assertEqual(acl_user.getRoles(), (user_role, 'Authenticated'))
+ self.assertEqual(type(acl_user.roles), ListType)
+ auth_name = getSecurityManager().getUser().getId()
+ self.assertEqual(auth_name, user_name)
+ # XXX: Changed in 0.9.0
+ #self.assertEqual(self._called, ['afterClear', 'beforeSetUp', 'afterSetUp'])
+ self.assertEqual(self._called, ['beforeSetUp', 'afterSetUp'])
+
+ def test_tearDown(self):
+ # Everything should be removed
+ self._setUp()
+ self._called = []
+ self._tearDown()
+ self.failIf(self.app.__dict__.has_key(folder_name))
+ auth_name = getSecurityManager().getUser().getUserName()
+ self.assertEqual(auth_name, 'Anonymous User')
+ self.assertEqual(self._called, ['beforeTearDown', 'beforeClose', 'afterClear'])
+
+ def test_setupFlag(self):
+ # Nothing should be set up
+ self._setup_fixture = 0
+ self._setUp()
+ self.failIf(hasattr_(self.app, folder_name))
+ auth_name = getSecurityManager().getUser().getUserName()
+ self.assertEqual(auth_name, 'Anonymous User')
+ # XXX: Changed in 0.9.0
+ #self.assertEqual(self._called, ['afterClear', 'beforeSetUp', 'afterSetUp'])
+ self.assertEqual(self._called, ['beforeSetUp', 'afterSetUp'])
+
+ # Bug tests
+
+ def test_setOwnerPermissions(self):
+ # Permissions should be modified for the Owner role
+ self.app = self._app()
+ self._setupFolder()
+ self.assertPermissionsOfRole([], 'Owner')
+ self.setPermissions(standard_permissions, 'Owner')
+ self.assertPermissionsOfRole(standard_permissions, 'Owner')
+
+ def test_setManagerPermissions(self):
+ # Permissions should *not* be modified for the Manager role
+ self.app = self._app()
+ self._setupFolder()
+ # Setting permissions for Manager role does not work like this
+ manager_perms = self.getPermissionsOfRole('Manager')
+ self.setPermissions(standard_permissions, 'Manager')
+ # Manager does still have all permissions
+ self.assertPermissionsOfRole(manager_perms, 'Manager')
+
+ def test_setManagerPermissions_2(self):
+ # Permissions should be modified for the Manager role
+ self.app = self._app()
+ self._setupFolder()
+ # However, it works like that (because we turn off acquisition?)
+ manager_perms = self.getPermissionsOfRole('Manager')
+ self.folder.manage_permission('Take ownership', ['Owner'], acquire=0)
+ self.assertPermissionsOfRole(['Take ownership'], 'Owner')
+ # Manager does not have 'Take ownership' anymore
+ manager_perms.remove('Take ownership')
+ self.assertPermissionsOfRole(manager_perms, 'Manager')
+
+ # Helpers
+
+ def getPermissionsOfRole(self, role, context=None):
+ '''Returns sorted list of permission names of the
+ given role in the given context.
+ '''
+ if context is None:
+ context = self.folder
+ perms = context.permissionsOfRole(role)
+ return [p['name'] for p in perms if p['selected']]
+
+ def assertPermissionsOfRole(self, permissions, role, context=None):
+ '''Compares list of permission names to permissions of the
+ given role in the given context. Fails if the lists are not
+ found equal.
+ '''
+ lhs = list(permissions)[:]
+ lhs.sort()
+ rhs = self.getPermissionsOfRole(role, context)
+ rhs.sort()
+ self.assertEqual(lhs, rhs)
+
+ def assertRolesOfUser(self, roles, user):
+ '''Compares list of role names to roles of user. Fails if the
+ lists are not found equal.
+ '''
+ lhs = list(roles)[:]
+ lhs.sort()
+ rhs = list(user.getRoles())[:]
+ rhs.remove('Authenticated')
+ rhs.sort()
+ self.assertEqual(lhs, rhs)
+
+
+from AccessControl.User import UserFolder
+from Acquisition import aq_inner, aq_parent, aq_chain
+
+class WrappingUserFolder(UserFolder):
+ '''User folder returning wrapped user objects'''
+
+ def getUser(self, name):
+ return UserFolder.getUser(self, name).__of__(self)
+
+
+class TestPlainUserFolder(ZopeTestCase.ZopeTestCase):
+ '''Tests whether user objects are properly wrapped'''
+
+ def testGetUserDoesNotWrapUser(self):
+ user = self.folder.acl_users.getUserById(user_name)
+ self.failIf(hasattr(user, 'aq_base'))
+ self.failUnless(user is aq_base(user))
+
+ def testLoggedInUserIsWrapped(self):
+ user = getSecurityManager().getUser()
+ self.assertEqual(user.getId(), user_name)
+ self.failUnless(hasattr(user, 'aq_base'))
+ self.failUnless(user.__class__.__name__, 'User')
+ self.failUnless(user.aq_parent.__class__.__name__, 'UserFolder')
+ self.failUnless(user.aq_parent.aq_parent.__class__.__name__, 'Folder')
+
+
+class TestWrappingUserFolder(ZopeTestCase.ZopeTestCase):
+ '''Tests whether user objects are properly wrapped'''
+
+ def _setupUserFolder(self):
+ self.folder._setObject('acl_users', WrappingUserFolder())
+
+ def testGetUserWrapsUser(self):
+ user = self.folder.acl_users.getUserById(user_name)
+ self.failUnless(hasattr(user, 'aq_base'))
+ self.failIf(user is aq_base(user))
+ self.failUnless(user.aq_parent.__class__.__name__, 'WrappingUserFolder')
+
+ def testLoggedInUserIsWrapped(self):
+ user = getSecurityManager().getUser()
+ self.assertEqual(user.getId(), user_name)
+ self.failUnless(hasattr(user, 'aq_base'))
+ self.failUnless(user.__class__.__name__, 'User')
+ self.failUnless(user.aq_parent.__class__.__name__, 'WrappingUserFolder')
+ self.failUnless(user.aq_parent.aq_parent.__class__.__name__, 'Folder')
+
+
+def test_suite():
+ from unittest import TestSuite, makeSuite
+ suite = TestSuite()
+ suite.addTest(makeSuite(TestZopeTestCase))
+ suite.addTest(makeSuite(TestPlainUserFolder))
+ suite.addTest(makeSuite(TestWrappingUserFolder))
+ return suite
+
+if __name__ == '__main__':
+ framework()
+
Added: Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/testing.log
===================================================================
Added: Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/tests.py
===================================================================
--- Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/tests.py 2006-08-19 02:33:50 UTC (rev 69678)
+++ Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/tests.py 2006-08-19 02:36:49 UTC (rev 69679)
@@ -0,0 +1,15 @@
+import os, sys
+import unittest
+suite = unittest.TestSuite()
+
+def test_suite():
+ names = os.listdir(os.path.dirname(__file__))
+ tests = [x for x in names \
+ if x.startswith('test') and x.endswith('.py') and not x == 'tests.py']
+
+ for test in tests:
+ Testing = __import__("Testing.ZopeTestCase." + test[:-3])
+ testmodule = getattr(Testing.ZopeTestCase, test[:-3])
+ if hasattr(testmodule, 'test_suite'):
+ suite.addTest(testmodule.test_suite())
+ return suite
Added: Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/threadutils.py
===================================================================
--- Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/threadutils.py 2006-08-19 02:33:50 UTC (rev 69678)
+++ Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/threadutils.py 2006-08-19 02:36:49 UTC (rev 69679)
@@ -0,0 +1,58 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+"""Parts of ZServer support are in this module so they can
+be imported more selectively.
+
+$Id: threadutils.py 40219 2005-11-18 15:05:47Z andreasjung $
+"""
+
+from threading import Thread
+from StringIO import StringIO
+
+dummyLOG = StringIO()
+
+
+def zserverRunner(host, port, log=None):
+ '''Runs an HTTP ZServer on host:port.'''
+ from ZServer import logger, asyncore
+ from ZServer import zhttp_server, zhttp_handler
+ if log is None: log = dummyLOG
+ lg = logger.file_logger(log)
+ hs = zhttp_server(ip=host, port=port, resolver=None, logger_object=lg)
+ zh = zhttp_handler(module='Zope2', uri_base='')
+ hs.install_handler(zh)
+ asyncore.loop()
+
+
+class QuietThread(Thread):
+ '''This thread eats all exceptions'''
+ def __init__(self, target=None, args=(), kwargs={}):
+ Thread.__init__(self, target=target, args=args, kwargs=kwargs)
+ self.__old_bootstrap = Thread._Thread__bootstrap
+ def __bootstrap(self):
+ try: self.__old_bootstrap(self)
+ except: pass
+ _Thread__bootstrap = __bootstrap
+
+
+def QuietPublisher(self, accept):
+ '''This server eats all exceptions'''
+ try: self.__old_init__(accept)
+ except: pass
+
+
+from ZServer.PubCore.ZServerPublisher import ZServerPublisher
+if not hasattr(ZServerPublisher, '__old_init__'):
+ ZServerPublisher.__old_init__ = ZServerPublisher.__init__
+ ZServerPublisher.__init__ = QuietPublisher
+
Added: Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/utils.py
===================================================================
--- Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/utils.py 2006-08-19 02:33:50 UTC (rev 69678)
+++ Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/utils.py 2006-08-19 02:36:49 UTC (rev 69679)
@@ -0,0 +1,233 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+"""Utility functions
+
+These functions are designed to be imported and run at
+module level to add functionality to the test environment.
+
+$Id: utils.py 66621 2006-04-06 21:30:58Z slinkp $
+"""
+
+import os
+import sys
+import time
+import random
+import transaction
+
+def appcall(function, *args, **kw):
+ '''Calls a function passing 'app' as first argument.'''
+ from base import app, close
+ app = app()
+ args = (app,) + args
+ try:
+ return function(*args, **kw)
+ finally:
+ transaction.abort()
+ close(app)
+
+
+def deferToZ2Layer(function):
+ '''
+ decorator assumes following:
+
+ * function only takes one argument: app
+
+ * if app is not passed in, function should be deferred
+
+ deferral queues execution of the function to the setup call of
+ Testing.ZopeTestCase.layer.Zope2Layer
+ '''
+ def wrapped(*args, **kwargs):
+ if args or kwargs.get('app', None):
+ return function(*args, **kwargs)
+ else:
+ import layer
+ def curryAppCall(*args, **kwargs):
+ return appcall(function, *args, **kwargs)
+ return layer._z2_callables.append((curryAppCall, args, kwargs))
+ return wrapped
+
+
+ at deferToZ2Layer
+def setupCoreSessions(app=None):
+ '''Sets up the session_data_manager e.a.'''
+ from Acquisition import aq_base
+ commit = 0
+
+ if not hasattr(app, 'temp_folder'):
+ from Products.TemporaryFolder.TemporaryFolder import MountedTemporaryFolder
+ tf = MountedTemporaryFolder('temp_folder', 'Temporary Folder')
+ app._setObject('temp_folder', tf)
+ commit = 1
+
+ if not hasattr(aq_base(app.temp_folder), 'session_data'):
+ from Products.Transience.Transience import TransientObjectContainer
+ toc = TransientObjectContainer('session_data',
+ 'Session Data Container',
+ timeout_mins=3,
+ limit=100)
+ app.temp_folder._setObject('session_data', toc)
+ commit = 1
+
+ if not hasattr(app, 'browser_id_manager'):
+ from Products.Sessions.BrowserIdManager import BrowserIdManager
+ bid = BrowserIdManager('browser_id_manager',
+ 'Browser Id Manager')
+ app._setObject('browser_id_manager', bid)
+ commit = 1
+
+ if not hasattr(app, 'session_data_manager'):
+ from Products.Sessions.SessionDataManager import SessionDataManager
+ sdm = SessionDataManager('session_data_manager',
+ title='Session Data Manager',
+ path='/temp_folder/session_data',
+ requestName='SESSION')
+ app._setObject('session_data_manager', sdm)
+ commit = 1
+
+ if commit:
+ transaction.commit()
+
+ at deferToZ2Layer
+def setupZGlobals(app=None):
+ '''Sets up the ZGlobals BTree required by ZClasses.'''
+
+ root = app._p_jar.root()
+ if not root.has_key('ZGlobals'):
+ from BTrees.OOBTree import OOBTree
+ root['ZGlobals'] = OOBTree()
+ transaction.commit()
+
+ at deferToZ2Layer
+def setupSiteErrorLog(app=None):
+ '''Sets up the error_log object required by ZPublisher.'''
+
+ if not hasattr(app, 'error_log'):
+ try:
+ from Products.SiteErrorLog.SiteErrorLog import SiteErrorLog
+ except ImportError:
+ pass
+ else:
+ app._setObject('error_log', SiteErrorLog())
+ transaction.commit()
+
+
+def importObjectFromFile(container, filename, quiet=0):
+ '''Imports an object from a (.zexp) file into the given container.'''
+ from ZopeLite import _print, _patched
+ quiet = quiet or not _patched
+ start = time.time()
+ if not quiet: _print("Importing %s ... " % os.path.basename(filename))
+ container._importObjectFromFile(filename, verify=0)
+ transaction.commit()
+ if not quiet: _print('done (%.3fs)\n' % (time.time() - start))
+
+
+_Z2HOST = None
+_Z2PORT = None
+
+def startZServer(number_of_threads=1, log=None):
+ '''Starts an HTTP ZServer thread.'''
+ global _Z2HOST, _Z2PORT
+ if _Z2HOST is None:
+ _Z2HOST = '127.0.0.1'
+ _Z2PORT = random.choice(range(55000, 55500))
+ from ZServer import setNumberOfThreads
+ setNumberOfThreads(number_of_threads)
+ from threadutils import QuietThread, zserverRunner
+ t = QuietThread(target=zserverRunner, args=(_Z2HOST, _Z2PORT, log))
+ t.setDaemon(1)
+ t.start()
+ time.sleep(0.1) # Sandor Palfy
+ return _Z2HOST, _Z2PORT
+
+
+def makerequest(app, stdout=sys.stdout):
+ '''Wraps the app into a fresh REQUEST.'''
+ from ZPublisher.BaseRequest import RequestContainer
+ from ZPublisher.Request import Request
+ from ZPublisher.Response import Response
+ response = Response(stdout=stdout)
+ environ = {}
+ environ['SERVER_NAME'] = _Z2HOST or 'nohost'
+ environ['SERVER_PORT'] = '%d' % (_Z2PORT or 80)
+ environ['REQUEST_METHOD'] = 'GET'
+ request = Request(sys.stdin, environ, response)
+ request._steps = ['noobject'] # Fake a published object
+ request['ACTUAL_URL'] = request.get('URL') # Zope 2.7.4
+
+ # set Zope3-style default skin so that the request is usable for
+ # Zope3-style view look-ups
+ from zope.app.publication.browser import setDefaultSkin
+ setDefaultSkin(request)
+
+ return app.__of__(RequestContainer(REQUEST=request))
+
+
+
+
+
+def makelist(arg):
+ '''Turns arg into a list. Where arg may be
+ list, tuple, or string.
+ '''
+ if type(arg) == type([]):
+ return arg
+ if type(arg) == type(()):
+ return list(arg)
+ if type(arg) == type(''):
+ return filter(None, [arg])
+ raise ValueError('Argument must be list, tuple, or string')
+
+def hasProduct(name):
+ '''Checks if a product can be found along Products.__path__'''
+ from OFS.Application import get_products
+ return name in [n[1] for n in get_products()]
+
+def _print(msg):
+ '''Writes 'msg' to stderr and flushes the stream.'''
+ sys.stderr.write(msg)
+ sys.stderr.flush()
+
+def setDebugMode(mode):
+ '''
+ Allows manual setting of Five's inspection of debug mode to allow for
+ zcml to fail meaningfully
+ '''
+ import Products.Five.fiveconfigure as fc
+ fc.debug_mode=mode
+
+def setAllLayers(suite, newlayer):
+ '''
+ helper function that iterates through all the subsuites in a
+ suite, resetting their layer to @param layer: the desired layer
+ class
+ '''
+ [setattr(subsuite, 'layer', newlayer) for subsuite in suite]
+ return suite
+
+__all__ = [
+ 'setupCoreSessions',
+ 'setupSiteErrorLog',
+ 'setupZGlobals',
+ 'startZServer',
+ 'importObjectFromFile',
+ 'appcall',
+ 'makerequest',
+ 'makelist',
+ 'hasProduct',
+ 'setDebugMode',
+ '_print',
+ 'setAllLayers'
+]
+
Added: Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/zopedoctest/FunctionalDocTest.txt
===================================================================
--- Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/zopedoctest/FunctionalDocTest.txt 2006-08-19 02:33:50 UTC (rev 69678)
+++ Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/zopedoctest/FunctionalDocTest.txt 2006-08-19 02:36:49 UTC (rev 69679)
@@ -0,0 +1,182 @@
+====================
+Functional doc tests
+====================
+
+Doctests are a way to write tests while documenting the thing that is
+tested at the same time. As an example, this file both documents
+functional doc tests *and* tests them.
+
+Doctests look like regular interactive interpreter sessions. That
+makes them very easy to create. Doctests can either occur in an
+object's or method's docstring or in a separate file. Use either
+``DocTestSuite`` or ``DocFileSuite`` in these cases.
+
+
+Creating functional doctests
+----------------------------
+
+Creating functional doctests is just as easy. Obviously, you cannot
+simply use an interpreter shell for the initial test creation.
+Instead, you can use the `tcpwatch` program to record browser sessions
+and turn them into tests:
+
+1. Start out with a clean ZODB database.
+
+ - Create a folder named `test_folder_1_` in the root folder.
+
+ - Create a user in the root user folder called `test_user_1_` with
+ the password `secret`.
+
+ - Create a role `test_role_1_` and grant the role to the test
+ user. Grant the permissions 'Access contents information' and
+ 'View' to the role.
+
+2. Install tcpwatch. You can get a recent version from Zope CVS:
+ http://cvs.zope.org/Packages/tcpwatch/
+
+3. Create a temporary directory to record tcpwatch output.
+
+4. Run tcpwatch using:
+ tcpwatch.py -L 8081:8080 -s -r tmpdir
+ (the ports are the listening port and forwarded-to port; the
+ second port must match the Zope configuration)
+
+5. In a browser, connect to the listening port and do whatever needs
+ to be recorded.
+
+6. Shut down tcpwatch.
+
+7. Run the script at Zope/lib/python/Testing/ZopeTestCase/doctest/dochttp.py
+ python2.3 dochttp.py tmpdir > .../mytest.txt
+
+8. Edit the generated text file to add explanations and elide
+ uninteresting portions of the output.
+
+9. In a functional test module (usually ftests.py), import
+ ``FunctionalDocFileSuite`` and instantiate it, passing the name of the
+ text file containing the test. For example:
+
+ import os, sys
+ if __name__ == '__main__':
+ execfile(os.path.join(sys.path[0], 'framework.py'))
+
+ from unittest import TestSuite
+ from Testing.ZopeTestCase import FunctionalDocFileSuite
+
+ def test_suite():
+ return TestSuite((
+ FunctionalDocFileSuite('FunctionalDocTest.txt'),
+ ))
+
+ if __name__ == '__main__':
+ framework()
+
+
+Examples
+--------
+
+Test Publish Document
+
+ >>> print http(r"""
+ ... GET /test_folder_1_/index_html HTTP/1.1
+ ... """, handle_errors=False)
+ HTTP/1.1 200 OK
+ Content-Length: 5
+ Content-Type: text/plain; charset=...
+ <BLANKLINE>
+ index
+
+Test Publish Script
+
+ >>> print http(r"""
+ ... GET /test_folder_1_/script HTTP/1.1
+ ... """, handle_errors=False)
+ HTTP/1.1 200 OK
+ Content-Length: 1
+ Content-Type: text/plain; charset=...
+ <BLANKLINE>
+ 1
+
+Test Publish Script with Argument
+
+ >>> print http(r"""
+ ... GET /test_folder_1_/script?a:int=2 HTTP/1.1
+ ... """, handle_errors=False)
+ HTTP/1.1 200 OK
+ Content-Length: 1
+ Content-Type: text/plain; charset=...
+ <BLANKLINE>
+ 3
+
+Test Server Error
+
+ >>> print http(r"""
+ ... GET /test_folder_1_/script?a=2 HTTP/1.1
+ ... """, handle_errors=True)
+ HTTP/1.1 500 Internal Server Error
+ ...Content-Type: text/html...TypeError...
+
+Test Unauthorized
+
+ >>> self.folder.index_html.manage_permission('View', ['Owner'])
+ >>> print http(r"""
+ ... GET /test_folder_1_/index_html HTTP/1.1
+ ... """, handle_errors=True)
+ HTTP/1.1 401 Unauthorized
+ ...
+ Www-Authenticate: basic realm=...
+
+Test Basic Authentication
+
+ >>> from AccessControl.Permissions import manage_properties
+ >>> self.setPermissions([manage_properties])
+
+ >>> print http(r"""
+ ... GET /test_folder_1_/index_html/change_title?title=Foo HTTP/1.1
+ ... Authorization: Basic %s
+ ... """ % user_auth, handle_errors=False)
+ HTTP/1.1 200 OK
+ Content-Length: 0
+ ...
+
+ >>> self.folder.index_html.title_or_id()
+ 'Foo'
+
+Test passing in non-base64-encoded login/pass
+
+ >>> from Testing.ZopeTestCase import user_name, user_password
+ >>> print http(r"""
+ ... GET /test_folder_1_/index_html/change_title?title=Baz HTTP/1.1
+ ... Authorization: Basic %s:%s
+ ... """ % (user_name, user_password), handle_errors=False)
+ HTTP/1.1 200 OK
+ Content-Length: 0
+ ...
+
+ >>> self.folder.index_html.title_or_id()
+ 'Baz'
+
+Test setting cookies
+
+ >>> print http(r"""
+ ... GET /test_folder_1_/index_html/set_cookie HTTP/1.1
+ ... """, handle_errors=False)
+ HTTP/1.1 200 OK
+ Content-Length: 0
+ ...
+ Set-Cookie: cookie_test="OK"
+ <BLANKLINE>
+
+Test reading cookies
+
+ >>> print http(r"""
+ ... GET /test_folder_1_/index_html/show_cookies HTTP/1.1
+ ... Cookie: foo=bar; baz="oki doki"
+ ... """, handle_errors=False)
+ HTTP/1.1 200 OK
+ Content-Length: 23
+ Content-Type: text/plain; charset=...
+ <BLANKLINE>
+ foo: bar
+ baz: oki doki
+ <BLANKLINE>
Added: Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/zopedoctest/README.txt
===================================================================
--- Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/zopedoctest/README.txt 2006-08-19 02:33:50 UTC (rev 69678)
+++ Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/zopedoctest/README.txt 2006-08-19 02:36:49 UTC (rev 69679)
@@ -0,0 +1,10 @@
+Doc test support for ZopeTestCase
+=================================
+
+Backport of functional doc tests from Zope 3 by
+Sidnei da Silva. See 'FunctionalDocTest.txt' for
+documentation.
+
+You can learn more about doc tests here:
+http://docs.python.org/lib/module-doctest.html
+
Added: Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/zopedoctest/WarningsTest.txt
===================================================================
--- Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/zopedoctest/WarningsTest.txt 2006-08-19 02:33:50 UTC (rev 69678)
+++ Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/zopedoctest/WarningsTest.txt 2006-08-19 02:36:49 UTC (rev 69679)
@@ -0,0 +1,27 @@
+Dummy Test
+==========
+
+This dummy test is used to verify that passing in a ``test_class``
+that doesn't subclass ``ZopeTestCase.Functional`` still works but
+issues a warning.
+
+ >>> from Testing import ZopeTestCase as zopetest
+ >>> hook = zopetest.WarningsHook()
+ >>> hook.install()
+ >>> suite = zopetest.FunctionalDocFileSuite('WarningsTest.txt',
+ ... package=zopetest.zopedoctest,
+ ... test_class=zopetest.ZopeTestCase)
+
+ >>> len(hook.warnings)
+ 1
+
+ >>> message, category, filename, lineno = hook.warnings[0]
+ >>> message
+ "The test_class you are using doesn't subclass from ZopeTestCase.Functional. Please fix that."
+ >>> category.__name__
+ 'UserWarning'
+
+We have to uninstall the hook so that other warnings don't get lost.
+
+ >>> hook.uninstall()
+
Added: Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/zopedoctest/ZopeDocTest.txt
===================================================================
--- Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/zopedoctest/ZopeDocTest.txt 2006-08-19 02:33:50 UTC (rev 69678)
+++ Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/zopedoctest/ZopeDocTest.txt 2006-08-19 02:36:49 UTC (rev 69679)
@@ -0,0 +1,95 @@
+==============
+Zope doc tests
+==============
+
+Doctests are a way to write tests while documenting the thing that is
+tested at the same time. As an example, this file both documents
+Zope doc tests *and* tests them.
+
+Doctests look like regular interactive interpreter sessions. That
+makes them very easy to create. Doctests can either occur in an
+object's or method's docstring or in a separate file. Use either
+``DocTestSuite`` or ``DocFileSuite`` in these cases.
+
+
+Creating Zope doc tests
+-----------------------
+
+Creating doc tests for Zope is easy. While we cannot simply use an
+interpeter shell to write our tests, we can reuse the ZopeTestCase
+infrastructure to set up the necessary environment.
+
+1. Create a text file, just like this one, containing prose
+ documentation interspersed with doctest ``Examples``.
+
+2. In a test module import ``ZopeDocFileSuite`` and instantiate it,
+ passing the name of the text file containing the tests.
+ For example:
+
+ import os, sys
+ if __name__ == '__main__':
+ execfile(os.path.join(sys.path[0], 'framework.py'))
+
+ from unittest import TestSuite
+ from Testing.ZopeTestCase import ZopeDocFileSuite
+
+ def test_suite():
+ return TestSuite((
+ ZopeDocFileSuite('ZopeDocTest.txt'),
+ ))
+
+ if __name__ == '__main__':
+ framework()
+
+
+Examples
+--------
+
+Here we are going to demonstrate that everything we know about
+ZopeTestCase is still true for doc tests. In particular, the default
+fixture is set up for doc tests just like for unit tests.
+
+ >>> from Testing.ZopeTestCase import folder_name, user_name
+ >>> from AccessControl import getSecurityManager
+
+There should be a folder:
+
+ >>> folder_name in self.app.objectIds()
+ True
+
+Containing a user folder:
+
+ >>> 'acl_users' in self.folder.objectIds()
+ True
+
+Containing the default user:
+
+ >>> user = self.folder.acl_users.getUserById(user_name)
+ >>> user is None
+ False
+
+The default user should be logged in:
+
+ >>> getSecurityManager().getUser().getId() == user_name
+ True
+
+The custom setUp method should have been run as well. See
+testZopeDocTest.py for its definition.
+
+ >>> 'object' in self.folder.objectIds()
+ True
+
+Now let's manipulate our test objects a bit:
+
+ >>> ob = self.folder.object
+ >>> print ob.title_or_id()
+ object
+
+ >>> ob.manage_changeProperties(title='Foo')
+ >>> print ob.title_or_id()
+ Foo
+
+ >>> self.folder.manage_delObjects('object')
+ >>> 'object' in self.folder.objectIds()
+ False
+
Added: Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/zopedoctest/__init__.py
===================================================================
--- Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/zopedoctest/__init__.py 2006-08-19 02:33:50 UTC (rev 69678)
+++ Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/zopedoctest/__init__.py 2006-08-19 02:36:49 UTC (rev 69679)
@@ -0,0 +1,20 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+"""ZopeTestCase doctest support
+
+$Id: __init__.py 66218M 2006-08-01 19:42:16Z (local) $
+"""
+
+from zope.testing.doctest import *
+from zope.testing.doctest import _normalize_module
+from functional import *
Added: Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/zopedoctest/framework.py
===================================================================
--- Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/zopedoctest/framework.py 2006-08-19 02:33:50 UTC (rev 69678)
+++ Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/zopedoctest/framework.py 2006-08-19 02:36:49 UTC (rev 69679)
@@ -0,0 +1,116 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+"""ZopeTestCase framework
+
+COPY THIS FILE TO YOUR 'tests' DIRECTORY.
+
+This version of framework.py will use the SOFTWARE_HOME
+environment variable to locate Zope and the Testing package.
+
+If the tests are run in an INSTANCE_HOME installation of Zope,
+Products.__path__ and sys.path with be adjusted to include the
+instance's Products and lib/python directories respectively.
+
+If you explicitly set INSTANCE_HOME prior to running the tests,
+auto-detection is disabled and the specified path will be used
+instead.
+
+If the 'tests' directory contains a custom_zodb.py file, INSTANCE_HOME
+will be adjusted to use it.
+
+If you set the ZEO_INSTANCE_HOME environment variable a ZEO setup
+is assumed, and you can attach to a running ZEO server (via the
+instance's custom_zodb.py).
+
+The following code should be at the top of every test module:
+
+ import os, sys
+ if __name__ == '__main__':
+ execfile(os.path.join(sys.path[0], 'framework.py'))
+
+...and the following at the bottom:
+
+ if __name__ == '__main__':
+ framework()
+
+$Id: framework.py 40219 2005-11-18 15:05:47Z andreasjung $
+"""
+
+__version__ = '0.2.4'
+
+# Save start state
+#
+__SOFTWARE_HOME = os.environ.get('SOFTWARE_HOME', '')
+__INSTANCE_HOME = os.environ.get('INSTANCE_HOME', '')
+
+if __SOFTWARE_HOME.endswith(os.sep):
+ __SOFTWARE_HOME = os.path.dirname(__SOFTWARE_HOME)
+
+if __INSTANCE_HOME.endswith(os.sep):
+ __INSTANCE_HOME = os.path.dirname(__INSTANCE_HOME)
+
+# Find and import the Testing package
+#
+if not sys.modules.has_key('Testing'):
+ p0 = sys.path[0]
+ if p0 and __name__ == '__main__':
+ os.chdir(p0)
+ p0 = ''
+ s = __SOFTWARE_HOME
+ p = d = s and s or os.getcwd()
+ while d:
+ if os.path.isdir(os.path.join(p, 'Testing')):
+ zope_home = os.path.dirname(os.path.dirname(p))
+ sys.path[:1] = [p0, p, zope_home]
+ break
+ p, d = s and ('','') or os.path.split(p)
+ else:
+ print 'Unable to locate Testing package.',
+ print 'You might need to set SOFTWARE_HOME.'
+ sys.exit(1)
+
+import Testing, unittest
+execfile(os.path.join(os.path.dirname(Testing.__file__), 'common.py'))
+
+# Include ZopeTestCase support
+#
+if 1: # Create a new scope
+
+ p = os.path.join(os.path.dirname(Testing.__file__), 'ZopeTestCase')
+
+ if not os.path.isdir(p):
+ print 'Unable to locate ZopeTestCase package.',
+ print 'You might need to install ZopeTestCase.'
+ sys.exit(1)
+
+ ztc_common = 'ztc_common.py'
+ ztc_common_global = os.path.join(p, ztc_common)
+
+ f = 0
+ if os.path.exists(ztc_common_global):
+ execfile(ztc_common_global)
+ f = 1
+ if os.path.exists(ztc_common):
+ execfile(ztc_common)
+ f = 1
+
+ if not f:
+ print 'Unable to locate %s.' % ztc_common
+ sys.exit(1)
+
+# Debug
+#
+print 'SOFTWARE_HOME: %s' % os.environ.get('SOFTWARE_HOME', 'Not set')
+print 'INSTANCE_HOME: %s' % os.environ.get('INSTANCE_HOME', 'Not set')
+sys.stdout.flush()
+
Added: Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/zopedoctest/functional.py
===================================================================
--- Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/zopedoctest/functional.py 2006-08-19 02:33:50 UTC (rev 69678)
+++ Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/zopedoctest/functional.py 2006-08-19 02:36:49 UTC (rev 69679)
@@ -0,0 +1,341 @@
+##############################################################################
+#
+# Copyright (c) 2005 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 (functional) doc tests
+
+$Id: functional.py 66137 2006-03-23 18:34:22Z shh $
+"""
+
+import sys, re, base64
+import warnings
+import transaction
+
+from zope.testing import doctest
+
+from Testing.ZopeTestCase import ZopeTestCase
+from Testing.ZopeTestCase import FunctionalTestCase
+from Testing.ZopeTestCase import Functional
+from Testing.ZopeTestCase import folder_name
+from Testing.ZopeTestCase import user_name
+from Testing.ZopeTestCase import user_password
+from Testing.ZopeTestCase import user_role
+from Testing.ZopeTestCase import standard_permissions
+from Testing.ZopeTestCase.sandbox import AppZapper
+from Testing.ZopeTestCase.functional import ResponseWrapper
+
+
+class HTTPHeaderOutput:
+
+ # zope.interface.implements(zope.server.interfaces.IHeaderOutput)
+
+ def __init__(self, protocol, omit):
+ self.headers = {}
+ self.headersl = []
+ self.protocol = protocol
+ self.omit = omit
+
+ def setResponseStatus(self, status, reason):
+ self.status, self.reason = status, reason
+
+ def setResponseHeaders(self, mapping):
+ self.headers.update(dict(
+ [('-'.join([s.capitalize() for s in name.split('-')]), v)
+ for name, v in mapping.items()
+ if name.lower() not in self.omit]
+ ))
+
+ def appendResponseHeaders(self, lst):
+ headers = [split_header(header) for header in lst]
+ self.headersl.extend(
+ [('-'.join([s.capitalize() for s in name.split('-')]), v)
+ for name, v in headers
+ if name.lower() not in self.omit]
+ )
+
+ def __str__(self):
+ out = ["%s: %s" % header for header in self.headers.items()]
+ out.extend(["%s: %s" % header for header in self.headersl])
+ out.sort()
+ out.insert(0, "%s %s %s" % (self.protocol, self.status, self.reason))
+ return '\n'.join(out)
+
+
+class DocResponseWrapper(ResponseWrapper):
+ """Response Wrapper for use in doctests
+ """
+
+ def __init__(self, response, outstream, path, header_output):
+ ResponseWrapper.__init__(self, response, outstream, path)
+ self.header_output = header_output
+
+ def __str__(self):
+ body = self.getBody()
+ if body:
+ return "%s\n\n%s" % (self.header_output, body)
+ return "%s\n" % (self.header_output)
+
+
+headerre = re.compile('(\S+): (.+)$')
+def split_header(header):
+ return headerre.match(header).group(1, 2)
+
+basicre = re.compile('Basic (.+)?:(.+)?$')
+def auth_header(header):
+ match = basicre.match(header)
+ if match:
+ import base64
+ u, p = match.group(1, 2)
+ if u is None:
+ u = ''
+ if p is None:
+ p = ''
+ auth = base64.encodestring('%s:%s' % (u, p))
+ return 'Basic %s' % auth[:-1]
+ return header
+
+
+def getRootFolder():
+ return AppZapper().app()
+
+def sync():
+ getRootFolder()._p_jar.sync()
+
+
+def http(request_string, handle_errors=True):
+ """Execute an HTTP request string via the publisher
+
+ This is used for HTTP doc tests.
+ """
+ import urllib
+ import rfc822
+ from cStringIO import StringIO
+ from ZPublisher.Response import Response
+ from ZPublisher.Test import publish_module
+ from AccessControl.SecurityManagement import getSecurityManager
+ from AccessControl.SecurityManagement import setSecurityManager
+
+ # Save current Security Manager
+ old_sm = getSecurityManager()
+
+ # Commit work done by previous python code.
+ transaction.commit()
+
+ # Discard leading white space to make call layout simpler
+ request_string = request_string.lstrip()
+
+ # split off and parse the command line
+ l = request_string.find('\n')
+ command_line = request_string[:l].rstrip()
+ request_string = request_string[l+1:]
+ method, path, protocol = command_line.split()
+ path = urllib.unquote(path)
+
+ instream = StringIO(request_string)
+
+ env = {"HTTP_HOST": 'localhost',
+ "HTTP_REFERER": 'localhost',
+ "REQUEST_METHOD": method,
+ "SERVER_PROTOCOL": protocol,
+ }
+
+ p = path.split('?')
+ if len(p) == 1:
+ env['PATH_INFO'] = p[0]
+ elif len(p) == 2:
+ [env['PATH_INFO'], env['QUERY_STRING']] = p
+ else:
+ raise TypeError, ''
+
+ header_output = HTTPHeaderOutput(
+ protocol, ('x-content-type-warning', 'x-powered-by',
+ 'bobo-exception-type', 'bobo-exception-file',
+ 'bobo-exception-value', 'bobo-exception-line'))
+
+ headers = [split_header(header)
+ for header in rfc822.Message(instream).headers]
+ for name, value in headers:
+ name = ('_'.join(name.upper().split('-')))
+ if name not in ('CONTENT_TYPE', 'CONTENT_LENGTH'):
+ name = 'HTTP_' + name
+ env[name] = value.rstrip()
+
+ if env.has_key('HTTP_AUTHORIZATION'):
+ env['HTTP_AUTHORIZATION'] = auth_header(env['HTTP_AUTHORIZATION'])
+
+ outstream = StringIO()
+ response = Response(stdout=outstream, stderr=sys.stderr)
+
+ publish_module('Zope2',
+ response=response,
+ stdin=instream,
+ environ=env,
+ debug=not handle_errors,
+ )
+ header_output.setResponseStatus(response.getStatus(), response.errmsg)
+ header_output.setResponseHeaders(response.headers)
+ header_output.appendResponseHeaders(response._cookie_list())
+ header_output.appendResponseHeaders(response.accumulated_headers.splitlines())
+
+ # Restore previous security manager, which may have been changed
+ # by calling the publish method above
+ setSecurityManager(old_sm)
+
+ # Sync connection
+ sync()
+
+ return DocResponseWrapper(response, outstream, path, header_output)
+
+
+class ZopeSuiteFactory:
+
+ def __init__(self, *args, **kw):
+ self._args = args
+ self._kw = kw
+ self.setup_globs()
+ self.setup_test_class()
+ self.setup_optionflags()
+
+ def doctestsuite(self):
+ return doctest.DocTestSuite(*self._args, **self._kw)
+
+ def docfilesuite(self):
+ return doctest.DocFileSuite(*self._args, **self._kw)
+
+ def setup_globs(self):
+ globs = self._kw.setdefault('globs', {})
+ globs['folder_name'] = folder_name
+ globs['user_name'] = user_name
+ globs['user_password'] = user_password
+ globs['user_role'] = user_role
+ globs['standard_permissions'] = standard_permissions
+
+ def setup_test_class(self):
+ test_class = self._kw.get('test_class', ZopeTestCase)
+
+ if 'test_class' in self._kw:
+ del self._kw['test_class']
+
+ # If the test_class does not have a runTest method, we add
+ # a dummy attribute so that TestCase construction works.
+ if not hasattr(test_class, 'runTest'):
+ setattr(test_class, 'runTest', None)
+
+ # Create a TestCase instance which will be used to execute
+ # the setUp and tearDown methods, as well as be passed into
+ # the test globals as 'self'.
+ test_instance = test_class()
+
+ kwsetUp = self._kw.get('setUp')
+ def setUp(test):
+ test_instance.setUp()
+ test.globs['test'] = test
+ test.globs['self'] = test_instance
+ if hasattr(test_instance, 'app'):
+ test.globs['app'] = test_instance.app
+ if hasattr(test_instance, 'folder'):
+ test.globs['folder'] = test_instance.folder
+ if hasattr(test_instance, 'portal'):
+ test.globs['portal'] = test_instance.portal
+ test.globs['portal_name'] = test_instance.portal.getId()
+ if kwsetUp is not None:
+ kwsetUp(test_instance)
+
+ self._kw['setUp'] = setUp
+
+ kwtearDown = self._kw.get('tearDown')
+ def tearDown(test):
+ if kwtearDown is not None:
+ kwtearDown(test_instance)
+ test_instance.tearDown()
+
+ self._kw['tearDown'] = tearDown
+
+ def setup_optionflags(self):
+ if 'optionflags' not in self._kw:
+ self._kw['optionflags'] = (doctest.ELLIPSIS
+ | doctest.NORMALIZE_WHITESPACE)
+
+
+class FunctionalSuiteFactory(ZopeSuiteFactory):
+
+ def setup_globs(self):
+ ZopeSuiteFactory.setup_globs(self)
+ globs = self._kw.setdefault('globs', {})
+ globs['http'] = http
+ globs['getRootFolder'] = getRootFolder
+ globs['sync'] = sync
+ globs['user_auth'] = base64.encodestring('%s:%s' % (user_name, user_password))
+
+ def setup_test_class(self):
+ test_class = self._kw.get('test_class', FunctionalTestCase)
+
+ # If the passed-in test_class doesn't subclass Functional,
+ # we mix it in for you, but we will issue a warning.
+ if not issubclass(test_class, Functional):
+ name = test_class.__name__
+ warnings.warn(("The test_class you are using doesn't "
+ "subclass from ZopeTestCase.Functional. "
+ "Please fix that."), UserWarning, 2)
+ if not 'Functional' in name:
+ name = 'Functional%s' % name
+ test_class = type(name, (Functional, test_class), {})
+
+ self._kw['test_class'] = test_class
+ ZopeSuiteFactory.setup_test_class(self)
+
+ def setup_optionflags(self):
+ if 'optionflags' not in self._kw:
+ self._kw['optionflags'] = (doctest.ELLIPSIS
+ | doctest.REPORT_NDIFF
+ | doctest.NORMALIZE_WHITESPACE)
+
+from Testing.ZopeTestCase.layer import Zope2Layer
+
+def setlayer(layer):
+ def wrapfactory(factory):
+ def wrapper(*args, **kwargs):
+ suite = factory(*args, **kwargs)
+ suite.layer=layer
+ return suite
+ return wrapper
+ return wrapfactory
+
+ at setlayer(Zope2Layer)
+def ZopeDocTestSuite(module=None, **kw):
+ module = doctest._normalize_module(module)
+ return ZopeSuiteFactory(module, **kw).doctestsuite()
+
+ at setlayer(Zope2Layer)
+def ZopeDocFileSuite(*paths, **kw):
+ if kw.get('module_relative', True):
+ kw['package'] = doctest._normalize_module(kw.get('package'))
+ return ZopeSuiteFactory(*paths, **kw).docfilesuite()
+
+ at setlayer(Zope2Layer)
+def FunctionalDocTestSuite(module=None, **kw):
+ module = doctest._normalize_module(module)
+ return FunctionalSuiteFactory(module, **kw).doctestsuite()
+
+ at setlayer(Zope2Layer)
+def FunctionalDocFileSuite(*paths, **kw):
+ if kw.get('module_relative', True):
+ kw['package'] = doctest._normalize_module(kw.get('package'))
+ return FunctionalSuiteFactory(*paths, **kw).docfilesuite()
+
+
+__all__ = [
+ 'ZopeDocTestSuite',
+ 'ZopeDocFileSuite',
+ 'FunctionalDocTestSuite',
+ 'FunctionalDocFileSuite',
+ ]
+
Added: Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/zopedoctest/testAuthHeaderTest.py
===================================================================
--- Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/zopedoctest/testAuthHeaderTest.py 2006-08-19 02:33:50 UTC (rev 69678)
+++ Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/zopedoctest/testAuthHeaderTest.py 2006-08-19 02:36:49 UTC (rev 69679)
@@ -0,0 +1,61 @@
+##############################################################################
+#
+# Copyright (c) 2005 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 for auth_header
+
+$Id: testAuthHeaderTest.py 40219 2005-11-18 15:05:47Z andreasjung $
+"""
+
+import os, sys
+if __name__ == '__main__':
+ execfile(os.path.join(sys.path[0], 'framework.py'))
+
+from unittest import TestSuite, makeSuite
+from Testing.ZopeTestCase import TestCase
+from Testing.ZopeTestCase import zopedoctest
+
+auth_header = zopedoctest.functional.auth_header
+
+
+class AuthHeaderTestCase(TestCase):
+
+ def test_auth_encoded(self):
+ header = 'Basic Z2xvYmFsbWdyOmdsb2JhbG1ncnB3'
+ self.assertEquals(auth_header(header), header)
+
+ def test_auth_non_encoded(self):
+ header = 'Basic globalmgr:globalmgrpw'
+ expected = 'Basic Z2xvYmFsbWdyOmdsb2JhbG1ncnB3'
+ self.assertEquals(auth_header(header), expected)
+
+ def test_auth_non_encoded_empty(self):
+ header = 'Basic globalmgr:'
+ expected = 'Basic Z2xvYmFsbWdyOg=='
+ self.assertEquals(auth_header(header), expected)
+ header = 'Basic :pass'
+ expected = 'Basic OnBhc3M='
+ self.assertEquals(auth_header(header), expected)
+
+ def test_auth_non_encoded_colon(self):
+ header = 'Basic globalmgr:pass:pass'
+ expected = 'Basic Z2xvYmFsbWdyOnBhc3M6cGFzcw=='
+ self.assertEquals(auth_header(header), expected)
+
+
+def test_suite():
+ return TestSuite((
+ makeSuite(AuthHeaderTestCase),
+ ))
+
+if __name__ == '__main__':
+ framework()
+
Added: Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/zopedoctest/testFunctionalDocTest.py
===================================================================
--- Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/zopedoctest/testFunctionalDocTest.py 2006-08-19 02:33:50 UTC (rev 69678)
+++ Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/zopedoctest/testFunctionalDocTest.py 2006-08-19 02:36:49 UTC (rev 69679)
@@ -0,0 +1,67 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+"""Example functional doctest
+
+$Id: testFunctionalDocTest.py 40959 2005-12-21 15:45:06Z shh $
+"""
+
+import os, sys
+if __name__ == '__main__':
+ execfile(os.path.join(sys.path[0], 'framework.py'))
+
+from unittest import TestSuite
+from Testing.ZopeTestCase import installProduct
+from Testing.ZopeTestCase import FunctionalDocTestSuite
+from Testing.ZopeTestCase import FunctionalDocFileSuite
+
+installProduct('PythonScripts')
+
+
+def setUp(self):
+ '''This method will run after the test_class' setUp.
+
+ >>> print http(r"""
+ ... GET /test_folder_1_/index_html HTTP/1.1
+ ... """)
+ HTTP/1.1 200 OK
+ Content-Length: 5
+ Content-Type: text/plain; charset=...
+ <BLANKLINE>
+ index
+ '''
+ self.folder.addDTMLDocument('index_html', file='index')
+
+ self.folder.manage_addProduct['PythonScripts'].manage_addPythonScript('script')
+ self.folder.script.ZPythonScript_edit(params='a=0', body='return a+1')
+
+ change_title = '''<dtml-call "manage_changeProperties(title=REQUEST.get('title'))">'''
+ self.folder.addDTMLMethod('change_title', file=change_title)
+
+ set_cookie = '''<dtml-call "REQUEST.RESPONSE.setCookie('cookie_test', 'OK')">'''
+ self.folder.addDTMLMethod('set_cookie', file=set_cookie)
+
+ show_cookies = '''<dtml-in "REQUEST.cookies.keys()">
+<dtml-var sequence-item>: <dtml-var "REQUEST.cookies[_['sequence-item']]">
+</dtml-in>'''
+ self.folder.addDTMLMethod('show_cookies', file=show_cookies)
+
+
+def test_suite():
+ return TestSuite((
+ FunctionalDocTestSuite(setUp=setUp),
+ FunctionalDocFileSuite('FunctionalDocTest.txt', setUp=setUp),
+ ))
+
+if __name__ == '__main__':
+ framework()
+
Added: Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/zopedoctest/testWarningsTest.py
===================================================================
--- Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/zopedoctest/testWarningsTest.py 2006-08-19 02:33:50 UTC (rev 69678)
+++ Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/zopedoctest/testWarningsTest.py 2006-08-19 02:36:49 UTC (rev 69679)
@@ -0,0 +1,33 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+"""Example doctest
+
+$Id: testWarningsTest.py 40219 2005-11-18 15:05:47Z andreasjung $
+"""
+
+import os, sys
+if __name__ == '__main__':
+ execfile(os.path.join(sys.path[0], 'framework.py'))
+
+from unittest import TestSuite
+from Testing.ZopeTestCase import ZopeDocFileSuite
+
+
+def test_suite():
+ return TestSuite((
+ ZopeDocFileSuite('WarningsTest.txt'),
+ ))
+
+if __name__ == '__main__':
+ framework()
+
Added: Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/zopedoctest/testZopeDocTest.py
===================================================================
--- Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/zopedoctest/testZopeDocTest.py 2006-08-19 02:33:50 UTC (rev 69678)
+++ Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/zopedoctest/testZopeDocTest.py 2006-08-19 02:36:49 UTC (rev 69679)
@@ -0,0 +1,44 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+"""Example Zope doctest
+
+$Id: testZopeDocTest.py 40219 2005-11-18 15:05:47Z andreasjung $
+"""
+
+import os, sys
+if __name__ == '__main__':
+ execfile(os.path.join(sys.path[0], 'framework.py'))
+
+from unittest import TestSuite
+from Testing.ZopeTestCase import ZopeDocTestSuite
+from Testing.ZopeTestCase import ZopeDocFileSuite
+
+
+def setUp(self):
+ '''This method will run after the test_class' setUp.
+
+ >>> 'object' in folder.objectIds()
+ True
+ '''
+ self.folder.manage_addFolder('object', '')
+
+
+def test_suite():
+ return TestSuite((
+ ZopeDocTestSuite(setUp=setUp),
+ ZopeDocFileSuite('ZopeDocTest.txt', setUp=setUp),
+ ))
+
+if __name__ == '__main__':
+ framework()
+
Added: Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/zopedoctest/tests.py
===================================================================
--- Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/zopedoctest/tests.py 2006-08-19 02:33:50 UTC (rev 69678)
+++ Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/zopedoctest/tests.py 2006-08-19 02:36:49 UTC (rev 69679)
@@ -0,0 +1,15 @@
+import os, sys
+import unittest
+suite = unittest.TestSuite()
+
+def test_suite():
+ names = os.listdir(os.path.dirname(__file__))
+ tests = [x for x in names \
+ if x.startswith('test') and x.endswith('.py') and not x == 'tests.py']
+
+ for test in tests:
+ Testing = __import__("Testing.ZopeTestCase.zopedoctest." + test[:-3])
+ testmodule = getattr(Testing.ZopeTestCase.zopedoctest, test[:-3])
+ if hasattr(testmodule, 'test_suite'):
+ suite.addTest(testmodule.test_suite())
+ return suite
Added: Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/ztc_common.py
===================================================================
--- Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/ztc_common.py 2006-08-19 02:33:50 UTC (rev 69678)
+++ Zope/branches/2.9-layer-support/lib/python/Testing/tmp/ztc-premerge/ztc_common.py 2006-08-19 02:36:49 UTC (rev 69679)
@@ -0,0 +1,188 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+"""ztc_common.py
+
+This file must be called from framework.py like so
+
+ execfile(os.path.join(os.path.dirname(Testing.__file__),
+ 'ZopeTestCase', 'ztc_common.py'))
+
+$Id: ztc_common.py 40820 2005-12-16 18:44:55Z shh $
+"""
+
+# Overwrites the default framework() method to expose the
+# TestRunner parameters and add profiler support.
+#
+def framework(stream=sys.stderr, descriptions=1, verbosity=1):
+ if __name__ != '__main__':
+ return
+
+ if len(sys.argv) > 1:
+ arg = sys.argv[1]
+ if arg in ('profile', 'profile-tests'):
+ os.environ['PROFILE_TESTS'] = '1'
+ elif arg == 'profile-setup':
+ os.environ['PROFILE_SETUP'] = '1'
+ elif arg == 'profile-teardown':
+ os.environ['PROFILE_TEARDOWN'] = '1'
+ else:
+ sys.exit(globals()[arg]() and 1 or 0)
+
+ result = TestRunner(stream, descriptions, verbosity).run(test_suite())
+ from Testing.ZopeTestCase import profiler; profiler.print_stats()
+ sys.exit(len(result.errors) + len(result.failures))
+
+
+# Configures the Zope environment
+#
+class Configurator:
+
+ def __init__(self):
+ '''Sets up the configurator.'''
+ self.cwd = self.realpath(os.getcwd())
+ self.software_home = self.realpath(os.environ.get('SOFTWARE_HOME', ''))
+ self.instance_home = self.realpath(globals()['__INSTANCE_HOME'])
+ self.zeo_instance_home = self.realpath(os.environ.get('ZEO_INSTANCE_HOME', ''))
+ self.zope_config = self.realpath(os.environ.get('ZOPE_CONFIG', ''))
+
+ def run(self):
+ '''Runs the configurator.'''
+ if self.zope_config:
+ # Don't configure anything if people use the ZOPE_CONFIG patch
+ return
+ if self.zeo_instance_home:
+ self.setup_zeo_instance_home()
+ self.setup_logging()
+ else:
+ if self.instance_home:
+ self.setup_instance_home()
+ else:
+ self.detect_and_setup_instance_home()
+ self.setup_logging()
+ self.setup_custom_zodb()
+
+ def setup_zeo_instance_home(self):
+ '''If ZEO_INSTANCE_HOME has been given, assume a ZEO setup and use the
+ instance's custom_zodb.py to connect to a running ZEO server.'''
+ if os.path.isdir(os.path.join(self.zeo_instance_home, 'Products')):
+ if os.path.exists(os.path.join(self.zeo_instance_home, 'custom_zodb.py')):
+ self.add_instance(self.zeo_instance_home)
+ if self.getconfig('testinghome'):
+ self.setconfig(testinghome=self.zeo_instance_home)
+ self.setconfig(instancehome=self.zeo_instance_home)
+ else:
+ os.environ['INSTANCE_HOME'] = INSTANCE_HOME = self.zeo_instance_home
+ self.setconfig(instancehome=self.zeo_instance_home)
+ else:
+ print 'Unable to locate custom_zodb.py in %s.' % self.zeo_instance_home
+ sys.exit(1)
+ else:
+ print 'Unable to locate Products directory in %s.' % self.zeo_instance_home
+ sys.exit(1)
+
+ def setup_instance_home(self):
+ '''If INSTANCE_HOME has been given, add the instance's Products
+ and lib/python directories to the appropriate paths.'''
+ if os.path.isdir(os.path.join(self.instance_home, 'Products')):
+ self.add_instance(self.instance_home)
+ if self.getconfig('testinghome'):
+ self.setconfig(instancehome=self.instance_home)
+ else:
+ print 'Unable to locate Products directory in %s.' % self.instance_home
+ sys.exit(1)
+
+ def detect_and_setup_instance_home(self):
+ '''If INSTANCE_HOME has not been given, try to detect whether we run
+ in an instance home installation by walking up from cwd until we
+ find a 'Products' dir.'''
+ if not self.cwd.startswith(self.software_home):
+ p = d = self.cwd
+ while d:
+ if os.path.isdir(os.path.join(p, 'Products')):
+ self.add_instance(p)
+ if self.getconfig('testinghome'):
+ self.setconfig(instancehome=p)
+ break
+ p, d = os.path.split(p)
+ else:
+ print 'Unable to locate Products directory.',
+ print 'You might need to set INSTANCE_HOME.'
+ sys.exit(1)
+
+ def setup_custom_zodb(self):
+ '''If there is a custom_zodb.py file in the tests dir, use it.
+ Note that the instance has already been set at this point
+ so redirecting INSTANCE_HOME should be safe.'''
+ if os.path.exists(os.path.join(self.cwd, 'custom_zodb.py')):
+ if self.getconfig('testinghome'):
+ self.setconfig(testinghome=self.cwd)
+ else:
+ os.environ['INSTANCE_HOME'] = INSTANCE_HOME = self.cwd
+ self.setconfig(instancehome=self.cwd)
+
+ def setup_logging(self):
+ '''If $INSTANCE_HOME/log.ini exists, load it.'''
+ logini = os.path.join(self.getconfig('instancehome'), 'log.ini')
+ if os.path.exists(logini):
+ import logging.config
+ logging.config.fileConfig(logini)
+
+ def add_instance(self, p):
+ '''Adds an INSTANCE_HOME directory to Products.__path__ and sys.path.'''
+ import Products
+ products = os.path.join(p, 'Products')
+ if os.path.isdir(products) and products not in Products.__path__:
+ Products.__path__.insert(0, products)
+ libpython = os.path.join(p, 'lib', 'python')
+ if os.path.isdir(libpython) and libpython not in sys.path:
+ sys.path.insert(0, libpython)
+
+ def getconfig(self, key):
+ '''Reads a value from Zope configuration.'''
+ try:
+ import App.config
+ except ImportError:
+ pass
+ else:
+ config = App.config.getConfiguration()
+ return getattr(config, key, None)
+
+ def setconfig(self, **kw):
+ '''Updates Zope configuration'''
+ try:
+ import App.config
+ except ImportError:
+ pass
+ else:
+ config = App.config.getConfiguration()
+ for key, value in kw.items():
+ setattr(config, key, value)
+ App.config.setConfiguration(config)
+
+ def realpath(self, path):
+ try:
+ from os.path import realpath
+ except ImportError:
+ try:
+ from App.Common import realpath
+ except ImportError:
+ realpath = os.path.abspath
+ if not path:
+ return path
+ return realpath(path)
+
+
+if __name__ == '__main__':
+ Configurator().run()
+ del Configurator
+
More information about the Zope-Checkins
mailing list