summaryrefslogtreecommitdiff
path: root/repoze/bfg/testing.py
diff options
context:
space:
mode:
authorChris McDonough <chrism@agendaless.com>2009-10-15 15:44:33 +0000
committerChris McDonough <chrism@agendaless.com>2009-10-15 15:44:33 +0000
commit17b8bc69b783be4b81a6c42818c6227845b16683 (patch)
treefa481f95e2508b6cf57185cec3e687372fa8ad18 /repoze/bfg/testing.py
parent083422c0c66c1aa53f9d96c6fd185e238bc51708 (diff)
downloadpyramid-17b8bc69b783be4b81a6c42818c6227845b16683.tar.gz
pyramid-17b8bc69b783be4b81a6c42818c6227845b16683.tar.bz2
pyramid-17b8bc69b783be4b81a6c42818c6227845b16683.zip
Features
-------- - Add ``setUp`` and ``tearDown`` functions to the ``repoze.bfg.testing`` module. Using ``setUp`` in a test setup and ``tearDown`` in a test teardown is now the recommended way to do component registry setup and teardown. Previously, it was recommended that a single function named ``repoze.bfg.testing.cleanUp`` be called in both the test setup and tear down. ``repoze.bfg.testing.cleanUp`` still exists (and will exist "forever" due to its widespread use); it is now just an alias for ``repoze.bfg.testing.setUp`` and is nominally deprecated. - The BFG component registry is now available in view and event subscriber code as an attribute of the request ie. ``request.registry``. This fact is currently undocumented except for this note, because BFG developers never need to interact with the registry directly anywhere else. - The BFG component registry now inherits from ``dict``, meaning that it can optionally be used as a simple dictionary. *Component* registrations performed against it via e.g. ``registerUtility``, ``registerAdapter``, and similar API methods are kept in a completely separate namespace than its dict members, so using the its component API methods won't effect the keys and values in the dictionary namespace. Likewise, though the component registry "happens to be" a dictionary, use of mutating dictionary methods such as ``__setitem__`` will have no influence on any component registrations made against it. In other words, the registry object you obtain via e.g. ``repoze.bfg.threadlocal.get_current_registry`` or ``request.registry`` happens to be both a component registry and a dictionary, but using its component-registry API won't impact data added to it via its dictionary API and vice versa. This is a forward compatibility move based on the goals of "marco". Documentation ------------- - Various tutorial test modules updated to use ``repoze.bfg.testing.setUp`` and ``repoze.bfg.testing.tearDown`` methods in order to encourage this as best practice going forward. Backwards Incompatibilities --------------------------- - Importing ``getSiteManager`` and ``get_registry`` from ``repoze.bfg.registry`` is no longer supported. These imports were deprecated in repoze.bfg 1.0. Import of ``getSiteManager`` should be done as ``from zope.component import getSiteManager``. Import of ``get_registry`` should be done as ``from repoze.bfg.threadlocal import get_current_registry``. This was done to prevent a circular import dependency. - Code bases which alternately invoke both ``zope.testing.cleanup.cleanUp`` and ``repoze.bfg.testing.cleanUp`` (treating them equivalently, using them interchangeably) in the setUp/tearDown of unit tests will begin to experience test failures due to lack of test isolation. The "right" mechanism is ``repoze.bfg.testing.cleanUp`` (or the combination of ``repoze.bfg.testing.setUp`` and ``repoze.bfg.testing.tearDown``). but a good number of legacy codebases will use ``zope.testing.cleanup.cleanUp`` instead. We support ``zope.testing.cleanup.cleanUp`` but not in combination with ``repoze.bfg.testing.cleanUp`` in the same codebase. You should use one or the other test cleanup function in a single codebase, but not both. Internal -------- - Created new ``repoze.bfg.configuration`` module which assumes responsibilities previously held by the ``repoze.bfg.registry`` and ``repoze.bfg.router`` modules (avoid a circular import dependency). - The result of the ``zope.component.getSiteManager`` function in unit tests set up with ``repoze.bfg.testing.cleanUp`` or ``repoze.bfg.testing.setUp`` will be an instance of ``repoze.bfg.registry.Registry`` instead of the global ``zope.component.globalregistry.base`` registry. This also means that the threadlocal ZCA API functions such as ``getAdapter`` and ``getUtility`` as well as internal BFG machinery (such as ``model_url`` and ``route_url``) will consult this registry within unit tests. This is a forward compatibility move based on the goals of "marco". - Removed ``repoze.bfg.testing.addCleanUp`` function and associated module-scope globals. This was never an API.
Diffstat (limited to 'repoze/bfg/testing.py')
-rw-r--r--repoze/bfg/testing.py82
1 files changed, 48 insertions, 34 deletions
diff --git a/repoze/bfg/testing.py b/repoze/bfg/testing.py
index 25a178f66..60a52aa66 100644
--- a/repoze/bfg/testing.py
+++ b/repoze/bfg/testing.py
@@ -1,12 +1,15 @@
import copy
+from zope.configuration.xmlconfig import _clearContext
+from zope.component import getSiteManager
from zope.deprecation import deprecated
-
from zope.interface import implements
from zope.interface import Interface
from repoze.bfg.interfaces import IRequest
+from repoze.bfg.registry import Registry
+
_marker = object()
def registerDummySecurityPolicy(userid=None, groupids=(), permissive=True):
@@ -171,8 +174,8 @@ def registerUtility(impl, iface=Interface, name=''):
<http://www.muthukadan.net/docs/zca.html>`_ for more information
about ZCA utilities."""
import zope.component
- gsm = zope.component.getGlobalSiteManager()
- gsm.registerUtility(impl, iface, name=name)
+ sm = zope.component.getSiteManager()
+ sm.registerUtility(impl, iface, name=name)
return impl
def registerAdapter(impl, for_=Interface, provides=Interface, name=''):
@@ -191,10 +194,10 @@ def registerAdapter(impl, for_=Interface, provides=Interface, name=''):
<http://www.muthukadan.net/docs/zca.html>`_ for more information
about ZCA adapters."""
import zope.component
- gsm = zope.component.getGlobalSiteManager()
+ sm = zope.component.getSiteManager()
if not isinstance(for_, (tuple, list)):
for_ = (for_,)
- gsm.registerAdapter(impl, for_, provides, name=name)
+ sm.registerAdapter(impl, for_, provides, name=name)
return impl
def registerSubscriber(subscriber, iface=Interface):
@@ -210,10 +213,10 @@ def registerSubscriber(subscriber, iface=Interface):
<http://www.muthukadan.net/docs/zca.html>`_ for more information
about ZCA subscribers."""
import zope.component
- gsm = zope.component.getGlobalSiteManager()
+ sm = zope.component.getSiteManager()
if not isinstance(iface, (tuple, list)):
iface = (iface,)
- gsm.registerHandler(subscriber, iface)
+ sm.registerHandler(subscriber, iface)
return subscriber
def registerTraverserFactory(traverser, for_=Interface):
@@ -227,7 +230,6 @@ def registerRoute(path, name, factory=None):
from repoze.bfg.interfaces import IRoutesMapper
from zope.component import queryUtility
from repoze.bfg.urldispatch import RoutesRootFactory
- from zope.component import getSiteManager
mapper = queryUtility(IRoutesMapper)
if mapper is None:
mapper = RoutesRootFactory(DummyRootFactory)
@@ -457,34 +459,46 @@ class DummyRequest:
self.marshalled = params # repoze.monty
self.__dict__.update(kw)
-_cleanups = []
+def setUp():
+ """Set up a fresh BFG testing registry. Use in the ``setUp``
+ method of unit tests that use the ``register*`` methods in the
+ testing module (e.g. if your unit test uses
+ ``repoze.bfg.testing.registerDummySecurityPolicy``). If you use
+ the ``register*`` functions without calling ``setUp``, unit tests
+ will not be isolated with respect to registrations they perform.
+ Additionally, the *global* component registry will be used, which
+ may have a different API than is expected by BFG itself.
+
+ .. note:: This feature is new as of :mod:`repoze.bfg` 1.1.
+ """
+ registry = Registry('testing')
+ getSiteManager.sethook(lambda *arg: registry)
+ _clearContext()
+
+def tearDown():
+ """Tear down a previously set up (via
+ ``repoze.bfg.testing.setUp``) testing registry. Use in the
+ ``tearDown`` method of unit tests that use the ``register*``
+ methods in the testing module (e.g. if your unit test uses
+ ``repoze.bfg.testing.registerDummySecurityPolicy``). Using
+ ``tearDown`` is effectively optional if you call setUp at the
+ beginning of every test which requires registry isolation.
-def addCleanUp(func, args=(), kw=None):
- """Register a cleanup routines
+ .. note:: This feature is new as of :mod:`repoze.bfg` 1.1.
- Pass a function to be called to cleanup global data.
- Optional argument tuple and keyword arguments may be passed.
"""
- if kw is None:
- kw = {}
- _cleanups.append((func, args, kw))
+ getSiteManager.reset()
def cleanUp():
- """Clean up BFG testing registrations. Use in the ``tearDown`` of
- unit tests that use the ``register*`` methods in the testing
- module (e.g. if your unit test uses
- ``repoze.bfg.testing.registerDummyRenderer`` or
- ``repoze.bfg.testing.registerDummySecurityPolicy``). If you use
- the ``register*`` functions without calling cleanUp, unit tests
- will not be isolated with respect to registrations they perform."""
- for func, args, kw in _cleanups:
- func(*args, **kw)
-
-from zope.component.globalregistry import base
-from zope.configuration.xmlconfig import _clearContext
-from repoze.bfg.registry import original_getSiteManager
-from repoze.bfg.threadlocal import manager
-addCleanUp(original_getSiteManager.reset)
-addCleanUp(manager.clear)
-addCleanUp(lambda: base.__init__('base'))
-addCleanUp(_clearContext)
+ """ Deprecated (as of BFG 1.1) function whichs sets up a new
+ registry for BFG testing registrations. Use in the ``setUp`` and
+ ``tearDown`` of unit tests that use the ``register*`` methods in
+ the testing module (e.g. if your unit test uses
+ ``repoze.bfg.testing.registerDummySecurityPolicy``). Use of this
+ function is deprecated in favor of using
+ ``repoze.bfg.testing.setUp`` in the test setUp and
+ ``repoze.bfg.testing.tearDown`` in the test tearDown. This is
+ currently just an alias for ``repoze.bfg.testing.setUp``.
+ Although this function is effectively deprecated, due to its
+ extensive production usage, it will never be removed."""
+ setUp()