From addf9976fd1ec2b3e5c9db80957ab7b6907edab1 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 23 Dec 2009 22:40:59 +0000 Subject: - The ``repoze.bfg.testing.registerRoutesMapper`` API (added in an early 1.2 alpha) was deprecated. Its import now generates a deprecation warning. - Docs roles. --- CHANGES.txt | 7 + repoze/bfg/configuration.py | 127 ++++++++---- repoze/bfg/testing.py | 429 ++++++++++++++++++++++----------------- repoze/bfg/tests/test_testing.py | 3 +- 4 files changed, 329 insertions(+), 237 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index b0f7a614f..5ac86a6a9 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -32,6 +32,13 @@ Documentation ``repoze.bfg.authorization``, and ``repoze.bfg.interfaces`` modules to API documentation. +Deprecations +------------ + +- The ``repoze.bfg.testing.registerRoutesMapper`` API (added in an + early 1.2 alpha) was deprecated. Its import now generates a + deprecation warning. + 1.2a7 (2009-12-20) ================== diff --git a/repoze/bfg/configuration.py b/repoze/bfg/configuration.py index 9028866a0..7ac284de0 100644 --- a/repoze/bfg/configuration.py +++ b/repoze/bfg/configuration.py @@ -344,13 +344,26 @@ class Configurator(object): return subscriber def add_settings(self, settings=None, **kw): - """ Add additional settings beyond the ones passed in as - ``settings`` to the constructor of this object to the - dictionarylike object which is returned from - :func:`repoze.bfg.settings.get_settings` API. The - ``settings`` argument should be a dictionarylike object or - ``None``. Arbitrary ``kw`` arguments can be passed in to - augment the settings dict.""" + """Augment the ``settings`` argument passed in to the + Configurator constructor with one or more 'setting' key/value + pairs. A setting is a single key/value pair in the + dictionary-ish object returned from the API + :func:`repoze.bfg.settings.get_settings`. + + You may pass a dictionary:: + + config.add_settings({'external_uri':'http://example.com'}) + + Or a set of key/value pairs:: + + config.add_settings(external_uri='http://example.com') + + This function is useful when you need to test code that + calls the :func:`repoze.bfg.settings.get_settings` API and which + uses return values from that API. + + .. note:: This method is new as of :mod:`repoze.bfg` 1.2. + """ if settings is None: settings = {} utility = self.registry.queryUtility(ISettings) @@ -1188,19 +1201,30 @@ class Configurator(object): def testing_securitypolicy(self, userid=None, groupids=(), permissive=True): - """Unit/integration testing helper: registers a a pair of - dummy :mod:`repoze.bfg` security policies: an - :term:`authorization policy` and an :term:`authentication - policy`) using the userid ``userid`` and the group ids - ``groupids``. If ``permissive`` is true, a 'permissive' - authorization policy is registered; this policy allows all - access. If ``permissive`` is false, a nonpermissive - authorization policy is registered; this policy denies all - access. This function is most useful when testing code that - uses the APIs named - :func:`repoze.bfg.security.has_permission`, + """Unit/integration testing helper: Registers a pair of faux + :mod:`repoze.bfg` security policies: a :term:`authentication + policy` and a :term:`authorization policy`. + + The behavior of the registered :term:`authorization policy` + depends on the ``permissive`` argument. If ``permissive`` is + true, a permissive :term:`authorization policy` is registered; + this policy allows all access. If ``permissive`` is false, a + nonpermissive :term:`authorization policy` is registered; this + policy denies all access. + + The behavior of the registered :term:`authentication policy` + depends on the values provided for the ``userid`` and + ``groupids`` argument. The authentication policy will return + the userid identifier implied by the ``userid`` argument and + the group ids implied by the ``groupids`` argument when the + :func:`repoze.bfg.security.authenticated_userid` or + :func:`repoze.bfg.security.effective_principals` APIs are + used. + + This function is most useful when testing code that uses + the APIs named :func:`repoze.bfg.security.has_permission`, :func:`repoze.bfg.security.authenticated_userid`, - :func:`repoze.bfg.security.effective_principals` and + :func:`repoze.bfg.security.effective_principals`, and :func:`repoze.bfg.security.principals_allowed_by_permission`. """ from repoze.bfg.testing import DummySecurityPolicy @@ -1210,16 +1234,18 @@ class Configurator(object): def testing_models(self, models): """Unit/integration testing helper: registers a dictionary of - models that can be resolved via - :func:`repoze.bfg.traversal.find_model`. This is most useful - for testing code that wants to call the - :func:`repoze.bfg.traversal.find_model` API. The - ``find_model`` API is called with a path as one of its - arguments. If the dictionary you register when calling this - method contains that path as a string key (e.g. ``/foo/bar`` - or ``foo/bar``), the corresponding value will be returned to - ``find_model`` (and thus to your code) when ``find_model`` is - called with an equivalent path string or tuple.""" + :term:`model` objects that can be resolved via the + :func:`repoze.bfg.traversal.find_model` API. + + The :func:`repoze.bfg.traversal.find_model` API is called with + a path as one of its arguments. If the dictionary you + register when calling this method contains that path as a + string key (e.g. ``/foo/bar`` or ``foo/bar``), the + corresponding value will be returned to ``find_model`` (and + thus to your code) when + :func:`repoze.bfg.traversal.find_model` is called with an + equivalent path string or tuple. + """ class DummyTraverserFactory: def __init__(self, context): self.context = context @@ -1235,17 +1261,23 @@ class Configurator(object): ITraverser) return models - def testing_add_subscriber(self, event_iface=Interface): + def testing_add_subscriber(self, event_iface=None): """Unit/integration testing helper: Registers a - :term:`subscriber` listening for events of the type - ``event_iface`` and returns a list which is appended to by the - subscriber. When an event is dispatched that matches - ``event_iface``, that event will be appended to the list. You - can then compare the values in the list to expected event - notifications. This method is useful when testing code that - wants to call :meth:`repoze.bfg.registry.Registry.notify`, + :term:`subscriber` which listens for events of the type + ``event_iface``. This method returns a list object which is + appended to by the subscriber whenever an event is captured. + + When an event is dispatched that matches the value implied by + the ``event_iface`` argument, that event will be appended to + the list. You can then compare the values in the list to + expected event notifications. This method is useful when + testing code that wants to call + :meth:`repoze.bfg.registry.Registry.notify`, :func:`zope.component.event.dispatch` or :func:`zope.component.event.objectEventNotify`. + + The default value of ``event_iface`` (``None``) implies a + subscriber registered for *any* kind of event. """ L = [] def subscriber(*event): @@ -1254,14 +1286,19 @@ class Configurator(object): return L def testing_add_template(self, path, renderer=None): - """ Register a template tenderer at ``path`` (usually a - relative filename ala ``templates/foo.pt``) and return the - renderer object. If the ``renderer`` argument is None, a - 'dummy' renderer will be used. This function is useful when - testing code that calls the ``render_template_to_response`` or - any other ``render_template*`` API of any of the built-in - templating systems (see :mod:`repoze.bfg.chameleon_zpt` and - :mod:`repoze.bfg.chameleon_text`).""" + """Unit/integration testing helper: register a template + tenderer at ``path`` (usually a relative filename ala + ``templates/foo.pt``) and return the renderer object. If the + ``renderer`` argument is None, a 'dummy' renderer will be + used. This function is useful when testing code that calls + the + :func:`repoze.bfg.chameleon_zpt.render_template_to_response` + function or + :func:`repoze.bfg.chameleon_text.render_template_to_response` + function or any other ``render_template*`` API of any built-in + templating system (see :mod:`repoze.bfg.chameleon_zpt` and + :mod:`repoze.bfg.chameleon_text`). + """ from repoze.bfg.testing import DummyTemplateRenderer if renderer is None: renderer = DummyTemplateRenderer() diff --git a/repoze/bfg/testing.py b/repoze/bfg/testing.py index 11127a65c..3f6d8e207 100644 --- a/repoze/bfg/testing.py +++ b/repoze/bfg/testing.py @@ -34,21 +34,35 @@ zcml_configure # prevent pyflakes from complaining _marker = object() def registerDummySecurityPolicy(userid=None, groupids=(), permissive=True): - """ Registers a a pair of dummy :mod:`repoze.bfg` security - policies: an :term:`authorization policy` and an - :term:`authentication policy`) using the userid ``userid`` and the - group ids ``groupids``. If ``permissive`` is true, a 'permissive' - authorization policy is registered; this policy allows all access. - If ``permissive`` is false, a nonpermissive authorization policy - is registered; this policy denies all access. This function is - most useful when testing code that uses the - ``repoze.bfg.security`` APIs named ``has_permission``, - ``authenticated_userid``, ``effective_principals``, - ``principals_allowed_by_permission``, and so on. + """ Registers a pair of faux :mod:`repoze.bfg` security policies: + a :term:`authentication policy` and a :term:`authorization + policy`. + + The behavior of the registered :term:`authorization policy` + depends on the ``permissive`` argument. If ``permissive`` is + true, a permissive :term:`authorization policy` is registered; + this policy allows all access. If ``permissive`` is false, a + nonpermissive :term:`authorization policy` is registered; this + policy denies all access. + + The behavior of the registered :term:`authentication policy` + depends on the values provided for the ``userid`` and ``groupids`` + argument. The authentication policy will return the userid + identifier implied by the ``userid`` argument and the group ids + implied by the ``groupids`` argument when the + :func:`repoze.bfg.security.authenticated_userid` or + :func:`repoze.bfg.security.effective_principals` APIs are used. + + This function is most useful when testing code that uses the APIs + named :func:`repoze.bfg.security.has_permission`, + :func:`repoze.bfg.security.authenticated_userid`, + :func:`repoze.bfg.security.effective_principals`, and + :func:`repoze.bfg.security.principals_allowed_by_permission`. .. warning:: This API is deprecated as of :mod:`repoze.bfg` 1.2. - Instead use the ``testing_securitypolicy`` method of a - :term:`Configurator` in your unit and integration tests. + Instead use the + :meth:`repoze.bfg.configuration.Configurator.testing_securitypolicy` + method in your unit and integration tests. """ registry = get_current_registry() config = Configurator(registry=registry) @@ -56,39 +70,47 @@ def registerDummySecurityPolicy(userid=None, groupids=(), permissive=True): permissive=permissive) def registerModels(models): - """ Registers a dictionary of models that can be resolved via - ``repoze.bfg.traversal.find_model``. This is most useful for - testing code that wants to call the - ``repoze.bfg.traversal.find_model`` API. The ``find_model`` API - is called with a path as one of its arguments. If the dictionary - you register when calling this method contains that path as a - string key (e.g. ``/foo/bar`` or ``foo/bar``), the corresponding - value will be returned to ``find_model`` (and thus to your code) - when ``find_model`` is called with an equivalent path string or - tuple. + """ Registers a dictionary of :term:`model` objects that can be + resolved via the :func:`repoze.bfg.traversal.find_model` API. + + The :func:`repoze.bfg.traversal.find_model` API is called with a + path as one of its arguments. If the dictionary you register when + calling this method contains that path as a string key + (e.g. ``/foo/bar`` or ``foo/bar``), the corresponding value will + be returned to ``find_model`` (and thus to your code) when + :func:`repoze.bfg.traversal.find_model` is called with an + equivalent path string or tuple. .. warning:: This API is deprecated as of :mod:`repoze.bfg` 1.2. - Instead use the ``testing_models`` method of a - :term:`Configurator` in your unit and integration tests. + Instead use the + :meth:`repoze.bfg.configuration.Configurator.testing_models` + method in your unit and integration tests. """ registry = get_current_registry() config = Configurator(registry=registry) return config.testing_models(models) -def registerEventListener(event_iface=Interface): +def registerEventListener(event_iface=None): """ Registers an :term:`event` listener (aka :term:`subscriber`) - listening for events of the type ``event_iface`` and returns a - list which is appended to by the subscriber. When an event is - dispatched that matches ``event_iface``, that event will be - appended to the list. You can then compare the values in the list - to expected event notifications. This method is useful when - testing code that wants to call ``registry.notify``, - ``zope.component.event.dispatch`` or - ``zope.component.event.objectEventNotify``. + listening for events of the type ``event_iface``. This method + returns a list object which is appended to by the subscriber + whenever an event is captured. + + When an event is dispatched that matches ``event_iface``, that + event will be appended to the list. You can then compare the + values in the list to expected event notifications. This method + is useful when testing code that wants to call + :meth:`repoze.bfg.registry.Registry.notify`, + :func:`zope.component.event.dispatch` or + :func:`zope.component.event.objectEventNotify`. + + The default value of ``event_iface`` (``None``) implies a + subscriber registered for *any* kind of event. .. warning:: This API is deprecated as of :mod:`repoze.bfg` 1.2. - Instead use the ``testing_add_subscriber`` method of a - :term:`Configurator` in your unit and integration tests. + Instead use the + :meth:`repoze.bfg.configuration.Cofigurator.testing_add_subscriber` + method in your unit and integration tests. """ registry = get_current_registry() config = Configurator(registry=registry) @@ -99,12 +121,17 @@ def registerTemplateRenderer(path, renderer=None): filename ala ``templates/foo.pt``) and return the renderer object. If the ``renderer`` argument is None, a 'dummy' renderer will be used. This function is useful when testing code that calls the - ``render_template_to_response`` or any other ``render_template*`` - API of any of the built-in templating systems. + :func:`repoze.bfg.chameleon_zpt.render_template_to_response` + function or + :func:`repoze.bfg.chameleon_text.render_template_to_response` + function or any other ``render_template*`` API of any built-in + templating system (see :mod:`repoze.bfg.chameleon_zpt` and + :mod:`repoze.bfg.chameleon_text`). .. warning:: This API is deprecated as of :mod:`repoze.bfg` 1.2. - Instead use the ``testing_add_template`` method of a - :term:`Configurator` in your unit and integration tests. + Instead use the + :meth:`repoze.bfg.configuration.Configurator.testing_add_template`` + method in your unit and integration tests. """ registry = get_current_registry() @@ -117,21 +144,26 @@ registerDummyRenderer = registerTemplateRenderer def registerView(name, result='', view=None, for_=(Interface, Interface), permission=None): - """ Registers a :mod:`repoze.bfg` view callable under the name - ``name``. The view will return a webob Response object with the - ``result`` value as its body attribute. To gain more control, if - you pass in a non-None ``view``, this view function will be used - instead of an automatically generated view function (and - ``result`` is not used). To protect the view using a - :term:`permission`, pass in a non-``None`` value as - ``permission``. This permission will be checked by any existing - security policy when view execution is attempted. This function - is useful when dealing with code that wants to call, - e.g. ``repoze.bfg.view.render_view_to_response``. + """ Registers a :mod:`repoze.bfg` :term:`view callable` under the + name implied by the ``name`` argument. The view will return a + :term:`WebOb` :term:`Response` object with the value implied by + the ``result`` argument as its ``body`` attribute. To gain more + control, if you pass in a non-``None`` ``view`` argument, this + value will be used as a view callable instead of an automatically + generated view callable (and ``result`` is not used). + + To protect the view using a :term:`permission`, pass in a + non-``None`` value as ``permission``. This permission will be + checked by any active :term:`authorization policy` when view + execution is attempted. + + This function is useful when testing code which calls + :func:`repoze.bfg.view.render_view_to_response`. .. warning:: This API is deprecated as of :mod:`repoze.bfg` 1.2. - Instead use the ``add_view`` method of a - :term:`Configurator` in your unit and integration tests. + Instead use the + :meth:`repoze.bfg.configuration.Configurator.add_view`` + method in your unit and integration tests. """ if view is None: def view(context, request): @@ -152,18 +184,8 @@ def registerView(name, result='', view=None, for_=(Interface, Interface), def registerViewPermission(name, result=True, viewpermission=None, for_=(Interface, Interface)): - """ Registers a :mod:`repoze.bfg` 'view permission' object under - the name ``name``. The view permission return a result denoted by - the ``result`` argument. If ``result`` is True, a - ``repoze.bfg.security.Allowed`` object is returned; else a - ``repoze.bfg.security.Denied`` object is returned. To gain more - control, if you pass in a non-None ``viewpermission``, this view - permission object will be used instead of an automatically - generated view permission (and ``result`` is not used). This - method is useful when dealing with code that wants to call, - e.g. ``repoze.bfg.view.view_execution_permitted``. Note that view - permissions are not checked unless a security policy is in effect - (see ``registerSecurityPolicy``). + """ Registers a :mod:`repoze.bfg` 'view permission' object under a + name implied by the ``name`` argument. .. warning:: This function was deprecated in repoze.bfg 1.1; it has no real effect in 1.2+. @@ -189,43 +211,53 @@ deprecated('registerViewPermission', '``permission`` argument.') def registerUtility(impl, iface=Interface, name=''): - """ Register a utility component. + """ Register a ZCA utility component. - ``impl`` is the implementation of the utility. ``iface`` is the - interface type ``zope.interface.Interface`` by default. ``name`` - is the empty string by default. + The ``impl`` argument specifies the implementation of the utility. + The ``iface`` argument specifies the :term:`interface` which will + be later required to look up the utility + (:class:`zope.interface.Interface`, by default). The ``name`` + argument implies the utility name; it is the empty string by + default. See `The ZCA book `_ for more information about ZCA utilities. .. warning:: This API is deprecated as of :mod:`repoze.bfg` 1.2. - Instead use the ``registerUtility`` method of the ``registry`` - attribute of a :term:`Configurator` in your unit and - integration tests. + Instead use the :meth:`repoze.bfg.Registry.registerUtility` + method. The ``registry`` attribute of a :term:`Configurator` + in your unit and integration tests is an intstance of the + :class:`repoze.bfg.Registry` class. """ reg = get_current_registry() reg.registerUtility(impl, iface, name=name) return impl def registerAdapter(impl, for_=Interface, provides=Interface, name=''): - """ Register an adapter component. + """ Register a ZCA adapter component. + + The ``impl`` argument specifies the implementation of the + component (often a class). The ``for_`` argument implies the + ``for`` interface type used for this registration; it is + :class:`zope.interface.Interface` by default. If ``for`` is not a + tuple or list, it will be converted to a one-tuple before being + passed to underlying :meth:`repoze.bfg.registry.registerAdapter` + API. - ``impl`` is the implementation of the component (often a class). - ``for_`` is the ``for`` interface type - ``zope.interface.Interface`` by default. If ``for`` is not a tuple - or list, it will be converted to a one-tuple before being passed - to underlying ZCA registerAdapter API. ``name`` is the empty - string by default. ``provides`` is the ZCA provides interface, - also ``zope.interface.Interface`` by default. ``name`` is the - name of the adapter, the empty string by default. + The ``provides`` argument specifies the ZCA 'provides' interface, + :class:`zope.interface.Interface` by default. + The ``name`` argument is the empty string by default; it implies + the name under which the adapter is registered. + See `The ZCA book `_ for more information about ZCA adapters. .. warning:: This API is deprecated as of :mod:`repoze.bfg` 1.2. - Instead use the ``registerAdapter`` method of the ``registry`` - attribute of a :term:`Configurator` in your unit and integration - tests. + Instead use the :meth:`repoze.bfg.Registry.registerAdapter` + method. The ``registry`` attribute of a :term:`Configurator` + in your unit and integration tests is an intstance of the + :class:`repoze.bfg.Registry` class. """ reg = get_current_registry() if not isinstance(for_, (tuple, list)): @@ -234,21 +266,24 @@ def registerAdapter(impl, for_=Interface, provides=Interface, name=''): return impl def registerSubscriber(subscriber, iface=Interface): - """ Register a subscriber component. + """ Register a ZCA subscriber component. + + The ``subscriber`` argument specifies the implementation of the + subscriber component (often a function). - ``subscriber`` is the implementation of the component (often a - function). ``iface`` is the interface type the subscriber will be - registered for (``zope.interface.Interface`` by default). If - ``iface`` is not a tuple or list, it will be converted to a - one-tuple before being passed to underlying ZCA registerHandler - query. + The ``iface`` argument is the interface type for which the + subscriber will be registered (:class:`zope.interface.Interface` + by default). If ``iface`` is not a tuple or list, it will be + converted to a one-tuple before being passed to the underlying ZCA + :meth:`repoze.bfg.registry.registerHandler` method. See `The ZCA book `_ for more information about ZCA subscribers. .. warning:: This API is deprecated as of :mod:`repoze.bfg` 1.2. - Instead use the ``add_subscriber`` method of a - :term:`Configurator` in your unit and integration tests. + Instead use the + :meth:`repoze.bfg.configuration.Configurator.add_subscriber` + method in your unit and integration tests. """ registry = get_current_registry() config = Configurator(registry) @@ -256,55 +291,53 @@ def registerSubscriber(subscriber, iface=Interface): def registerRoute(path, name, factory=None): """ Register a new :term:`route` using a path - (e.g. ``:pagename``), a name (e.g. 'home'), and an optional root - factory. This is useful for testing code that calls - e.g. ``route_url``. + (e.g. ``:pagename``), a name (e.g. ``home``), and an optional root + factory. + + The ``path`` argument implies the route path. The ``name`` + argument implies the route name. The ``factory`` argument implies + a :term:`root factory` associated with the route. + + This API is useful for testing code that calls + e.g. :func:`repoze.bfg.url.route_url`. .. note:: This API was added in :mod:`repoze.bfg` version 1.1. .. warning:: This API is deprecated as of :mod:`repoze.bfg` 1.2. - Instead use the ``add_route`` method of a - :term:`Configurator` in your unit and integration tests. + Instead use the + :meth:`repoze.bfg.configuration.Configurator.add_route` + method in your unit and integration tests. """ reg = get_current_registry() config = Configurator(registry=reg) return config.add_route(name, path, factory=factory) def registerRoutesMapper(root_factory=None): - """ Register a new routes mapper using the provided - ``root_factory`` as the root factory it wraps. If - ``root_factory`` is ``None``, use a default root factory - implementation. - - Use of this function is beneficial when you want to register an - empty routes mapper with a custom ``root_factory``. - - Note that ``repoze.bfg.testing.registerRoute`` also registers a - route mapper if one is not already registered, thus it is not - necessary to call this function before calling - ``repoze.bfg.testing.registerRoute``. However, if - ``repoze.bfg.registerRoutesMapper`` *is* called before - ``repoze.bfg.testing.registerRoute``, the routes mapper registered - by ``repoze.bfg.testing.registerRoutesMapper`` will be used as the - mapper in which the route is registered during - ``repoze.bfg.testing.registerRoute``. + """ Register a routes 'mapper' object. .. note:: This API was added in :mod:`repoze.bfg` version 1.1. - .. warning:: This API is not useful in :mod:`repoze.bfg` 1.2 or better - because a route mapper is no longer required to be - present for successful operation of the system without - any routes present. + .. warning:: This API is deprecated in :mod:`repoze.bfg` 1.2: + a route mapper is no longer required to be present for + successful system operation. """ mapper = RoutesMapper() reg = get_current_registry() reg.registerUtility(mapper, IRoutesMapper) return mapper +deprecated('registerRoutesMapper', + 'registerRoutesMapper has been deprecated. As of repoze.bfg ' + 'version 1.2, a route mapper is not required to be registered ' + 'for normal system operation; if you actually do want a route to ' + 'be registered, use the ' + '``repoze.bfg.configuration.Configurator.add_route`` ' + 'method; this will cause a route mapper to be registered also.') + def registerSettings(dictarg=None, **kw): - """ Register one or more 'setting' key/value pairs. A setting is + """Register one or more 'setting' key/value pairs. A setting is a single key/value pair in the dictionary-ish object returned from - the API ``repoze.bfg.settings.get_settings()``. + the API :func:`repoze.bfg.settings.get_settings`. You may pass a dictionary:: @@ -315,14 +348,15 @@ def registerSettings(dictarg=None, **kw): registerSettings(external_uri='http://example.com') Use of this function is required when you need to test code that - calls the ``repoze.bfg.settings.get_settings()`` API and uses - return values from it. + calls the :func:`repoze.bfg.settings.get_settings` API and which + uses return values from that API. .. note:: This API is new as of :mod:`repoze.bfg` 1.1. .. warning:: This API is deprecated as of :mod:`repoze.bfg` 1.2. - Instead use the ``add_settings`` method of a - :term:`Configurator` in your unit and integration tests. + Instead use the + :meth:`repoze.bfg.configuration.Configurator.add_settings` + method in your unit and integration tests. """ registry = get_current_registry() config = Configurator(registry=registry) @@ -368,10 +402,10 @@ class DummySecurityPolicy: class DummyTemplateRenderer: """ An instance of this class is returned from - ``registerTemplateRenderer``. It has a helper function - (``assert_``) that makes it possible to make an assertion which - compares data passed to the renderer by the view function against - expected key/value pairs. + :func:`repoze.bfg.testing.registerTemplateRenderer`. It has a + helper function (``assert_``) that makes it possible to make an + assertion which compares data passed to the renderer by the view + function against expected key/value pairs. """ def __init__(self, string_response=''): @@ -397,10 +431,11 @@ class DummyTemplateRenderer: def assert_(self, **kw): """ Accept an arbitrary set of assertion key/value pairs. For each assertion key/value pair assert that the renderer - (eg. ``render_template_to_response``) received the key with a - value that equals the asserted value. If the renderer did not - receive the key at all, or the value received by the renderer - doesn't match the assertion value, raise an AssertionError.""" + (eg. :func:`repoze.bfg.chameleon_zpt.render_template_to_response`) + received the key with a value that equals the asserted + value. If the renderer did not receive the key at all, or the + value received by the renderer doesn't match the assertion + value, raise an :exc:`AssertionError`.""" for k, v in kw.items(): myval = self._received.get(k, _marker) if myval is _marker: @@ -414,19 +449,18 @@ class DummyTemplateRenderer: return True class DummyModel: - """ A dummy :mod:`repoze.bfg` model object. The value of ``name`` - to the constructor will be used as the ``__name__`` attribute of - the model. the value of ``parent`` will be used as the - ``__parent__`` attribute of the model. """ + """ A dummy :mod:`repoze.bfg` :term:`model` object.""" def __init__(self, __name__=None, __parent__=None, __provides__=None, **kw): - """ The he model's ``__name__`` attribute will be set to the - value of ``__name__``, and the model's ``__parent__`` - attribute will be set to the value of ``__parent__``. If - ``__provides__`` is specified, it should be an interface - object or tuple of interface objects that will be attached to - the resulting model via ``zope.interface.alsoProvides``. Any - extra keywords will be set as direct attributes of the model.""" + """ The model's ``__name__`` attribute will be set to the + value of the ``__name__`` argument, and the model's + ``__parent__`` attribute will be set to the value of the + ``__parent__`` argument. If ``__provides__`` is specified, it + should be an interface object or tuple of interface objects + that will be attached to the resulting model via + :func:`zope.interface.alsoProvides`. Any extra keywords passed + in the ``kw`` argumnent will be set as direct attributes of + the model object.""" self.__name__ = __name__ self.__parent__ = __parent__ if __provides__ is not None: @@ -482,10 +516,11 @@ class DummyModel: def clone(self, __name__=_marker, __parent__=_marker, **kw): """ Create a clone of the model object. If ``__name__`` or - ``__parent__`` is passed in, use the value to override the - existing ``__name__`` or ``__parent__`` of the model. If any - extra keyword args are passed in, use these keywords to add to - or override existing model keywords (attributes).""" + ``__parent__`` arguments are passed, use these values to + override the existing ``__name__`` or ``__parent__`` of the + model. If any extra keyword args are passed in via the ``kw`` + aargument, use these keywords to add to or override existing + model keywords (attributes).""" oldkw = self.kw.copy() oldkw.update(kw) inst = self.__class__(self.__name__, self.__parent__, **oldkw) @@ -558,8 +593,8 @@ class DummyRequest: def setUp(registry=None, request=None, hook_zca=True): """ - Set BFG registry and request thread locals for the duration of a - single unit test. + Set :mod:`repoze.bfg` registry and request thread locals for the + duration of a single unit test. .. note:: The ``setUp`` function is new as of :mod:`repoze.bfg` 1.1. @@ -567,56 +602,66 @@ def setUp(registry=None, request=None, hook_zca=True): Use this function in the ``setUp`` method of a unittest test case which directly or indirectly uses: - - any of the ``register*`` functions in ``repoze.bfg.testing`` - (such as ``repoze.bfg.testing.registerModels``) + - any of the ``register*`` functions in :mod:`repoze.bfg.testing` + (such as :func:`repoze.bfg.testing.registerModels`) + + - any method of the :class:`repoze.bfg.configuration.Configurator` + object returned by this function. - - the ``repoze.bfg.threadlocal.get_current_registry`` or - ``repoze.bfg.threadlocal.get_current_request`` functions. + - the :func:`repoze.bfg.threadlocal.get_current_registry` or + :func:`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. + :func:`repoze.bfg.threadlocal.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 + :term:`application registry` will be created (an instance of the + :class:`repoze.bfg.registry.Registry` class). If the ``registry`` + argument is not ``None``, the value passed in should be an + instance of the :class:`repoze.bfg.registry.Registry` class or a + suitable testing analogue. + + After ``setUp`` is finished, the registry returned by the + :func:`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) . + :func:`repoze.bfg.testing.tearDown` is called (or + :func:`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( + If the ``hook_zca`` argument is ``True``, ``setUp`` will attempt + to perform the operation ``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. + (e.g. :func:`zope.component.getSiteManager`, + :func:`zope.component.getAdapter`, and so on) to use the registry + constructed by ``setUp`` as the value it returns from + :func:`zope.component.getSiteManager`. If the + :mod:`zope.component` package cannot be imported, or if + ``hook_zca`` is ``False``, the hook will not be set. + + This function returns an instance of the + :class:`repoze.bfg.configuration.Configurator` class, which can be + used for further configuration to set up an environment suitable + for a unit or integration test. The ``registry`` attribute + attached to the Configurator instance represents the 'current' + :term:`application registry`; the same registry will be returned + by :func:`repoze.bfg.threadlocal.get_current_registry` during the + execution of the test. .. note:: The ``hook_zca`` argument is new as of :mod:`repoze.bfg` 1.2. - .. warning:: Although this method of tearing a test setup down + .. note:: The return value (a ``Configurator`` instance) is new as + of :mod:`repoze.bfg` 1.2 (previous versions used to return + ``None``) + + .. warning:: Although this method of setting up a test registry will never disappear, after :mod:`repoze.bfg` 1.2a6, using the ``begin`` and ``end`` methods of a ``Configurator`` are prefered to using @@ -630,18 +675,20 @@ def setUp(registry=None, request=None, hook_zca=True): config = Configurator(registry=registry) hook_zca and config.hook_zca() config.begin(request=request) + return config 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. + """Undo the effects :func:`repoze.bfg.testing.setUp`. Use this + function in the ``tearDown`` method of a unit test that uses + :func:`repoze.bfg.testing.setUp` in its ``setUp`` method. .. note:: This function is new as of :mod:`repoze.bfg` 1.1. 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. + :func:`zope.component.getSiteManager.reset`. This undoes the + action of :func:`repoze.bfg.testing.setUp` called with the + argument ``hook_zca=True``. If :mod:`zope.component` cannot be + imported, ignore the argument. .. note:: The ``unhook_zca`` argument is new as of :mod:`repoze.bfg` 1.2. @@ -677,9 +724,9 @@ def tearDown(unhook_zca=True): _clearContext() # XXX why? def cleanUp(*arg, **kw): - """ ``repoze.bfg.testing.cleanUp`` is an alias for - ``repoze.bfg.testing.setUp``. Although this function is + """ :func:`repoze.bfg.testing.cleanUp` is an alias for + :func:`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(*arg, **kw) + return setUp(*arg, **kw) diff --git a/repoze/bfg/tests/test_testing.py b/repoze/bfg/tests/test_testing.py index 4762eda19..1b3d731fa 100644 --- a/repoze/bfg/tests/test_testing.py +++ b/repoze/bfg/tests/test_testing.py @@ -560,9 +560,10 @@ class Test_setUp(unittest.TestCase): old = True manager.push(old) try: - self._callFUT() + config = self._callFUT() current = manager.get() self.failIf(current is old) + self.assertEqual(config.registry, current['registry']) self.assertEqual(current['registry'].__class__, Registry) self.assertEqual(current['request'], None) finally: -- cgit v1.2.3