From d0b398eeb8ce9e1b13b2c93674e220d804d2de2e Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 27 Nov 2009 04:46:05 +0000 Subject: - The ``repoze.bfg.testing.setUp`` function now accepts three extra optional keyword arguments: ``registry``, ``request`` and ``hook_zca``. If the ``registry`` argument is not ``None``, the argument will be treated as the registry that is set as the "current registry" (it will be returned by ``repoze.bfg.threadlocal.get_current_registry``) for the duration of the test. If the ``registry`` argument is ``None`` (the default), a new registry is created and used for the duration of the test. The value of the ``request`` argument is used as the "current request" (it will be returned by ``repoze.bfg.threadlocal.get_current_request``) for the duration of the test; it defaults to ``None``. If ``hook_zca`` is ``True`` (the default), the ``zope.component.getSiteManager`` function will be hooked with a function that returns the value of ``registry`` (or the default-created registry if ``registry`` is ``None``) instead of the registry returned by ``zope.component.getGlobalSiteManager``, causing the Zope Component Architecture API (``getSiteManager``, ``getAdapter``, ``getUtility``, and so on) to use the registry we're using for testing instead of the global ZCA registry. - The ``repoze.bfg.testing.tearDown`` function now accepts an ``unhook_zca`` argument. If this argument is ``True`` (the default), ``zope.component.getSiteManager.reset()`` will be called, causing the "base" registry to once again start returnining the result of ``zope.component.getSiteManager``. - Remove hook_zca and unhook_zca methods from Configurator. --- repoze/bfg/testing.py | 135 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 93 insertions(+), 42 deletions(-) (limited to 'repoze/bfg/testing.py') diff --git a/repoze/bfg/testing.py b/repoze/bfg/testing.py index cfcf82125..d7648686b 100644 --- a/repoze/bfg/testing.py +++ b/repoze/bfg/testing.py @@ -1,6 +1,5 @@ import copy -from zope.component import getSiteManager from zope.configuration.xmlconfig import _clearContext from zope.deprecation import deprecated @@ -522,53 +521,105 @@ class DummyRequest: self.registry = get_current_registry() self.__dict__.update(kw) -def setUp(): +def setUp(registry=None, request=None, hook_zca=True): """ - 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, a *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. + Set BFG registry and request thread locals for the duration of a + unit test. + + .. note:: The ``setUp`` function is new as of :mod:`repoze.bfg` + 1.1. + + Use in the ``setUp`` method of unit test code which uses any of + the ``register*`` functions in ``repoze.bfg.testing`` (such as + ``repoze.bfg.testing.registerDummySecurityPolicy``) or unit test + code that uses the ``repoze.bfg.threadlocal.get_current_registry`` + or ``repoze.bfg.threadlocal.get_current_request`` functions. + + If you use the ``testing.register*`` APIs, or the + ``get_current_*`` functions (or call :mod:`repoze.bfg` code that + uses these functions) without calling ``setUp``, + ``get_current_registry`` will return a *global* :term:`application + registry`, which may cause unit tests to not be isolated with + respect to registrations they perform. + + If the ``registry`` argument is ``None``, a new empty + :term:`application registry` will be created (an instance of + ``repoze.bfg.registry.Registry``). If the argument is not + ``None``, the value passed in should be an instance of the + :mod:`repoze.bfg.registry.Registry` class or a suitable testing + analogue. After ``setUp`` is finished, the registry returned by + the ``repoze.bfg.threadlocal.get_current_request`` function will + be the passed (or constructed) registry until + ``repoze.bfg.testing.tearDown`` is called (or + ``repoze.bfg.testing.setUp`` is called again) . + + .. note:: The ``registry`` argument is new as of :mod:`repoze.bfg` + 1.2. + + When ``setUp`` is finished, the value of the ``request`` argument + to ``setUp`` will be returned by the + ``repoze.bfg.threadlocal.get_current_registry`` function until + ``repoze.bfg.testing.tearDown`` is called (or + ``repoze.bfg.testing.setUp`` is called again) .. + + .. note:: The ``request`` argument is new as of :mod:`repoze.bfg` + 1.2. + + If ``hook_zca`` is True, ``setUp`` will attempt to perform + ``zope.component.getSiteManager.sethook( + repoze.bfg.threadlocal.get_current_registry)``, which will cause + the :term:`Zope Component Architecture` global API + (e.g. ``getSiteManager``, ``getAdapter``, and so on) to use the + registry constructed by ``setUp` as the value it returns from + ``zope.component.getSiteManager``. If ``zope.component`` cannot + be imported, or if ``hook_zca`` is ``False``, the hook will not be + set. + + .. note:: The ``hook_zca`` argument is new as of :mod:`repoze.bfg` + 1.2. """ - from repoze.bfg.registry import Registry - registry = Registry('testing') manager.clear() - request = DummyRequest() - request.registry = registry + if registry is None: + from repoze.bfg.registry import Registry + registry = Registry('testing') manager.push({'registry':registry, 'request':request}) - getSiteManager.sethook(get_current_registry) - _clearContext() # XXX why? + if hook_zca: + try: + from zope.component import getSiteManager + getSiteManager.sethook(get_current_registry) + except ImportError: + pass + +def tearDown(unhook_zca=True): + """Undo the effects ``repoze.bfg.testing.setUp``. Use this + function in the ``tearDown`` of a unit test that uses + ``repoze.bfg.testing.setUp`` in its setUp method. + + .. note:: This function is new as of :mod:`repoze.bfg` 1.1. -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. + If the ``unhook_zca`` argument is ``True`` (the default), call + ``zope.component.getSiteManager.reset()``. This undoes the action + of ``repze.bfg.testing.setUp`` called with ``hook_zca=True``. If + ``zope.component`` cannot be imported, ignore the argument. - .. note:: This feature is new as of :mod:`repoze.bfg` 1.1. + .. note:: The ``unhook_zca`` argument is new as of + :mod:`repoze.bfg` 1.2. """ - getSiteManager.reset() - manager.pop() - -def cleanUp(): - """ 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 + if unhook_zca: + from zope.component import getSiteManager + getSiteManager.reset() + info = manager.pop() + manager.clear() + if info is not None: + reg = info['registry'] + if hasattr(reg, '__init__') and hasattr(reg, '__name__'): + reg.__init__(reg.__name__) + _clearContext() # XXX why? + +def cleanUp(*arg, **kw): + """ ``repoze.bfg.testing.cleanUp`` is an alias for + ``repoze.bfg.testing.setUp``. Although this function is + effectively deprecated as of :mod:`repoze.bfg` 1.1, due to its extensive production usage, it will never be removed.""" - setUp() + setUp(*arg, **kw) -- cgit v1.2.3