diff options
| author | Chris McDonough <chrism@agendaless.com> | 2009-11-27 04:46:05 +0000 |
|---|---|---|
| committer | Chris McDonough <chrism@agendaless.com> | 2009-11-27 04:46:05 +0000 |
| commit | d0b398eeb8ce9e1b13b2c93674e220d804d2de2e (patch) | |
| tree | a71b6007259ad04172273bcfed65f7183be6ed22 | |
| parent | f850ec2bf2565e1fb227afa77c2ec2e72fe96522 (diff) | |
| download | pyramid-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.txt | 37 | ||||
| -rw-r--r-- | docs/api/configuration.rst | 5 | ||||
| -rw-r--r-- | repoze/bfg/configuration.py | 45 | ||||
| -rw-r--r-- | repoze/bfg/testing.py | 135 | ||||
| -rw-r--r-- | repoze/bfg/tests/test_configuration.py | 38 | ||||
| -rw-r--r-- | repoze/bfg/tests/test_testing.py | 250 | ||||
| -rw-r--r-- | repoze/bfg/view.py | 6 |
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 |
