summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris McDonough <chrism@agendaless.com>2009-11-27 04:46:05 +0000
committerChris McDonough <chrism@agendaless.com>2009-11-27 04:46:05 +0000
commitd0b398eeb8ce9e1b13b2c93674e220d804d2de2e (patch)
treea71b6007259ad04172273bcfed65f7183be6ed22
parentf850ec2bf2565e1fb227afa77c2ec2e72fe96522 (diff)
downloadpyramid-d0b398eeb8ce9e1b13b2c93674e220d804d2de2e.tar.gz
pyramid-d0b398eeb8ce9e1b13b2c93674e220d804d2de2e.tar.bz2
pyramid-d0b398eeb8ce9e1b13b2c93674e220d804d2de2e.zip
- 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.
-rw-r--r--CHANGES.txt37
-rw-r--r--docs/api/configuration.rst5
-rw-r--r--repoze/bfg/configuration.py45
-rw-r--r--repoze/bfg/testing.py135
-rw-r--r--repoze/bfg/tests/test_configuration.py38
-rw-r--r--repoze/bfg/tests/test_testing.py250
-rw-r--r--repoze/bfg/view.py6
7 files changed, 305 insertions, 211 deletions
diff --git a/CHANGES.txt b/CHANGES.txt
index 9ff5bf9c8..dd448f3eb 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -9,13 +9,36 @@ Features
"imperatively" configured applications and traditional
declaratively-configured applications.
-- The ``repoze.bfg.testing.setUp`` function now causes a "dummy"
- request object to be created (an instance of
- ``repoze.bfg.testing.DummyRequest``). The DummyRequest object is
- available via ``repoze.bfg.threadlocal.get_current_request`` when
- this API is used in the setUp of a unit test. Previously this
- function did not create a request object; it instead assigned
- ``None`` to the threadlocal request value.
+- 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``.
- The ``run.py`` module in various ``repoze.bfg`` ``paster`` templates
now use a ``repoze.bfg.configuration.Configurator`` class instead of
diff --git a/docs/api/configuration.rst b/docs/api/configuration.rst
index b23c34aa1..25f12a50b 100644
--- a/docs/api/configuration.rst
+++ b/docs/api/configuration.rst
@@ -17,8 +17,6 @@
.. automethod:: add_view
- .. automethod:: hook_zca()
-
.. automethod:: load_zcml(spec)
.. automethod:: make_wsgi_app()
@@ -32,6 +30,3 @@
.. automethod:: set_notfound_view(view=None, attr=None, renderer=None, wrapper=None)
.. automethod:: set_security_policies
-
- .. automethod:: unhook_zca()
-
diff --git a/repoze/bfg/configuration.py b/repoze/bfg/configuration.py
index 02e402796..1dd41b0d1 100644
--- a/repoze/bfg/configuration.py
+++ b/repoze/bfg/configuration.py
@@ -103,11 +103,6 @@ class Configurator(object):
application. If it is ``None``, a default root factory will be
used.
- If ``zcml_file`` is passed, it should be a filename relative to
- the caller package, an absolute filename, or a :term:`resource
- specification`. The file it refers to should contain
- :term:`ZCML`. The ZCML represented in this file will be loaded.
-
If ``authentication_policy`` is passed, it should be an instance
of an :term:`authentication policy`.
@@ -253,33 +248,6 @@ class Configurator(object):
# API
- def hook_zca(self):
- """
- If this method is called, the configurator will run
- ``zope.component.getSiteManager.sethook(
- repoze.bfg.threadlocals.get_current_registry)``. This causes
- the ``zope.component.getSiteManager`` API to return the
- :mod:`repoze.bfg` thread local registry. This has the effect
- of causing ``zope.component`` thread local API functions such
- as ``getUtility`` and ``getMultiAdapter`` to use the
- :mod:`repoze.bfg` registry instead of the global Zope registry
- during the scope of every :mod:`repoze.bfg` :term:`request`.
- """
- from zope.component import getSiteManager
- getSiteManager.sethook(get_current_registry)
-
- def unhook_zca(self):
- """
- If this method is called, the configurator constructor will
- run ``zope.component.getSiteManager.reset()``. This causes
- the ``zope.component.getSiteManager`` API to return the
- original registry assigned to it (usually the Zope global
- registry), effectively undoing the work of the ``hook_zca``
- method.
- """
- from zope.component import getSiteManager
- getSiteManager.reset()
-
def add_subscriber(self, subscriber, iface=None):
""" Add an event subscriber for the event stream implied by
the supplied ``iface`` interface. The ``subscriber`` argument
@@ -1023,12 +991,17 @@ def _accept_wrap(view, accept):
return accept_view
# note that ``options`` is a b/w compat alias for ``settings`` and
-# ``Configurator`` is a testing dep inj
+# ``Configurator`` and getSiteManager is a testing dep inj
def make_app(root_factory, package=None, filename='configure.zcml',
- settings=None, options=None, Configurator=Configurator):
+ settings=None, options=None, Configurator=Configurator,
+ getSiteManager=None):
""" Return a Router object, representing a fully configured
``repoze.bfg`` WSGI application.
+ .. warning:: Use of this function is deprecated as of
+ :mod:`repoze.bfg` 1.2. You should instead use a
+ ``Configurator`` as shown in :ref:`configuration_narr`.
+
``root_factory`` must be a callable that accepts a :term:`request`
object and which returns a traversal root object. The traversal
root returned by the root factory is the *default* traversal root;
@@ -1065,7 +1038,9 @@ def make_app(root_factory, package=None, filename='configure.zcml',
settings = settings or options or {}
config = Configurator(package=package, settings=settings,
root_factory=root_factory)
- config.hook_zca()
+ if getSiteManager is None:
+ from zope.component import getSiteManager
+ getSiteManager.sethook(get_current_registry)
zcml_file = settings.get('configure_zcml', filename)
config.load_zcml(zcml_file)
return config.make_wsgi_app()
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)
diff --git a/repoze/bfg/tests/test_configuration.py b/repoze/bfg/tests/test_configuration.py
index ae75494e4..ed84735b4 100644
--- a/repoze/bfg/tests/test_configuration.py
+++ b/repoze/bfg/tests/test_configuration.py
@@ -134,31 +134,6 @@ class ConfiguratorTests(unittest.TestCase):
self.assertEqual(config.registry.getUtility(IRendererFactory, 'yeah'),
renderer)
- def test_hook_zca(self):
- from zope.component import getSiteManager
- from repoze.bfg.threadlocal import get_current_registry
- try:
- getSiteManager.reset()
- config = self._makeOne()
- config.hook_zca()
- hooked = getSiteManager.sethook(None)
- self.assertEqual(hooked, get_current_registry)
- finally:
- getSiteManager.reset()
-
- def test_unhook_zca(self):
- from zope.component import getSiteManager
- try:
- config = self._makeOne()
- reg = object()
- hook = lambda *arg: reg
- hooked = getSiteManager.sethook(hook)
- self.assertEqual(getSiteManager(), reg)
- config.unhook_zca()
- self.assertNotEqual(getSiteManager(), reg)
- finally:
- getSiteManager.reset()
-
def test_add_subscriber_defaults(self):
from zope.interface import implements
from zope.interface import Interface
@@ -2488,14 +2463,17 @@ class TestMakeApp(unittest.TestCase):
return make_app(*arg, **kw)
def test_it(self):
+ from repoze.bfg.threadlocal import get_current_registry
settings = {'a':1}
rootfactory = object()
+ gsm = DummyGetSiteManager()
app = self._callFUT(rootfactory, settings=settings,
- Configurator=DummyConfigurator)
+ Configurator=DummyConfigurator,
+ getSiteManager=gsm)
self.assertEqual(app.root_factory, rootfactory)
self.assertEqual(app.settings, settings)
self.assertEqual(app.zcml_file, 'configure.zcml')
- self.assertEqual(app.zca_hooked, True)
+ self.assertEqual(gsm.hook, get_current_registry)
def test_it_options_means_settings(self):
settings = {'a':1}
@@ -2633,3 +2611,9 @@ class DummyMultiView:
return 'OK1'
def __permitted__(self, context, request):
""" """
+
+class DummyGetSiteManager(object):
+ def sethook(self, hook):
+ self.hook = hook
+
+
diff --git a/repoze/bfg/tests/test_testing.py b/repoze/bfg/tests/test_testing.py
index da2b08e71..6341825ef 100644
--- a/repoze/bfg/tests/test_testing.py
+++ b/repoze/bfg/tests/test_testing.py
@@ -1,27 +1,24 @@
-from repoze.bfg.testing import setUp
-from repoze.bfg.testing import tearDown
import unittest
-class TestTestingFunctions(unittest.TestCase):
+class TestBase(unittest.TestCase):
def setUp(self):
- setUp()
- from repoze.bfg.threadlocal import get_current_registry
- self.registry = get_current_registry()
+ from repoze.bfg.threadlocal import manager
+ from repoze.bfg.registry import Registry
+ manager.clear()
+ registry = Registry('testing')
+ self.registry = registry
+ manager.push({'registry':registry, 'request':None})
from zope.deprecation import __show__
__show__.off()
def tearDown(self):
- tearDown()
+ from repoze.bfg.threadlocal import manager
+ manager.clear()
from zope.deprecation import __show__
__show__.on()
- def _makeRequest(self, **extra_environ):
- from repoze.bfg.threadlocal import get_current_request
- request = get_current_request()
- request.environ.update(extra_environ)
- return request
-
+class Test_registerDummySecurityPolicy(TestBase):
def test_registerDummySecurityPolicy(self):
from repoze.bfg import testing
testing.registerDummySecurityPolicy('user', ('group1', 'group2'),
@@ -36,6 +33,7 @@ class TestTestingFunctions(unittest.TestCase):
self.assertEqual(ut.groupids, ('group1', 'group2'))
self.assertEqual(ut.permissive, False)
+class Test_registerModels(TestBase):
def test_registerModels(self):
ob1 = object()
ob2 = object()
@@ -62,6 +60,7 @@ class TestTestingFunctions(unittest.TestCase):
from repoze.bfg.traversal import find_model
self.assertEqual(find_model(None, '/ob1'), ob1)
+class Test_registerTemplateRenderer(TestBase):
def test_registerTemplateRenderer(self):
from repoze.bfg import testing
renderer = testing.registerTemplateRenderer('templates/foo')
@@ -80,36 +79,24 @@ class TestTestingFunctions(unittest.TestCase):
self.assertRaises(ValueError, render_template_to_response,
'templates/foo', foo=1, bar=2)
+class Test_registerEventListener(TestBase):
def test_registerEventListener_single(self):
from repoze.bfg import testing
- from zope.interface import implements
- from zope.interface import Interface
- class IEvent(Interface):
- pass
- class Event:
- implements(IEvent)
- L = testing.registerEventListener(IEvent)
- from zope.component.event import dispatch
- event = Event()
- dispatch(event)
+ L = testing.registerEventListener(IDummy)
+ event = DummyEvent()
+ self.registry.notify(event)
self.assertEqual(len(L), 1)
self.assertEqual(L[0], event)
- dispatch(object())
+ self.registry.notify(object())
self.assertEqual(len(L), 1)
def test_registerEventListener_multiple(self):
from repoze.bfg import testing
- from zope.interface import implements
- from zope.interface import Interface
- class IEvent(Interface):
- pass
- class Event:
- object = 'foo'
- implements(IEvent)
- L = testing.registerEventListener((Interface, IEvent))
- from zope.component.event import objectEventNotify
- event = Event()
- objectEventNotify(event)
+ L = testing.registerEventListener((Interface, IDummy))
+ event = DummyEvent()
+ event.object = 'foo'
+ # the below is the equivalent of z.c.event.objectEventNotify(event)
+ self.registry.subscribers((event.object, event), None)
self.assertEqual(len(L), 2)
self.assertEqual(L[0], 'foo')
self.assertEqual(L[1], event)
@@ -117,21 +104,22 @@ class TestTestingFunctions(unittest.TestCase):
def test_registerEventListener_defaults(self):
from repoze.bfg import testing
L = testing.registerEventListener()
- from zope.component.event import dispatch
event = object()
- dispatch(event)
+ self.registry.notify(event)
self.assertEqual(L[-1], event)
event2 = object()
- dispatch(event2)
+ self.registry.notify(event2)
self.assertEqual(L[-1], event2)
+class Test_registerView(TestBase):
def test_registerView_defaults(self):
from repoze.bfg import testing
view = testing.registerView('moo.html')
import types
self.failUnless(isinstance(view, types.FunctionType))
from repoze.bfg.view import render_view_to_response
- request = self._makeRequest()
+ request = DummyRequest()
+ request.registry = self.registry
response = render_view_to_response(None, request, 'moo.html')
self.assertEqual(view(None, None).body, response.body)
@@ -141,7 +129,8 @@ class TestTestingFunctions(unittest.TestCase):
import types
self.failUnless(isinstance(view, types.FunctionType))
from repoze.bfg.view import render_view_to_response
- request = self._makeRequest()
+ request = DummyRequest()
+ request.registry = self.registry
response = render_view_to_response(None, request, 'moo.html')
self.assertEqual(response.body, 'yo')
@@ -154,7 +143,8 @@ class TestTestingFunctions(unittest.TestCase):
import types
self.failUnless(isinstance(view, types.FunctionType))
from repoze.bfg.view import render_view_to_response
- request = self._makeRequest()
+ request = DummyRequest()
+ request.registry = self.registry
response = render_view_to_response(None, request, 'moo.html')
self.assertEqual(response.body, '123')
@@ -168,7 +158,8 @@ class TestTestingFunctions(unittest.TestCase):
import types
self.failUnless(isinstance(view, types.FunctionType))
from repoze.bfg.view import render_view_to_response
- request = self._makeRequest()
+ request = DummyRequest()
+ request.registry = self.registry
self.assertRaises(Forbidden, render_view_to_response,
None, request, 'moo.html')
@@ -194,7 +185,8 @@ class TestTestingFunctions(unittest.TestCase):
import types
self.failUnless(isinstance(view, types.FunctionType))
from repoze.bfg.view import render_view_to_response
- request = self._makeRequest()
+ request = DummyRequest()
+ request.registry = self.registry
result = render_view_to_response(None, request, 'moo.html')
self.assertEqual(result.app_iter, ['123'])
@@ -227,6 +219,7 @@ class TestTestingFunctions(unittest.TestCase):
(Interface, Interface), IViewPermission, 'moo.html')
self.assertEqual(result, True)
+class Test_registerAdapter(TestBase):
def test_registerAdapter(self):
from zope.interface import implements
from zope.interface import Interface
@@ -251,6 +244,7 @@ class TestTestingFunctions(unittest.TestCase):
self.assertEqual(adapter.context, for1)
self.assertEqual(adapter.request, for2)
+class Test_registerUtility(TestBase):
def test_registerUtility(self):
from zope.interface import implements
from zope.interface import Interface
@@ -265,34 +259,27 @@ class TestTestingFunctions(unittest.TestCase):
testing.registerUtility(utility, iface, name='mudge')
self.assertEqual(self.registry.getUtility(iface, name='mudge')(), 'foo')
+class Test_registerRoute(TestBase):
def test_registerRoute(self):
from repoze.bfg.url import route_url
from repoze.bfg.interfaces import IRoutesMapper
from repoze.bfg.testing import registerRoute
- class Factory:
- def __init__(self, environ):
- """ """
- class DummyRequest:
- application_url = 'http://example.com'
- registerRoute(':pagename', 'home', Factory)
+ registerRoute(':pagename', 'home', DummyFactory)
mapper = self.registry.getUtility(IRoutesMapper)
self.assertEqual(len(mapper.routelist), 1)
request = DummyRequest()
self.assertEqual(route_url('home', request, pagename='abc'),
'http://example.com/abc')
+class Test_registerRoutesMapper(TestBase):
def test_registerRoutesMapper(self):
from repoze.bfg.interfaces import IRoutesMapper
from repoze.bfg.testing import registerRoutesMapper
- class Factory:
- def __init__(self, environ):
- """ """
- class DummyRequest:
- application_url = 'http://example.com'
result = registerRoutesMapper()
mapper = self.registry.getUtility(IRoutesMapper)
self.assertEqual(result, mapper)
+class Test_registerSettings(TestBase):
def test_registerSettings(self):
from repoze.bfg.interfaces import ISettings
from repoze.bfg.testing import registerSettings
@@ -538,52 +525,127 @@ class TestDummyTemplateRenderer(unittest.TestCase):
result = renderer({'a':1, 'b':2})
self.assertEqual(result, 'abc')
-class TestSetUp(unittest.TestCase):
- def setUp(self):
- from zope.component import getSiteManager
- getSiteManager.reset()
-
- def _callFUT(self, ):
+class Test_setUp(unittest.TestCase):
+ def _callFUT(self, **kw):
from repoze.bfg.testing import setUp
- return setUp()
+ return setUp(**kw)
- def test_it(self):
- from zope.component.globalregistry import base
- from zope.interface import Interface
+ def test_it_defaults(self):
+ from repoze.bfg.threadlocal import manager
+ from repoze.bfg.threadlocal import get_current_registry
+ from repoze.bfg.registry import Registry
from zope.component import getSiteManager
- getSiteManager.sethook(lambda *arg: base)
- class IFoo(Interface):
- pass
- def foo():
- """ """
- base.registerUtility(foo, IFoo)
- sm = getSiteManager()
- self.assertEqual(sm.queryUtility(IFoo), foo)
- self._callFUT()
- newsm = getSiteManager()
- self.assertEqual(newsm.queryUtility(IFoo), None)
-
-class TestCleanUp(TestSetUp):
- def _callFUT(self, ):
- from repoze.bfg.testing import cleanUp
- return cleanUp()
-
-class TestTearDown(unittest.TestCase):
- def setUp(self):
+ old = True
+ manager.push(old)
+ try:
+ self._callFUT()
+ current = manager.get()
+ self.failIf(current is old)
+ self.assertEqual(current['registry'].__class__, Registry)
+ self.assertEqual(current['request'], None)
+ finally:
+ result = getSiteManager.sethook(None)
+ self.assertEqual(result, get_current_registry)
+ getSiteManager.reset()
+ manager.clear()
+
+ def test_it_with_registry(self):
+ from zope.component import getSiteManager
+ from repoze.bfg.threadlocal import manager
+ registry = object()
+ try:
+ self._callFUT(registry=registry)
+ current = manager.get()
+ self.assertEqual(current['registry'], registry)
+ finally:
+ getSiteManager.reset()
+ manager.clear()
+
+ def test_it_with_request(self):
from zope.component import getSiteManager
- getSiteManager.reset()
+ from repoze.bfg.threadlocal import manager
+ request = object()
+ try:
+ self._callFUT(request=request)
+ current = manager.get()
+ self.assertEqual(current['request'], request)
+ finally:
+ getSiteManager.reset()
+ manager.clear()
+
+ def test_it_with_hook_zca_false(self):
+ from zope.component import getSiteManager
+ from repoze.bfg.threadlocal import manager
+ registry = object()
+ try:
+ self._callFUT(registry=registry, hook_zca=False)
+ sm = getSiteManager()
+ self.failIf(sm is registry)
+ finally:
+ getSiteManager.reset()
+ manager.clear()
+
+class Test_cleanUp(Test_setUp):
+ def _callFUT(self, *arg, **kw):
+ from repoze.bfg.testing import cleanUp
+ return cleanUp(*arg, **kw)
- def _callFUT(self, ):
+class Test_tearDown(unittest.TestCase):
+ def _callFUT(self, **kw):
from repoze.bfg.testing import tearDown
- return tearDown()
+ return tearDown(**kw)
- def test_it(self):
- from zope.component.globalregistry import base
+ def test_defaults(self):
+ from repoze.bfg.threadlocal import manager
from zope.component import getSiteManager
- getSiteManager.sethook(lambda *arg: 'foo')
- sm = getSiteManager()
- self.assertEqual(sm, 'foo')
- self._callFUT()
- newsm = getSiteManager()
- self.assertEqual(newsm, base)
+ registry = DummyRegistry()
+ old = {'registry':registry}
+ hook = lambda *arg: None
+ try:
+ getSiteManager.sethook(hook)
+ manager.push(old)
+ self._callFUT()
+ current = manager.get()
+ self.assertNotEqual(current, old)
+ self.assertEqual(registry.inited, 2)
+ finally:
+ result = getSiteManager.sethook(None)
+ self.assertNotEqual(result, hook)
+ getSiteManager.reset()
+ manager.clear()
+
+ def test_unhook_zc_false(self):
+ from repoze.bfg.threadlocal import manager
+ from zope.component import getSiteManager
+ hook = lambda *arg: None
+ try:
+ getSiteManager.sethook(hook)
+ self._callFUT(unhook_zca=False)
+ finally:
+ result = getSiteManager.sethook(None)
+ self.assertEqual(result, hook)
+ getSiteManager.reset()
+ manager.clear()
+
+from zope.interface import Interface
+from zope.interface import implements
+
+class IDummy(Interface):
+ pass
+
+class DummyEvent:
+ implements(IDummy)
+
+class DummyRequest:
+ application_url = 'http://example.com'
+
+class DummyFactory:
+ def __init__(self, environ):
+ """ """
+
+class DummyRegistry(object):
+ inited = 0
+ __name__ = 'name'
+ def __init__(self, name=''):
+ self.inited = self.inited + 1
diff --git a/repoze/bfg/view.py b/repoze/bfg/view.py
index f037ed839..d682d762b 100644
--- a/repoze/bfg/view.py
+++ b/repoze/bfg/view.py
@@ -28,6 +28,7 @@ from repoze.bfg.interfaces import IView
from repoze.bfg.path import caller_package
from repoze.bfg.resource import resolve_resource_spec
from repoze.bfg.static import PackageURLParser
+from repoze.bfg.threadlocal import get_current_registry
# b/c imports
from repoze.bfg.security import view_execution_permitted
@@ -61,7 +62,10 @@ def render_view_to_response(context, request, name='', secure=True):
``args`` attribute explains why the view access was disallowed.
If ``secure`` is ``False``, no permission checking is done."""
provides = map(providedBy, (context, request))
- reg = request.registry
+ try:
+ reg = request.registry
+ except AttributeError:
+ reg = get_current_registry()
view = reg.adapters.lookup(provides, IView, name=name)
if view is None:
return None