diff options
23 files changed, 735 insertions, 585 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index d045d261a..9926e7adc 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -9,6 +9,38 @@ Features ``bfg_view`` decorator. See the ``Views`` narrative documentation chapter for more information about these predicates. +- 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 ------------- @@ -18,6 +50,56 @@ Documentation - Point all index URLs at the literal 1.1 index (this alpha cycle may go on a while). +- 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. + 1.1a5 (2009-10-10) ================== diff --git a/docs/api/testing.rst b/docs/api/testing.rst index f64d78337..94c231459 100644 --- a/docs/api/testing.rst +++ b/docs/api/testing.rst @@ -25,6 +25,10 @@ .. autofunction:: registerRoute + .. autofunction:: setUp + + .. autofunction:: tearDown + .. autofunction:: cleanUp .. autoclass:: DummyModel diff --git a/docs/narr/unittesting.rst b/docs/narr/unittesting.rst index 064be4739..885d7be36 100644 --- a/docs/narr/unittesting.rst +++ b/docs/narr/unittesting.rst @@ -50,10 +50,10 @@ unittest TestCase that used the testing API. class MyTest(unittest.TestCase): def setUp(self): - testing.cleanUp() + testing.setUp() def tearDown(self): - testing.cleanUp() + testing.tearDown() def test_view_fn_not_submitted(self): from my.package import view_fn @@ -105,11 +105,12 @@ assertion. We assert at the end of this that the renderer's ``say`` attribute is ``Yo``, as this is what is expected of the view function in the branch it's testing. -Note that the test calls the ``repoze.bfg.testing.cleanUp`` function -in its ``setUp`` and ``tearDown`` functions. This is required to +Note that the test calls the ``repoze.bfg.testing.setUp`` function in +its ``setUp`` method and the ``repoze.bfg.testing.tearDown`` function +in its ``tearDown`` method. Use of this pattern is required to perform cleanup between the test runs. If you use any of the testing -API, be sure to call this function at setup and teardown of individual -tests. +API, be sure to call ``repoze.bfg.testing.setUp`` in the test setup +and ``repoze.bfg.testing.tearDown`` in the test teardown. See the :ref:`testing_module` chapter for the entire :mod:`repoze.bfg` -specific testing API. This chapter describes APIs for registering a diff --git a/docs/tutorials/bfgwiki2/src/authorization/tutorial/tests.py b/docs/tutorials/bfgwiki2/src/authorization/tutorial/tests.py index 2a1d43749..52d2fed86 100644 --- a/docs/tutorials/bfgwiki2/src/authorization/tutorial/tests.py +++ b/docs/tutorials/bfgwiki2/src/authorization/tutorial/tests.py @@ -17,6 +17,12 @@ def _registerRoutes(): testing.registerRoute('add_page/:pagename', 'add_page') class ViewWikiTests(unittest.TestCase): + def setUp(self): + testing.setUp() + + def tearDown(self): + testing.tearDown() + def test_it(self): from tutorial.views import view_wiki testing.registerRoute(':pagename', 'view_page') @@ -27,9 +33,11 @@ class ViewWikiTests(unittest.TestCase): class ViewPageTests(unittest.TestCase): def setUp(self): self.session = _initTestingDB() + testing.setUp() def tearDown(self): self.session.remove() + testing.tearDown() def _callFUT(self, request): from tutorial.views import view_page @@ -59,9 +67,11 @@ class ViewPageTests(unittest.TestCase): class AddPageTests(unittest.TestCase): def setUp(self): self.session = _initTestingDB() + testing.setUp() def tearDown(self): self.session.remove() + testing.tearDown() def _callFUT(self, request): from tutorial.views import add_page @@ -89,9 +99,11 @@ class AddPageTests(unittest.TestCase): class EditPageTests(unittest.TestCase): def setUp(self): self.session = _initTestingDB() + testing.setUp() def tearDown(self): self.session.remove() + testing.tearDown() def _callFUT(self, request): from tutorial.views import edit_page diff --git a/docs/tutorials/bfgwiki2/src/views/tutorial/tests.py b/docs/tutorials/bfgwiki2/src/views/tutorial/tests.py index 2a1d43749..52d2fed86 100644 --- a/docs/tutorials/bfgwiki2/src/views/tutorial/tests.py +++ b/docs/tutorials/bfgwiki2/src/views/tutorial/tests.py @@ -17,6 +17,12 @@ def _registerRoutes(): testing.registerRoute('add_page/:pagename', 'add_page') class ViewWikiTests(unittest.TestCase): + def setUp(self): + testing.setUp() + + def tearDown(self): + testing.tearDown() + def test_it(self): from tutorial.views import view_wiki testing.registerRoute(':pagename', 'view_page') @@ -27,9 +33,11 @@ class ViewWikiTests(unittest.TestCase): class ViewPageTests(unittest.TestCase): def setUp(self): self.session = _initTestingDB() + testing.setUp() def tearDown(self): self.session.remove() + testing.tearDown() def _callFUT(self, request): from tutorial.views import view_page @@ -59,9 +67,11 @@ class ViewPageTests(unittest.TestCase): class AddPageTests(unittest.TestCase): def setUp(self): self.session = _initTestingDB() + testing.setUp() def tearDown(self): self.session.remove() + testing.tearDown() def _callFUT(self, request): from tutorial.views import add_page @@ -89,9 +99,11 @@ class AddPageTests(unittest.TestCase): class EditPageTests(unittest.TestCase): def setUp(self): self.session = _initTestingDB() + testing.setUp() def tearDown(self): self.session.remove() + testing.tearDown() def _callFUT(self, request): from tutorial.views import edit_page diff --git a/repoze/bfg/configuration.py b/repoze/bfg/configuration.py new file mode 100644 index 000000000..629a58047 --- /dev/null +++ b/repoze/bfg/configuration.py @@ -0,0 +1,134 @@ +import os +import sys +import threading + +import zope.component + +from zope.component import getGlobalSiteManager +from zope.component import getSiteManager + +from repoze.bfg.interfaces import IAuthenticationPolicy +from repoze.bfg.interfaces import IAuthorizationPolicy +from repoze.bfg.interfaces import IDefaultRootFactory +from repoze.bfg.interfaces import ILogger +from repoze.bfg.interfaces import IRootFactory +from repoze.bfg.interfaces import IRoutesMapper +from repoze.bfg.interfaces import ISettings + +from repoze.bfg.authorization import ACLAuthorizationPolicy +from repoze.bfg.log import make_stream_logger +from repoze.bfg.registry import Registry +from repoze.bfg.settings import Settings +from repoze.bfg.settings import get_options +from repoze.bfg.threadlocal import get_current_registry +from repoze.bfg.threadlocal import manager +from repoze.bfg.urldispatch import RoutesRootFactory +from repoze.bfg.zcml import zcml_configure + +def make_registry(root_factory, package=None, filename='configure.zcml', + authentication_policy=None, authorization_policy=None, + options=None, registry=None, debug_logger=None, + manager=manager, os=os, lock=threading.Lock()): + # registry, debug_logger, manager, os and lock *only* for unittests + if options is None: + options = {} + + if not 'configure_zcml' in options: + options['configure_zcml'] = filename + + settings = Settings(get_options(options)) + filename = settings['configure_zcml'] + + # not os.path.isabs below for windows systems + if (':' in filename) and (not os.path.isabs(filename)): + package, filename = filename.split(':', 1) + __import__(package) + package = sys.modules[package] + + if registry is None: + regname = filename + if package: + regname = package.__name__ + registry = Registry(regname) + + registry.registerUtility(settings, ISettings) + + if debug_logger is None: + debug_logger = make_stream_logger('repoze.bfg.debug', sys.stderr) + registry.registerUtility(debug_logger, ILogger, 'repoze.bfg.debug') + + if root_factory is None: + root_factory = DefaultRootFactory + + # register the *default* root factory so apps can find it later + registry.registerUtility(root_factory, IDefaultRootFactory) + + mapper = RoutesRootFactory(root_factory) + registry.registerUtility(mapper, IRoutesMapper) + + if authentication_policy: + debug_logger.warn( + 'The "authentication_policy" and "authorization_policy" ' + 'arguments to repoze.bfg.router.make_app have been deprecated ' + 'in repoze.bfg version 1.0. Instead of using these arguments to ' + 'configure an authorization/authentication policy pair, use ' + 'a pair of ZCML directives (such as "authtktauthenticationpolicy" ' + 'and "aclauthorizationpolicy" documented within the Security ' + 'chapter in the BFG documentation. If you need to use a custom ' + 'authentication or authorization policy, you should make a ZCML ' + 'directive for it and use that directive within your ' + 'application\'s ZCML') + registry.registerUtility(authentication_policy, IAuthenticationPolicy) + if authorization_policy is None: + authorization_policy = ACLAuthorizationPolicy() + registry.registerUtility(authorization_policy, IAuthorizationPolicy) + + # We push our ZCML-defined configuration into an app-local + # component registry in order to allow more than one bfg app to live + # in the same process space without one unnecessarily stomping on + # the other's component registrations (although I suspect directives + # that have side effects are going to fail). The only way to do + # that currently is to override zope.component.getGlobalSiteManager + # for the duration of the ZCML includes. We acquire a lock in case + # another make_app runs in a different thread simultaneously, in a + # vain attempt to prevent mixing of registrations. There's not much + # we can do about non-makeRegistry code that tries to use the global + # site manager API directly in a different thread while we hold the + # lock. Those registrations will end up in our application's + # registry. + + lock.acquire() + manager.push({'registry':registry, 'request':None}) + try: + getSiteManager.sethook(get_current_registry) + zope.component.getGlobalSiteManager = get_current_registry + zcml_configure(filename, package) + finally: + # intentional: do not call getSiteManager.reset(); executing + # this function means we're taking over getSiteManager for the + # lifetime of this process + zope.component.getGlobalSiteManager = getGlobalSiteManager + lock.release() + manager.pop() + + if mapper.has_routes(): + # if the user had any <route/> statements in his configuration, + # use the RoutesRootFactory as the IRootFactory; otherwise use the + # default root factory (optimization; we don't want to go through + # the Routes logic if we know there are no routes to match) + root_factory = mapper + + registry.registerUtility(root_factory, IRootFactory) + + return registry + +class DefaultRootFactory: + __parent__ = None + __name__ = None + def __init__(self, environ): + if 'bfg.routes.matchdict' in environ: + # provide backwards compatibility for applications which + # used routes (at least apps without any custom "context + # factory") in BFG 0.9.X and before + self.__dict__.update(environ['bfg.routes.matchdict']) + diff --git a/repoze/bfg/registry.py b/repoze/bfg/registry.py index 06cd1b804..796ac0dfa 100644 --- a/repoze/bfg/registry.py +++ b/repoze/bfg/registry.py @@ -1,21 +1,15 @@ -import threading - -from zope.component import getGlobalSiteManager -from zope.component import getSiteManager as original_getSiteManager from zope.component.registry import Components -from zope.deprecation import deprecated -import zope.component - -from repoze.bfg.threadlocal import get_current_registry -from repoze.bfg.threadlocal import manager -from repoze.bfg.zcml import zcml_configure -class Registry(Components): +class Registry(Components, dict): # for optimization purposes, if no listeners are listening, don't try # to notify them has_listeners = False + def reset(self): + self.__init__(self.__name__) + self.clear() + def registerSubscriptionAdapter(self, *arg, **kw): result = Components.registerSubscriptionAdapter(self, *arg, **kw) self.has_listeners = True @@ -32,46 +26,3 @@ class Registry(Components): for ignored in self.subscribers(events, None): """ """ -def populateRegistry(registry, filename, package, lock=threading.Lock(), - manager=manager): # lock and manager for testing - - """ We push our ZCML-defined configuration into an app-local - component registry in order to allow more than one bfg app to live - in the same process space without one unnecessarily stomping on - the other's component registrations (although I suspect directives - that have side effects are going to fail). The only way to do - that currently is to override zope.component.getGlobalSiteManager - for the duration of the ZCML includes. We acquire a lock in case - another make_app runs in a different thread simultaneously, in a - vain attempt to prevent mixing of registrations. There's not much - we can do about non-makeRegistry code that tries to use the global - site manager API directly in a different thread while we hold the - lock. Those registrations will end up in our application's - registry.""" - - lock.acquire() - manager.push({'registry':registry, 'request':None}) - try: - original_getSiteManager.sethook(get_current_registry) - zope.component.getGlobalSiteManager = get_current_registry - zcml_configure(filename, package) - finally: - zope.component.getGlobalSiteManager = getGlobalSiteManager - lock.release() - manager.pop() - -getSiteManager = get_current_registry # b/c - -deprecated('getSiteManager', - 'As of repoze.bfg 1.0, any import of getSiteManager from' - '``repoze.bfg.registry`` is ' - 'deprecated. Use ``from zope.compponent import getSiteManager ' - 'instead.') - -get_registry = get_current_registry # b/c - -deprecated('get_registry', - 'As of repoze.bfg 1.0, any import of get_registry from' - '``repoze.bfg.registry`` is ' - 'deprecated. Use ``from repoze.bfg.threadlocal import ' - 'get_current_registry instead.') diff --git a/repoze/bfg/router.py b/repoze/bfg/router.py index e2b2b6830..1b894129b 100644 --- a/repoze/bfg/router.py +++ b/repoze/bfg/router.py @@ -1,40 +1,28 @@ -import os -import sys +from zope.component.event import dispatch from zope.interface import implements from zope.interface import providedBy -from zope.component.event import dispatch - -from repoze.bfg.interfaces import IAuthenticationPolicy -from repoze.bfg.interfaces import IAuthorizationPolicy -from repoze.bfg.interfaces import IDefaultRootFactory from repoze.bfg.interfaces import IForbiddenView from repoze.bfg.interfaces import ILogger from repoze.bfg.interfaces import INotFoundView from repoze.bfg.interfaces import IRootFactory from repoze.bfg.interfaces import IRouter -from repoze.bfg.interfaces import IRoutesMapper from repoze.bfg.interfaces import ISettings from repoze.bfg.interfaces import ITraverserFactory from repoze.bfg.interfaces import IView -from repoze.bfg.authorization import ACLAuthorizationPolicy +from repoze.bfg.configuration import make_registry +from repoze.bfg.configuration import DefaultRootFactory from repoze.bfg.events import NewRequest from repoze.bfg.events import NewResponse from repoze.bfg.events import WSGIApplicationCreatedEvent from repoze.bfg.exceptions import Forbidden from repoze.bfg.exceptions import NotFound -from repoze.bfg.log import make_stream_logger -from repoze.bfg.registry import Registry -from repoze.bfg.registry import populateRegistry from repoze.bfg.request import request_factory -from repoze.bfg.settings import Settings -from repoze.bfg.settings import get_options from repoze.bfg.threadlocal import manager from repoze.bfg.traversal import ModelGraphTraverser from repoze.bfg.traversal import _traverse -from repoze.bfg.urldispatch import RoutesRootFactory from repoze.bfg.view import default_forbidden_view from repoze.bfg.view import default_notfound_view @@ -76,6 +64,14 @@ class Router(object): try: root = self.root_factory(environ) request = request_factory(environ) + + # webob.Request's __setattr__ (as of 0.9.5 and lower) is a + # bottleneck; since we're sure we're using a + # webob.Request, we can go around its back and set stuff + # into the environ directly + attrs = environ.setdefault('webob.adhoc_attrs', {}) + attrs['registry'] = registry + threadlocals['request'] = request registry.has_listeners and registry.notify(NewRequest(request)) traverser = registry.queryAdapter(root, ITraverserFactory) @@ -86,16 +82,7 @@ class Router(object): tdict['context'], tdict['view_name'], tdict['subpath'], tdict['traversed'], tdict['virtual_root'], tdict['virtual_root_path']) - - # webob.Request's __setattr__ (as of 0.9.5 and lower) is a - # bottleneck; since we're sure we're using a - # webob.Request, we can go around its back and set stuff - # into the environ directly - if 'webob.adhoc_attrs' in environ: - attrs = environ.setdefault('webob.adhoc_attrs', {}) - attrs.update(tdict) - else: - environ['webob.adhoc_attrs'] = tdict + attrs.update(tdict) provides = map(providedBy, (context, request)) view_callable = registry.adapters.lookup( @@ -142,11 +129,10 @@ class Router(object): finally: manager.pop() +# make_registry kw arg for unit testing only def make_app(root_factory, package=None, filename='configure.zcml', authentication_policy=None, authorization_policy=None, - options=None, registry=None, debug_logger=None, - manager=manager, os=os): - # registry, debug_logger, manager and os *only* for unittests + options=None, manager=manager, make_registry=make_registry): """ Return a Router object, representing a fully configured ``repoze.bfg`` WSGI application. @@ -180,72 +166,10 @@ def make_app(root_factory, package=None, filename='configure.zcml', PasteDeploy file), with each key representing the option and the key's value representing the specific option value, e.g. ``{'reload_templates':True}``""" - if options is None: - options = {} - - if not 'configure_zcml' in options: - options['configure_zcml'] = filename - - settings = Settings(get_options(options)) - filename = settings['configure_zcml'] - - # not os.path.isabs below for windows systems - if (':' in filename) and (not os.path.isabs(filename)): - package, filename = filename.split(':', 1) - __import__(package) - package = sys.modules[package] - - if registry is None: - regname = filename - if package: - regname = package.__name__ - registry = Registry(regname) - - registry.registerUtility(settings, ISettings) - - if debug_logger is None: - debug_logger = make_stream_logger('repoze.bfg.debug', sys.stderr) - registry.registerUtility(debug_logger, ILogger, 'repoze.bfg.debug') - - if root_factory is None: - root_factory = DefaultRootFactory - - # register the *default* root factory so apps can find it later - registry.registerUtility(root_factory, IDefaultRootFactory) - - mapper = RoutesRootFactory(root_factory) - registry.registerUtility(mapper, IRoutesMapper) - - if authentication_policy: - debug_logger.warn( - 'The "authentication_policy" and "authorization_policy" ' - 'arguments to repoze.bfg.router.make_app have been deprecated ' - 'in repoze.bfg version 1.0. Instead of using these arguments to ' - 'configure an authorization/authentication policy pair, use ' - 'a pair of ZCML directives (such as "authtktauthenticationpolicy" ' - 'and "aclauthorizationpolicy" documented within the Security ' - 'chapter in the BFG documentation. If you need to use a custom ' - 'authentication or authorization policy, you should make a ZCML ' - 'directive for it and use that directive within your ' - 'application\'s ZCML') - registry.registerUtility(authentication_policy, IAuthenticationPolicy) - if authorization_policy is None: - authorization_policy = ACLAuthorizationPolicy() - registry.registerUtility(authorization_policy, IAuthorizationPolicy) - - populateRegistry(registry, filename, package) - - if mapper.has_routes(): - # if the user had any <route/> statements in his configuration, - # use the RoutesRootFactory as the IRootFactory; otherwise use the - # default root factory (optimization; we don't want to go through - # the Routes logic if we know there are no routes to match) - root_factory = mapper - - registry.registerUtility(root_factory, IRootFactory) - + registry = make_registry(root_factory, package, filename, + authentication_policy, authorization_policy, + options) app = Router(registry) - # We push the registry on to the stack here in case any ZCA API is # used in listeners subscribed to the WSGIApplicationCreatedEvent # we send. @@ -256,16 +180,5 @@ def make_app(root_factory, package=None, filename='configure.zcml', dispatch(WSGIApplicationCreatedEvent(app)) finally: manager.pop() - return app -class DefaultRootFactory: - __parent__ = None - __name__ = None - def __init__(self, environ): - if 'bfg.routes.matchdict' in environ: - # provide backwards compatibility for applications which - # used routes (at least apps without any custom "context - # factory") in BFG 0.9.X and before - self.__dict__.update(environ['bfg.routes.matchdict']) - 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() diff --git a/repoze/bfg/tests/test_chameleon_text.py b/repoze/bfg/tests/test_chameleon_text.py index a6384887f..a0fb946d1 100644 --- a/repoze/bfg/tests/test_chameleon_text.py +++ b/repoze/bfg/tests/test_chameleon_text.py @@ -19,7 +19,14 @@ class Base: import os here = os.path.abspath(os.path.dirname(__file__)) return os.path.join(here, 'fixtures', name) + + def _registerUtility(self, utility, iface, name=''): + from zope.component import getSiteManager + sm = getSiteManager() + sm.registerUtility(utility, iface, name=name) + return sm + class TextTemplateRendererTests(Base, unittest.TestCase): def _getTargetClass(self): from repoze.bfg.chameleon_text import TextTemplateRenderer @@ -92,13 +99,11 @@ class RenderTemplateToResponseTests(Base, unittest.TestCase): self.assertEqual(len(result.headerlist), 2) def test_iresponsefactory_override(self): - from zope.component import getGlobalSiteManager - gsm = getGlobalSiteManager() from webob import Response class Response2(Response): pass from repoze.bfg.interfaces import IResponseFactory - gsm.registerUtility(Response2, IResponseFactory) + self._registerUtility(Response2, IResponseFactory) minimal = self._getTemplatePath('minimal.txt') result = self._callFUT(minimal) self.failUnless(isinstance(result, Response2)) @@ -109,40 +114,34 @@ class GetRendererTests(Base, unittest.TestCase): return get_renderer(name) def test_nonabs_registered(self): - from zope.component import getGlobalSiteManager from zope.component import queryUtility from repoze.bfg.chameleon_text import TextTemplateRenderer from repoze.bfg.interfaces import ITemplateRenderer minimal = self._getTemplatePath('minimal.txt') utility = TextTemplateRenderer(minimal) - gsm = getGlobalSiteManager() - gsm.registerUtility(utility, ITemplateRenderer, name=minimal) + self._registerUtility(utility, ITemplateRenderer, name=minimal) result = self._callFUT(minimal) self.assertEqual(result, utility) self.assertEqual(queryUtility(ITemplateRenderer, minimal), utility) def test_nonabs_unregistered(self): - from zope.component import getGlobalSiteManager from zope.component import queryUtility from repoze.bfg.chameleon_text import TextTemplateRenderer from repoze.bfg.interfaces import ITemplateRenderer minimal = self._getTemplatePath('minimal.txt') self.assertEqual(queryUtility(ITemplateRenderer, minimal), None) utility = TextTemplateRenderer(minimal) - gsm = getGlobalSiteManager() - gsm.registerUtility(utility, ITemplateRenderer, name=minimal) + self._registerUtility(utility, ITemplateRenderer, name=minimal) result = self._callFUT(minimal) self.assertEqual(result, utility) self.assertEqual(queryUtility(ITemplateRenderer, minimal), utility) def test_explicit_registration(self): - from zope.component import getGlobalSiteManager from repoze.bfg.interfaces import ITemplateRenderer class Dummy: template = object() - gsm = getGlobalSiteManager() utility = Dummy() - gsm.registerUtility(utility, ITemplateRenderer, name='foo') + self._registerUtility(utility, ITemplateRenderer, name='foo') result = self._callFUT('foo') self.failUnless(result is utility) @@ -158,42 +157,36 @@ class GetTemplateTests(unittest.TestCase, Base): return get_template(name) def test_nonabs_registered(self): - from zope.component import getGlobalSiteManager from zope.component import queryUtility from repoze.bfg.chameleon_text import TextTemplateRenderer from repoze.bfg.interfaces import ITemplateRenderer minimal = self._getTemplatePath('minimal.txt') utility = TextTemplateRenderer(minimal) - gsm = getGlobalSiteManager() - gsm.registerUtility(utility, ITemplateRenderer, name=minimal) + self._registerUtility(utility, ITemplateRenderer, name=minimal) result = self._callFUT(minimal) self.assertEqual(result.filename, minimal) self.assertEqual(queryUtility(ITemplateRenderer, minimal), utility) def test_nonabs_unregistered(self): - from zope.component import getGlobalSiteManager from zope.component import queryUtility from repoze.bfg.chameleon_text import TextTemplateRenderer from repoze.bfg.interfaces import ITemplateRenderer minimal = self._getTemplatePath('minimal.txt') self.assertEqual(queryUtility(ITemplateRenderer, minimal), None) utility = TextTemplateRenderer(minimal) - gsm = getGlobalSiteManager() - gsm.registerUtility(utility, ITemplateRenderer, name=minimal) + self._registerUtility(utility, ITemplateRenderer, name=minimal) result = self._callFUT(minimal) self.assertEqual(result.filename, minimal) self.assertEqual(queryUtility(ITemplateRenderer, minimal), utility) def test_explicit_registration(self): - from zope.component import getGlobalSiteManager from repoze.bfg.interfaces import ITemplateRenderer class Dummy: template = object() def implementation(self): return self.template - gsm = getGlobalSiteManager() utility = Dummy() - gsm.registerUtility(utility, ITemplateRenderer, name='foo') + self._registerUtility(utility, ITemplateRenderer, name='foo') result = self._callFUT('foo') self.failUnless(result is utility.template) diff --git a/repoze/bfg/tests/test_chameleon_zpt.py b/repoze/bfg/tests/test_chameleon_zpt.py index 381a1d0bf..0a78c1caa 100644 --- a/repoze/bfg/tests/test_chameleon_zpt.py +++ b/repoze/bfg/tests/test_chameleon_zpt.py @@ -13,6 +13,12 @@ class Base(object): import os here = os.path.abspath(os.path.dirname(__file__)) return os.path.join(here, 'fixtures', name) + + def _registerUtility(self, utility, iface, name=''): + from zope.component import getSiteManager + sm = getSiteManager() + sm.registerUtility(utility, iface, name=name) + return sm class ZPTTemplateRendererTests(Base, unittest.TestCase): def _getTargetClass(self): @@ -84,13 +90,11 @@ class RenderTemplateToResponseTests(Base, unittest.TestCase): self.assertEqual(len(result.headerlist), 2) def test_iresponsefactory_override(self): - from zope.component import getGlobalSiteManager - gsm = getGlobalSiteManager() from webob import Response class Response2(Response): pass from repoze.bfg.interfaces import IResponseFactory - gsm.registerUtility(Response2, IResponseFactory) + self._registerUtility(Response2, IResponseFactory) minimal = self._getTemplatePath('minimal.pt') result = self._callFUT(minimal) self.failUnless(isinstance(result, Response2)) @@ -101,40 +105,34 @@ class GetRendererTests(Base, unittest.TestCase): return get_renderer(name) def test_nonabs_registered(self): - from zope.component import getGlobalSiteManager from zope.component import queryUtility from repoze.bfg.chameleon_zpt import ZPTTemplateRenderer from repoze.bfg.interfaces import ITemplateRenderer minimal = self._getTemplatePath('minimal.pt') utility = ZPTTemplateRenderer(minimal) - gsm = getGlobalSiteManager() - gsm.registerUtility(utility, ITemplateRenderer, name=minimal) + self._registerUtility(utility, ITemplateRenderer, name=minimal) result = self._callFUT(minimal) self.assertEqual(result, utility) self.assertEqual(queryUtility(ITemplateRenderer, minimal), utility) def test_nonabs_unregistered(self): - from zope.component import getGlobalSiteManager from zope.component import queryUtility from repoze.bfg.chameleon_zpt import ZPTTemplateRenderer from repoze.bfg.interfaces import ITemplateRenderer minimal = self._getTemplatePath('minimal.pt') self.assertEqual(queryUtility(ITemplateRenderer, minimal), None) utility = ZPTTemplateRenderer(minimal) - gsm = getGlobalSiteManager() - gsm.registerUtility(utility, ITemplateRenderer, name=minimal) + self._registerUtility(utility, ITemplateRenderer, name=minimal) result = self._callFUT(minimal) self.assertEqual(result, utility) self.assertEqual(queryUtility(ITemplateRenderer, minimal), utility) def test_explicit_registration(self): - from zope.component import getGlobalSiteManager from repoze.bfg.interfaces import ITemplateRenderer class Dummy: template = object() - gsm = getGlobalSiteManager() utility = Dummy() - gsm.registerUtility(utility, ITemplateRenderer, name='foo') + self._registerUtility(utility, ITemplateRenderer, name='foo') result = self._callFUT('foo') self.failUnless(result is utility) @@ -144,42 +142,36 @@ class GetTemplateTests(Base, unittest.TestCase): return get_template(name) def test_nonabs_registered(self): - from zope.component import getGlobalSiteManager from zope.component import queryUtility from repoze.bfg.chameleon_zpt import ZPTTemplateRenderer from repoze.bfg.interfaces import ITemplateRenderer minimal = self._getTemplatePath('minimal.pt') utility = ZPTTemplateRenderer(minimal) - gsm = getGlobalSiteManager() - gsm.registerUtility(utility, ITemplateRenderer, name=minimal) + self._registerUtility(utility, ITemplateRenderer, name=minimal) result = self._callFUT(minimal) self.assertEqual(result.filename, minimal) self.assertEqual(queryUtility(ITemplateRenderer, minimal), utility) def test_nonabs_unregistered(self): - from zope.component import getGlobalSiteManager from zope.component import queryUtility from repoze.bfg.chameleon_zpt import ZPTTemplateRenderer from repoze.bfg.interfaces import ITemplateRenderer minimal = self._getTemplatePath('minimal.pt') self.assertEqual(queryUtility(ITemplateRenderer, minimal), None) utility = ZPTTemplateRenderer(minimal) - gsm = getGlobalSiteManager() - gsm.registerUtility(utility, ITemplateRenderer, name=minimal) + self._registerUtility(utility, ITemplateRenderer, name=minimal) result = self._callFUT(minimal) self.assertEqual(result.filename, minimal) self.assertEqual(queryUtility(ITemplateRenderer, minimal), utility) def test_explicit_registration(self): - from zope.component import getGlobalSiteManager from repoze.bfg.interfaces import ITemplateRenderer class Dummy: template = object() def implementation(self): return self.template - gsm = getGlobalSiteManager() utility = Dummy() - gsm.registerUtility(utility, ITemplateRenderer, name='foo') + self._registerUtility(utility, ITemplateRenderer, name='foo') result = self._callFUT('foo') self.failUnless(result is utility.template) diff --git a/repoze/bfg/tests/test_configuration.py b/repoze/bfg/tests/test_configuration.py new file mode 100644 index 000000000..b2fc27e3e --- /dev/null +++ b/repoze/bfg/tests/test_configuration.py @@ -0,0 +1,266 @@ +import unittest + +from repoze.bfg.testing import cleanUp + +class MakeRegistryTests(unittest.TestCase): + def setUp(self): + cleanUp() + + def tearDown(self): + cleanUp() + + def _callFUT(self, *arg, **kw): + from repoze.bfg.router import make_registry + return make_registry(*arg, **kw) + + def test_fixtureapp_default_filename_withpackage(self): + manager = DummyRegistryManager() + from repoze.bfg.tests import fixtureapp + rootfactory = DummyRootFactory(None) + registry = self._callFUT(rootfactory, fixtureapp) + self.assertEqual(registry.__name__, 'repoze.bfg.tests.fixtureapp') + from repoze.bfg.tests.fixtureapp.models import IFixture + self.failUnless(registry.queryUtility(IFixture)) # only in c.zcml + + def test_fixtureapp_explicit_filename(self): + manager = DummyRegistryManager() + from repoze.bfg.tests import fixtureapp + rootfactory = DummyRootFactory(None) + registry = self._callFUT( + rootfactory, fixtureapp, filename='another.zcml', + manager=manager) + self.assertEqual(registry.__name__, 'repoze.bfg.tests.fixtureapp') + from repoze.bfg.tests.fixtureapp.models import IFixture + self.failIf(registry.queryUtility(IFixture)) # only in c.zcml + + def test_fixtureapp_explicit_filename_in_options(self): + import os + manager = DummyRegistryManager() + rootfactory = DummyRootFactory(None) + from repoze.bfg.tests import fixtureapp + zcmlfile = os.path.join(os.path.dirname(fixtureapp.__file__), + 'another.zcml') + registry = self._callFUT( + rootfactory, fixtureapp, filename='configure.zcml', + options={'configure_zcml':zcmlfile}, + manager=manager) + self.assertEqual(registry.__name__, 'repoze.bfg.tests.fixtureapp') + from repoze.bfg.tests.fixtureapp.models import IFixture + self.failIf(registry.queryUtility(IFixture)) # only in c.zcml + + def test_fixtureapp_explicit_specification_in_options(self): + manager = DummyRegistryManager() + rootfactory = DummyRootFactory(None) + from repoze.bfg.tests import fixtureapp + zcmlfile = 'repoze.bfg.tests.fixtureapp.subpackage:yetanother.zcml' + registry = self._callFUT( + rootfactory, fixtureapp, filename='configure.zcml', + options={'configure_zcml':zcmlfile}, + manager=manager) + self.assertEqual(registry.__name__, + 'repoze.bfg.tests.fixtureapp.subpackage') + from repoze.bfg.tests.fixtureapp.models import IFixture + self.failIf(registry.queryUtility(IFixture)) # only in c.zcml + + def test_fixtureapp_filename_hascolon_isabs(self): + manager = DummyRegistryManager() + rootfactory = DummyRootFactory(None) + from repoze.bfg.tests import fixtureapp + zcmlfile = 'repoze.bfg.tests.fixtureapp.subpackage:yetanother.zcml' + class Dummy: + def isabs(self, name): + return True + os = Dummy() + os.path = Dummy() + self.assertRaises(IOError, self._callFUT, + rootfactory, + fixtureapp, + filename='configure.zcml', + options={'configure_zcml':zcmlfile}, + manager=manager, + os=os) + + def test_custom_settings(self): + manager = DummyRegistryManager() + options= {'mysetting':True} + from repoze.bfg.tests import fixtureapp + rootfactory = DummyRootFactory(None) + registry = self._callFUT(rootfactory, fixtureapp, options=options, + manager=manager) + from repoze.bfg.interfaces import ISettings + settings = registry.getUtility(ISettings) + self.assertEqual(settings.reload_templates, False) + self.assertEqual(settings.debug_authorization, False) + self.assertEqual(settings.mysetting, True) + + def test_registrations(self): + manager = DummyRegistryManager() + options= {'reload_templates':True, + 'debug_authorization':True} + from repoze.bfg.tests import fixtureapp + rootfactory = DummyRootFactory(None) + registry = self._callFUT(rootfactory, fixtureapp, options=options, + manager=manager) + from repoze.bfg.interfaces import ISettings + from repoze.bfg.interfaces import ILogger + from repoze.bfg.interfaces import IRootFactory + settings = registry.getUtility(ISettings) + logger = registry.getUtility(ILogger, name='repoze.bfg.debug') + rootfactory = registry.getUtility(IRootFactory) + self.assertEqual(logger.name, 'repoze.bfg.debug') + self.assertEqual(settings.reload_templates, True) + self.assertEqual(settings.debug_authorization, True) + self.assertEqual(rootfactory, rootfactory) + self.failUnless(manager.pushed and manager.popped) + + def test_routes_in_config_with_rootfactory(self): + options= {'reload_templates':True, + 'debug_authorization':True} + from repoze.bfg.urldispatch import RoutesRootFactory + from repoze.bfg.tests import routesapp + rootfactory = DummyRootFactory(None) + registry = self._callFUT(rootfactory, routesapp, options=options) + from repoze.bfg.interfaces import ISettings + from repoze.bfg.interfaces import ILogger + from repoze.bfg.interfaces import IRootFactory + settings = registry.getUtility(ISettings) + logger = registry.getUtility(ILogger, name='repoze.bfg.debug') + effective_rootfactory = registry.getUtility(IRootFactory) + self.assertEqual(logger.name, 'repoze.bfg.debug') + self.assertEqual(settings.reload_templates, True) + self.assertEqual(settings.debug_authorization, True) + self.failUnless(isinstance(effective_rootfactory, RoutesRootFactory)) + self.assertEqual(effective_rootfactory.default_root_factory, + rootfactory) + + def test_routes_in_config_no_rootfactory(self): + options= {'reload_templates':True, + 'debug_authorization':True} + from repoze.bfg.urldispatch import RoutesRootFactory + from repoze.bfg.router import DefaultRootFactory + from repoze.bfg.tests import routesapp + registry = self._callFUT(None, routesapp, options=options) + from repoze.bfg.interfaces import ISettings + from repoze.bfg.interfaces import ILogger + from repoze.bfg.interfaces import IRootFactory + settings = registry.getUtility(ISettings) + logger = registry.getUtility(ILogger, name='repoze.bfg.debug') + rootfactory = registry.getUtility(IRootFactory) + self.assertEqual(logger.name, 'repoze.bfg.debug') + self.assertEqual(settings.reload_templates, True) + self.assertEqual(settings.debug_authorization, True) + self.failUnless(isinstance(rootfactory, RoutesRootFactory)) + self.assertEqual(rootfactory.default_root_factory, DefaultRootFactory) + + def test_no_routes_in_config_no_rootfactory(self): + from repoze.bfg.router import DefaultRootFactory + from repoze.bfg.interfaces import IRootFactory + options= {'reload_templates':True, + 'debug_authorization':True} + from repoze.bfg.tests import fixtureapp + registry = self._callFUT(None, fixtureapp, options=options) + rootfactory = registry.getUtility(IRootFactory) + self.assertEqual(rootfactory, DefaultRootFactory) + + def test_authorization_policy_no_authentication_policy(self): + from repoze.bfg.interfaces import IAuthorizationPolicy + authzpolicy = DummyContext() + from repoze.bfg.tests import routesapp + logger = DummyLogger() + registry = self._callFUT( + None, routesapp, authorization_policy=authzpolicy, + debug_logger=logger) + self.failIf(registry.queryUtility(IAuthorizationPolicy)) + self.assertEqual(logger.messages, []) + + def test_authentication_policy_no_authorization_policy(self): + from repoze.bfg.interfaces import IAuthorizationPolicy + from repoze.bfg.interfaces import IAuthenticationPolicy + from repoze.bfg.authorization import ACLAuthorizationPolicy + authnpolicy = DummyContext() + from repoze.bfg.tests import routesapp + logger = DummyLogger() + registry = self._callFUT( + None, routesapp, authentication_policy=authnpolicy, + debug_logger=logger) + self.assertEqual(registry.getUtility(IAuthenticationPolicy), + authnpolicy) + self.assertEqual( + registry.getUtility(IAuthorizationPolicy).__class__, + ACLAuthorizationPolicy) + self.assertEqual(len(logger.messages), 1) # deprecation warning + + def test_authentication_policy_and_authorization_policy(self): + from repoze.bfg.interfaces import IAuthorizationPolicy + from repoze.bfg.interfaces import IAuthenticationPolicy + authnpolicy = DummyContext() + authzpolicy = DummyContext() + from repoze.bfg.tests import routesapp + logger = DummyLogger() + registry = self._callFUT( + None, routesapp, authentication_policy=authnpolicy, + authorization_policy = authzpolicy, + debug_logger=logger) + self.assertEqual(registry.getUtility(IAuthenticationPolicy), + authnpolicy) + self.assertEqual(registry.getUtility(IAuthorizationPolicy), + authzpolicy) + self.assertEqual(len(logger.messages), 1) # deprecation warning + + def test_lock_and_unlock(self): + from repoze.bfg.tests import fixtureapp + rootfactory = DummyRootFactory(None) + dummylock = DummyLock() + registry = self._callFUT( + rootfactory, fixtureapp, filename='configure.zcml', + lock=dummylock) + self.assertEqual(dummylock.acquired, True) + self.assertEqual(dummylock.released, True) + +class DummyRegistryManager: + def push(self, registry): + from repoze.bfg.threadlocal import manager + manager.push(registry) + self.pushed = True + + def pop(self): + from repoze.bfg.threadlocal import manager + manager.pop() + self.popped = True + +class DummyRootFactory: + def __init__(self, root): + self.root = root + + def __call__(self, environ): + return self.root + +class DummyLogger: + def __init__(self): + self.messages = [] + def info(self, msg): + self.messages.append(msg) + warn = info + debug = info + +class DummyContext: + pass + +class DummyLock: + def acquire(self): + self.acquired = True + + def release(self): + self.released = True + +class DummyThreadLocalManager: + def __init__(self, data): + self.data = data + + def pop(self): + self.popped = True + return self.data + + def push(self, data): + self.pushed = data + diff --git a/repoze/bfg/tests/test_registry.py b/repoze/bfg/tests/test_registry.py index f1bc6a6f0..57e8134c9 100644 --- a/repoze/bfg/tests/test_registry.py +++ b/repoze/bfg/tests/test_registry.py @@ -1,7 +1,5 @@ import unittest -from repoze.bfg.testing import cleanUp - class TestRegistry(unittest.TestCase): def _getTargetClass(self): from repoze.bfg.registry import Registry @@ -39,47 +37,3 @@ class TestRegistry(unittest.TestCase): registry.registerSubscriptionAdapter(EventHandler, [IFoo], Interface) self.assertEqual(registry.has_listeners, True) -class TestPopulateRegistry(unittest.TestCase): - def setUp(self): - cleanUp() - - def tearDown(self): - cleanUp() - - def _callFUT(self, *arg, **kw): - from repoze.bfg.registry import populateRegistry - return populateRegistry(*arg, **kw) - - def test_it(self): - from repoze.bfg.tests import fixtureapp - dummylock = DummyLock() - dummyregmgr = DummyThreadLocalManager({'registry':None}) - from zope.component.registry import Components - registry = Components('hello') - self._callFUT(registry, - 'configure.zcml', - fixtureapp, - lock=dummylock, - manager=dummyregmgr) - self.assertEqual(dummylock.acquired, True) - self.assertEqual(dummylock.released, True) - self.assertEqual(dummyregmgr.data['registry'], None) - -class DummyThreadLocalManager: - def __init__(self, data): - self.data = data - - def pop(self): - self.popped = True - return self.data - - def push(self, data): - self.pushed = data - -class DummyLock: - def acquire(self): - self.acquired = True - - def release(self): - self.released = True - diff --git a/repoze/bfg/tests/test_router.py b/repoze/bfg/tests/test_router.py index 5c39b65f0..151734b9b 100644 --- a/repoze/bfg/tests/test_router.py +++ b/repoze/bfg/tests/test_router.py @@ -2,7 +2,7 @@ import unittest from repoze.bfg.testing import cleanUp -class RouterTests(unittest.TestCase): +class TestRouter(unittest.TestCase): def setUp(self): from repoze.bfg.registry import Registry from zope.component import getSiteManager @@ -407,230 +407,6 @@ class RouterTests(unittest.TestCase): self.assertEqual(len(router.threadlocal_manager.pushed), 1) self.assertEqual(len(router.threadlocal_manager.popped), 1) -class MakeAppTests(unittest.TestCase): - def setUp(self): - cleanUp() - - def tearDown(self): - cleanUp() - - def _callFUT(self, *arg, **kw): - from repoze.bfg.router import make_app - return make_app(*arg, **kw) - - def test_fixtureapp_default_filename_withpackage(self): - manager = DummyRegistryManager() - from repoze.bfg.tests import fixtureapp - rootfactory = DummyRootFactory(None) - app = self._callFUT(rootfactory, fixtureapp, manager=manager) - self.assertEqual(app.registry.__name__, 'repoze.bfg.tests.fixtureapp') - from repoze.bfg.tests.fixtureapp.models import IFixture - self.failUnless(app.registry.queryUtility(IFixture)) # only in c.zcml - - def test_fixtureapp_explicit_filename(self): - manager = DummyRegistryManager() - from repoze.bfg.tests import fixtureapp - rootfactory = DummyRootFactory(None) - app = self._callFUT(rootfactory, fixtureapp, filename='another.zcml', - manager=manager) - self.assertEqual(app.registry.__name__, 'repoze.bfg.tests.fixtureapp') - from repoze.bfg.tests.fixtureapp.models import IFixture - self.failIf(app.registry.queryUtility(IFixture)) # only in c.zcml - - def test_fixtureapp_explicit_filename_in_options(self): - import os - manager = DummyRegistryManager() - rootfactory = DummyRootFactory(None) - from repoze.bfg.tests import fixtureapp - zcmlfile = os.path.join(os.path.dirname(fixtureapp.__file__), - 'another.zcml') - app = self._callFUT(rootfactory, fixtureapp, filename='configure.zcml', - options={'configure_zcml':zcmlfile}, - manager=manager) - self.assertEqual(app.registry.__name__, 'repoze.bfg.tests.fixtureapp') - from repoze.bfg.tests.fixtureapp.models import IFixture - self.failIf(app.registry.queryUtility(IFixture)) # only in c.zcml - - def test_fixtureapp_explicit_specification_in_options(self): - manager = DummyRegistryManager() - rootfactory = DummyRootFactory(None) - from repoze.bfg.tests import fixtureapp - zcmlfile = 'repoze.bfg.tests.fixtureapp.subpackage:yetanother.zcml' - app = self._callFUT(rootfactory, fixtureapp, filename='configure.zcml', - options={'configure_zcml':zcmlfile}, - manager=manager) - self.assertEqual(app.registry.__name__, - 'repoze.bfg.tests.fixtureapp.subpackage') - from repoze.bfg.tests.fixtureapp.models import IFixture - self.failIf(app.registry.queryUtility(IFixture)) # only in c.zcml - - def test_fixtureapp_filename_hascolon_isabs(self): - manager = DummyRegistryManager() - rootfactory = DummyRootFactory(None) - from repoze.bfg.tests import fixtureapp - zcmlfile = 'repoze.bfg.tests.fixtureapp.subpackage:yetanother.zcml' - class Dummy: - def isabs(self, name): - return True - os = Dummy() - os.path = Dummy() - self.assertRaises(IOError, self._callFUT, - rootfactory, - fixtureapp, - filename='configure.zcml', - options={'configure_zcml':zcmlfile}, - manager=manager, - os=os) - - def test_event(self): - manager = DummyRegistryManager() - def subscriber(event): - event.app.created = True - from repoze.bfg.interfaces import IWSGIApplicationCreatedEvent - from zope.component import getGlobalSiteManager - getGlobalSiteManager().registerHandler( - subscriber, - (IWSGIApplicationCreatedEvent,) - ) - from repoze.bfg.tests import fixtureapp - rootfactory = DummyRootFactory(None) - app = self._callFUT(rootfactory, fixtureapp, manager=manager) - assert app.created is True - - def test_custom_settings(self): - manager = DummyRegistryManager() - options= {'mysetting':True} - from repoze.bfg.tests import fixtureapp - rootfactory = DummyRootFactory(None) - app = self._callFUT(rootfactory, fixtureapp, options=options, - manager=manager) - from repoze.bfg.interfaces import ISettings - settings = app.registry.getUtility(ISettings) - self.assertEqual(settings.reload_templates, False) - self.assertEqual(settings.debug_authorization, False) - self.assertEqual(settings.mysetting, True) - - def test_registrations(self): - manager = DummyRegistryManager() - options= {'reload_templates':True, - 'debug_authorization':True} - from repoze.bfg.tests import fixtureapp - rootfactory = DummyRootFactory(None) - app = self._callFUT(rootfactory, fixtureapp, options=options, - manager=manager) - from repoze.bfg.interfaces import ISettings - from repoze.bfg.interfaces import ILogger - from repoze.bfg.interfaces import IRootFactory - settings = app.registry.getUtility(ISettings) - logger = app.registry.getUtility(ILogger, name='repoze.bfg.debug') - rootfactory = app.registry.getUtility(IRootFactory) - self.assertEqual(logger.name, 'repoze.bfg.debug') - self.assertEqual(settings.reload_templates, True) - self.assertEqual(settings.debug_authorization, True) - self.assertEqual(rootfactory, rootfactory) - self.failUnless(manager.pushed and manager.popped) - - def test_routes_in_config_with_rootfactory(self): - manager = DummyRegistryManager() - options= {'reload_templates':True, - 'debug_authorization':True} - from repoze.bfg.urldispatch import RoutesRootFactory - from repoze.bfg.tests import routesapp - rootfactory = DummyRootFactory(None) - app = self._callFUT(rootfactory, routesapp, options=options, - manager=manager) - from repoze.bfg.interfaces import ISettings - from repoze.bfg.interfaces import ILogger - from repoze.bfg.interfaces import IRootFactory - settings = app.registry.getUtility(ISettings) - logger = app.registry.getUtility(ILogger, name='repoze.bfg.debug') - effective_rootfactory = app.registry.getUtility(IRootFactory) - self.assertEqual(logger.name, 'repoze.bfg.debug') - self.assertEqual(settings.reload_templates, True) - self.assertEqual(settings.debug_authorization, True) - self.failUnless(isinstance(effective_rootfactory, RoutesRootFactory)) - self.assertEqual(effective_rootfactory.default_root_factory, - rootfactory) - self.failUnless(manager.pushed and manager.popped) - - def test_routes_in_config_no_rootfactory(self): - manager = DummyRegistryManager() - options= {'reload_templates':True, - 'debug_authorization':True} - from repoze.bfg.urldispatch import RoutesRootFactory - from repoze.bfg.router import DefaultRootFactory - from repoze.bfg.tests import routesapp - app = self._callFUT(None, routesapp, options=options, - manager=manager) - from repoze.bfg.interfaces import ISettings - from repoze.bfg.interfaces import ILogger - from repoze.bfg.interfaces import IRootFactory - settings = app.registry.getUtility(ISettings) - logger = app.registry.getUtility(ILogger, name='repoze.bfg.debug') - rootfactory = app.registry.getUtility(IRootFactory) - self.assertEqual(logger.name, 'repoze.bfg.debug') - self.assertEqual(settings.reload_templates, True) - self.assertEqual(settings.debug_authorization, True) - self.failUnless(isinstance(rootfactory, RoutesRootFactory)) - self.assertEqual(rootfactory.default_root_factory, DefaultRootFactory) - self.failUnless(manager.pushed and manager.popped) - - def test_no_routes_in_config_no_rootfactory(self): - manager = DummyRegistryManager() - from repoze.bfg.router import DefaultRootFactory - from repoze.bfg.interfaces import IRootFactory - options= {'reload_templates':True, - 'debug_authorization':True} - from repoze.bfg.tests import fixtureapp - app = self._callFUT(None, fixtureapp, options=options, - manager=manager) - rootfactory = app.registry.getUtility(IRootFactory) - self.assertEqual(rootfactory, DefaultRootFactory) - - def test_authorization_policy_no_authentication_policy(self): - manager = DummyRegistryManager() - from repoze.bfg.interfaces import IAuthorizationPolicy - authzpolicy = DummyContext() - from repoze.bfg.tests import routesapp - logger = DummyLogger() - app = self._callFUT(None, routesapp, authorization_policy=authzpolicy, - debug_logger=logger, manager=manager) - self.failIf(app.registry.queryUtility(IAuthorizationPolicy)) - self.assertEqual(logger.messages, []) - - def test_authentication_policy_no_authorization_policy(self): - manager = DummyRegistryManager() - from repoze.bfg.interfaces import IAuthorizationPolicy - from repoze.bfg.interfaces import IAuthenticationPolicy - from repoze.bfg.authorization import ACLAuthorizationPolicy - authnpolicy = DummyContext() - from repoze.bfg.tests import routesapp - logger = DummyLogger() - app = self._callFUT(None, routesapp, authentication_policy=authnpolicy, - debug_logger=logger, manager=manager) - self.assertEqual(app.registry.getUtility(IAuthenticationPolicy), - authnpolicy) - self.assertEqual( - app.registry.getUtility(IAuthorizationPolicy).__class__, - ACLAuthorizationPolicy) - self.assertEqual(len(logger.messages), 1) # deprecation warning - - def test_authentication_policy_and_authorization_policy(self): - manager = DummyRegistryManager() - from repoze.bfg.interfaces import IAuthorizationPolicy - from repoze.bfg.interfaces import IAuthenticationPolicy - authnpolicy = DummyContext() - authzpolicy = DummyContext() - from repoze.bfg.tests import routesapp - logger = DummyLogger() - app = self._callFUT(None, routesapp, authentication_policy=authnpolicy, - authorization_policy = authzpolicy, - debug_logger=logger, manager=manager) - self.assertEqual(app.registry.getUtility(IAuthenticationPolicy), - authnpolicy) - self.assertEqual(app.registry.getUtility(IAuthorizationPolicy), - authzpolicy) - self.assertEqual(len(logger.messages), 1) # deprecation warning class TestDefaultRootFactory(unittest.TestCase): def _getTargetClass(self): @@ -652,13 +428,38 @@ class TestDefaultRootFactory(unittest.TestCase): self.assertEqual(root.a, 1) self.assertEqual(root.b, 2) +class TestMakeApp(unittest.TestCase): + def setUp(self): + cleanUp() -class DummyRegistryManager: - def push(self, registry): - self.pushed = True + def tearDown(self): + cleanUp() - def pop(self): - self.popped = True + def _callFUT(self, *arg, **kw): + from repoze.bfg.router import make_app + return make_app(None, *arg, **kw) + + def test_it(self): + from repoze.bfg.interfaces import IWSGIApplicationCreatedEvent + from zope.component import getSiteManager + from repoze.bfg.tests import fixtureapp + sm = getSiteManager() + class DummyMakeRegistry(object): + def __call__(self, *arg): + self.arg = arg + return sm + def subscriber(event): + event.app.created = True + dummy_make_registry = DummyMakeRegistry() + manager = DummyRegistryManager() + sm.registerHandler(subscriber, (IWSGIApplicationCreatedEvent,)) + rootfactory = DummyRootFactory(None) + app = self._callFUT(rootfactory, fixtureapp, manager=manager, + make_registry=dummy_make_registry) + self.failUnless(app.created) + self.failUnless(manager.pushed) + self.failUnless(manager.popped) + self.assertEqual(len(dummy_make_registry.arg), 6) class DummyContext: pass @@ -720,3 +521,10 @@ class DummyLogger: warn = info debug = info +class DummyRegistryManager: + def push(self, registry): + self.pushed = True + + def pop(self): + self.popped = True + diff --git a/repoze/bfg/tests/test_security.py b/repoze/bfg/tests/test_security.py index ef08e8641..d3d89923d 100644 --- a/repoze/bfg/tests/test_security.py +++ b/repoze/bfg/tests/test_security.py @@ -124,18 +124,18 @@ class TestViewExecutionPermitted(unittest.TestCase): self.request = request return allow checker = Checker() - gsm = zope.component.getGlobalSiteManager() - gsm.registerAdapter(checker, (Interface, Interface), - ISecuredView, - view_name) + sm = zope.component.getSiteManager() + sm.registerAdapter(checker, (Interface, Interface), + ISecuredView, + view_name) return checker def test_no_permission(self): import zope.component - gsm = zope.component.getGlobalSiteManager() + sm = zope.component.getSiteManager() from repoze.bfg.interfaces import ISettings settings = dict(debug_authorization=True) - gsm.registerUtility(settings, ISettings) + sm.registerUtility(settings, ISettings) context = DummyContext() request = DummyRequest({}) result = self._callFUT(context, request, '') @@ -162,16 +162,16 @@ def _registerAuthenticationPolicy(result): from repoze.bfg.interfaces import IAuthenticationPolicy policy = DummyAuthenticationPolicy(result) import zope.component - gsm = zope.component.getGlobalSiteManager() - gsm.registerUtility(policy, IAuthenticationPolicy) + sm = zope.component.getSiteManager() + sm.registerUtility(policy, IAuthenticationPolicy) return policy def _registerAuthorizationPolicy(result): from repoze.bfg.interfaces import IAuthorizationPolicy policy = DummyAuthorizationPolicy(result) import zope.component - gsm = zope.component.getGlobalSiteManager() - gsm.registerUtility(policy, IAuthorizationPolicy) + sm = zope.component.getSiteManager() + sm.registerUtility(policy, IAuthorizationPolicy) return policy diff --git a/repoze/bfg/tests/test_settings.py b/repoze/bfg/tests/test_settings.py index bef8297bf..ba43fac04 100644 --- a/repoze/bfg/tests/test_settings.py +++ b/repoze/bfg/tests/test_settings.py @@ -35,10 +35,11 @@ class TestGetSettings(unittest.TestCase): self.assertEqual(self._callFUT(), None) def test_it_withsettings(self): + from zope.component import getSiteManager from repoze.bfg.interfaces import ISettings - from zope.component import provideUtility + sm = getSiteManager() settings = {'a':1} - provideUtility(settings, ISettings) + sm.registerUtility(settings, ISettings) self.assertEqual(self._callFUT(), settings) class TestGetOptions(unittest.TestCase): diff --git a/repoze/bfg/tests/test_testing.py b/repoze/bfg/tests/test_testing.py index 05cddc980..7e468725a 100644 --- a/repoze/bfg/tests/test_testing.py +++ b/repoze/bfg/tests/test_testing.py @@ -507,39 +507,52 @@ class TestDummyTemplateRenderer(unittest.TestCase): result = renderer({'a':1, 'b':2}) self.assertEqual(result, 'abc') -class CleanUpTests(object): +class TestSetUp(unittest.TestCase): def setUp(self): - from repoze.bfg.testing import _cleanups - self._old_cleanups = _cleanups[:] - - def tearDown(self): - from repoze.bfg import testing - testing._cleanups = self._old_cleanups - -class TestAddCleanUp(CleanUpTests, unittest.TestCase): - def _getFUT(self, ): - from repoze.bfg.testing import addCleanUp - return addCleanUp + from zope.component import getSiteManager + getSiteManager.reset() + + def _callFUT(self, ): + from repoze.bfg.testing import setUp + return setUp() def test_it(self): - addCleanUp = self._getFUT() - addCleanUp(1, ('a', 'b'), {'foo':'bar'}) - from repoze.bfg.testing import _cleanups - self.assertEqual(_cleanups[-1], (1, ('a', 'b'), {'foo':'bar'})) + from zope.component.globalregistry import base + from zope.interface import Interface + 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(CleanUpTests, unittest.TestCase): - def _getFUT(self, ): +class TestCleanUp(TestSetUp): + def _callFUT(self, ): from repoze.bfg.testing import cleanUp - return cleanUp + return cleanUp() + +class TestTearDown(unittest.TestCase): + def setUp(self): + from zope.component import getSiteManager + getSiteManager.reset() + + def _callFUT(self, ): + from repoze.bfg.testing import tearDown + return tearDown() def test_it(self): - from repoze.bfg.testing import _cleanups - cleanUp = self._getFUT() - L = [] - def f(*arg, **kw): - L.append((arg, kw)) - _cleanups.append((f, ('a', '1'), {'kw':'1'})) - cleanUp() - self.assertEqual(L, [(('a', '1'), {'kw':'1'})]) - + from zope.component.globalregistry import base + from zope.component import getSiteManager + getSiteManager.sethook(lambda *arg: 'foo') + sm = getSiteManager() + self.assertEqual(sm, 'foo') + self._callFUT() + newsm = getSiteManager() + self.assertEqual(newsm, base) diff --git a/repoze/bfg/tests/test_threadlocal.py b/repoze/bfg/tests/test_threadlocal.py index 2cf405508..09a25debd 100644 --- a/repoze/bfg/tests/test_threadlocal.py +++ b/repoze/bfg/tests/test_threadlocal.py @@ -21,10 +21,11 @@ class TestThreadLocalManager(unittest.TestCase): self.assertEqual(local.get(), 1) def test_default(self): - from zope.component import getGlobalSiteManager - local = self._makeOne(getGlobalSiteManager) + def thedefault(): + return '123' + local = self._makeOne(thedefault) self.assertEqual(local.stack, []) - self.assertEqual(local.get(), getGlobalSiteManager()) + self.assertEqual(local.get(), '123') def test_push_and_pop(self): local = self._makeOne() diff --git a/repoze/bfg/tests/test_traversal.py b/repoze/bfg/tests/test_traversal.py index a4e90bc07..69a8b4b6f 100644 --- a/repoze/bfg/tests/test_traversal.py +++ b/repoze/bfg/tests/test_traversal.py @@ -391,10 +391,10 @@ class FindModelTests(unittest.TestCase): def _registerTraverserFactory(self, traverser): import zope.component - gsm = zope.component.getGlobalSiteManager() + sm = zope.component.getSiteManager() from repoze.bfg.interfaces import ITraverserFactory from zope.interface import Interface - gsm.registerAdapter(traverser, (Interface,), ITraverserFactory) + sm.registerAdapter(traverser, (Interface,), ITraverserFactory) def test_list(self): model = DummyContext() @@ -663,10 +663,10 @@ class TraversalContextURLTests(unittest.TestCase): def _registerTraverserFactory(self, traverser): import zope.component - gsm = zope.component.getGlobalSiteManager() + sm = zope.component.getSiteManager() from repoze.bfg.interfaces import ITraverserFactory from zope.interface import Interface - gsm.registerAdapter(traverser, (Interface,), ITraverserFactory) + sm.registerAdapter(traverser, (Interface,), ITraverserFactory) def test_class_conforms_to_IContextURL(self): from zope.interface.verify import verifyClass @@ -849,12 +849,12 @@ class TestVirtualRoot(unittest.TestCase): return virtual_root(model, request) def test_registered(self): - from zope.component import getGlobalSiteManager + from zope.component import getSiteManager from repoze.bfg.interfaces import IContextURL from zope.interface import Interface - gsm = getGlobalSiteManager() - gsm.registerAdapter(DummyContextURL, (Interface,Interface), - IContextURL) + sm = getSiteManager() + sm.registerAdapter(DummyContextURL, (Interface,Interface), + IContextURL) context = DummyContext() request = DummyRequest() result = self._callFUT(context, request) @@ -880,10 +880,10 @@ class TraverseTests(unittest.TestCase): def _registerTraverserFactory(self, traverser): import zope.component - gsm = zope.component.getGlobalSiteManager() + sm = zope.component.getSiteManager() from repoze.bfg.interfaces import ITraverserFactory from zope.interface import Interface - gsm.registerAdapter(traverser, (Interface,), ITraverserFactory) + sm.registerAdapter(traverser, (Interface,), ITraverserFactory) def test_list(self): model = DummyContext() @@ -977,10 +977,10 @@ class UnderTraverseTests(unittest.TestCase): def _registerTraverserFactory(self, traverser): import zope.component - gsm = zope.component.getGlobalSiteManager() + sm = zope.component.getSiteManager() from repoze.bfg.interfaces import ITraverserFactory from zope.interface import Interface - gsm.registerAdapter(traverser, (Interface,), ITraverserFactory) + sm.registerAdapter(traverser, (Interface,), ITraverserFactory) def test_default_traverser_factory(self): context = DummyContext() diff --git a/repoze/bfg/tests/test_url.py b/repoze/bfg/tests/test_url.py index 1199328e3..6754f6f34 100644 --- a/repoze/bfg/tests/test_url.py +++ b/repoze/bfg/tests/test_url.py @@ -16,15 +16,15 @@ class ModelURLTests(unittest.TestCase): def _registerContextURL(self): from repoze.bfg.interfaces import IContextURL from zope.interface import Interface - from zope.component import getGlobalSiteManager + from zope.component import getSiteManager class DummyContextURL(object): def __init__(self, context, request): pass def __call__(self): return 'http://example.com/context/' - gsm = getGlobalSiteManager() - gsm.registerAdapter(DummyContextURL, (Interface, Interface), - IContextURL) + sm = getSiteManager() + sm.registerAdapter(DummyContextURL, (Interface, Interface), + IContextURL) def test_root_default(self): self._registerContextURL() diff --git a/repoze/bfg/tests/test_view.py b/repoze/bfg/tests/test_view.py index 8e2310c09..eee5a61bd 100644 --- a/repoze/bfg/tests/test_view.py +++ b/repoze/bfg/tests/test_view.py @@ -11,9 +11,9 @@ class BaseTest(object): def _registerView(self, app, name, *for_): import zope.component - gsm = zope.component.getGlobalSiteManager() + sm = zope.component.getSiteManager() from repoze.bfg.interfaces import IView - gsm.registerAdapter(app, for_, IView, name) + sm.registerAdapter(app, for_, IView, name) def _makeEnviron(self, **extras): environ = { @@ -466,8 +466,8 @@ class AppendSlashNotFoundView(unittest.TestCase): return self.routelist mapper = DummyMapper() import zope.component - gsm = zope.component.getGlobalSiteManager() - gsm.registerUtility(mapper, IRoutesMapper) + sm = zope.component.getSiteManager() + sm.registerUtility(mapper, IRoutesMapper) return mapper def test_no_mapper(self): diff --git a/repoze/bfg/tests/test_zcml.py b/repoze/bfg/tests/test_zcml.py index 1f0fc44d8..d592fd902 100644 --- a/repoze/bfg/tests/test_zcml.py +++ b/repoze/bfg/tests/test_zcml.py @@ -1486,11 +1486,11 @@ class TestConnectRouteFunction(unittest.TestCase): return connect_route(path, name, factory) def _registerRoutesMapper(self): - from zope.component import getGlobalSiteManager - gsm = getGlobalSiteManager() + from zope.component import getSiteManager + sm = getSiteManager() mapper = DummyMapper() from repoze.bfg.interfaces import IRoutesMapper - gsm.registerUtility(mapper, IRoutesMapper) + sm.registerUtility(mapper, IRoutesMapper) return mapper def test_defaults(self): diff --git a/repoze/bfg/threadlocal.py b/repoze/bfg/threadlocal.py index 5039ec92f..4fa53fa1e 100644 --- a/repoze/bfg/threadlocal.py +++ b/repoze/bfg/threadlocal.py @@ -1,4 +1,5 @@ import threading + from zope.component import getGlobalSiteManager class ThreadLocalManager(threading.local): @@ -30,10 +31,8 @@ class ThreadLocalManager(threading.local): self.stack[:] = [] def defaults(): - defaults = {'request':None} gsm = getGlobalSiteManager() - defaults['registry'] = gsm - return defaults + return {'request':None, 'registry':gsm} manager = ThreadLocalManager(default=defaults) |
