diff options
| author | Chris McDonough <chrism@plope.com> | 2010-10-25 10:29:31 -0400 |
|---|---|---|
| committer | Chris McDonough <chrism@plope.com> | 2010-10-25 10:29:31 -0400 |
| commit | 64372401084889a440c9d990a0febc221e3e4b5c (patch) | |
| tree | c8939a341505d19f19fa6918d264b4e1d95326f8 /repoze | |
| parent | c8e78c2037806f3e5dab57de635bf80865b7061d (diff) | |
| download | pyramid-64372401084889a440c9d990a0febc221e3e4b5c.tar.gz pyramid-64372401084889a440c9d990a0febc221e3e4b5c.tar.bz2 pyramid-64372401084889a440c9d990a0febc221e3e4b5c.zip | |
first pass at converting bfg to pyramid namespace
Diffstat (limited to 'repoze')
200 files changed, 0 insertions, 29405 deletions
diff --git a/repoze/bfg/__init__.py b/repoze/bfg/__init__.py deleted file mode 100644 index f33bdbc35..000000000 --- a/repoze/bfg/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__import__('pkg_resources').declare_namespace(__name__) #pragma NO COVERAGE diff --git a/repoze/bfg/authentication.py b/repoze/bfg/authentication.py deleted file mode 100644 index 54e106af5..000000000 --- a/repoze/bfg/authentication.py +++ /dev/null @@ -1,441 +0,0 @@ -from codecs import utf_8_decode -from codecs import utf_8_encode -import datetime -import time - -from paste.auth import auth_tkt -from paste.request import get_cookies - -from zope.interface import implements - -from repoze.bfg.interfaces import IAuthenticationPolicy - -from repoze.bfg.request import add_global_response_headers -from repoze.bfg.security import Authenticated -from repoze.bfg.security import Everyone - -class CallbackAuthenticationPolicy(object): - """ Abstract class """ - def authenticated_userid(self, request): - userid = self._get_userid(request) - if userid is None: - return None - if self.callback is None: - return userid - if self.callback(userid, request) is not None: # is not None! - return userid - - def effective_principals(self, request): - effective_principals = [Everyone] - userid = self._get_userid(request) - if userid is None: - return effective_principals - if self.callback is None: - groups = [] - else: - groups = self.callback(userid, request) - if groups is None: # is None! - return effective_principals - effective_principals.append(Authenticated) - effective_principals.append(userid) - effective_principals.extend(groups) - - return effective_principals - - -class RepozeWho1AuthenticationPolicy(CallbackAuthenticationPolicy): - """ A :mod:`repoze.bfg` :term:`authentication policy` which - obtains data from the :mod:`repoze.who` 1.X WSGI 'API' (the - ``repoze.who.identity`` key in the WSGI environment). - - Constructor Arguments - - ``identifier_name`` - - Default: ``auth_tkt``. The :mod:`repoze.who` plugin name that - performs remember/forget. Optional. - - ``callback`` - - Default: ``None``. A callback passed the :mod:`repoze.who` - identity and the :term:`request`, expected to return ``None`` - if the user represented by the identity doesn't exist or a - sequence of group identifiers (possibly empty) if the user - does exist. If ``callback`` is None, the userid will be - assumed to exist with no groups. - """ - implements(IAuthenticationPolicy) - - def __init__(self, identifier_name='auth_tkt', callback=None): - self.identifier_name = identifier_name - self.callback = callback - - def _get_identity(self, request): - return request.environ.get('repoze.who.identity') - - def _get_identifier(self, request): - plugins = request.environ.get('repoze.who.plugins') - if plugins is None: - return None - identifier = plugins[self.identifier_name] - return identifier - - def authenticated_userid(self, request): - identity = self._get_identity(request) - if identity is None: - return None - if self.callback is None: - return identity['repoze.who.userid'] - if self.callback(identity, request) is not None: # is not None! - return identity['repoze.who.userid'] - - def effective_principals(self, request): - effective_principals = [Everyone] - identity = self._get_identity(request) - if identity is None: - return effective_principals - if self.callback is None: - groups = [] - else: - groups = self.callback(identity, request) - if groups is None: # is None! - return effective_principals - userid = identity['repoze.who.userid'] - effective_principals.append(Authenticated) - effective_principals.append(userid) - effective_principals.extend(groups) - - return effective_principals - - def remember(self, request, principal, **kw): - identifier = self._get_identifier(request) - if identifier is None: - return [] - environ = request.environ - identity = {'repoze.who.userid':principal} - return identifier.remember(environ, identity) - - def forget(self, request): - identifier = self._get_identifier(request) - if identifier is None: - return [] - identity = self._get_identity(request) - return identifier.forget(request.environ, identity) - -class RemoteUserAuthenticationPolicy(CallbackAuthenticationPolicy): - """ A :mod:`repoze.bfg` :term:`authentication policy` which - obtains data from the ``REMOTE_USER`` WSGI environment variable. - - Constructor Arguments - - ``environ_key`` - - Default: ``REMOTE_USER``. The key in the WSGI environ which - provides the userid. - - ``callback`` - - Default: ``None``. A callback passed the userid and the request, - expected to return None if the userid doesn't exist or a sequence - of group identifiers (possibly empty) if the user does exist. - If ``callback`` is None, the userid will be assumed to exist with no - groups. - """ - implements(IAuthenticationPolicy) - - def __init__(self, environ_key='REMOTE_USER', callback=None): - self.environ_key = environ_key - self.callback = callback - - def _get_userid(self, request): - return request.environ.get(self.environ_key) - - def remember(self, request, principal, **kw): - return [] - - def forget(self, request): - return [] - -class AuthTktAuthenticationPolicy(CallbackAuthenticationPolicy): - """ A :mod:`repoze.bfg` :term:`authentication policy` which - obtains data from an :class:`paste.auth.auth_tkt` cookie. - - Constructor Arguments - - ``secret`` - - The secret (a string) used for auth_tkt cookie signing. - Required. - - ``callback`` - - Default: ``None``. A callback passed the userid and the - request, expected to return ``None`` if the userid doesn't - exist or a sequence of group identifiers (possibly empty) if - the user does exist. If ``callback`` is ``None``, the userid - will be assumed to exist with no groups. Optional. - - ``cookie_name`` - - Default: ``repoze.bfg.auth_tkt``. The cookie name used - (string). Optional. - - ``secure`` - - Default: ``False``. Only send the cookie back over a secure - conn. Optional. - - ``include_ip`` - - Default: ``False``. Make the requesting IP address part of - the authentication data in the cookie. Optional. - - ``timeout`` - - Default: ``None``. Maximum number of seconds which a newly - issued ticket will be considered valid. After this amount of - time, the ticket will expire (effectively logging the user - out). If this value is ``None``, the ticket never expires. - Optional. - - ``reissue_time`` - - Default: ``None``. If this parameter is set, it represents the - number of seconds that must pass before an authentication token - cookie is reissued. The duration is measured as the number of - seconds since the last auth_tkt cookie was issued and 'now'. - If the ``timeout`` value is ``None``, this parameter has no - effect. If this parameter is provided, and the value of - ``timeout`` is not ``None``, the value of ``reissue_time`` must - be smaller than value of ``timeout``. A good rule of thumb: if - you want auto-reissued cookies: set this to the ``timeout`` - value divided by ten. If this value is ``0``, a new ticket - cookie will be reissued on every request which needs - authentication. Optional. - - ``max_age`` - - Default: ``None``. The max age of the auth_tkt cookie, in - seconds. This differs from ``timeout`` inasmuch as ``timeout`` - represents the lifetime of the ticket contained in the cookie, - while this value represents the lifetime of the cookie itself. - When this value is set, the cookie's ``Max-Age`` and - ``Expires`` settings will be set, allowing the auth_tkt cookie - to last between browser sessions. It is typically nonsensical - to set this to a value that is lower than ``timeout`` or - ``reissue_time``, although it is not explicitly prevented. - Optional. - - ``path`` - - Default: ``/``. The path for which the auth_tkt cookie is valid. - May be desirable if the application only serves part of a domain. - Optional. - - ``http_only`` - - Default: ``False``. Hide cookie from JavaScript by setting the - HttpOnly flag. Not honored by all browsers. - Optional. - """ - implements(IAuthenticationPolicy) - def __init__(self, - secret, - callback=None, - cookie_name='repoze.bfg.auth_tkt', - secure=False, - include_ip=False, - timeout=None, - reissue_time=None, - max_age=None, - path="/", - http_only=False, - ): - self.cookie = AuthTktCookieHelper( - secret, - cookie_name=cookie_name, - secure=secure, - include_ip=include_ip, - timeout=timeout, - reissue_time=reissue_time, - max_age=max_age, - http_only=http_only, - path=path, - ) - self.callback = callback - - def _get_userid(self, request): - result = self.cookie.identify(request) - if result: - return result['userid'] - - def remember(self, request, principal, **kw): - """ Accepts the following kw args: ``max_age``.""" - return self.cookie.remember(request, principal, **kw) - - def forget(self, request): - return self.cookie.forget(request) - -def b64encode(v): - return v.encode('base64').strip().replace('\n', '') - -def b64decode(v): - return v.decode('base64') - -EXPIRE = object() - -class AuthTktCookieHelper(object): - auth_tkt = auth_tkt # for tests - - userid_type_decoders = { - 'int':int, - 'unicode':lambda x: utf_8_decode(x)[0], # bw compat for old cookies - 'b64unicode': lambda x: utf_8_decode(b64decode(x))[0], - 'b64str': lambda x: b64decode(x), - } - - userid_type_encoders = { - int: ('int', str), - long: ('int', str), - unicode: ('b64unicode', lambda x: b64encode(utf_8_encode(x)[0])), - str: ('b64str', lambda x: b64encode(x)), - } - - def __init__(self, secret, cookie_name='auth_tkt', secure=False, - include_ip=False, timeout=None, reissue_time=None, - max_age=None, http_only=False, path="/"): - self.secret = secret - self.cookie_name = cookie_name - self.include_ip = include_ip - self.secure = secure - self.timeout = timeout - if reissue_time is not None and timeout is not None: - if reissue_time > timeout: - raise ValueError('reissue_time must be lower than timeout') - self.reissue_time = reissue_time - self.max_age = max_age - self.http_only = http_only - self.path = path - - static_flags = [] - if self.secure: - static_flags.append('; Secure') - if self.http_only: - static_flags.append('; HttpOnly') - self.static_flags = "".join(static_flags) - - def _get_cookies(self, environ, value, max_age=None): - if max_age is EXPIRE: - max_age = "; Max-Age=0; Expires=Wed, 31-Dec-97 23:59:59 GMT" - elif max_age is not None: - later = datetime.datetime.utcnow() + datetime.timedelta( - seconds=int(max_age)) - # Wdy, DD-Mon-YY HH:MM:SS GMT - expires = later.strftime('%a, %d %b %Y %H:%M:%S GMT') - # the Expires header is *required* at least for IE7 (IE7 does - # not respect Max-Age) - max_age = "; Max-Age=%s; Expires=%s" % (max_age, expires) - else: - max_age = '' - - cur_domain = environ.get('HTTP_HOST', environ.get('SERVER_NAME')) - wild_domain = '.' + cur_domain - - cookies = [ - ('Set-Cookie', '%s="%s"; Path=%s%s%s' % ( - self.cookie_name, value, self.path, max_age, self.static_flags)), - ('Set-Cookie', '%s="%s"; Path=%s; Domain=%s%s%s' % ( - self.cookie_name, value, self.path, cur_domain, max_age, - self.static_flags)), - ('Set-Cookie', '%s="%s"; Path=%s; Domain=%s%s%s' % ( - self.cookie_name, value, self.path, wild_domain, max_age, - self.static_flags)) - ] - - return cookies - - def identify(self, request): - environ = request.environ - cookies = get_cookies(environ) - cookie = cookies.get(self.cookie_name) - - if cookie is None or not cookie.value: - return None - - if self.include_ip: - remote_addr = environ['REMOTE_ADDR'] - else: - remote_addr = '0.0.0.0' - - try: - timestamp, userid, tokens, user_data = self.auth_tkt.parse_ticket( - self.secret, cookie.value, remote_addr) - except self.auth_tkt.BadTicket: - return None - - now = time.time() - - if self.timeout and ( (timestamp + self.timeout) < now ): - return None - - userid_typename = 'userid_type:' - user_data_info = user_data.split('|') - for datum in filter(None, user_data_info): - if datum.startswith(userid_typename): - userid_type = datum[len(userid_typename):] - decoder = self.userid_type_decoders.get(userid_type) - if decoder: - userid = decoder(userid) - - reissue = self.reissue_time is not None - - if not hasattr(request, '_authtkt_reissued'): - if reissue and ( (now - timestamp) > self.reissue_time): - headers = self.remember(request, userid, max_age=self.max_age) - add_global_response_headers(request, headers) - request._authtkt_reissued = True - - environ['REMOTE_USER_TOKENS'] = tokens - environ['REMOTE_USER_DATA'] = user_data - environ['AUTH_TYPE'] = 'cookie' - - identity = {} - identity['timestamp'] = timestamp - identity['userid'] = userid - identity['tokens'] = tokens - identity['userdata'] = user_data - return identity - - def forget(self, request): - # return a set of expires Set-Cookie headers - environ = request.environ - return self._get_cookies(environ, '', max_age=EXPIRE) - - def remember(self, request, userid, max_age=None): - max_age = max_age or self.max_age - environ = request.environ - - if self.include_ip: - remote_addr = environ['REMOTE_ADDR'] - else: - remote_addr = '0.0.0.0' - - user_data = '' - - encoding_data = self.userid_type_encoders.get(type(userid)) - if encoding_data: - encoding, encoder = encoding_data - userid = encoder(userid) - user_data = 'userid_type:%s' % encoding - - ticket = self.auth_tkt.AuthTicket( - self.secret, - userid, - remote_addr, - user_data=user_data, - cookie_name=self.cookie_name, - secure=self.secure) - - cookie_value = ticket.cookie_value() - return self._get_cookies(environ, cookie_value, max_age) - diff --git a/repoze/bfg/authorization.py b/repoze/bfg/authorization.py deleted file mode 100644 index 8c46b4a33..000000000 --- a/repoze/bfg/authorization.py +++ /dev/null @@ -1,133 +0,0 @@ -from zope.interface import implements - -from repoze.bfg.interfaces import IAuthorizationPolicy - -from repoze.bfg.location import lineage -from repoze.bfg.security import ACLAllowed -from repoze.bfg.security import ACLDenied -from repoze.bfg.security import Allow -from repoze.bfg.security import Deny -from repoze.bfg.security import Everyone - -class ACLAuthorizationPolicy(object): - """ An :term:`authorization policy` which consults an :term:`ACL` - object attached to a :term:`context` to determine authorization - information about a :term:`principal` or multiple principals. - If the context is part of a :term:`lineage`, the context's parents - are consulted for ACL information too. The following is true - about this security policy. - - - When checking whether the 'current' user is permitted (via the - ``permits`` method), the security policy consults the - ``context`` for an ACL first. If no ACL exists on the context, - or one does exist but the ACL does not explicitly allow or deny - access for any of the effective principals, consult the - context's parent ACL, and so on, until the lineage is exhausted - or we determine that the policy permits or denies. - - During this processing, if any :data:`repoze.bfg.security.Deny` - ACE is found matching any principal in ``principals``, stop - processing by returning an - :class:`repoze.bfg.security.ACLDenied` instance (equals - ``False``) immediately. If any - :data:`repoze.bfg.security.Allow` ACE is found matching any - principal, stop processing by returning an - :class:`repoze.bfg.security.ACLAllowed` instance (equals - ``True``) immediately. If we exhaust the context's - :term:`lineage`, and no ACE has explicitly permitted or denied - access, return an instance of - :class:`repoze.bfg.security.ACLDenied` (equals ``False``). - - - When computing principals allowed by a permission via the - :func:`repoze.bfg.security.principals_allowed_by_permission` - method, we compute the set of principals that are explicitly - granted the ``permission`` in the provided ``context``. We do - this by walking 'up' the object graph *from the root* to the - context. During this walking process, if we find an explicit - :data:`repoze.bfg.security.Allow` ACE for a principal that - matches the ``permission``, the principal is included in the - allow list. However, if later in the walking process that - principal is mentioned in any :data:`repoze.bfg.security.Deny` - ACE for the permission, the principal is removed from the allow - list. If a :data:`repoze.bfg.security.Deny` to the principal - :data:`repoze.bfg.security.Everyone` is encountered during the - walking process that matches the ``permission``, the allow list - is cleared for all principals encountered in previous ACLs. The - walking process ends after we've processed the any ACL directly - attached to ``context``; a set of principals is returned. - """ - - implements(IAuthorizationPolicy) - - def permits(self, context, principals, permission): - """ Return an instance of - :class:`repoze.bfg.security.ACLAllowed` instance if the policy - permits access, return an instance of - :class:`repoze.bfg.security.ACLDenied` if not.""" - - acl = '<No ACL found on any object in model lineage>' - - for location in lineage(context): - try: - acl = location.__acl__ - except AttributeError: - continue - - for ace in acl: - ace_action, ace_principal, ace_permissions = ace - if ace_principal in principals: - if not hasattr(ace_permissions, '__iter__'): - ace_permissions = [ace_permissions] - if permission in ace_permissions: - if ace_action == Allow: - return ACLAllowed(ace, acl, permission, - principals, location) - else: - return ACLDenied(ace, acl, permission, - principals, location) - - # default deny (if no ACL in lineage at all, or if none of the - # principals were mentioned in any ACE we found) - return ACLDenied( - '<default deny>', - acl, - permission, - principals, - context) - - def principals_allowed_by_permission(self, context, permission): - """ Return the set of principals explicitly granted the - permission named ``permission`` according to the ACL directly - attached to the ``context`` as well as inherited ACLs based on - the :term:`lineage`.""" - allowed = set() - - for location in reversed(list(lineage(context))): - # NB: we're walking *up* the object graph from the root - try: - acl = location.__acl__ - except AttributeError: - continue - - allowed_here = set() - denied_here = set() - - for ace_action, ace_principal, ace_permissions in acl: - if not hasattr(ace_permissions, '__iter__'): - ace_permissions = [ace_permissions] - if ace_action == Allow and permission in ace_permissions: - if not ace_principal in denied_here: - allowed_here.add(ace_principal) - if ace_action == Deny and permission in ace_permissions: - denied_here.add(ace_principal) - if ace_principal == Everyone: - # clear the entire allowed set, as we've hit a - # deny of Everyone ala (Deny, Everyone, ALL) - allowed = set() - break - elif ace_principal in allowed: - allowed.remove(ace_principal) - - allowed.update(allowed_here) - - return allowed diff --git a/repoze/bfg/chameleon_text.py b/repoze/bfg/chameleon_text.py deleted file mode 100644 index 4a9d2655e..000000000 --- a/repoze/bfg/chameleon_text.py +++ /dev/null @@ -1,139 +0,0 @@ -import sys - -from zope.interface import implements - -try: - from chameleon.core.template import TemplateFile - TemplateFile # prevent pyflakes complaining about a redefinition below -except ImportError: # pragma: no cover - exc_class, exc, tb = sys.exc_info() - # Chameleon doesn't work on non-CPython platforms - class TemplateFile(object): - def __init__(self, *arg, **kw): - raise ImportError, exc, tb - -try: - from chameleon.zpt.language import Parser - Parser # prevent pyflakes complaining about a redefinition below -except ImportError: # pragma: no cover - # Chameleon doesn't work on non-CPython platforms - class Parser(object): - pass - -from repoze.bfg.interfaces import ITemplateRenderer -from repoze.bfg.interfaces import IChameleonTranslate - -from repoze.bfg.decorator import reify -from repoze.bfg import renderers -from repoze.bfg.path import caller_package -from repoze.bfg.settings import get_settings -from repoze.bfg.threadlocal import get_current_registry - -class TextTemplateFile(TemplateFile): - default_parser = Parser() - - def __init__(self, filename, parser=None, format='text', doctype=None, - **kwargs): - if parser is None: - parser = self.default_parser - super(TextTemplateFile, self).__init__(filename, parser, format, - doctype, **kwargs) - -def renderer_factory(path): - return renderers.template_renderer_factory(path, TextTemplateRenderer) - -class TextTemplateRenderer(object): - implements(ITemplateRenderer) - def __init__(self, path): - self.path = path - - @reify # avoid looking up reload_templates before manager pushed - def template(self): - settings = get_settings() - debug = False - auto_reload = False - if settings: - # using .get here is a strategy to be kind to old *tests* rather - # than being kind to any existing production system - auto_reload = settings.get('reload_templates') - debug = settings.get('debug_templates') - reg = get_current_registry() - translate = None - if reg is not None: - translate = reg.queryUtility(IChameleonTranslate) - return TextTemplateFile(self.path, - auto_reload=auto_reload, - debug=debug, - translate=translate) - - def implementation(self): - return self.template - - def __call__(self, value, system): - try: - system.update(value) - except (TypeError, ValueError): - raise ValueError('renderer was passed non-dictionary as value') - result = self.template(**system) - return result - -def get_renderer(path): - """ Return a callable object which can be used to render a - :term:`Chameleon` text template using the template implied by the - ``path`` argument. The ``path`` argument may be a - package-relative path, an absolute path, or a :term:`resource - specification`. - - .. warning:: This API is deprecated in :mod:`repoze.bfg` 1.3. Use - :func:`repoze.bfg.renderers.get_renderer` instead. - """ - package = caller_package() - factory = renderers.RendererHelper(path, package=package) - return factory.get_renderer() - -def get_template(path): - """ Return the underyling object representing a :term:`Chameleon` - text template using the template implied by the ``path`` argument. - The ``path`` argument may be a package-relative path, an absolute - path, or a :term:`resource specification`. - - .. warning:: This API is deprecated in :mod:`repoze.bfg` 1.3. Use - the ``implementation()`` method of a template renderer retrieved via - :func:`repoze.bfg.renderers.get_renderer` instead. - """ - package = caller_package() - factory = renderers.RendererHelper(path, package=package) - return factory.get_renderer().implementation() - -def render_template(path, **kw): - """ Render a :term:`Chameleon` text template using the template - implied by the ``path`` argument. The ``path`` argument may be a - package-relative path, an absolute path, or a :term:`resource - specification`. The arguments in ``*kw`` are passed as top-level - names to the template, and so may be used within the template - itself. Returns a string. - - .. warning:: This API is deprecated in :mod:`repoze.bfg` 1.3. Use - :func:`repoze.bfg.renderers.render` instead. - """ - package = caller_package() - request = kw.pop('request', None) - renderer = renderers.RendererHelper(path, package=package) - return renderer.render(kw, None, request=request) - -def render_template_to_response(path, **kw): - """ Render a :term:`Chameleon` text template using the template - implied by the ``path`` argument. The ``path`` argument may be a - package-relative path, an absolute path, or a :term:`resource - specification`. The arguments in ``*kw`` are passed as top-level - names to the template, and so may be used within the template - itself. Returns a :term:`Response` object with the body as the - template result. - - .. warning:: This API is deprecated in :mod:`repoze.bfg` 1.3. Use - :func:`repoze.bfg.renderers.render_to_response` instead. - """ - package = caller_package() - request = kw.pop('request', None) - renderer = renderers.RendererHelper(path, package=package) - return renderer.render_to_response(kw, None, request=request) diff --git a/repoze/bfg/chameleon_zpt.py b/repoze/bfg/chameleon_zpt.py deleted file mode 100644 index 3c1c59f1c..000000000 --- a/repoze/bfg/chameleon_zpt.py +++ /dev/null @@ -1,121 +0,0 @@ -import sys - -from zope.interface import implements - -try: - from chameleon.zpt.template import PageTemplateFile - PageTemplateFile # prevent pyflakes complaining about a redefinition below -except ImportError: # pragma: no cover - exc_class, exc, tb = sys.exc_info() - # Chameleon doesn't work on non-CPython platforms - class PageTemplateFile(object): - def __init__(self, *arg, **kw): - raise ImportError, exc, tb - -from repoze.bfg.interfaces import IChameleonTranslate -from repoze.bfg.interfaces import ITemplateRenderer - -from repoze.bfg.decorator import reify -from repoze.bfg.path import caller_package -from repoze.bfg import renderers -from repoze.bfg.settings import get_settings -from repoze.bfg.threadlocal import get_current_registry - -def renderer_factory(path): - return renderers.template_renderer_factory(path, ZPTTemplateRenderer) - -class ZPTTemplateRenderer(object): - implements(ITemplateRenderer) - def __init__(self, path): - self.path = path - - @reify # avoid looking up reload_templates before manager pushed - def template(self): - settings = get_settings() - debug = False - auto_reload = False - if settings: - # using .get here is a strategy to be kind to old *tests* rather - # than being kind to any existing production system - auto_reload = settings.get('reload_templates') - debug = settings.get('debug_templates') - reg = get_current_registry() - translate = None - if reg is not None: - translate = reg.queryUtility(IChameleonTranslate) - return PageTemplateFile(self.path, - auto_reload=auto_reload, - debug=debug, - translate=translate) - - def implementation(self): - return self.template - - def __call__(self, value, system): - try: - system.update(value) - except (TypeError, ValueError): - raise ValueError('renderer was passed non-dictionary as value') - result = self.template(**system) - return result - -def get_renderer(path): - """ Return a callable object which can be used to render a - :term:`Chameleon` ZPT template using the template implied by the - ``path`` argument. The ``path`` argument may be a - package-relative path, an absolute path, or a :term:`resource - specification`. - - .. warning:: This API is deprecated in :mod:`repoze.bfg` 1.3. Use - :func:`repoze.bfg.renderers.get_renderer` instead. - """ - package = caller_package() - factory = renderers.RendererHelper(path, package=package) - return factory.get_renderer() - -def get_template(path): - """ Return the underyling object representing a :term:`Chameleon` - ZPT template using the template implied by the ``path`` argument. - The ``path`` argument may be a package-relative path, an absolute - path, or a :term:`resource specification`. - - .. warning:: This API is deprecated in :mod:`repoze.bfg` 1.3. Use - the ``implementation()`` method of a template renderer retrieved via - :func:`repoze.bfg.renderers.get_renderer` instead. - """ - package = caller_package() - factory = renderers.RendererHelper(path, package=package) - return factory.get_renderer().implementation() - -def render_template(path, **kw): - """ Render a :term:`Chameleon` ZPT template using the template - implied by the ``path`` argument. The ``path`` argument may be a - package-relative path, an absolute path, or a :term:`resource - specification`. The arguments in ``*kw`` are passed as top-level - names to the template, and so may be used within the template - itself. Returns a string. - - .. warning:: This API is deprecated in :mod:`repoze.bfg` 1.3. Use - :func:`repoze.bfg.renderers.render` instead. - """ - package = caller_package() - request = kw.pop('request', None) - renderer = renderers.RendererHelper(path, package=package) - return renderer.render(kw, None, request=request) - -def render_template_to_response(path, **kw): - """ Render a :term:`Chameleon` ZPT template using the template - implied by the ``path`` argument. The ``path`` argument may be a - package-relative path, an absolute path, or a :term:`resource - specification`. The arguments in ``*kw`` are passed as top-level - names to the template, and so may be used within the template - itself. Returns a :term:`Response` object with the body as the - template result. - - .. warning:: This API is deprecated in :mod:`repoze.bfg` 1.3. Use - :func:`repoze.bfg.renderers.render_to_response` instead. - """ - package = caller_package() - request = kw.pop('request', None) - renderer = renderers.RendererHelper(path, package=package) - return renderer.render_to_response(kw, None, request=request) diff --git a/repoze/bfg/compat/__init__.py b/repoze/bfg/compat/__init__.py deleted file mode 100644 index 205175132..000000000 --- a/repoze/bfg/compat/__init__.py +++ /dev/null @@ -1,143 +0,0 @@ -# Some code in this file was lifted wholesale from Django -# <http://djangoproject.com> (see -# http://code.djangoproject.com/browser/django/trunk/LICENSE for -# license text; BSD-like) - -# License for code in this file that was taken from Python 2.5. - -# PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 -# -------------------------------------------- -# -# 1. This LICENSE AGREEMENT is between the Python Software Foundation -# ("PSF"), and the Individual or Organization ("Licensee") accessing and -# otherwise using this software ("Python") in source or binary form and -# its associated documentation. -# -# 2. Subject to the terms and conditions of this License Agreement, PSF -# hereby grants Licensee a nonexclusive, royalty-free, world-wide -# license to reproduce, analyze, test, perform and/or display publicly, -# prepare derivative works, distribute, and otherwise use Python -# alone or in any derivative version, provided, however, that PSF's -# License Agreement and PSF's notice of copyright, i.e., "Copyright (c) -# 2001, 2002, 2003, 2004, 2005, 2006, 2007 Python Software Foundation; -# All Rights Reserved" are retained in Python alone or in any derivative -# version prepared by Licensee. -# -# 3. In the event Licensee prepares a derivative work that is based on -# or incorporates Python or any part thereof, and wants to make -# the derivative work available to others as provided herein, then -# Licensee hereby agrees to include in any such work a brief summary of -# the changes made to Python. -# -# 4. PSF is making Python available to Licensee on an "AS IS" -# basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR -# IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND -# DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS -# FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT -# INFRINGE ANY THIRD PARTY RIGHTS. -# -# 5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON -# FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS -# A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON, -# OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. -# -# 6. This License Agreement will automatically terminate upon a material -# breach of its terms and conditions. -# -# 7. Nothing in this License Agreement shall be deemed to create any -# relationship of agency, partnership, or joint venture between PSF and -# Licensee. This License Agreement does not grant permission to use PSF -# trademarks or trade name in a trademark sense to endorse or promote -# products or services of Licensee, or any third party. -# -# 8. By copying, installing or otherwise using Python, Licensee -# agrees to be bound by the terms and conditions of this License -# Agreement. - - -try: # pragma: no cover - from functools import wraps -except ImportError: #pragma no cover - # < 2.5 - def curry(_curried_func, *args, **kwargs): - def _curried(*moreargs, **morekwargs): - return _curried_func(*(args+moreargs), **dict(kwargs, **morekwargs)) - return _curried - - ### Begin from Python 2.5 functools.py ################################### - # Summary of changes made to the Python 2.5 code below: - # * swapped ``partial`` for ``curry`` to maintain backwards-compatibility - # in Django. - # * Wrapped the ``setattr`` call in ``update_wrapper`` with a try-except - # block to make it compatible with Python 2.3, which doesn't allow - # assigning to ``__name__``. - - # Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 Python Software - # Foundation. - # All Rights Reserved. - ########################################################################## - - # update_wrapper() and wraps() are tools to help write - # wrapper functions that can handle naive introspection - - WRAPPER_ASSIGNMENTS = ('__module__', '__name__', '__doc__') - WRAPPER_UPDATES = ('__dict__',) - def update_wrapper(wrapper, - wrapped, - assigned = WRAPPER_ASSIGNMENTS, - updated = WRAPPER_UPDATES): - """Update a wrapper function to look like the wrapped function - - wrapper is the function to be updated - wrapped is the original function - assigned is a tuple naming the attributes assigned directly - from the wrapped function to the wrapper function (defaults to - functools.WRAPPER_ASSIGNMENTS) - updated is a tuple naming the attributes off the wrapper that - are updated with the corresponding attribute from the wrapped - function (defaults to functools.WRAPPER_UPDATES) - """ - for attr in assigned: - setattr(wrapper, attr, getattr(wrapped, attr)) - - for attr in updated: - getattr(wrapper, attr).update(getattr(wrapped, attr)) - # Return the wrapper so this can be used as a decorator via curry() - return wrapper - - def wraps(wrapped, - assigned = WRAPPER_ASSIGNMENTS, - updated = WRAPPER_UPDATES): - """Decorator factory to apply update_wrapper() to a wrapper function - - Returns a decorator that invokes update_wrapper() with the decorated - function as the wrapper argument and the arguments to wraps() as the - remaining arguments. Default arguments are as for update_wrapper(). - This is a convenience function to simplify applying curry() to - update_wrapper(). - """ - return curry(update_wrapper, wrapped=wrapped, - assigned=assigned, updated=updated) - -### End from Python 2.5 functools.py ########################################## - -try: - all = all -except NameError: # pragma: no cover - def all(iterable): - for element in iterable: - if not element: - return False - return True - -try: - import json -except ImportError: # pragma: no cover - import simplejson as json - -try: - from hashlib import md5 -except ImportError: # pragma: no cover - import md5 - md5 = md5.new - diff --git a/repoze/bfg/configuration.py b/repoze/bfg/configuration.py deleted file mode 100644 index 88bdcba58..000000000 --- a/repoze/bfg/configuration.py +++ /dev/null @@ -1,2697 +0,0 @@ -import os -import re -import sys -import threading -import inspect -import pkg_resources - -import venusian - -from translationstring import ChameleonTranslate - -from zope.configuration import xmlconfig - -from zope.interface import Interface -from zope.interface import implementedBy -from zope.interface.interfaces import IInterface -from zope.interface import implements - -from repoze.bfg.interfaces import IAuthenticationPolicy -from repoze.bfg.interfaces import IAuthorizationPolicy -from repoze.bfg.interfaces import IChameleonTranslate -from repoze.bfg.interfaces import IDebugLogger -from repoze.bfg.interfaces import IDefaultPermission -from repoze.bfg.interfaces import IDefaultRootFactory -from repoze.bfg.interfaces import IExceptionViewClassifier -from repoze.bfg.interfaces import ILocaleNegotiator -from repoze.bfg.interfaces import IMultiView -from repoze.bfg.interfaces import IPackageOverrides -from repoze.bfg.interfaces import IRendererFactory -from repoze.bfg.interfaces import IRendererGlobalsFactory -from repoze.bfg.interfaces import IRequest -from repoze.bfg.interfaces import IRequestFactory -from repoze.bfg.interfaces import IRootFactory -from repoze.bfg.interfaces import IRouteRequest -from repoze.bfg.interfaces import IRoutesMapper -from repoze.bfg.interfaces import ISecuredView -from repoze.bfg.interfaces import ISettings -from repoze.bfg.interfaces import IStaticURLInfo -from repoze.bfg.interfaces import ITranslationDirectories -from repoze.bfg.interfaces import ITraverser -from repoze.bfg.interfaces import IView -from repoze.bfg.interfaces import IViewClassifier -from repoze.bfg.interfaces import IExceptionResponse -from repoze.bfg.interfaces import IException - -from repoze.bfg import chameleon_text -from repoze.bfg import chameleon_zpt -from repoze.bfg import renderers -from repoze.bfg.renderers import RendererHelper -from repoze.bfg.authorization import ACLAuthorizationPolicy -from repoze.bfg.compat import all -from repoze.bfg.compat import md5 -from repoze.bfg.events import ApplicationCreated -from repoze.bfg.exceptions import Forbidden -from repoze.bfg.exceptions import NotFound -from repoze.bfg.exceptions import PredicateMismatch -from repoze.bfg.exceptions import ConfigurationError -from repoze.bfg.i18n import get_localizer -from repoze.bfg.log import make_stream_logger -from repoze.bfg.path import caller_package -from repoze.bfg.path import package_path -from repoze.bfg.path import package_of -from repoze.bfg.registry import Registry -from repoze.bfg.request import route_request_iface -from repoze.bfg.resource import PackageOverrides -from repoze.bfg.resource import resolve_resource_spec -from repoze.bfg.settings import Settings -from repoze.bfg.static import StaticURLInfo -from repoze.bfg.threadlocal import get_current_registry -from repoze.bfg.threadlocal import get_current_request -from repoze.bfg.threadlocal import manager -from repoze.bfg.traversal import traversal_path -from repoze.bfg.traversal import DefaultRootFactory -from repoze.bfg.traversal import find_interface -from repoze.bfg.urldispatch import RoutesMapper -from repoze.bfg.view import render_view_to_response -from repoze.bfg.view import default_exceptionresponse_view - -MAX_ORDER = 1 << 30 -DEFAULT_PHASH = md5().hexdigest() - -DEFAULT_RENDERERS = ( - ('.pt', chameleon_zpt.renderer_factory), - ('.txt', chameleon_text.renderer_factory), - ('json', renderers.json_renderer_factory), - ('string', renderers.string_renderer_factory), - ) - -_marker = object() - -class Configurator(object): - """ - A Configurator is used to configure a :mod:`repoze.bfg` - :term:`application registry`. - - The Configurator accepts a number of arguments: ``registry``, - ``package``, ``settings``, ``root_factory``, - ``authentication_policy``, ``authorization_policy``, ``renderers`` - ``debug_logger``, ``locale_negotiator``, ``request_factory``, and - ``renderer_globals_factory``. - - If the ``registry`` argument is passed as a non-``None`` value, it - must be an instance of the :class:`repoze.bfg.registry.Registry` - class representing the registry to configure. If ``registry`` is - ``None``, the configurator will create a - :class:`repoze.bfg.registry.Registry` instance itself; it will - also perform some default configuration that would not otherwise - be done. After construction, the configurator may be used to add - configuration to the registry. The overall state of a registry is - called the 'configuration state'. - - .. warning:: If a ``registry`` is passed to the Configurator - constructor, all other constructor arguments except ``package`` - are ignored. - - If the ``package`` argument is passed, it must be a reference to a - Python :term:`package` (e.g. ``sys.modules['thepackage']``) or a - :term:`dotted Python name` to same. This value is used as a basis - to convert relative paths passed to various configuration methods, - such as methods which accept a ``renderer`` argument, into - absolute paths. If ``None`` is passed (the default), the package - is assumed to be the Python package in which the *caller* of the - ``Configurator`` constructor lives. - - If the ``settings`` argument is passed, it should be a Python - dictionary representing the deployment settings for this - application. These are later retrievable using the - :meth:`repoze.bfg.configuration.Configurator.get_settings` and - :func:`repoze.bfg.settings.get_settings` APIs. - - If the ``root_factory`` argument is passed, it should be an object - representing the default :term:`root factory` for your application - or a :term:`dotted Python name` to same. If it is ``None``, a - default root factory will be used. - - If ``authentication_policy`` is passed, it should be an instance - of an :term:`authentication policy` or a :term:`dotted Python - name` to same. - - If ``authorization_policy`` is passed, it should be an instance of - an :term:`authorization policy` or a :term:`dotted Python name` to - same. - - .. note:: A ``ConfigurationError`` will be raised when an - authorization policy is supplied without also supplying an - authentication policy (authorization requires authentication). - - If ``renderers`` is passed, it should be a list of tuples - representing a set of :term:`renderer` factories which should be - configured into this application (each tuple representing a set of - positional values that should be passed to - :meth:`repoze.bfg.configuration.Configurator.add_renderer`). If - it is not passed, a default set of renderer factories is used. - - If ``debug_logger`` is not passed, a default debug logger that - logs to stderr will be used. If it is passed, it should be an - instance of the :class:`logging.Logger` (PEP 282) standard library - class or a :term:`dotted Python name` to same. The debug logger - is used by :mod:`repoze.bfg` itself to log warnings and - authorization debugging information. - - If ``locale_negotiator`` is passed, it should be a :term:`locale - negotiator` implementation or a :term:`dotted Python name` to - same. See :ref:`custom_locale_negotiator`. - - If ``request_factory`` is passed, it should be a :term:`request - factory` implementation or a :term:`dotted Python name` to same. - See :ref:`custom_request_factory`. By default it is ``None``, - which means use the default request factory. - - If ``renderer_globals_factory`` is passed, it should be a - :term:`renderer globals` factory implementation or a :term:`dotted - Python name` to same. See :ref:`custom_renderer_globals_factory`. - By default, it is ``None``, which means use no renderer globals - factory. - - If ``default_permission`` is passed, it should be a - :term:`permission` string to be used as the default permission for - all view configuration registrations performed against this - Configurator. An example of a permission string:``'view'``. - Adding a default permission makes it unnecessary to protect each - view configuration with an explicit permission, unless your - application policy requires some exception for a particular view. - By default, ``default_permission`` is ``None``, meaning that view - configurations which do not explicitly declare a permission will - always be executable by entirely anonymous users (any - authorization policy in effect is ignored). See also - :ref:`setting_a_default_permission`. - """ - - manager = manager # for testing injection - venusian = venusian # for testing injection - def __init__(self, - registry=None, - package=None, - settings=None, - root_factory=None, - authentication_policy=None, - authorization_policy=None, - renderers=DEFAULT_RENDERERS, - debug_logger=None, - locale_negotiator=None, - request_factory=None, - renderer_globals_factory=None, - default_permission=None): - if package is None: - package = caller_package() - name_resolver = DottedNameResolver(package) - self.name_resolver = name_resolver - self.package_name = name_resolver.package_name - self.package = name_resolver.package - self.registry = registry - if registry is None: - registry = Registry(self.package_name) - self.registry = registry - self.setup_registry( - settings=settings, - root_factory=root_factory, - authentication_policy=authentication_policy, - authorization_policy=authorization_policy, - renderers=renderers, - debug_logger=debug_logger, - locale_negotiator=locale_negotiator, - request_factory=request_factory, - renderer_globals_factory=renderer_globals_factory, - default_permission=default_permission, - ) - - def _set_settings(self, mapping): - settings = Settings(mapping or {}) - self.registry.registerUtility(settings, ISettings) - return settings - - def _set_root_factory(self, factory): - """ Add a :term:`root factory` to the current configuration - state. If the ``factory`` argument is ``None`` a default root - factory will be registered.""" - factory = self.maybe_dotted(factory) - if factory is None: - factory = DefaultRootFactory - self.registry.registerUtility(factory, IRootFactory) - self.registry.registerUtility(factory, IDefaultRootFactory) # b/c - - def _set_authentication_policy(self, policy, _info=u''): - """ Add a :mod:`repoze.bfg` :term:`authentication policy` to - the current configuration.""" - policy = self.maybe_dotted(policy) - self.registry.registerUtility(policy, IAuthenticationPolicy, info=_info) - - def _set_authorization_policy(self, policy, _info=u''): - """ Add a :mod:`repoze.bfg` :term:`authorization policy` to - the current configuration state (also accepts a :term:`dotted - Python name`.""" - policy = self.maybe_dotted(policy) - self.registry.registerUtility(policy, IAuthorizationPolicy, info=_info) - - def _make_spec(self, path_or_spec): - package, filename = resolve_resource_spec(path_or_spec, - self.package_name) - if package is None: - return filename # absolute filename - return '%s:%s' % (package, filename) - - def _split_spec(self, path_or_spec): - return resolve_resource_spec(path_or_spec, self.package_name) - - def _derive_view(self, view, permission=None, predicates=(), - attr=None, renderer_name=None, wrapper_viewname=None, - viewname=None, accept=None, order=MAX_ORDER, - phash=DEFAULT_PHASH): - view = self.maybe_dotted(view) - authn_policy = self.registry.queryUtility(IAuthenticationPolicy) - authz_policy = self.registry.queryUtility(IAuthorizationPolicy) - settings = self.registry.queryUtility(ISettings) - logger = self.registry.queryUtility(IDebugLogger) - mapped_view = _map_view(view, attr, renderer_name, self.registry, - self.package) - owrapped_view = _owrap_view(mapped_view, viewname, wrapper_viewname) - secured_view = _secure_view(owrapped_view, permission, - authn_policy, authz_policy) - debug_view = _authdebug_view(secured_view, permission, - authn_policy, authz_policy, settings, - logger) - predicated_view = _predicate_wrap(debug_view, predicates) - derived_view = _attr_wrap(predicated_view, accept, order, phash) - return derived_view - - def _override(self, package, path, override_package, override_prefix, - _info=u'', PackageOverrides=PackageOverrides): - pkg_name = package.__name__ - override_pkg_name = override_package.__name__ - override = self.registry.queryUtility( - IPackageOverrides, name=pkg_name) - if override is None: - override = PackageOverrides(package) - self.registry.registerUtility(override, IPackageOverrides, - name=pkg_name, info=_info) - override.insert(path, override_pkg_name, override_prefix) - - def _set_security_policies(self, authentication, authorization=None): - if authorization is None: - authorization = ACLAuthorizationPolicy() # default - if authorization and not authentication: - raise ConfigurationError( - 'If the "authorization" is passed a value, ' - 'the "authentication" argument must also be ' - 'passed a value; authorization requires authentication.') - self._set_authentication_policy(authentication) - self._set_authorization_policy(authorization) - - def _fix_registry(self): - """ Fix up a ZCA component registry that is not a - repoze.bfg.registry.Registry by adding analogues of - ``has_listeners`` and ``notify`` through monkey-patching.""" - - if not hasattr(self.registry, 'notify'): - def notify(*events): - [ _ for _ in self.registry.subscribers(events, None) ] - self.registry.notify = notify - - if not hasattr(self.registry, 'has_listeners'): - self.registry.has_listeners = True - - # API - - def with_package(self, package): - """ Return a new Configurator instance with the same registry - as this configurator using the package supplied as the - ``package`` argument to the new configurator. ``package`` may - be an actual Python package object or a Python dotted name - representing a package.""" - return self.__class__(registry=self.registry, package=package) - - def maybe_dotted(self, dotted): - """ Resolve the :term:`dotted Python name` ``dotted`` to a - global Python object. If ``dotted`` is not a string, return - it without attempting to do any name resolution. If - ``dotted`` is a relative dotted name (e.g. ``.foo.bar``, - consider it relative to the ``package`` argument supplied to - this Configurator's constructor.""" - return self.name_resolver.maybe_resolve(dotted) - - def absolute_resource_spec(self, relative_spec): - """ Resolve the potentially relative :term:`resource - specification` string passed as ``relative_spec`` into an - absolute resource specification string and return the string. - Use the ``package`` of this configurator as the package to - which the resource specification will be considered relative - when generating an absolute resource specification. If the - provided ``relative_spec`` argument is already absolute, or if - the ``relative_spec`` is not a string, it is simply returned.""" - if not isinstance(relative_spec, basestring): - return relative_spec - return self._make_spec(relative_spec) - - def setup_registry(self, settings=None, root_factory=None, - authentication_policy=None, authorization_policy=None, - renderers=DEFAULT_RENDERERS, debug_logger=None, - locale_negotiator=None, request_factory=None, - renderer_globals_factory=None, - default_permission=None): - """ When you pass a non-``None`` ``registry`` argument to the - :term:`Configurator` constructor, no initial 'setup' is - performed against the registry. This is because the registry - you pass in may have already been initialized for use under - :mod:`repoze.bfg` via a different configurator. However, in - some circumstances, such as when you want to use the Zope - 'global` registry instead of a registry created as a result of - the Configurator constructor, or when you want to reset the - initial setup of a registry, you *do* want to explicitly - initialize the registry associated with a Configurator for use - under :mod:`repoze.bfg`. Use ``setup_registry`` to do this - initialization. - - ``setup_registry`` configures settings, a root factory, - security policies, renderers, a debug logger, a locale - negotiator, and various other settings using the - configurator's current registry, as per the descriptions in - the Configurator constructor.""" - self._fix_registry() - self._set_settings(settings) - self._set_root_factory(root_factory) - debug_logger = self.maybe_dotted(debug_logger) - if debug_logger is None: - debug_logger = make_stream_logger('repoze.bfg.debug', sys.stderr) - registry = self.registry - registry.registerUtility(debug_logger, IDebugLogger) - registry.registerUtility(debug_logger, IDebugLogger, - 'repoze.bfg.debug') # b /c - if authentication_policy or authorization_policy: - self._set_security_policies(authentication_policy, - authorization_policy) - for name, renderer in renderers: - self.add_renderer(name, renderer) - self.add_view(default_exceptionresponse_view, - context=IExceptionResponse) - if locale_negotiator: - locale_negotiator = self.maybe_dotted(locale_negotiator) - registry.registerUtility(locale_negotiator, ILocaleNegotiator) - if request_factory: - request_factory = self.maybe_dotted(request_factory) - self.set_request_factory(request_factory) - if renderer_globals_factory: - renderer_globals_factory=self.maybe_dotted(renderer_globals_factory) - self.set_renderer_globals_factory(renderer_globals_factory) - if default_permission: - self.set_default_permission(default_permission) - - # getSiteManager is a unit testing dep injection - def hook_zca(self, getSiteManager=None): - """ Call :func:`zope.component.getSiteManager.sethook` with - the argument - :data:`repoze.bfg.threadlocal.get_current_registry`, causing - the :term:`Zope Component Architecture` 'global' APIs such as - :func:`zope.component.getSiteManager`, - :func:`zope.component.getAdapter` and others to use the - :mod:`repoze.bfg` :term:`application registry` rather than the - Zope 'global' registry. If :mod:`zope.component` cannot be - imported, this method will raise an :exc:`ImportError`.""" - if getSiteManager is None: - from zope.component import getSiteManager - getSiteManager.sethook(get_current_registry) - - # getSiteManager is a unit testing dep injection - def unhook_zca(self, getSiteManager=None): - """ Call :func:`zope.component.getSiteManager.reset` to undo - the action of - :meth:`repoze.bfg.configuration.Configurator.hook_zca`. If - :mod:`zope.component` cannot be imported, this method will - raise an :exc:`ImportError`.""" - if getSiteManager is None: # pragma: no cover - from zope.component import getSiteManager - getSiteManager.reset() - - def begin(self, request=None): - """ Indicate that application or test configuration has begun. - This pushes a dictionary containing the :term:`application - registry` implied by ``registry`` attribute of this - configurator and the :term:`request` implied by the - ``request`` argument on to the :term:`thread local` stack - consulted by various :mod:`repoze.bfg.threadlocal` API - functions.""" - self.manager.push({'registry':self.registry, 'request':request}) - - def end(self): - """ Indicate that application or test configuration has ended. - This pops the last value pushed on to the :term:`thread local` - stack (usually by the ``begin`` method) and returns that - value. - """ - return self.manager.pop() - - def derive_view(self, view, attr=None, renderer=None): - """ - - Create a :term:`view callable` using the function, instance, - or class (or :term:`dotted Python name` referring to the same) - provided as ``view`` object. - - This is API is useful to framework extenders who create - pluggable systems which need to register 'proxy' view - callables for functions, instances, or classes which meet the - requirements of being a :mod:`repoze.bfg` view callable. For - example, a ``some_other_framework`` function in another - framework may want to allow a user to supply a view callable, - but he may want to wrap the view callable in his own before - registering the wrapper as a :mod:`repoze.bfg` view callable. - Because a :mod:`repoze.bfg` view callable can be any of a - number of valid objects, the framework extender will not know - how to call the user-supplied object. Running it through - ``derive_view`` normalizes it to a callable which accepts two - arguments: ``context`` and ``request``. - - For example: - - .. code-block:: python - - def some_other_framework(user_supplied_view): - config = Configurator(reg) - proxy_view = config.derive_view(user_supplied_view) - def my_wrapper(context, request): - do_something_that_mutates(request) - return proxy_view(context, request) - config.add_view(my_wrapper) - - The ``view`` object provided should be one of the following: - - - A function or another non-class callable object that accepts - a :term:`request` as a single positional argument and which - returns a :term:`response` object. - - - A function or other non-class callable object that accepts - two positional arguments, ``context, request`` and which - returns a :term:`response` object. - - - A class which accepts a single positional argument in its - constructor named ``request``, and which has a ``__call__`` - method that accepts no arguments that returns a - :term:`response` object. - - - A class which accepts two positional arguments named - ``context, request``, and which has a ``__call__`` method - that accepts no arguments that returns a :term:`response` - object. - - - A :term:`dotted Python name` which refers to any of the - kinds of objects above. - - This API returns a callable which accepts the arguments - ``context, request`` and which returns the result of calling - the provided ``view`` object. - - The ``attr`` keyword argument is most useful when the view - object is a class. It names the method that should be used as - the callable. If ``attr`` is not provided, the attribute - effectively defaults to ``__call__``. See - :ref:`class_as_view` for more information. - - The ``renderer`` keyword argument should be a renderer - name. If supplied, it will cause the returned callable to use - a :term:`renderer` to convert the user-supplied view result to - a :term:`response` object. If a ``renderer`` argument is not - supplied, the user-supplied view must itself return a - :term:`response` object. """ - - return self._derive_view(view, attr=attr, renderer_name=renderer) - - def add_subscriber(self, subscriber, iface=None, info=u''): - """Add an event :term:`subscriber` for the event stream - implied by the supplied ``iface`` interface. The - ``subscriber`` argument represents a callable object (or a - :term:`dotted Python name` which identifies a callable); it - will be called with a single object ``event`` whenever - :mod:`repoze.bfg` emits an :term:`event` associated with the - ``iface``, which may be an :term:`interface` or a class or a - :term:`dotted Python name` to a global object representing an - interface or a class. Using the default ``iface`` value, - ``None`` will cause the subscriber to be registered for all - event types. See :ref:`events_chapter` for more information - about events and subscribers.""" - dotted = self.maybe_dotted - subscriber, iface = dotted(subscriber), dotted(iface) - if iface is None: - iface = (Interface,) - if not isinstance(iface, (tuple, list)): - iface = (iface,) - self.registry.registerHandler(subscriber, iface, info=info) - return subscriber - - def add_settings(self, settings=None, **kw): - """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` and - :meth:`repoze.bfg.configuration.Configurator.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 (or the - :meth:`repoze.bfg.configuration.Configurator.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) - if utility is None: - utility = self._set_settings(settings) - utility.update(settings) - utility.update(kw) - - def get_settings(self): - """ - Return a 'settings' object for the current application. A - 'settings' object is a dictionary-like object that contains - key/value pairs based on the dictionary passed as the ``settings`` - argument to the :class:`repoze.bfg.configuration.Configurator` - constructor or the :func:`repoze.bfg.router.make_app` API. - - .. note:: For backwards compatibility, dictionary keys can also be - looked up as attributes of the settings object. - - .. note:: the :class:`repoze.bfg.settings.get_settings` function - performs the same duty.""" - return self.registry.queryUtility(ISettings) - - def make_wsgi_app(self): - """ Returns a :mod:`repoze.bfg` WSGI application representing - the current configuration state and sends a - :class:`repoze.bfg.interfaces.IApplicationCreated` - event to all listeners.""" - from repoze.bfg.router import Router # avoid circdep - app = Router(self.registry) - # We push the registry on to the stack here in case any code - # that depends on the registry threadlocal APIs used in - # listeners subscribed to the IApplicationCreated event. - self.manager.push({'registry':self.registry, 'request':None}) - try: - self.registry.notify(ApplicationCreated(app)) - finally: - self.manager.pop() - return app - - def load_zcml(self, spec='configure.zcml', lock=threading.Lock()): - """ Load configuration from a :term:`ZCML` file into the - current configuration state. The ``spec`` argument is an - absolute filename, a relative filename, or a :term:`resource - specification`, defaulting to ``configure.zcml`` (relative to - the package of the configurator's caller).""" - package_name, filename = self._split_spec(spec) - if package_name is None: # absolute filename - package = self.package - else: - __import__(package_name) - package = sys.modules[package_name] - - lock.acquire() - self.manager.push({'registry':self.registry, 'request':None}) - try: - xmlconfig.file(filename, package, execute=True) - finally: - lock.release() - self.manager.pop() - return self.registry - - def add_view(self, view=None, name="", for_=None, permission=_marker, - request_type=None, route_name=None, request_method=None, - request_param=None, containment=None, attr=None, - renderer=None, wrapper=None, xhr=False, accept=None, - header=None, path_info=None, custom_predicates=(), - context=None, _info=u''): - """ Add a :term:`view configuration` to the current - configuration state. Arguments to ``add_view`` are broken - down below into *predicate* arguments and *non-predicate* - arguments. Predicate arguments narrow the circumstances in - which the view callable will be invoked when a request is - presented to :mod:`repoze.bfg`; non-predicate arguments are - informational. - - Non-Predicate Arguments - - view - - A :term:`view callable` or a :term:`dotted Python name` - which refers to a view callable. This argument is required - unless a ``renderer`` argument also exists. If a - ``renderer`` argument is passed, and a ``view`` argument is - not provided, the view callable defaults to a callable that - returns an empty dictionary (see - :ref:`views_which_use_a_renderer`). - - permission - - The name of a :term:`permission` that the user must possess - in order to invoke the :term:`view callable`. See - :ref:`view_security_section` for more information about view - security and permissions. If ``permission`` is omitted, a - *default* permission may be used for this view registration - if one was named as the - :class:`repoze.bfg.configuration.Configurator` constructor's - ``default_permission`` argument, or if - :meth:`repoze.bfg.configuration.Configurator.set_default_permission` - was used prior to this view registration. Pass ``None`` as - the permission to explicitly indicate that the view should - always be executable by entirely anonymous users, regardless - of the default permission, bypassing any - :term:`authorization policy` that may be in effect. - - attr - - The view machinery defaults to using the ``__call__`` method - of the :term:`view callable` (or the function itself, if the - view callable is a function) to obtain a response. The - ``attr`` value allows you to vary the method attribute used - to obtain the response. For example, if your view was a - class, and the class has a method named ``index`` and you - wanted to use this method instead of the class' ``__call__`` - method to return the response, you'd say ``attr="index"`` in the - view configuration for the view. This is - most useful when the view definition is a class. - - renderer - - This is either a single string term (e.g. ``json``) or a - string implying a path or :term:`resource specification` - (e.g. ``templates/views.pt``) naming a :term:`renderer` - implementation. If the ``renderer`` value does not contain - a dot ``.``, the specified string will be used to look up a - renderer implementation, and that renderer implementation - will be used to construct a response from the view return - value. If the ``renderer`` value contains a dot (``.``), - the specified term will be treated as a path, and the - filename extension of the last element in the path will be - used to look up the renderer implementation, which will be - passed the full path. The renderer implementation will be - used to construct a :term:`response` from the view return - value. - - Note that if the view itself returns a :term:`response` (see - :ref:`the_response`), the specified renderer implementation - is never called. - - When the renderer is a path, although a path is usually just - a simple relative pathname (e.g. ``templates/foo.pt``, - implying that a template named "foo.pt" is in the - "templates" directory relative to the directory of the - current :term:`package` of the Configurator), a path can be - absolute, starting with a slash on UNIX or a drive letter - prefix on Windows. The path can alternately be a - :term:`resource specification` in the form - ``some.dotted.package_name:relative/path``, making it - possible to address template resources which live in a - separate package. - - The ``renderer`` attribute is optional. If it is not - defined, the "null" renderer is assumed (no rendering is - performed and the value is passed back to the upstream - :mod:`repoze.bfg` machinery unmolested). - - wrapper - - The :term:`view name` of a different :term:`view - configuration` which will receive the response body of this - view as the ``request.wrapped_body`` attribute of its own - :term:`request`, and the :term:`response` returned by this - view as the ``request.wrapped_response`` attribute of its - own request. Using a wrapper makes it possible to "chain" - views together to form a composite response. The response - of the outermost wrapper view will be returned to the user. - The wrapper view will be found as any view is found: see - :ref:`view_lookup`. The "best" wrapper view will be found - based on the lookup ordering: "under the hood" this wrapper - view is looked up via - ``repoze.bfg.view.render_view_to_response(context, request, - 'wrapper_viewname')``. The context and request of a wrapper - view is the same context and request of the inner view. If - this attribute is unspecified, no view wrapping is done. - - Predicate Arguments - - name - - The :term:`view name`. Read :ref:`traversal_chapter` to - understand the concept of a view name. - - context - - An object or a :term:`dotted Python name` referring to an - interface or class object that the :term:`context` must be - an instance of, *or* the :term:`interface` that the - :term:`context` must provide in order for this view to be - found and called. This predicate is true when the - :term:`context` is an instance of the represented class or - if the :term:`context` provides the represented interface; - it is otherwise false. This argument may also be provided - to ``add_view`` as ``for_`` (an older, still-supported - spelling). - - route_name - - This value must match the ``name`` of a :term:`route - configuration` declaration (see :ref:`urldispatch_chapter`) - that must match before this view will be called. Note that - the ``route`` configuration referred to by ``route_name`` - usually has a ``*traverse`` token in the value of its - ``path``, representing a part of the path that will be used - by :term:`traversal` against the result of the route's - :term:`root factory`. - - .. warning:: Using this argument services an advanced - feature that isn't often used unless you want to perform - traversal *after* a route has matched. See - :ref:`hybrid_chapter` for more information on using this - advanced feature. - - request_type - - This value should be an :term:`interface` that the - :term:`request` must provide in order for this view to be - found and called. This value exists only for backwards - compatibility purposes. - - request_method - - This value can either be one of the strings ``GET``, - ``POST``, ``PUT``, ``DELETE``, or ``HEAD`` representing an - HTTP ``REQUEST_METHOD``. A view declaration with this - argument ensures that the view will only be called when the - request's ``method`` attribute (aka the ``REQUEST_METHOD`` of - the WSGI environment) string matches the supplied value. - - request_param - - This value can be any string. A view declaration with this - argument ensures that the view will only be called when the - :term:`request` has a key in the ``request.params`` - dictionary (an HTTP ``GET`` or ``POST`` variable) that has a - name which matches the supplied value. If the value - supplied has a ``=`` sign in it, - e.g. ``request_params="foo=123"``, then the key (``foo``) - must both exist in the ``request.params`` dictionary, *and* - the value must match the right hand side of the expression - (``123``) for the view to "match" the current request. - - containment - - This value should be a Python class or :term:`interface` or - a :term:`dotted Python name` to such an object that a parent - object in the :term:`lineage` must provide in order for this - view to be found and called. The nodes in your object graph - must be "location-aware" to use this feature. See - :ref:`location_aware` for more information about - location-awareness. - - xhr - - This value should be either ``True`` or ``False``. If this - value is specified and is ``True``, the :term:`request` - must possess an ``HTTP_X_REQUESTED_WITH`` (aka - ``X-Requested-With``) header that has the value - ``XMLHttpRequest`` for this view to be found and called. - This is useful for detecting AJAX requests issued from - jQuery, Prototype and other Javascript libraries. - - accept - - The value of this argument represents a match query for one - or more mimetypes in the ``Accept`` HTTP request header. If - this value is specified, it must be in one of the following - forms: a mimetype match token in the form ``text/plain``, a - wildcard mimetype match token in the form ``text/*`` or a - match-all wildcard mimetype match token in the form ``*/*``. - If any of the forms matches the ``Accept`` header of the - request, this predicate will be true. - - header - - This value represents an HTTP header name or a header - name/value pair. If the value contains a ``:`` (colon), it - will be considered a name/value pair - (e.g. ``User-Agent:Mozilla/.*`` or ``Host:localhost``). The - value portion should be a regular expression. If the value - does not contain a colon, the entire value will be - considered to be the header name - (e.g. ``If-Modified-Since``). If the value evaluates to a - header name only without a value, the header specified by - the name must be present in the request for this predicate - to be true. If the value evaluates to a header name/value - pair, the header specified by the name must be present in - the request *and* the regular expression specified as the - value must match the header value. Whether or not the value - represents a header name or a header name/value pair, the - case of the header name is not significant. - - path_info - - This value represents a regular expression pattern that will - be tested against the ``PATH_INFO`` WSGI environment - variable. If the regex matches, this predicate will be - ``True``. - - - custom_predicates - - This value should be a sequence of references to custom - predicate callables. Use custom predicates when no set of - predefined predicates do what you need. Custom predicates - can be combined with predefined predicates as necessary. - Each custom predicate callable should accept two arguments: - ``context`` and ``request`` and should return either - ``True`` or ``False`` after doing arbitrary evaluation of - the context and/or the request. If all callables return - ``True``, the associated view callable will be considered - viable for a given request. - - .. note:: This feature is new as of :mod:`repoze.bfg` 1.2. - """ - view = self.maybe_dotted(view) - context = self.maybe_dotted(context) - for_ = self.maybe_dotted(for_) - containment = self.maybe_dotted(containment) - - if not view: - if renderer: - def view(context, request): - return {} - else: - raise ConfigurationError('"view" was not specified and ' - 'no "renderer" specified') - - if request_type in ('GET', 'HEAD', 'PUT', 'POST', 'DELETE'): - # b/w compat for 1.0 - request_method = request_type - request_type = None - - if request_type is not None: - request_type = self.maybe_dotted(request_type) - if not IInterface.providedBy(request_type): - raise ConfigurationError( - 'request_type must be an interface, not %s' % request_type) - - request_iface = IRequest - - if route_name is not None: - request_iface = self.registry.queryUtility(IRouteRequest, - name=route_name) - if request_iface is None: - deferred_views = getattr(self.registry, - 'deferred_route_views', None) - if deferred_views is None: - deferred_views = self.registry.deferred_route_views = {} - info = dict( - view=view, name=name, for_=for_, permission=permission, - request_type=request_type, route_name=route_name, - request_method=request_method, request_param=request_param, - containment=containment, attr=attr, - renderer=renderer, wrapper=wrapper, xhr=xhr, accept=accept, - header=header, path_info=path_info, - custom_predicates=custom_predicates, context=context, - _info=u'' - ) - view_info = deferred_views.setdefault(route_name, []) - view_info.append(info) - return - - order, predicates, phash = _make_predicates(xhr=xhr, - request_method=request_method, path_info=path_info, - request_param=request_param, header=header, accept=accept, - containment=containment, request_type=request_type, - custom=custom_predicates) - - if permission is _marker: - # intent: will be None if no default permission is registered - permission = self.registry.queryUtility(IDefaultPermission) - - derived_view = self._derive_view(view, permission, predicates, attr, - renderer, wrapper, name, accept, order, - phash) - - if context is None: - context = for_ - - r_context = context - if r_context is None: - r_context = Interface - if not IInterface.providedBy(r_context): - r_context = implementedBy(r_context) - - registered = self.registry.adapters.registered - - # A multiviews is a set of views which are registered for - # exactly the same context type/request type/name triad. Each - # consituent view in a multiview differs only by the - # predicates which it possesses. - - # To find a previously registered view for a context - # type/request type/name triad, we need to use the - # ``registered`` method of the adapter registry rather than - # ``lookup``. ``registered`` ignores interface inheritance - # for the required and provided arguments, returning only a - # view registered previously with the *exact* triad we pass - # in. - - # We need to do this three times, because we use three - # different interfaces as the ``provided`` interface while - # doing registrations, and ``registered`` performs exact - # matches on all the arguments it receives. - - old_view = None - - for view_type in (IView, ISecuredView, IMultiView): - old_view = registered((IViewClassifier, request_iface, r_context), - view_type, name) - if old_view is not None: - break - - isexc = isexception(context) - - def regclosure(): - if hasattr(view, '__call_permissive__'): - view_iface = ISecuredView - else: - view_iface = IView - self.registry.registerAdapter( - derived_view, - (IViewClassifier, request_iface, context), - view_iface, name, info=_info) - if isexc: - self.registry.registerAdapter( - derived_view, - (IExceptionViewClassifier, request_iface, context), - view_iface, name, info=_info) - - is_multiview = IMultiView.providedBy(old_view) - old_phash = getattr(old_view, '__phash__', DEFAULT_PHASH) - - if old_view is None: - # - No component was yet registered for any of our I*View - # interfaces exactly; this is the first view for this - # triad. - regclosure() - - elif (not is_multiview) and (old_phash == phash): - # - A single view component was previously registered with - # the same predicate hash as this view; this registration - # is therefore an override. - regclosure() - - else: - # - A view or multiview was already registered for this - # triad, and the new view is not an override. - - # XXX we could try to be more efficient here and register - # a non-secured view for a multiview if none of the - # multiview's consituent views have a permission - # associated with them, but this code is getting pretty - # rough already - if is_multiview: - multiview = old_view - else: - multiview = MultiView(name) - old_accept = getattr(old_view, '__accept__', None) - old_order = getattr(old_view, '__order__', MAX_ORDER) - multiview.add(old_view, old_order, old_accept, old_phash) - multiview.add(derived_view, order, accept, phash) - for view_type in (IView, ISecuredView): - # unregister any existing views - self.registry.adapters.unregister( - (IViewClassifier, request_iface, r_context), - view_type, name=name) - if isexc: - self.registry.adapters.unregister( - (IExceptionViewClassifier, request_iface, r_context), - view_type, name=name) - self.registry.registerAdapter( - multiview, - (IViewClassifier, request_iface, context), - IMultiView, name=name, info=_info) - if isexc: - self.registry.registerAdapter( - multiview, - (IExceptionViewClassifier, request_iface, context), - IMultiView, name=name, info=_info) - - def add_route(self, - name, - pattern=None, - view=None, - view_for=None, - permission=None, - factory=None, - for_=None, - header=None, - xhr=False, - accept=None, - path_info=None, - request_method=None, - request_param=None, - traverse=None, - custom_predicates=(), - view_permission=None, - renderer=None, - view_renderer=None, - view_context=None, - view_attr=None, - use_global_views=False, - path=None, - pregenerator=None, - _info=u''): - """ Add a :term:`route configuration` to the current - configuration state, as well as possibly a :term:`view - configuration` to be used to specify a :term:`view callable` - that will be invoked when this route matches. The arguments - to this method are divided into *predicate*, *non-predicate*, - and *view-related* types. :term:`Route predicate` arguments - narrow the circumstances in which a route will be match a - request; non-predicate arguments are informational. - - Non-Predicate Arguments - - name - - The name of the route, e.g. ``myroute``. This attribute is - required. It must be unique among all defined routes in a given - application. - - factory - - A Python object (often a function or a class) or a - :term:`dotted Python name` which refers to the same object - that will generate a :mod:`repoze.bfg` :term:`context` - object when this route matches. For example, - ``mypackage.models.MyFactoryClass``. If this argument is - not specified, a default root factory will be used. - - traverse - - If you would like to cause the :term:`context` to be - something other than the :term:`root` object when this route - matches, you can spell a traversal pattern as the - ``traverse`` argument. This traversal pattern will be used - as the traversal path: traversal will begin at the root - object implied by this route (either the global root, or the - object returned by the ``factory`` associated with this - route). - - The syntax of the ``traverse`` argument is the same as it is - for ``pattern``. For example, if the ``pattern`` provided to - ``add_route`` is ``articles/:article/edit``, and the - ``traverse`` argument provided to ``add_route`` is - ``/:article``, when a request comes in that causes the route - to match in such a way that the ``article`` match value is - '1' (when the request URI is ``/articles/1/edit``), the - traversal path will be generated as ``/1``. This means that - the root object's ``__getitem__`` will be called with the - name ``1`` during the traversal phase. If the ``1`` object - exists, it will become the :term:`context` of the request. - :ref:`traversal_chapter` has more information about - traversal. - - If the traversal path contains segment marker names which - are not present in the ``pattern`` argument, a runtime error - will occur. The ``traverse`` pattern should not contain - segment markers that do not exist in the ``pattern`` - argument. - - A similar combining of routing and traversal is available - when a route is matched which contains a ``*traverse`` - remainder marker in its pattern (see - :ref:`using_traverse_in_a_route_pattern`). The ``traverse`` - argument to add_route allows you to associate route patterns - with an arbitrary traversal path without using a a - ``*traverse`` remainder marker; instead you can use other - match information. - - Note that the ``traverse`` argument to ``add_route`` is - ignored when attached to a route that has a ``*traverse`` - remainder marker in its pattern. - - .. note:: This feature is new as of :mod:`repoze.bfg` 1.3. - - pregenerator - - This option should be a callable object that implements the - :class:`repoze.bfg.interfaces.IRoutePregenerator` - interface. A :term:`pregenerator` is a callable called by - the :mod:`repoze.bfg.url.route_url` function to augment or - replace the arguments it is passed when generating a URL - for the route. This is a feature not often used directly - by applications, it is meant to be hooked by frameworks - that use :mod:`repoze.bfg` as a base. - - .. note:: This feature is new as of :mod:`repoze.bfg` 1.3. - - Predicate Arguments - - pattern - - The pattern of the route e.g. ``ideas/:idea``. This - argument is required. See :ref:`route_path_pattern_syntax` - for information about the syntax of route patterns. If the - pattern doesn't match the current URL, route matching - continues. - - .. note:: For backwards compatibility purposes (as of - :mod:`repoze.bfg` 1.3), a ``path`` keyword argument - passed to this function will be used to represent the - pattern value if the ``pattern`` argument is ``None``. - If both ``path`` and ``pattern`` are passed, ``pattern`` - wins. - - xhr - - This value should be either ``True`` or ``False``. If this - value is specified and is ``True``, the :term:`request` must - possess an ``HTTP_X_REQUESTED_WITH`` (aka - ``X-Requested-With``) header for this route to match. This - is useful for detecting AJAX requests issued from jQuery, - Prototype and other Javascript libraries. If this predicate - returns ``False``, route matching continues. - - request_method - - A string representing an HTTP method name, e.g. ``GET``, - ``POST``, ``HEAD``, ``DELETE``, ``PUT``. If this argument - is not specified, this route will match if the request has - *any* request method. If this predicate returns ``False``, - route matching continues. - - path_info - - This value represents a regular expression pattern that will - be tested against the ``PATH_INFO`` WSGI environment - variable. If the regex matches, this predicate will return - ``True``. If this predicate returns ``False``, route - matching continues. - - request_param - - This value can be any string. A view declaration with this - argument ensures that the associated route will only match - when the request has a key in the ``request.params`` - dictionary (an HTTP ``GET`` or ``POST`` variable) that has a - name which matches the supplied value. If the value - supplied as the argument has a ``=`` sign in it, - e.g. ``request_params="foo=123"``, then the key - (``foo``) must both exist in the ``request.params`` dictionary, and - the value must match the right hand side of the expression (``123``) - for the route to "match" the current request. If this predicate - returns ``False``, route matching continues. - - header - - This argument represents an HTTP header name or a header - name/value pair. If the argument contains a ``:`` (colon), - it will be considered a name/value pair - (e.g. ``User-Agent:Mozilla/.*`` or ``Host:localhost``). If - the value contains a colon, the value portion should be a - regular expression. If the value does not contain a colon, - the entire value will be considered to be the header name - (e.g. ``If-Modified-Since``). If the value evaluates to a - header name only without a value, the header specified by - the name must be present in the request for this predicate - to be true. If the value evaluates to a header name/value - pair, the header specified by the name must be present in - the request *and* the regular expression specified as the - value must match the header value. Whether or not the value - represents a header name or a header name/value pair, the - case of the header name is not significant. If this - predicate returns ``False``, route matching continues. - - accept - - This value represents a match query for one or more - mimetypes in the ``Accept`` HTTP request header. If this - value is specified, it must be in one of the following - forms: a mimetype match token in the form ``text/plain``, a - wildcard mimetype match token in the form ``text/*`` or a - match-all wildcard mimetype match token in the form ``*/*``. - If any of the forms matches the ``Accept`` header of the - request, this predicate will be true. If this predicate - returns ``False``, route matching continues. - - custom_predicates - - This value should be a sequence of references to custom - predicate callables. Use custom predicates when no set of - predefined predicates does what you need. Custom predicates - can be combined with predefined predicates as necessary. - Each custom predicate callable should accept two arguments: - ``info`` and ``request`` and should return either ``True`` - or ``False`` after doing arbitrary evaluation of the info - and/or the request. If all custom and non-custom predicate - callables return ``True`` the associated route will be - considered viable for a given request. If any predicate - callable returns ``False``, route matching continues. Note - that the value ``info`` passed to a custom route predicate - is a dictionary containing matching information; see - :ref:`custom_route_predicates` for more information about - ``info``. - - .. note:: This feature is new as of :mod:`repoze.bfg` 1.2. - - .. note:: The ``info`` argument passed to a custom predicate - in versions prior to :mod:`repoze.bfg` 1.3 was - always ``None``. - - View-Related Arguments - - view - - A Python object or :term:`dotted Python name` to the same - object that will be used as a view callable when this route - matches. e.g. ``mypackage.views.my_view``. - - view_context - - A class or an :term:`interface` or :term:`dotted Python - name` to the same object which the :term:`context` of the - view should match for the view named by the route to be - used. This argument is only useful if the ``view`` - attribute is used. If this attribute is not specified, the - default (``None``) will be used. - - If the ``view`` argument is not provided, this argument has - no effect. - - This attribute can also be spelled as ``for_`` or ``view_for``. - - view_permission - - The permission name required to invoke the view associated - with this route. e.g. ``edit``. (see - :ref:`using_security_with_urldispatch` for more information - about permissions). - - If the ``view`` attribute is not provided, this argument has - no effect. - - This argument can also be spelled as ``permission``. - - view_renderer - - This is either a single string term (e.g. ``json``) or a - string implying a path or :term:`resource specification` - (e.g. ``templates/views.pt``). If the renderer value is a - single term (does not contain a dot ``.``), the specified - term will be used to look up a renderer implementation, and - that renderer implementation will be used to construct a - response from the view return value. If the renderer term - contains a dot (``.``), the specified term will be treated - as a path, and the filename extension of the last element in - the path will be used to look up the renderer - implementation, which will be passed the full path. The - renderer implementation will be used to construct a response - from the view return value. See - :ref:`views_which_use_a_renderer` for more information. - - If the ``view`` argument is not provided, this argument has - no effect. - - This argument can also be spelled as ``renderer``. - - view_attr - - The view machinery defaults to using the ``__call__`` method - of the view callable (or the function itself, if the view - callable is a function) to obtain a response dictionary. - The ``attr`` value allows you to vary the method attribute - used to obtain the response. For example, if your view was - a class, and the class has a method named ``index`` and you - wanted to use this method instead of the class' ``__call__`` - method to return the response, you'd say ``attr="index"`` in - the view configuration for the view. This is - most useful when the view definition is a class. - - If the ``view`` argument is not provided, this argument has no - effect. - - use_global_views - - When a request matches this route, and view lookup cannot - find a view which has a ``route_name`` predicate argument - that matches the route, try to fall back to using a view - that otherwise matches the context, request, and view name - (but which does not match the route_name predicate). - - .. note:: This feature is new as of :mod:`repoze.bfg` 1.2. - - """ - # these are route predicates; if they do not match, the next route - # in the routelist will be tried - ignored, predicates, ignored = _make_predicates( - xhr=xhr, - request_method=request_method, - path_info=path_info, - request_param=request_param, - header=header, - accept=accept, - traverse=traverse, - custom=custom_predicates - ) - - - request_iface = self.registry.queryUtility(IRouteRequest, name=name) - if request_iface is None: - bases = use_global_views and (IRequest,) or () - request_iface = route_request_iface(name, bases) - self.registry.registerUtility( - request_iface, IRouteRequest, name=name) - deferred_views = getattr(self.registry, 'deferred_route_views', {}) - view_info = deferred_views.pop(name, ()) - for info in view_info: - self.add_view(**info) - - if view: - if view_context is None: - view_context = view_for - if view_context is None: - view_context = for_ - view_permission = view_permission or permission - view_renderer = view_renderer or renderer - self.add_view( - permission=view_permission, - context=view_context, - view=view, - name='', - route_name=name, - renderer=view_renderer, - attr=view_attr, - _info=_info, - ) - - mapper = self.get_routes_mapper() - - factory = self.maybe_dotted(factory) - if pattern is None: - pattern = path - if pattern is None: - raise ConfigurationError('"pattern" argument may not be None') - return mapper.connect(name, pattern, factory, predicates=predicates, - pregenerator=pregenerator) - - def get_routes_mapper(self): - """ Return the :term:`routes mapper` object associated with - this configurator's :term:`registry`.""" - mapper = self.registry.queryUtility(IRoutesMapper) - if mapper is None: - mapper = RoutesMapper() - self.registry.registerUtility(mapper, IRoutesMapper) - return mapper - - def scan(self, package=None, categories=None, _info=u''): - """ Scan a Python package and any of its subpackages for - objects marked with :term:`configuration decoration` such as - :class:`repoze.bfg.view.bfg_view`. Any decorated object found - will influence the current configuration state. - - The ``package`` argument should be a Python :term:`package` or - module object (or a :term:`dotted Python name` which refers to - such a package or module). If ``package`` is ``None``, the - package of the *caller* is used. - - The ``categories`` argument, if provided, should be the - :term:`Venusian` 'scan categories' to use during scanning. - Providing this argument is not often necessary; specifying - scan categories is an extremely advanced usage. - - By default, ``categories`` is ``None`` which will execute - *all* Venusian decorator callbacks including - :mod:`repoze.bfg`-related decorators such as ``bfg_view``. If - this is not desirable because the codebase has other - Venusian-using decorators that aren't meant to be invoked - during a particular scan, use ``('bfg',)`` as a ``categories`` - value to limit the execution of decorator callbacks to only - those registered by :mod:`repoze.bfg` itself. Or pass a - sequence of Venusian scan categories as necessary - (e.g. ``('bfg', 'myframework')``) to limit the decorators - called to the set of categories required. - """ - package = self.maybe_dotted(package) - if package is None: # pragma: no cover - package = caller_package() - - scanner = self.venusian.Scanner(config=self) - scanner.scan(package, categories=categories) - - def add_renderer(self, name, factory, _info=u''): - """ - Add a :mod:`repoze.bfg` :term:`renderer` factory to the - current configuration state. - - The ``name`` argument is the renderer name. - - The ``factory`` argument is Python reference to an - implementation of a :term:`renderer` factory or a - :term:`dotted Python name` to same. - - Note that this function must be called *before* any - ``add_view`` invocation that names the renderer name as an - argument. As a result, it's usually a better idea to pass - globally used renderers into the ``Configurator`` constructor - in the sequence of renderers passed as ``renderer`` than it is - to use this method. - """ - factory = self.maybe_dotted(factory) - self.registry.registerUtility( - factory, IRendererFactory, name=name, info=_info) - - def override_resource(self, to_override, override_with, - _info=u'', _override=None,): - """ Add a :mod:`repoze.bfg` resource override to the current - configuration state. - - ``to_override`` is a :term:`resource specification` to the - resource being overridden. - - ``override_with`` is a :term:`resource specification` to the - resource that is performing the override. - - See :ref:`resources_chapter` for more - information about resource overrides.""" - if to_override == override_with: - raise ConfigurationError('You cannot override a resource with ' - 'itself') - - package = to_override - path = '' - if ':' in to_override: - package, path = to_override.split(':', 1) - - override_package = override_with - override_prefix = '' - if ':' in override_with: - override_package, override_prefix = override_with.split(':', 1) - - if path and path.endswith('/'): - if override_prefix and (not override_prefix.endswith('/')): - raise ConfigurationError( - 'A directory cannot be overridden with a file (put a slash ' - 'at the end of override_with if necessary)') - - if override_prefix and override_prefix.endswith('/'): - if path and (not path.endswith('/')): - raise ConfigurationError( - 'A file cannot be overridden with a directory (put a slash ' - 'at the end of to_override if necessary)') - - __import__(package) - __import__(override_package) - package = sys.modules[package] - override_package = sys.modules[override_package] - - override = _override or self._override # test jig - override(package, path, override_package, override_prefix, - _info=_info) - - def set_forbidden_view(self, view=None, attr=None, renderer=None, - wrapper=None, _info=u''): - """ Add a default forbidden view to the current configuration - state. - - .. warning:: This method has been deprecated in - :mod:`repoze.bfg` 1.3. *Do not use it for new development; - it should only be used to support older code bases which - depend upon it.* See :ref:`changing_the_forbidden_view` to - see how a forbidden view should be registered in new - projects. - - .. note:: For backwards compatibility with :mod:`repoze.bfg` - 1.2, unlike an 'exception view' as described in - :ref:`exception_views`, a ``context, request`` view - callable registered using this API should not expect to - receive the exception as its first (``context``) argument. - Instead it should expect to receive the 'real' context as - found via context-finding or ``None`` if no context could - be found. The exception causing the registered view to be - called is however still available as ``request.exception``. - - The ``view`` argument should be a :term:`view callable` or a - :term:`dotted Python name` which refers to a view callable. - - The ``attr`` argument should be the attribute of the view - callable used to retrieve the response (see the ``add_view`` - method's ``attr`` argument for a description). - - The ``renderer`` argument should be the name of (or path to) a - :term:`renderer` used to generate a response for this view - (see the - :meth:`repoze.bfg.configuration.Configurator.add_view` - method's ``renderer`` argument for information about how a - configurator relates to a renderer). - - The ``wrapper`` argument should be the name of another view - which will wrap this view when rendered (see the ``add_view`` - method's ``wrapper`` argument for a description).""" - view = self._derive_view(view, attr=attr, renderer_name=renderer) - def bwcompat_view(context, request): - context = getattr(request, 'context', None) - return view(context, request) - return self.add_view(bwcompat_view, context=Forbidden, - wrapper=wrapper, _info=_info) - - def set_notfound_view(self, view=None, attr=None, renderer=None, - wrapper=None, _info=u''): - """ Add a default not found view to the current configuration - state. - - .. warning:: This method has been deprecated in - :mod:`repoze.bfg` 1.3. *Do not use it for new development; - it should only be used to support older code bases which - depend upon it.* See :ref:`changing_the_notfound_view` to - see how a not found view should be registered in new - projects. - - ..note:: For backwards compatibility with :mod:`repoze.bfg` - 1.2, unlike an 'exception view' as described in - :ref:`exception_views`, a ``context, request`` view - callable registered using this API should not expect to - receive the exception as its first (``context``) argument. - Instead it should expect to receive the 'real' context as - found via context-finding or ``None`` if no context could - be found. The exception causing the registered view to be - called is however still available as ``request.exception``. - - The ``view`` argument should be a :term:`view callable` or a - :term:`dotted Python name` which refers to a view callable. - - The ``attr`` argument should be the attribute of the view - callable used to retrieve the response (see the ``add_view`` - method's ``attr`` argument for a description). - - The ``renderer`` argument should be the name of (or path to) a - :term:`renderer` used to generate a response for this view - (see the - :meth:`repoze.bfg.configuration.Configurator.add_view` - method's ``renderer`` argument for information about how a - configurator relates to a renderer). - - The ``wrapper`` argument should be the name of another view - which will wrap this view when rendered (see the ``add_view`` - method's ``wrapper`` argument for a description). - """ - view = self._derive_view(view, attr=attr, renderer_name=renderer) - def bwcompat_view(context, request): - context = getattr(request, 'context', None) - return view(context, request) - return self.add_view(bwcompat_view, context=NotFound, - wrapper=wrapper, _info=_info) - - def set_request_factory(self, factory): - """ The object passed as ``factory`` should be an object (or a - :term:`dotted Python name` which refers to an object) which - will be used by the :mod:`repoze.bfg` router to create all - request objects. This factory object must have the same - methods and attributes as the - :class:`repoze.bfg.request.Request` class (particularly - ``__call__``, and ``blank``). - - .. note:: Using the :meth:``request_factory`` argument to the - :class:`repoze.bfg.configuration.Configurator` constructor - can be used to achieve the same purpose. - """ - factory = self.maybe_dotted(factory) - self.registry.registerUtility(factory, IRequestFactory) - - def set_renderer_globals_factory(self, factory): - """ The object passed as ``factory`` should be an callable (or - a :term:`dotted Python name` which refers to an callable) that - will be used by the :mod:`repoze.bfg` rendering machinery as a - renderers global factory (see :ref:`adding_renderer_globals`). - - The ``factory`` callable must accept a single argument named - ``system`` (which will be a dictionary) and it must return a - dictionary. When an application uses a renderer, the - factory's return dictionary will be merged into the ``system`` - dictionary, and therefore will be made available to the code - which uses the renderer. - - .. note:: Using the :meth:`renderer_globals_factory` - argument to the - :class:`repoze.bfg.configuration.Configurator` constructor - can be used to achieve the same purpose. - """ - factory = self.maybe_dotted(factory) - self.registry.registerUtility(factory, IRendererGlobalsFactory) - - def set_locale_negotiator(self, negotiator): - """ - Set the :term:`locale negotiator` for this application. The - :term:`locale negotiator` is a callable which accepts a - :term:`request` object and which returns a :term:`locale - name`. The ``negotiator`` argument should be the locale - negotiator implementation or a :term:`dotted Python name` - which refers to such an implementation. - - Later calls to this method override earlier calls; there can - be only one locale negotiator active at a time within an - application. See :ref:`activating_translation` for more - information. - - .. note: This API is new as of :mod:`repoze.bfg` version 1.3. - - .. note:: Using the ``locale_negotiator`` argument to the - :class:`repoze.bfg.configuration.Configurator` constructor - can be used to achieve the same purpose. - """ - negotiator = self.maybe_dotted(negotiator) - self.registry.registerUtility(negotiator, ILocaleNegotiator) - - def set_default_permission(self, permission): - """ - Set the default permission to be used by all subsequent - :term:`view configuration` registrations. ``permission`` - should be a :term:`permission` string to be used as the - default permission. An example of a permission - string:``'view'``. Adding a default permission makes it - unnecessary to protect each view configuration with an - explicit permission, unless your application policy requires - some exception for a particular view. - - If a default permission is *not* set, views represented by - view configuration registrations which do not explicitly - declare a permission will be executable by entirely anonymous - users (any authorization policy is ignored). - - Later calls to this method override earlier calls; there can - be only one default permission active at a time within an - application. - - See also :ref:`setting_a_default_permission`. - - .. note: This API is new as of :mod:`repoze.bfg` version 1.3. - - .. note:: Using the ``default_permission`` argument to the - :class:`repoze.bfg.configuration.Configurator` constructor - can be used to achieve the same purpose. - """ - self.registry.registerUtility(permission, IDefaultPermission) - - def add_translation_dirs(self, *specs): - """ Add one or more :term:`translation directory` paths to the - current configuration state. The ``specs`` argument is a - sequence that may contain absolute directory paths - (e.g. ``/usr/share/locale``) or :term:`resource specification` - names naming a directory path (e.g. ``some.package:locale``) - or a combination of the two. - - Example: - - .. code-block:: python - - add_translations_dirs('/usr/share/locale', 'some.package:locale') - - .. note: This API is new as of :mod:`repoze.bfg` version 1.3. - """ - for spec in specs: - - package_name, filename = self._split_spec(spec) - if package_name is None: # absolute filename - directory = filename - else: - __import__(package_name) - package = sys.modules[package_name] - directory = os.path.join(package_path(package), filename) - - if not os.path.isdir(os.path.realpath(directory)): - raise ConfigurationError('"%s" is not a directory' % directory) - - tdirs = self.registry.queryUtility(ITranslationDirectories) - if tdirs is None: - tdirs = [] - self.registry.registerUtility(tdirs, ITranslationDirectories) - - tdirs.insert(0, directory) - - if specs: - - # We actually only need an IChameleonTranslate function - # utility to be registered zero or one times. We register the - # same function once for each added translation directory, - # which does too much work, but has the same effect. - - def translator(msg): - request = get_current_request() - localizer = get_localizer(request) - return localizer.translate(msg) - - ctranslate = ChameleonTranslate(translator) - self.registry.registerUtility(ctranslate, IChameleonTranslate) - - def add_static_view(self, name, path, **kw): - """ Add a view used to render static resources such as images - and CSS files. - - The ``name`` argument is a string representing :term:`view - name` of the view which is registered. It may alternately be - a *url prefix*. - - The ``path`` argument is the path on disk where the static - files reside. This can be an absolute path, a - package-relative path, or a :term:`resource specification`. - - The ``cache_max_age`` keyword argument is input to set the - ``Expires`` and ``Cache-Control`` headers for static resources - served. Note that this argument has no effect when the - ``name`` is a *url prefix*. - - *Usage* - - The ``add_static_view`` function is typically used in - conjunction with the :func:`repoze.bfg.url.static_url` - function. ``add_static_view`` adds a view which renders a - static resource when some URL is visited; - :func:`repoze.bfg.url.static_url` generates a URL to that - resource. - - The ``name`` argument to ``add_static_view`` is usually a - :term:`view name`. When this is the case, the - :func:`repoze.bfg.url.static_url` API will generate a URL - which points to a BFG view, which will serve up a set of - resources that live in the package itself. For example: - - .. code-block:: python - - add_static_view('images', 'mypackage:images/') - - Code that registers such a view can generate URLs to the view - via :func:`repoze.bfg.url.static_url`: - - .. code-block:: python - - static_url('mypackage:images/logo.png', request) - - When ``add_static_view`` is called with a ``name`` argument - that represents a simple view name, as it is above, subsequent - calls to :func:`repoze.bfg.url.static_url` with paths that - start with the ``path`` argument passed to ``add_static_view`` - will generate a URL something like ``http://<BFG app - URL>/images/logo.png``, which will cause the ``logo.png`` file - in the ``images`` subdirectory of the ``mypackage`` package to - be served. - - ``add_static_view`` can alternately be used with a ``name`` - argument which is a *URL*, causing static resources to be - served from an external webserver. This happens when the - ``name`` argument is a URL (detected as any string with a - slash in it). In this mode, the ``name`` is used as the URL - prefix when generating a URL using - :func:`repoze.bfg.url.static_url`. For example, if - ``add_static_view`` is called like so: - - .. code-block:: python - - add_static_view('http://example.com/images', 'mypackage:images/') - - Subsequently, the URLs generated by - :func:`repoze.bfg.url.static_url` for that static view will be - prefixed with ``http://example.com/images``: - - .. code-block:: python - - static_url('mypackage:images/logo.png', request) - - When ``add_static_view`` is called with a ``name`` argument - that is the URL prefix ``http://example.com/images``, - subsequent calls to :func:`repoze.bfg.url.static_url` with - paths that start with the ``path`` argument passed to - ``add_static_view`` will generate a URL something like - ``http://example.com/logo.png``. The external webserver - listening on ``example.com`` must be itself configured to - respond properly to such a request. - - See :ref:`static_resources_section` for more information. - """ - spec = self._make_spec(path) - info = self.registry.queryUtility(IStaticURLInfo) - if info is None: - info = StaticURLInfo(self) - self.registry.registerUtility(info, IStaticURLInfo) - - info.add(name, spec, **kw) - - # testing API - def testing_securitypolicy(self, userid=None, groupids=(), - permissive=True): - """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.principals_allowed_by_permission`. - """ - from repoze.bfg.testing import DummySecurityPolicy - policy = DummySecurityPolicy(userid, groupids, permissive) - self.registry.registerUtility(policy, IAuthorizationPolicy) - self.registry.registerUtility(policy, IAuthenticationPolicy) - - def testing_models(self, models): - """Unit/integration testing helper: 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. - """ - class DummyTraverserFactory: - def __init__(self, context): - self.context = context - - def __call__(self, request): - path = request['PATH_INFO'] - ob = models[path] - traversed = traversal_path(path) - return {'context':ob, 'view_name':'','subpath':(), - 'traversed':traversed, 'virtual_root':ob, - 'virtual_root_path':(), 'root':ob} - self.registry.registerAdapter(DummyTraverserFactory, (Interface,), - ITraverser) - return models - - def testing_add_subscriber(self, event_iface=None): - """Unit/integration testing helper: Registers a - :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. - """ - event_iface = self.maybe_dotted(event_iface) - L = [] - def subscriber(*event): - L.extend(event) - self.add_subscriber(subscriber, event_iface) - return L - - def testing_add_renderer(self, path, renderer=None): - """Unit/integration testing helper: register a renderer at - ``path`` (usually a relative filename ala ``templates/foo.pt`` - or a resource specification) 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.renderers.render` function or - :func:`repoze.bfg.renderers.render_to_response` function or - any other ``render_*`` or ``get_*`` API of the - :mod:`repoze.bfg.renderers` module. - - Note that calling this method for with a ``path`` argument - representing a renderer factory type (e.g. for ``foo.pt`` - usually implies the ``chameleon_zpt`` renderer factory) - clobbers any existing renderer factory registered for that - type. - - .. note:: This method is also available under the alias - ``testing_add_template`` (an older name for it). - - .. note:: This method is new in :mod:`repoze.bfg` 1.3 (the - method named ``testing_add_template`` had the same signature - and purpose in previous releases).. - """ - from repoze.bfg.testing import DummyRendererFactory - helper = RendererHelper(path, registry=self.registry) - factory = helper.factory - if not isinstance(factory, DummyRendererFactory): - factory = DummyRendererFactory(helper.renderer_type, helper.factory) - self.registry.registerUtility(factory, IRendererFactory, - name=helper.renderer_type) - - from repoze.bfg.testing import DummyTemplateRenderer - if renderer is None: - renderer = DummyTemplateRenderer() - factory.add(helper.renderer_name, renderer) - return renderer - - testing_add_template = testing_add_renderer - -def _make_predicates(xhr=None, request_method=None, path_info=None, - request_param=None, header=None, accept=None, - containment=None, request_type=None, - traverse=None, custom=()): - - # PREDICATES - # ---------- - # - # Given an argument list, a predicate list is computed. - # Predicates are added to a predicate list in (presumed) - # computation expense order. All predicates associated with a - # view or route must evaluate true for the view or route to - # "match" during a request. Elsewhere in the code, we evaluate - # predicates using a generator expression. The fastest predicate - # should be evaluated first, then the next fastest, and so on, as - # if one returns false, the remainder of the predicates won't need - # to be evaluated. - # - # While we compute predicates, we also compute a predicate hash - # (aka phash) that can be used by a caller to identify identical - # predicate lists. - # - # ORDERING - # -------- - # - # A "order" is computed for the predicate list. An order is - # a scoring. - # - # Each predicate is associated with a weight value, which is a - # multiple of 2. The weight of a predicate symbolizes the - # relative potential "importance" of the predicate to all other - # predicates. A larger weight indicates greater importance. - # - # All weights for a given predicate list are bitwise ORed together - # to create a "score"; this score is then subtracted from - # MAX_ORDER and divided by an integer representing the number of - # predicates+1 to determine the order. - # - # The order represents the ordering in which a "multiview" ( a - # collection of views that share the same context/request/name - # triad but differ in other ways via predicates) will attempt to - # call its set of views. Views with lower orders will be tried - # first. The intent is to a) ensure that views with more - # predicates are always evaluated before views with fewer - # predicates and b) to ensure a stable call ordering of views that - # share the same number of predicates. Views which do not have - # any predicates get an order of MAX_ORDER, meaning that they will - # be tried very last. - - predicates = [] - weights = [] - h = md5() - - if xhr: - def xhr_predicate(context, request): - return request.is_xhr - weights.append(1 << 1) - predicates.append(xhr_predicate) - h.update('xhr:%r' % bool(xhr)) - - if request_method is not None: - def request_method_predicate(context, request): - return request.method == request_method - weights.append(1 << 2) - predicates.append(request_method_predicate) - h.update('request_method:%r' % request_method) - - if path_info is not None: - try: - path_info_val = re.compile(path_info) - except re.error, why: - raise ConfigurationError(why[0]) - def path_info_predicate(context, request): - return path_info_val.match(request.path_info) is not None - weights.append(1 << 3) - predicates.append(path_info_predicate) - h.update('path_info:%r' % path_info) - - if request_param is not None: - request_param_val = None - if '=' in request_param: - request_param, request_param_val = request_param.split('=', 1) - def request_param_predicate(context, request): - if request_param_val is None: - return request_param in request.params - return request.params.get(request_param) == request_param_val - weights.append(1 << 4) - predicates.append(request_param_predicate) - h.update('request_param:%r=%r' % (request_param, request_param_val)) - - if header is not None: - header_name = header - header_val = None - if ':' in header: - header_name, header_val = header.split(':', 1) - try: - header_val = re.compile(header_val) - except re.error, why: - raise ConfigurationError(why[0]) - def header_predicate(context, request): - if header_val is None: - return header_name in request.headers - val = request.headers.get(header_name) - if val is None: - return False - return header_val.match(val) is not None - weights.append(1 << 5) - predicates.append(header_predicate) - h.update('header:%r=%r' % (header_name, header_val)) - - if accept is not None: - def accept_predicate(context, request): - return accept in request.accept - weights.append(1 << 6) - predicates.append(accept_predicate) - h.update('accept:%r' % accept) - - if containment is not None: - def containment_predicate(context, request): - return find_interface(context, containment) is not None - weights.append(1 << 7) - predicates.append(containment_predicate) - h.update('containment:%r' % hash(containment)) - - if request_type is not None: - def request_type_predicate(context, request): - return request_type.providedBy(request) - weights.append(1 << 8) - predicates.append(request_type_predicate) - h.update('request_type:%r' % hash(request_type)) - - if traverse is not None: - # ``traverse`` can only be used as a *route* "predicate"; it - # adds 'traverse' to the matchdict if it's specified in the - # routing args. This causes the ModelGraphTraverser to use - # the resolved traverse pattern as the traversal path. - from repoze.bfg.urldispatch import _compile_route - _, tgenerate = _compile_route(traverse) - def traverse_predicate(context, request): - if 'traverse' in context: - return True - m = context['match'] - tvalue = tgenerate(m) - m['traverse'] = traversal_path(tvalue) - return True - # This isn't actually a predicate, it's just a infodict - # modifier that injects ``traverse`` into the matchdict. As a - # result, the ``traverse_predicate`` function above always - # returns True, and we don't need to update the hash or attach - # a weight to it - predicates.append(traverse_predicate) - - if custom: - for num, predicate in enumerate(custom): - predicates.append(predicate) - # using hash() here rather than id() is intentional: we - # want to allow custom predicates that are part of - # frameworks to be able to define custom __hash__ - # functions for custom predicates, so that the hash output - # of predicate instances which are "logically the same" - # may compare equal. - h.update('custom%s:%r' % (num, hash(predicate))) - weights.append(1 << 10) - - score = 0 - for bit in weights: - score = score | bit - order = (MAX_ORDER - score) / (len(predicates) + 1) - phash = h.hexdigest() - return order, predicates, phash - -class MultiView(object): - implements(IMultiView) - - def __init__(self, name): - self.name = name - self.media_views = {} - self.views = [] - self.accepts = [] - - def add(self, view, order, accept=None, phash=None): - if phash is not None: - for i, (s, v, h) in enumerate(list(self.views)): - if phash == h: - self.views[i] = (order, view, phash) - return - - if accept is None or '*' in accept: - self.views.append((order, view, phash)) - self.views.sort() - else: - subset = self.media_views.setdefault(accept, []) - subset.append((order, view, phash)) - subset.sort() - accepts = set(self.accepts) - accepts.add(accept) - self.accepts = list(accepts) # dedupe - - def get_views(self, request): - if self.accepts and hasattr(request, 'accept'): - accepts = self.accepts[:] - views = [] - while accepts: - match = request.accept.best_match(accepts) - if match is None: - break - subset = self.media_views[match] - views.extend(subset) - accepts.remove(match) - views.extend(self.views) - return views - return self.views - - def match(self, context, request): - for order, view, phash in self.get_views(request): - if not hasattr(view, '__predicated__'): - return view - if view.__predicated__(context, request): - return view - raise PredicateMismatch(self.name) - - def __permitted__(self, context, request): - view = self.match(context, request) - if hasattr(view, '__permitted__'): - return view.__permitted__(context, request) - return True - - def __call_permissive__(self, context, request): - view = self.match(context, request) - view = getattr(view, '__call_permissive__', view) - return view(context, request) - - def __call__(self, context, request): - for order, view, phash in self.get_views(request): - try: - return view(context, request) - except PredicateMismatch: - continue - raise PredicateMismatch(self.name) - -def decorate_view(wrapped_view, original_view): - if wrapped_view is original_view: - return False - wrapped_view.__module__ = original_view.__module__ - wrapped_view.__doc__ = original_view.__doc__ - try: - wrapped_view.__name__ = original_view.__name__ - except AttributeError: - wrapped_view.__name__ = repr(original_view) - try: - wrapped_view.__permitted__ = original_view.__permitted__ - except AttributeError: - pass - try: - wrapped_view.__call_permissive__ = original_view.__call_permissive__ - except AttributeError: - pass - try: - wrapped_view.__predicated__ = original_view.__predicated__ - except AttributeError: - pass - try: - wrapped_view.__accept__ = original_view.__accept__ - except AttributeError: - pass - try: - wrapped_view.__order__ = original_view.__order__ - except AttributeError: - pass - return True - -def requestonly(class_or_callable, attr=None): - """ Return true of the class or callable accepts only a request argument, - as opposed to something that accepts context, request """ - if attr is None: - attr = '__call__' - if inspect.isfunction(class_or_callable): - fn = class_or_callable - elif inspect.isclass(class_or_callable): - try: - fn = class_or_callable.__init__ - except AttributeError: - return False - else: - try: - fn = getattr(class_or_callable, attr) - except AttributeError: - return False - - try: - argspec = inspect.getargspec(fn) - except TypeError: - return False - - args = argspec[0] - defaults = argspec[3] - - if hasattr(fn, 'im_func'): - # it's an instance method - if not args: - return False - args = args[1:] - if not args: - return False - - if len(args) == 1: - return True - - elif args[0] == 'request': - if len(args) - len(defaults) == 1: - return True - - return False - -def is_response(ob): - if ( hasattr(ob, 'app_iter') and hasattr(ob, 'headerlist') and - hasattr(ob, 'status') ): - return True - return False - -def _map_view(view, attr=None, renderer_name=None, registry=None, package=None): - wrapped_view = view - - helper = None - if renderer_name: - helper = RendererHelper(renderer_name, - registry=registry, - package=package) - - if inspect.isclass(view): - # If the object we've located is a class, turn it into a - # function that operates like a Zope view (when it's invoked, - # construct an instance using 'context' and 'request' as - # position arguments, then immediately invoke the __call__ - # method of the instance with no arguments; __call__ should - # return an IResponse). - if requestonly(view, attr): - # its __init__ accepts only a single request argument, - # instead of both context and request - def _bfg_class_requestonly_view(context, request): - inst = view(request) - if attr is None: - response = inst() - else: - response = getattr(inst, attr)() - if helper is not None: - if not is_response(response): - system = {'view':inst, 'renderer_name':renderer_name, - 'context':context, 'request':request} - response = helper.render_to_response(response, system, - request=request) - return response - wrapped_view = _bfg_class_requestonly_view - else: - # its __init__ accepts both context and request - def _bfg_class_view(context, request): - inst = view(context, request) - if attr is None: - response = inst() - else: - response = getattr(inst, attr)() - if helper is not None: - if not is_response(response): - system = {'view':inst, 'renderer_name':renderer_name, - 'context':context, 'request':request} - response = helper.render_to_response(response, system, - request=request) - return response - wrapped_view = _bfg_class_view - - elif requestonly(view, attr): - # its __call__ accepts only a single request argument, - # instead of both context and request - def _bfg_requestonly_view(context, request): - if attr is None: - response = view(request) - else: - response = getattr(view, attr)(request) - - if helper is not None: - if not is_response(response): - system = {'view':view, 'renderer_name':renderer_name, - 'context':context, 'request':request} - response = helper.render_to_response(response, system, - request=request) - return response - wrapped_view = _bfg_requestonly_view - - elif attr: - def _bfg_attr_view(context, request): - response = getattr(view, attr)(context, request) - if helper is not None: - if not is_response(response): - system = {'view':view, 'renderer_name':renderer_name, - 'context':context, 'request':request} - response = helper.render_to_response(response, system, - request=request) - return response - wrapped_view = _bfg_attr_view - - elif helper is not None: - def _rendered_view(context, request): - response = view(context, request) - if not is_response(response): - system = {'view':view, 'renderer_name':renderer_name, - 'context':context, 'request':request} - response = helper.render_to_response(response, system, - request=request) - return response - wrapped_view = _rendered_view - - decorate_view(wrapped_view, view) - return wrapped_view - -def _owrap_view(view, viewname, wrapper_viewname): - if not wrapper_viewname: - return view - def _owrapped_view(context, request): - response = view(context, request) - request.wrapped_response = response - request.wrapped_body = response.body - request.wrapped_view = view - wrapped_response = render_view_to_response(context, request, - wrapper_viewname) - if wrapped_response is None: - raise ValueError( - 'No wrapper view named %r found when executing view ' - 'named %r' % (wrapper_viewname, viewname)) - return wrapped_response - decorate_view(_owrapped_view, view) - return _owrapped_view - -def _predicate_wrap(view, predicates): - if not predicates: - return view - def predicate_wrapper(context, request): - if all((predicate(context, request) for predicate in predicates)): - return view(context, request) - raise PredicateMismatch('predicate mismatch for view %s' % view) - def checker(context, request): - return all((predicate(context, request) for predicate in - predicates)) - predicate_wrapper.__predicated__ = checker - decorate_view(predicate_wrapper, view) - return predicate_wrapper - -def _secure_view(view, permission, authn_policy, authz_policy): - wrapped_view = view - if authn_policy and authz_policy and (permission is not None): - def _secured_view(context, request): - principals = authn_policy.effective_principals(request) - if authz_policy.permits(context, principals, permission): - return view(context, request) - msg = getattr(request, 'authdebug_message', - 'Unauthorized: %s failed permission check' % view) - raise Forbidden(msg) - _secured_view.__call_permissive__ = view - def _permitted(context, request): - principals = authn_policy.effective_principals(request) - return authz_policy.permits(context, principals, permission) - _secured_view.__permitted__ = _permitted - wrapped_view = _secured_view - decorate_view(wrapped_view, view) - - return wrapped_view - -def _authdebug_view(view, permission, authn_policy, authz_policy, settings, - logger): - wrapped_view = view - if settings and settings.get('debug_authorization', False): - def _authdebug_view(context, request): - view_name = getattr(request, 'view_name', None) - - if authn_policy and authz_policy: - if permission is None: - msg = 'Allowed (no permission registered)' - else: - principals = authn_policy.effective_principals(request) - msg = str(authz_policy.permits(context, principals, - permission)) - else: - msg = 'Allowed (no authorization policy in use)' - - view_name = getattr(request, 'view_name', None) - url = getattr(request, 'url', None) - msg = ('debug_authorization of url %s (view name %r against ' - 'context %r): %s' % (url, view_name, context, msg)) - logger and logger.debug(msg) - if request is not None: - request.authdebug_message = msg - return view(context, request) - - wrapped_view = _authdebug_view - decorate_view(wrapped_view, view) - - return wrapped_view - -def _attr_wrap(view, accept, order, phash): - # this is a little silly but we don't want to decorate the original - # function with attributes that indicate accept, order, and phash, - # so we use a wrapper - if (accept is None) and (order == MAX_ORDER) and (phash == DEFAULT_PHASH): - return view # defaults - def attr_view(context, request): - return view(context, request) - attr_view.__accept__ = accept - attr_view.__order__ = order - attr_view.__phash__ = phash - decorate_view(attr_view, view) - return attr_view - -def isexception(o): - if IInterface.providedBy(o): - if IException.isEqualOrExtendedBy(o): - return True - return ( - isinstance(o, Exception) or - (inspect.isclass(o) and (issubclass(o, Exception))) - ) - -# note that ``options`` is a b/w compat alias for ``settings`` and -# ``Configurator`` is a testing dep inj -def make_app(root_factory, package=None, filename='configure.zcml', - settings=None, options=None, Configurator=Configurator): - """ Return a Router object, representing a fully configured - :mod:`repoze.bfg` WSGI application. - - .. warning:: Use of this function is deprecated as of - :mod:`repoze.bfg` 1.2. You should instead use a - :class:`repoze.bfg.configuration.Configurator` instance to - perform startup configuration as shown in - :ref:`configuration_narr`. - - ``root_factory`` must be a callable that accepts a :term:`request` - object and which returns a traversal root object. The traversal - root returned by the root factory is the *default* traversal root; - it can be overridden on a per-view basis. ``root_factory`` may be - ``None``, in which case a 'default default' traversal root is - used. - - ``package`` is a Python :term:`package` or module representing the - application's package. It is optional, defaulting to ``None``. - ``package`` may be ``None``. If ``package`` is ``None``, the - ``filename`` passed or the value in the ``options`` dictionary - named ``configure_zcml`` must be a) absolute pathname to a - :term:`ZCML` file that represents the application's configuration - *or* b) a :term:`resource specification` to a :term:`ZCML` file in - the form ``dotted.package.name:relative/file/path.zcml``. - - ``filename`` is the filesystem path to a ZCML file (optionally - relative to the package path) that should be parsed to create the - application registry. It defaults to ``configure.zcml``. It can - also be a ;term:`resource specification` in the form - ``dotted_package_name:relative/file/path.zcml``. Note that if any - value for ``configure_zcml`` is passed within the ``settings`` - dictionary, the value passed as ``filename`` will be ignored, - replaced with the ``configure_zcml`` value. - - ``settings``, if used, should be a dictionary containing runtime - settings (e.g. the key/value pairs in an app section of a - PasteDeploy file), with each key representing the option and the - key's value representing the specific option value, - e.g. ``{'reload_templates':True}``. Note that the keyword - parameter ``options`` is a backwards compatibility alias for the - ``settings`` keyword parameter. - """ - settings = settings or options or {} - zcml_file = settings.get('configure_zcml', filename) - config = Configurator(package=package, settings=settings, - root_factory=root_factory) - config.hook_zca() - config.begin() - config.load_zcml(zcml_file) - config.end() - return config.make_wsgi_app() - - -class DottedNameResolver(object): - """ This class resolves dotted name references to 'global' Python - objects (objects which can be imported) to those objects. - - Two dotted name styles are supported during deserialization: - - - ``pkg_resources``-style dotted names where non-module attributes - of a package are separated from the rest of the path using a ':' - e.g. ``package.module:attr``. - - - ``zope.dottedname``-style dotted names where non-module - attributes of a package are separated from the rest of the path - using a '.' e.g. ``package.module.attr``. - - These styles can be used interchangeably. If the serialization - contains a ``:`` (colon), the ``pkg_resources`` resolution - mechanism will be chosen, otherwise the ``zope.dottedname`` - resolution mechanism will be chosen. - - The constructor accepts a single argument named ``package`` which - should be a one of: - - - a Python module or package object - - - A fully qualified (not relative) dotted name to a module or package - - - The value ``None`` - - The ``package`` is used when relative dotted names are supplied to - the resolver's ``resolve`` and ``maybe_resolve`` methods. A - dotted name which has a ``.`` (dot) or ``:`` (colon) as its first - character is treated as relative. - - If the value ``None`` is supplied as the package name, the - resolver will only be able to resolve fully qualified (not - relative) names. Any attempt to resolve a relative name when the - ``package`` is ``None`` will result in an - :exc:`repoze.bfg.configuration.ConfigurationError` exception. - - If a *module* or *module name* (as opposed to a package or package - name) is supplied as ``package``, its containing package is - computed and this package used to derive the package name (all - names are resolved relative to packages, never to modules). For - example, if the ``package`` argument to this type was passed the - string ``xml.dom.expatbuilder``, and ``.mindom`` is supplied to - the ``resolve`` method, the resulting import would be for - ``xml.minidom``, because ``xml.dom.expatbuilder`` is a module - object, not a package object. - - If a *package* or *package name* (as opposed to a module or module - name) is supplied as ``package``, this package will be used to - relative compute dotted names. For example, if the ``package`` - argument to this type was passed the string ``xml.dom``, and - ``.minidom`` is supplied to the ``resolve`` method, the resulting - import would be for ``xml.minidom``. - - When a dotted name cannot be resolved, a - :class:`repoze.bfg.exceptions.ConfigurationError` error is raised. - """ - def __init__(self, package): - if package is None: - self.package_name = None - self.package = None - else: - if isinstance(package, basestring): - try: - __import__(package) - except ImportError: - raise ConfigurationError( - 'The dotted name %r cannot be imported' % (package,)) - package = sys.modules[package] - self.package = package_of(package) - self.package_name = self.package.__name__ - - def _pkg_resources_style(self, value): - """ package.module:attr style """ - if value.startswith('.') or value.startswith(':'): - if not self.package_name: - raise ConfigurationError( - 'relative name %r irresolveable without ' - 'package_name' % (value,)) - if value in ['.', ':']: - value = self.package_name - else: - value = self.package_name + value - return pkg_resources.EntryPoint.parse( - 'x=%s' % value).load(False) - - def _zope_dottedname_style(self, value): - """ package.module.attr style """ - module = self.package_name and self.package_name or None - if value == '.': - if self.package_name is None: - raise ConfigurationError( - 'relative name %r irresolveable without package' % (value,)) - name = module.split('.') - else: - name = value.split('.') - if not name[0]: - if module is None: - raise ConfigurationError( - 'relative name %r irresolveable without ' - 'package' % (value,) - ) - module = module.split('.') - name.pop(0) - while not name[0]: - module.pop() - name.pop(0) - name = module + name - - used = name.pop(0) - found = __import__(used) - for n in name: - used += '.' + n - try: - found = getattr(found, n) - except AttributeError: - __import__(used) - found = getattr(found, n) # pragma: no cover - - return found - - def resolve(self, dotted): - if not isinstance(dotted, basestring): - raise ConfigurationError('%r is not a string' % (dotted,)) - return self.maybe_resolve(dotted) - - def maybe_resolve(self, dotted): - if isinstance(dotted, basestring): - try: - if ':' in dotted: - return self._pkg_resources_style(dotted) - else: - return self._zope_dottedname_style(dotted) - except ImportError: - raise ConfigurationError( - 'The dotted name %r cannot be imported' % (dotted,)) - return dotted - diff --git a/repoze/bfg/decorator.py b/repoze/bfg/decorator.py deleted file mode 100644 index 98d7b36b5..000000000 --- a/repoze/bfg/decorator.py +++ /dev/null @@ -1,20 +0,0 @@ -class reify(object): - - """ Put the result of a method which uses this (non-data) - descriptor decorator in the instance dict after the first call, - effectively replacing the decorator with an instance variable.""" - - def __init__(self, wrapped): - self.wrapped = wrapped - try: - self.__doc__ = wrapped.__doc__ - except: # pragma: no cover - pass - - def __get__(self, inst, objtype=None): - if inst is None: - return self - val = self.wrapped(inst) - setattr(inst, self.wrapped.__name__, val) - return val - diff --git a/repoze/bfg/encode.py b/repoze/bfg/encode.py deleted file mode 100644 index 127c405ed..000000000 --- a/repoze/bfg/encode.py +++ /dev/null @@ -1,107 +0,0 @@ -import re - -always_safe = ('ABCDEFGHIJKLMNOPQRSTUVWXYZ' - 'abcdefghijklmnopqrstuvwxyz' - '0123456789' '_.-') -_safemaps = {} -_must_quote = {} - -def url_quote(s, safe=''): - """quote('abc def') -> 'abc%20def' - - Faster version of Python stdlib urllib.quote which also quotes - the '/' character. - - Each part of a URL, e.g. the path info, the query, etc., has a - different set of reserved characters that must be quoted. - - RFC 2396 Uniform Resource Identifiers (URI): Generic Syntax lists - the following reserved characters. - - reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | - "$" | "," - - Each of these characters is reserved in some component of a URL, - but not necessarily in all of them. - - Unlike the default version of this function in the Python stdlib, - by default, the quote function is intended for quoting individual - path segments instead of an already composed path that might have - '/' characters in it. Thus, it *will* encode any '/' character it - finds in a string. - """ - cachekey = (safe, always_safe) - try: - safe_map = _safemaps[cachekey] - if not _must_quote[cachekey].search(s): - return s - except KeyError: - safe += always_safe - _must_quote[cachekey] = re.compile(r'[^%s]' % safe) - safe_map = {} - for i in range(256): - c = chr(i) - safe_map[c] = (c in safe) and c or ('%%%02X' % i) - _safemaps[cachekey] = safe_map - res = map(safe_map.__getitem__, s) - return ''.join(res) - -def quote_plus(s, safe=''): - """ Version of stdlib quote_plus which uses faster url_quote """ - if ' ' in s: - s = url_quote(s, safe + ' ') - return s.replace(' ', '+') - return url_quote(s, safe) - -def urlencode(query, doseq=True): - """ - An alternate implementation of Python's stdlib `urllib.urlencode - function <http://docs.python.org/library/urllib.html>`_ which - accepts unicode keys and values within the ``query`` - dict/sequence; all Unicode keys and values are first converted to - UTF-8 before being used to compose the query string. - - The value of ``query`` must be a sequence of two-tuples - representing key/value pairs *or* an object (often a dictionary) - with an ``.items()`` method that returns a sequence of two-tuples - representing key/value pairs. - - For minimal calling convention backwards compatibility, this - version of urlencode accepts *but ignores* a second argument - conventionally named ``doseq``. The Python stdlib version behaves - differently when ``doseq`` is False and when a sequence is - presented as one of the values. This version always behaves in - the ``doseq=True`` mode, no matter what the value of the second - argument. - - See the Python stdlib documentation for ``urllib.urlencode`` for - more information. - """ - try: - # presumed to be a dictionary - query = query.items() - except AttributeError: - pass - - result = '' - prefix = '' - - for (k, v) in query: - if k.__class__ is unicode: - k = k.encode('utf-8') - k = quote_plus(str(k)) - if hasattr(v, '__iter__'): - for x in v: - if x.__class__ is unicode: - x = x.encode('utf-8') - x = quote_plus(str(x)) - result += '%s%s=%s' % (prefix, k, x) - prefix = '&' - else: - if v.__class__ is unicode: - v = v.encode('utf-8') - v = quote_plus(str(v)) - result += '%s%s=%s' % (prefix, k, v) - prefix = '&' - - return result diff --git a/repoze/bfg/events.py b/repoze/bfg/events.py deleted file mode 100644 index efcbdf61f..000000000 --- a/repoze/bfg/events.py +++ /dev/null @@ -1,163 +0,0 @@ -import venusian - -from zope.interface import implements - -from repoze.bfg.interfaces import IContextFound -from repoze.bfg.interfaces import INewRequest -from repoze.bfg.interfaces import INewResponse -from repoze.bfg.interfaces import IApplicationCreated - -class subscriber(object): - """ Decorator activated via a :term:`scan` which treats the - function being decorated as an event subscriber for the set of - interfaces passed as ``*ifaces`` to the decorator constructor. - - For example: - - .. code-block:: python - - from repoze.bfg.interfaces import INewRequest - from repoze.bfg.events import subscriber - - @subscriber(INewRequest) - def mysubscriber(event): - event.request.foo = 1 - - More than one event type can be passed as a construtor argument: - - .. code-block:: python - - from repoze.bfg.interfaces import INewRequest - from repoze.bfg.events import subscriber - - @subscriber(INewRequest, INewResponse) - def mysubscriber(event): - print event - - When the ``subscriber`` decorator is used without passing an arguments, - the function it decorates is called for every event sent: - - .. code-block:: python - - from repoze.bfg.interfaces import INewRequest - from repoze.bfg.events import subscriber - - @subscriber() - def mysubscriber(event): - print event - - This method will have no effect until a :term:`scan` is performed - against the package or module which contains it, ala: - - .. code-block:: python - - from repoze.bfg.configuration import Configurator - config = Configurator() - config.scan('somepackage_containing_subscribers') - - """ - venusian = venusian # for unit testing - - def __init__(self, *ifaces): - self.ifaces = ifaces - - def register(self, scanner, name, wrapped): - config = scanner.config - config.add_subscriber(wrapped, self.ifaces) - - def __call__(self, wrapped): - self.venusian.attach(wrapped, self.register, category='bfg') - return wrapped - -class NewRequest(object): - """ An instance of this class is emitted as an :term:`event` - whenever :mod:`repoze.bfg` begins to process a new request. The - even instance has an attribute, ``request``, which is a - :term:`request` object. This event class implements the - :class:`repoze.bfg.interfaces.INewRequest` interface.""" - implements(INewRequest) - def __init__(self, request): - self.request = request - -class NewResponse(object): - """ An instance of this class is emitted as an :term:`event` - whenever any :mod:`repoze.bfg` :term:`view` or :term:`exception - view` returns a :term:`response`. - - The instance has two attributes:``request``, which is the request - which caused the response, and ``response``, which is the response - object returned by a view or renderer. - - If the ``response`` was generated by an :term:`exception view`, - the request will have an attribute named ``exception``, which is - the exception object which caused the exception view to be - executed. If the response was generated by a 'normal' view, the - request will not have this attribute. - - This event will not be generated if a response cannot be created - due to an exception that is not caught by an exception view (no - response is created under this circumstace). - - This class implements the - :class:`repoze.bfg.interfaces.INewResponse` interface. - - .. note:: - - Postprocessing a response is usually better handled in a WSGI - :term:`middleware` component than in subscriber code that is - called by a :class:`repoze.bfg.interfaces.INewResponse` event. - The :class:`repoze.bfg.interfaces.INewResponse` event exists - almost purely for symmetry with the - :class:`repoze.bfg.interfaces.INewRequest` event. - """ - implements(INewResponse) - def __init__(self, request, response): - self.request = request - self.response = response - -class ContextFound(object): - """ An instance of this class is emitted as an :term:`event` after - the :mod:`repoze.bfg` :term:`router` finds a :term:`context` - object (after it performs traversal) but before any view code is - executed. The instance has an attribute, ``request``, which is - the request object generated by :mod:`repoze.bfg`. - - Notably, the request object will have an attribute named - ``context``, which is the context that will be provided to the - view which will eventually be called, as well as other attributes - attached by context-finding code. - - This class implements the - :class:`repoze.bfg.interfaces.IContextFound` interface. - - .. note:: As of :mod:`repoze.bfg` 1.3, for backwards compatibility - purposes, this event may also be imported as - :class:`repoze.bfg.events.AfterTraversal`. - """ - implements(IContextFound) - def __init__(self, request): - self.request = request - -AfterTraversal = ContextFound # b/c as of 1.3 - -class ApplicationCreated(object): - """ An instance of this class is emitted as an :term:`event` when - the :meth:`repoze.bfg.configuration.Configurator.make_wsgi_app` is - called. The instance has an attribute, ``app``, which is an - instance of the :term:`router` that will handle WSGI requests. - This class implements the - :class:`repoze.bfg.interfaces.IApplicationCreated` interface. - - .. note:: For backwards compatibility purposes, this class can - also be imported as - :class:`repoze.bfg.events.WSGIApplicationCreatedEvent`. This - was the name of the event class before :mod:`repoze.bfg` 1.3. - - """ - implements(IApplicationCreated) - def __init__(self, app): - self.app = app - self.object = app - -WSGIApplicationCreatedEvent = ApplicationCreated # b/c (as of 1.3) - diff --git a/repoze/bfg/exceptions.py b/repoze/bfg/exceptions.py deleted file mode 100644 index 9b885d9dc..000000000 --- a/repoze/bfg/exceptions.py +++ /dev/null @@ -1,92 +0,0 @@ -from zope.configuration.exceptions import ConfigurationError as ZCE -from zope.interface import implements - -from repoze.bfg.decorator import reify -from repoze.bfg.interfaces import IExceptionResponse -import cgi - -class ExceptionResponse(Exception): - """ Abstract class to support behaving as a WSGI response object """ - implements(IExceptionResponse) - status = None - - def __init__(self, message=''): - Exception.__init__(self, message) # B / C - self.message = message - - @reify # defer execution until asked explicitly - def app_iter(self): - return [ - """ - <html> - <title>%s</title> - <body> - <h1>%s</h1> - <code>%s</code> - </body> - </html> - """ % (self.status, self.status, cgi.escape(self.message)) - ] - - @reify # defer execution until asked explicitly - def headerlist(self): - return [ - ('Content-Length', str(len(self.app_iter[0]))), - ('Content-Type', 'text/html') - ] - - -class Forbidden(ExceptionResponse): - """ - Raise this exception within :term:`view` code to immediately - return the :term:`forbidden view` to the invoking user. Usually - this is a basic ``401`` page, but the forbidden view can be - customized as necessary. See :ref:`changing_the_forbidden_view`. - - This exception's constructor accepts a single positional argument, - which should be a string. The value of this string will be placed - into the WSGI environment by the router under the - ``repoze.bfg.message`` key, for availability to the - :term:`Forbidden View`. - """ - status = '401 Unauthorized' - -class NotFound(ExceptionResponse): - """ - Raise this exception within :term:`view` code to immediately - return the :term:`Not Found view` to the invoking user. Usually - this is a basic ``404`` page, but the Not Found view can be - customized as necessary. See :ref:`changing_the_notfound_view`. - - This exception's constructor accepts a single positional argument, - which should be a string. The value of this string will be placed - into the WSGI environment by the router under the - ``repoze.bfg.message`` key, for availability to the :term:`Not Found - View`. - """ - status = '404 Not Found' - -class PredicateMismatch(NotFound): - """ - Internal exception (not an API) raised by multiviews when no - view matches. This exception subclasses the ``NotFound`` - exception only one reason: if it reaches the main exception - handler, it should be treated like a ``NotFound`` by any exception - view registrations. - """ - -class URLDecodeError(UnicodeDecodeError): - """ - This exception is raised when :mod:`repoze.bfg` cannot - successfully decode a URL or a URL path segment. This exception - it behaves just like the Python builtin - :exc:`UnicodeDecodeError`. It is a subclass of the builtin - :exc:`UnicodeDecodeError` exception only for identity purposes, - mostly so an exception view can be registered when a URL cannot be - decoded. - """ - -class ConfigurationError(ZCE): - """ Raised when inappropriate input values are supplied to an API - method of a :term:`Configurator`""" - diff --git a/repoze/bfg/i18n.py b/repoze/bfg/i18n.py deleted file mode 100644 index c3ba7efad..000000000 --- a/repoze/bfg/i18n.py +++ /dev/null @@ -1,322 +0,0 @@ -import gettext -import os - -from translationstring import Translator -from translationstring import Pluralizer -from translationstring import TranslationString # API -from translationstring import TranslationStringFactory # API - -TranslationString = TranslationString # PyFlakes -TranslationStringFactory = TranslationStringFactory # PyFlakes - -from repoze.bfg.interfaces import ILocalizer -from repoze.bfg.interfaces import ITranslationDirectories -from repoze.bfg.interfaces import ILocaleNegotiator - -from repoze.bfg.settings import get_settings -from repoze.bfg.threadlocal import get_current_registry - -class Localizer(object): - """ - An object providing translation and pluralizations related to - the current request's locale name. A - :class:`repoze.bfg.i18n.Localizer` object is created using the - :func:`repoze.bfg.i18n.get_localizer` function. - """ - def __init__(self, locale_name, translations): - self.locale_name = locale_name - self.translations = translations - self.pluralizer = None - self.translator = None - - def translate(self, tstring, domain=None, mapping=None): - """ - Translate a :term:`translation string` to the current language - and interpolate any *replacement markers* in the result. The - ``translate`` method accepts three arguments: ``tstring`` - (required), ``domain`` (optional) and ``mapping`` (optional). - When called, it will translate the ``tstring`` translation - string to a ``unicode`` object using the current locale. If - the current locale could not be determined, the result of - interpolation of the default value is returned. The optional - ``domain`` argument can be used to specify or override the - domain of the ``tstring`` (useful when ``tstring`` is a normal - string rather than a translation string). The optional - ``mapping`` argument can specify or override the ``tstring`` - interpolation mapping, useful when the ``tstring`` argument is - a simple string instead of a translation string. - - Example:: - - from repoze.bfg.18n import TranslationString - ts = TranslationString('Add ${item}', domain='mypackage', - mapping={'item':'Item'}) - translated = localizer.translate(ts) - - Example:: - - translated = localizer.translate('Add ${item}', domain='mypackage', - mapping={'item':'Item'}) - - """ - if self.translator is None: - self.translator = Translator(self.translations) - return self.translator(tstring, domain=domain, mapping=mapping) - - def pluralize(self, singular, plural, n, domain=None, mapping=None): - """ - Return a Unicode string translation by using two - :term:`message identifier` objects as a singular/plural pair - and an ``n`` value representing the number that appears in the - message using gettext plural forms support. The ``singular`` - and ``plural`` objects passed may be translation strings or - unicode strings. ``n`` represents the number of elements. - ``domain`` is the translation domain to use to do the - pluralization, and ``mapping`` is the interpolation mapping - that should be used on the result. Note that if the objects - passed are translation strings, their domains and mappings are - ignored. The domain and mapping arguments must be used - instead. If the ``domain`` is not supplied, a default domain - is used (usually ``messages``). - - Example:: - - num = 1 - translated = localizer.pluralize('Add ${num} item', - 'Add ${num} items', - num, - mapping={'num':num}) - - - """ - if self.pluralizer is None: - self.pluralizer = Pluralizer(self.translations) - return self.pluralizer(singular, plural, n, domain=domain, - mapping=mapping) - - -def default_locale_negotiator(request): - """ The default :term:`locale negotiator`. Returns a locale name - or ``None``. - - - First, the negotiator looks for the ``_LOCALE_`` attribute of - the request object (possibly set by a view or a listener for an - :term:`event`). - - - Then it looks for the ``request.params['_LOCALE_']`` value. - - - Then it looks for the ``request.cookies['_LOCALE_']`` value. - - - Finally, the negotiator returns ``None`` if the locale could not - be determined via any of the previous checks (when a locale - negotiator returns ``None``, it signifies that the - :term:`default locale name` should be used.) - """ - name = '_LOCALE_' - locale_name = getattr(request, name, None) - if locale_name is None: - locale_name = request.params.get(name) - if locale_name is None: - locale_name = request.cookies.get(name) - return locale_name - -def negotiate_locale_name(request): - """ Negotiate and return the :term:`locale name` associated with - the current request (never cached).""" - try: - registry = request.registry - except AttributeError: - registry = get_current_registry() - negotiator = registry.queryUtility(ILocaleNegotiator, - default=default_locale_negotiator) - locale_name = negotiator(request) - - if locale_name is None: - settings = get_settings() or {} - locale_name = settings.get('default_locale_name', 'en') - - return locale_name - -def get_locale_name(request): - """ Return the :term:`locale name` associated with the current - request (possibly cached).""" - locale_name = getattr(request, 'bfg_locale_name', None) - if locale_name is None: - locale_name = negotiate_locale_name(request) - request.bfg_locale_name = locale_name - return locale_name - -def get_localizer(request): - """ Retrieve a :class:`repoze.bfg.i18n.Localizer` object - corresponding to the current request's locale name. """ - localizer = getattr(request, 'bfg_localizer', None) - - if localizer is None: - # no locale object cached on request - try: - registry = request.registry - except AttributeError: - registry = get_current_registry() - - current_locale_name = get_locale_name(request) - localizer = registry.queryUtility(ILocalizer, name=current_locale_name) - - if localizer is None: - # no localizer utility registered yet - translations = Translations() - translations._catalog = {} - tdirs = registry.queryUtility(ITranslationDirectories, default=[]) - for tdir in tdirs: - locale_dirs = [ (lname, os.path.join(tdir, lname)) for lname in - os.listdir(tdir) ] - for locale_name, locale_dir in locale_dirs: - if locale_name != current_locale_name: - continue - messages_dir = os.path.join(locale_dir, 'LC_MESSAGES') - if not os.path.isdir(os.path.realpath(messages_dir)): - continue - for mofile in os.listdir(messages_dir): - mopath = os.path.realpath(os.path.join(messages_dir, - mofile)) - if mofile.endswith('.mo') and os.path.isfile(mopath): - mofp = open(mopath, 'rb') - domain = mofile[:-3] - dtrans = Translations(mofp, domain) - translations.add(dtrans) - - localizer = Localizer(locale_name=current_locale_name, - translations=translations) - registry.registerUtility(localizer, ILocalizer, - name=current_locale_name) - request.bfg_localizer = localizer - - return localizer - -class Translations(gettext.GNUTranslations, object): - """An extended translation catalog class (ripped off from Babel) """ - - DEFAULT_DOMAIN = 'messages' - - def __init__(self, fileobj=None, domain=DEFAULT_DOMAIN): - """Initialize the translations catalog. - - :param fileobj: the file-like object the translation should be read - from - """ - gettext.GNUTranslations.__init__(self, fp=fileobj) - self.files = filter(None, [getattr(fileobj, 'name', None)]) - self.domain = domain - self._domains = {} - - @classmethod - def load(cls, dirname=None, locales=None, domain=DEFAULT_DOMAIN): - """Load translations from the given directory. - - :param dirname: the directory containing the ``MO`` files - :param locales: the list of locales in order of preference (items in - this list can be either `Locale` objects or locale - strings) - :param domain: the message domain - :return: the loaded catalog, or a ``NullTranslations`` instance if no - matching translations were found - :rtype: `Translations` - """ - if locales is not None: - if not isinstance(locales, (list, tuple)): - locales = [locales] - locales = [str(l) for l in locales] - if not domain: - domain = cls.DEFAULT_DOMAIN - filename = gettext.find(domain, dirname, locales) - if not filename: - return gettext.NullTranslations() - return cls(fileobj=open(filename, 'rb'), domain=domain) - - def __repr__(self): - return '<%s: "%s">' % (type(self).__name__, - self._info.get('project-id-version')) - - def add(self, translations, merge=True): - """Add the given translations to the catalog. - - If the domain of the translations is different than that of the - current catalog, they are added as a catalog that is only accessible - by the various ``d*gettext`` functions. - - :param translations: the `Translations` instance with the messages to - add - :param merge: whether translations for message domains that have - already been added should be merged with the existing - translations - :return: the `Translations` instance (``self``) so that `merge` calls - can be easily chained - :rtype: `Translations` - """ - domain = getattr(translations, 'domain', self.DEFAULT_DOMAIN) - if merge and domain == self.domain: - return self.merge(translations) - - existing = self._domains.get(domain) - if merge and existing is not None: - existing.merge(translations) - else: - translations.add_fallback(self) - self._domains[domain] = translations - - return self - - def merge(self, translations): - """Merge the given translations into the catalog. - - Message translations in the specified catalog override any messages - with the same identifier in the existing catalog. - - :param translations: the `Translations` instance with the messages to - merge - :return: the `Translations` instance (``self``) so that `merge` calls - can be easily chained - :rtype: `Translations` - """ - if isinstance(translations, gettext.GNUTranslations): - self._catalog.update(translations._catalog) - if isinstance(translations, Translations): - self.files.extend(translations.files) - - return self - - def dgettext(self, domain, message): - """Like ``gettext()``, but look the message up in the specified - domain. - """ - return self._domains.get(domain, self).gettext(message) - - def ldgettext(self, domain, message): - """Like ``lgettext()``, but look the message up in the specified - domain. - """ - return self._domains.get(domain, self).lgettext(message) - - def dugettext(self, domain, message): - """Like ``ugettext()``, but look the message up in the specified - domain. - """ - return self._domains.get(domain, self).ugettext(message) - - def dngettext(self, domain, singular, plural, num): - """Like ``ngettext()``, but look the message up in the specified - domain. - """ - return self._domains.get(domain, self).ngettext(singular, plural, num) - - def ldngettext(self, domain, singular, plural, num): - """Like ``lngettext()``, but look the message up in the specified - domain. - """ - return self._domains.get(domain, self).lngettext(singular, plural, num) - - def dungettext(self, domain, singular, plural, num): - """Like ``ungettext()`` but look the message up in the specified - domain. - """ - return self._domains.get(domain, self).ungettext(singular, plural, num) - diff --git a/repoze/bfg/includes/__init__.py b/repoze/bfg/includes/__init__.py deleted file mode 100644 index 9faa798e8..000000000 --- a/repoze/bfg/includes/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# includes package: referred to by generated apps diff --git a/repoze/bfg/includes/configure.zcml b/repoze/bfg/includes/configure.zcml deleted file mode 100644 index 6a373fa5d..000000000 --- a/repoze/bfg/includes/configure.zcml +++ /dev/null @@ -1,5 +0,0 @@ -<configure xmlns="http://namespaces.repoze.org/bfg"> - - <include file="meta.zcml" /> - -</configure> diff --git a/repoze/bfg/includes/meta.zcml b/repoze/bfg/includes/meta.zcml deleted file mode 100644 index 58ab1c782..000000000 --- a/repoze/bfg/includes/meta.zcml +++ /dev/null @@ -1,117 +0,0 @@ -<configure - xmlns="http://namespaces.zope.org/zope" - xmlns:meta="http://namespaces.zope.org/meta"> - - <meta:directives namespace="http://namespaces.repoze.org/bfg"> - - <meta:directive - name="view" - schema="repoze.bfg.zcml.IViewDirective" - handler="repoze.bfg.zcml.view" - /> - - <meta:directive - name="scan" - schema="repoze.bfg.zcml.IScanDirective" - handler="repoze.bfg.zcml.scan" - /> - - <meta:directive - name="notfound" - schema="repoze.bfg.zcml.ISystemViewDirective" - handler="repoze.bfg.zcml.notfound" - /> - - <meta:directive - name="forbidden" - schema="repoze.bfg.zcml.ISystemViewDirective" - handler="repoze.bfg.zcml.forbidden" - /> - - <meta:directive - name="route" - schema="repoze.bfg.zcml.IRouteDirective" - handler="repoze.bfg.zcml.route" - /> - - <meta:directive - name="resource" - schema="repoze.bfg.zcml.IResourceDirective" - handler="repoze.bfg.zcml.resource" - /> - - <meta:directive - name="static" - schema="repoze.bfg.zcml.IStaticDirective" - handler="repoze.bfg.zcml.static" - /> - - <meta:directive - name="renderer" - schema="repoze.bfg.zcml.IRendererDirective" - handler="repoze.bfg.zcml.renderer" - /> - - <meta:directive - name="repozewho1authenticationpolicy" - schema="repoze.bfg.zcml.IRepozeWho1AuthenticationPolicyDirective" - handler="repoze.bfg.zcml.repozewho1authenticationpolicy" - /> - - <meta:directive - name="remoteuserauthenticationpolicy" - schema="repoze.bfg.zcml.IRemoteUserAuthenticationPolicyDirective" - handler="repoze.bfg.zcml.remoteuserauthenticationpolicy" - /> - - <meta:directive - name="authtktauthenticationpolicy" - schema="repoze.bfg.zcml.IAuthTktAuthenticationPolicyDirective" - handler="repoze.bfg.zcml.authtktauthenticationpolicy" - /> - - <meta:directive - name="aclauthorizationpolicy" - schema="repoze.bfg.zcml.IACLAuthorizationPolicyDirective" - handler="repoze.bfg.zcml.aclauthorizationpolicy" - /> - - <meta:directive - name="translationdir" - schema="repoze.bfg.zcml.ITranslationDirDirective" - handler="repoze.bfg.zcml.translationdir" - /> - - <meta:directive - name="localenegotiator" - schema="repoze.bfg.zcml.ILocaleNegotiatorDirective" - handler="repoze.bfg.zcml.localenegotiator" - /> - - <meta:directive - name="adapter" - schema="repoze.bfg.zcml.IAdapterDirective" - handler="repoze.bfg.zcml.adapter" - /> - - <meta:directive - name="subscriber" - schema="repoze.bfg.zcml.ISubscriberDirective" - handler="repoze.bfg.zcml.subscriber" - /> - - <meta:directive - name="utility" - schema="repoze.bfg.zcml.IUtilityDirective" - handler="repoze.bfg.zcml.utility" - /> - - <meta:directive - name="default_permission" - schema="repoze.bfg.zcml.IDefaultPermissionDirective" - handler="repoze.bfg.zcml.default_permission" - /> - - </meta:directives> - -</configure> diff --git a/repoze/bfg/interfaces.py b/repoze/bfg/interfaces.py deleted file mode 100644 index d67fd2dfb..000000000 --- a/repoze/bfg/interfaces.py +++ /dev/null @@ -1,379 +0,0 @@ -from zope.interface import Attribute -from zope.interface import Interface - -# public API interfaces - -class IContextFound(Interface): - """ An event type that is emitted after :mod:`repoze.bfg` finds a - :term:`context` object but before it calls any view code. See the - documentation attached to :class:`repoze.bfg.events.ContextFound` - for more information. - - .. note:: For backwards compatibility with versions of - :mod:`repoze.bfg` before 1.3, this event interface can also be - imported as :class:`repoze.bfg.interfaces.IAfterTraversal`. - """ - request = Attribute('The request object') - -IAfterTraversal = IContextFound - -class INewRequest(Interface): - """ An event type that is emitted whenever :mod:`repoze.bfg` - begins to process a new request. See the documentation attached - to :class:`repoze.bfg.events.NewRequest` for more information.""" - request = Attribute('The request object') - -class INewResponse(Interface): - """ An event type that is emitted whenever any :mod:`repoze.bfg` - view returns a response. See the - documentation attached to :class:`repoze.bfg.events.NewResponse` - for more information.""" - request = Attribute('The request object') - response = Attribute('The response object') - -class IApplicationCreated(Interface): - """ Event issued when the - :meth:`repoze.bfg.configuration.Configurator.make_wsgi_app` method - is called. See the documentation attached to - :class:`repoze.bfg.events.ApplicationCreated` for more - information. - - .. note:: For backwards compatibility with :mod:`repoze.bfg` - versions before 1.3, this interface can also be imported as - :class:`repoze.bfg.interfaces.IWSGIApplicationCreatedEvent`. - """ - app = Attribute(u"Created application") - -IWSGIApplicationCreatedEvent = IApplicationCreated # b /c - -class IResponse(Interface): # not an API - status = Attribute('WSGI status code of response') - headerlist = Attribute('List of response headers') - app_iter = Attribute('Iterable representing the response body') - -class IException(Interface): # not an API - """ An interface representing a generic exception """ - -class IExceptionResponse(IException, IResponse): - """ An interface representing a WSGI response which is also an - exception object. Register an exception view using this interface - as a ``context`` to apply the registered view for all exception - types raised by :mod:`repoze.bfg` internally - (:class:`repoze.bfg.exceptions.NotFound` and - :class:`repoze.bfg.exceptions.Forbidden`).""" - -# internal interfaces - -class IRequest(Interface): - """ Request type interface attached to all request objects """ - -IRequest.combined = IRequest # for exception view lookups - -class IRouteRequest(Interface): - """ *internal only* interface used as in a utility lookup to find - route-specific interfaces. Not an API.""" - -class IAuthenticationPolicy(Interface): - """ An object representing a BFG authentication policy. """ - def authenticated_userid(request): - """ Return the authenticated userid or ``None`` if no - authenticated userid can be found. """ - - def effective_principals(request): - """ Return a sequence representing the effective principals - including the userid and any groups belonged to by the current - user, including 'system' groups such as Everyone and - Authenticated. """ - - def remember(request, principal, **kw): - """ Return a set of headers suitable for 'remembering' the - principal named ``principal`` when set in a response. An - individual authentication policy and its consumers can decide - on the composition and meaning of **kw. """ - - def forget(request): - """ Return a set of headers suitable for 'forgetting' the - current user on subsequent requests. """ - -class IAuthorizationPolicy(Interface): - """ An object representing a BFG authorization policy. """ - def permits(context, principals, permission): - """ Return True if any of the principals is allowed the - permission in the current context, else return False """ - - def principals_allowed_by_permission(context, permission): - """ Return a set of principal identifiers allowed by the permission """ - -class IStaticURLInfo(Interface): - """ A policy for generating URLs to static resources """ - def add(name, spec, **extra): - """ Add a new static info registration """ - - def generate(path, request, **kw): - """ Generate a URL for the given path """ - -class IResponseFactory(Interface): - """ A utility which generates a response factory """ - def __call__(): - """ Return a response factory (e.g. a callable that returns an - object implementing IResponse, e.g. ``webob.Response``; it - should accept all the arguments that the webob.Response class - accepts)""" - -class IRequestFactory(Interface): - """ A utility which generates a request """ - def __call__(environ): - """ Return an object implementing IRequest, e.g. an instance - of ``repoze.bfg.request.Request``""" - - def blank(path): - """ Return an empty request object (see - ``webob.Request.blank``)""" - -class IViewClassifier(Interface): - """ *Internal only* marker interface for views.""" - -class IExceptionViewClassifier(Interface): - """ *Internal only* marker interface for exception views.""" - -class IView(Interface): - def __call__(context, request): - """ Must return an object that implements IResponse. May - optionally raise ``repoze.bfg.exceptions.Forbidden`` if an - authorization failure is detected during view execution or - ``repoze.bfg.exceptions.NotFound`` if the not found page is - meant to be returned.""" - -class ISecuredView(IView): - """ *Internal only* interface. Not an API. """ - def __call_permissive__(context, request): - """ Guaranteed-permissive version of __call__ """ - - def __permitted__(context, request): - """ Return True if view execution will be permitted using the - context and request, False otherwise""" - -class IMultiView(ISecuredView): - """ *internal only*. A multiview is a secured view that is a - collection of other views. Each of the views is associated with - zero or more predicates. Not an API.""" - def add(view, predicates, order, accept=None, phash=None): - """ Add a view to the multiview. """ - -class IRootFactory(Interface): - def __call__(request): - """ Return a root object based on the request """ - -class IDefaultRootFactory(Interface): - def __call__(request): - """ Return the *default* root object for an application """ - -class ITraverser(Interface): - def __call__(request): - """ Return a dictionary with (at least) the keys ``root``, - ``context``, ``view_name``, ``subpath``, ``traversed``, - ``virtual_root``, and ``virtual_root_path``. These values are - typically the result of an object graph traversal. ``root`` - is the physical root object, ``context`` will be a model - object, ``view_name`` will be the view name used (a Unicode - name), ``subpath`` will be a sequence of Unicode names that - followed the view name but were not traversed, ``traversed`` - will be a sequence of Unicode names that were traversed - (including the virtual root path, if any) ``virtual_root`` - will be a model object representing the virtual root (or the - physical root if traversal was not performed), and - ``virtual_root_path`` will be a sequence representing the - virtual root path (a sequence of Unicode names) or None if - traversal was not performed. - - Extra keys for special purpose functionality can be added as - necessary. - - All values returned in the dictionary will be made available - as attributes of the ``request`` object. - """ - -ITraverserFactory = ITraverser # b / c for 1.0 code - -class IRenderer(Interface): - def __call__(value, system): - """ Call a the renderer implementation with the result of the - view (``value``) passed in and return a result (a string or - unicode object useful as a response body). Values computed by - the system are passed by the system in the ``system`` - parameter, which is a dictionary. Keys in the dictionary - include: ``view`` (the view callable that returned the value), - ``renderer_name`` (the template name or simple name of the - renderer), ``context`` (the context object passed to the - view), and ``request`` (the request object passed to the - view).""" - -class IRendererFactory(Interface): - def __call__(name): - """ Return an object that implements ``IRenderer`` """ - -class IRendererGlobalsFactory(Interface): - def __call__(system_values): - """ Return a dictionary of global renderer values (aka - top-level template names). The ``system_values`` value passed - in will be a dictionary that includes at least a ``request`` - key, indicating the current request, and the value - ``renderer_name``, which will be the name of the renderer in - use.""" - -class ITemplateRenderer(IRenderer): - def implementation(): - """ Return the object that the underlying templating system - uses to render the template; it is typically a callable that - accepts arbitrary keyword arguments and returns a string or - unicode object """ - -class IViewPermission(Interface): - def __call__(context, request): - """ Return True if the permission allows, return False if it denies. """ - -class IRouter(Interface): - """WSGI application which routes requests to 'view' code based on - a view registry.""" - registry = Attribute( - """Component architecture registry local to this application.""") - -class ISettings(Interface): - """ Runtime settings utility for repoze.bfg; represents the - deployment settings for the application. Implements a mapping - interface.""" - -# this interface, even if it becomes unused within BFG, is imported by -# other packages (such as repoze.bfg.traversalwrapper) -class ILocation(Interface): - """Objects that have a structural location""" - __parent__ = Attribute("The parent in the location hierarchy") - __name__ = Attribute("The name within the parent") - -class IDebugLogger(Interface): - """ Interface representing a PEP 282 logger """ - -ILogger = IDebugLogger # b/c - -class IRoutePregenerator(Interface): - def __call__(request, elements, kw): - """ A pregenerator is a function associated by a developer - with a :term:`route`. The pregenerator for a route is called - by :func:`repoze.bfg.url.route_url` in order to adjust the set - of arguments passed to it by the user for special purposes, - such as Pylons 'subdomain' support. It will influence the URL - returned by ``route_url``. - - A pregenerator should return a two-tuple of ``(elements, kw)`` - after examining the originals passed to this function, which - are the arguments ``(request, elements, kw)``. The simplest - pregenerator is:: - - def pregenerator(request, elements, kw): - return elements, kw - - You can employ a pregenerator by passing a ``pregenerator`` - argument to the - :meth:`repoze.bfg.configuration.Configurator.add_route` - function. - - .. note:: This interface is new as of :mod:`repoze.bfg` 1.3. - """ - -class IRoute(Interface): - """ Interface representing the type of object returned from - ``IRoutesMapper.get_route``""" - name = Attribute('The route name') - pattern = Attribute('The route pattern') - factory = Attribute( - 'The :term:`root factory` used by the :mod:`repoze.bfg` router ' - 'when this route matches (or ``None``)') - predicates = Attribute( - 'A sequence of :term:`route predicate` objects used to ' - 'determine if a request matches this route or not or not after ' - 'basic pattern matching has been completed.') - pregenerator = Attribute('This attribute should either be ``None`` or ' - 'a callable object implementing the ' - '``IRoutePregenerator`` interface') - def match(path): - """ - If the ``path`` passed to this function can be matched by the - ``pattern`` of this route, return a dictionary (the - 'matchdict'), which will contain keys representing the dynamic - segment markers in the pattern mapped to values extracted from - the provided ``path``. - - If the ``path`` passed to this function cannot be matched by - the ``pattern`` of this route, return ``None``. - """ - def generate(kw): - """ - Generate a URL based on filling in the dynamic segment markers - in the pattern using the ``kw`` dictionary provided. - """ - -class IRoutesMapper(Interface): - """ Interface representing a Routes ``Mapper`` object """ - def get_routes(): - """ Return a sequence of Route objects registered in the mapper.""" - - def has_routes(): - """ Returns ``True`` if any route has been registered. """ - - def get_route(name): - """ Returns an ``IRoute`` object if a route with the name ``name`` - was registered, otherwise return ``None``.""" - - def connect(name, pattern, factory=None, predicates=()): - """ Add a new route. """ - - def generate(name, kw): - """ Generate a URL using the route named ``name`` with the - keywords implied by kw""" - - def __call__(request): - """ Return a dictionary containing matching information for - the request; the ``route`` key of this dictionary will either - be a Route object or ``None`` if no route matched; the - ``match`` key will be the matchdict or ``None`` if no route - matched.""" - -class IContextURL(Interface): - """ An adapter which deals with URLs related to a context. - """ - def virtual_root(): - """ Return the virtual root related to a request and the - current context""" - - def __call__(): - """ Return a URL that points to the context """ - -class IPackageOverrides(Interface): - """ Utility for pkg_resources overrides """ - -# VH_ROOT_KEY is an interface; its imported from other packages (e.g. -# traversalwrapper) -VH_ROOT_KEY = 'HTTP_X_VHM_ROOT' - -class IChameleonTranslate(Interface): - """ Internal interface representing a chameleon translate function """ - def __call__(msgid, domain=None, mapping=None, context=None, - target_language=None, default=None): - """ Translate a mess of arguments to a Unicode object """ - -class ILocalizer(Interface): - """ Localizer for a specific language """ - -class ILocaleNegotiator(Interface): - def __call__(request): - """ Return a locale name """ - -class ITranslationDirectories(Interface): - """ A list object representing all known translation directories - for an application""" - -class IDefaultPermission(Interface): - """ A string object representing the default permission to be used - for all view configurations which do not explicitly declare their - own.""" - diff --git a/repoze/bfg/location.py b/repoze/bfg/location.py deleted file mode 100644 index 7472129d2..000000000 --- a/repoze/bfg/location.py +++ /dev/null @@ -1,66 +0,0 @@ -############################################################################## -# -# Copyright (c) 2003 Zope Corporation and Contributors. -# All Rights Reserved. -# -# This software is subject to the provisions of the Zope Public License, -# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. -# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -# FOR A PARTICULAR PURPOSE. -# -############################################################################## - -def inside(model1, model2): - """Is ``model1`` 'inside' ``model2``? Return ``True`` if so, else - ``False``. - - ``model1`` is 'inside' ``model2`` if ``model2`` is a - :term:`lineage` ancestor of ``model1``. It is a lineage ancestor - if its parent (or one of its parent's parents, etc.) is an - ancestor. - """ - while model1 is not None: - if model1 is model2: - return True - model1 = model1.__parent__ - - return False - -def lineage(model): - """ - Return a generator representing the :term:`lineage` of the - :term:`model` object implied by the ``model`` argument. The - generator first returns ``model`` unconditionally. Then, if - ``model`` supplies a ``__parent__`` attribute, return the object - represented by ``model.__parent__``. If *that* object has a - ``__parent__`` attribute, return that object's parent, and so on, - until the object being inspected either has no ``__parent__`` - attribute or which has a ``__parent__`` attribute of ``None``. - For example, if the object tree is:: - - thing1 = Thing() - thing2 = Thing() - thing2.__parent__ = thing1 - - Calling ``lineage(thing2)`` will return a generator. When we turn - it into a list, we will get:: - - list(lineage(thing2)) - [ <Thing object at thing2>, <Thing object at thing1> ] - """ - while model is not None: - yield model - # The common case is that the AttributeError exception below - # is exceptional as long as the developer is a "good citizen" - # who has a root object with a __parent__ of None. Using an - # exception here instead of a getattr with a default is an - # important micro-optimization, because this function is - # called in any non-trivial application over and over again to - # generate URLs and paths. - try: - model = model.__parent__ - except AttributeError: - model = None - diff --git a/repoze/bfg/log.py b/repoze/bfg/log.py deleted file mode 100644 index b8762e6e2..000000000 --- a/repoze/bfg/log.py +++ /dev/null @@ -1,16 +0,0 @@ -import logging - -def make_stream_logger( - name, stream, levelname='DEBUG', fmt='%(asctime)s %(message)s'): - """ Return an object which implements - ``repoze.bfg.interfaces.IDebugLogger`` (ie. a Python PEP 282 logger - instance) with the name ``name`` using the stream (or open - filehandle) ``stream``, logging at ``levelname`` log level or - above with format ``fmt``. """ - handler = logging.StreamHandler(stream) - formatter = logging.Formatter(fmt) - handler.setFormatter(formatter) - logger = logging.Logger(name) - logger.addHandler(handler) - logger.setLevel(getattr(logging, levelname)) - return logger diff --git a/repoze/bfg/paster.py b/repoze/bfg/paster.py deleted file mode 100644 index e8ce46ce2..000000000 --- a/repoze/bfg/paster.py +++ /dev/null @@ -1,111 +0,0 @@ -import os -import sys -from code import interact - -from paste.deploy import loadapp -from paste.script.command import Command -from paste.script.templates import Template -from paste.util.template import paste_script_template_renderer - -from repoze.bfg.scripting import get_root - - -class StarterProjectTemplate(Template): - _template_dir = 'paster_templates/starter' - summary = 'repoze.bfg starter project' - template_renderer = staticmethod(paste_script_template_renderer) - -class ZODBProjectTemplate(Template): - _template_dir = 'paster_templates/zodb' - summary = 'repoze.bfg ZODB starter project' - template_renderer = staticmethod(paste_script_template_renderer) - -class RoutesAlchemyProjectTemplate(Template): - _template_dir = 'paster_templates/routesalchemy' - summary = 'repoze.bfg SQLAlchemy project using Routes (no traversal)' - template_renderer = staticmethod(paste_script_template_renderer) - -class AlchemyProjectTemplate(Template): - _template_dir = 'paster_templates/alchemy' - summary = 'repoze.bfg SQLAlchemy project using traversal' - template_renderer = staticmethod(paste_script_template_renderer) - -def get_app(config_file, name, loadapp=loadapp): - """ Return the WSGI application named ``name`` in the PasteDeploy - config file ``config_file``""" - config_name = 'config:%s' % config_file - here_dir = os.getcwd() - app = loadapp(config_name, name=name, relative_to=here_dir) - return app - -_marker = object() -class BFGShellCommand(Command): - """Open an interactive shell with a :mod:`repoze.bfg` app loaded. - - This command accepts two positional arguments: - - ``config_file`` -- specifies the PasteDeploy config file to use - for the interactive shell. - - ``section_name`` -- specifies the section name in the PasteDeploy - config file that represents the application. - - Example:: - - $ paster bfgshell myapp.ini main - - .. note:: You should use a ``section_name`` that refers to the - actual ``app`` section in the config file that points at - your BFG app without any middleware wrapping, or this - command will almost certainly fail. - - """ - summary = "Open an interactive shell with a repoze.bfg app loaded" - - min_args = 2 - max_args = 2 - group_name = 'bfg' - - parser = Command.standard_parser(simulate=True) - parser.add_option('-d', '--disable-ipython', - action='store_true', - dest='disable_ipython', - help="Don't use IPython even if it is available") - - interact = (interact,) # for testing - loadapp = (loadapp,) # for testing - get_app = staticmethod(get_app) # hook point - get_root = staticmethod(get_root) # hook point - verbose = 3 - - def __init__(self, *arg, **kw): - # needs to be in constructor to support Jython (used to be at class - # scope as ``usage = '\n' + __doc__``. - self.usage = '\n' + self.__doc__ - Command.__init__(self, *arg, **kw) - - def command(self, IPShell=_marker): - if IPShell is _marker: - try: #pragma no cover - from IPython.Shell import IPShell - except ImportError: #pragma no cover - IPShell = None - cprt =('Type "help" for more information. "root" is the BFG app ' - 'root object.') - banner = "Python %s on %s\n%s" % (sys.version, sys.platform, cprt) - config_file, section_name = self.args - self.logging_file_config(config_file) - app = self.get_app(config_file, section_name, loadapp=self.loadapp[0]) - root, closer = self.get_root(app) - if IPShell is not None and not self.options.disable_ipython: - try: - shell = IPShell(argv=[], user_ns={'root':root}) - shell.IP.BANNER = shell.IP.BANNER + '\n\n' + banner - shell.mainloop() - finally: - closer() - else: - try: - self.interact[0](banner, local={'root':root}) - finally: - closer() diff --git a/repoze/bfg/paster_templates/alchemy/+package+/__init__.py b/repoze/bfg/paster_templates/alchemy/+package+/__init__.py deleted file mode 100755 index cbdfd3ac6..000000000 --- a/repoze/bfg/paster_templates/alchemy/+package+/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# A package - diff --git a/repoze/bfg/paster_templates/alchemy/+package+/configure.zcml b/repoze/bfg/paster_templates/alchemy/+package+/configure.zcml deleted file mode 100644 index 521f06ba4..000000000 --- a/repoze/bfg/paster_templates/alchemy/+package+/configure.zcml +++ /dev/null @@ -1,23 +0,0 @@ -<configure xmlns="http://namespaces.repoze.org/bfg"> - - <!-- this must be included for the view declarations to work --> - <include package="repoze.bfg.includes" /> - - <view - context=".models.MyApp" - view=".views.view_root" - renderer="templates/root.pt" - /> - - <view - context=".models.MyModel" - view=".views.view_model" - renderer="templates/model.pt" - /> - - <static - name="static" - path="templates/static" - /> - -</configure> diff --git a/repoze/bfg/paster_templates/alchemy/+package+/models.py b/repoze/bfg/paster_templates/alchemy/+package+/models.py deleted file mode 100755 index 336613cf9..000000000 --- a/repoze/bfg/paster_templates/alchemy/+package+/models.py +++ /dev/null @@ -1,88 +0,0 @@ -import transaction - -from sqlalchemy.orm import scoped_session -from sqlalchemy.orm import sessionmaker - -from sqlalchemy.ext.declarative import declarative_base - -from sqlalchemy.exc import IntegrityError -from sqlalchemy.orm.exc import NoResultFound - -from sqlalchemy import create_engine -from sqlalchemy import Integer -from sqlalchemy import Unicode -from sqlalchemy import Column - -from zope.sqlalchemy import ZopeTransactionExtension - -DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension())) -Base = declarative_base() - -class MyModel(Base): - __tablename__ = 'models' - id = Column(Integer, primary_key=True) - name = Column(Unicode(255), unique=True) - value = Column(Integer) - - def __init__(self, name, value): - self.name = name - self.value = value - -class MyApp(object): - __name__ = None - __parent__ = None - - def __getitem__(self, key): - session= DBSession() - try: - id = int(key) - except (ValueError, TypeError): - raise KeyError(key) - - query = session.query(MyModel).filter_by(id=id) - - try: - item = query.one() - item.__parent__ = self - item.__name__ = key - return item - except NoResultFound: - raise KeyError(key) - - def get(self, key, default=None): - try: - item = self.__getitem__(key) - except KeyError: - item = default - return item - - def __iter__(self): - session= DBSession() - query = session.query(MyModel) - return iter(query) - -root = MyApp() - -def default_get_root(request): - return root - -def populate(): - session = DBSession() - model = MyModel(name=u'test name',value=55) - session.add(model) - session.flush() - transaction.commit() - -def initialize_sql(db_string, db_echo=False): - engine = create_engine(db_string, echo=db_echo) - DBSession.configure(bind=engine) - Base.metadata.bind = engine - Base.metadata.create_all(engine) - try: - populate() - except IntegrityError: - pass - -def appmaker(db_string, db_echo=False): - initialize_sql(db_string, db_echo) - return default_get_root diff --git a/repoze/bfg/paster_templates/alchemy/+package+/run.py_tmpl b/repoze/bfg/paster_templates/alchemy/+package+/run.py_tmpl deleted file mode 100644 index 026505f3a..000000000 --- a/repoze/bfg/paster_templates/alchemy/+package+/run.py_tmpl +++ /dev/null @@ -1,23 +0,0 @@ -from repoze.bfg.configuration import Configurator -from paste.deploy.converters import asbool - -from {{package}}.models import appmaker - -def app(global_config, **settings): - """ This function returns a WSGI application. - - It is usually called by the PasteDeploy framework during - ``paster serve``. - """ - zcml_file = settings.get('configure_zcml', 'configure.zcml') - db_string = settings.get('db_string') - if db_string is None: - raise ValueError("No 'db_string' value in application configuration.") - db_echo = settings.get('db_echo', 'false') - get_root = appmaker(db_string, asbool(db_echo)) - config = Configurator(settings=settings, root_factory=get_root) - config.begin() - config.load_zcml(zcml_file) - config.end() - return config.make_wsgi_app() - diff --git a/repoze/bfg/paster_templates/alchemy/+package+/templates/model.pt b/repoze/bfg/paster_templates/alchemy/+package+/templates/model.pt deleted file mode 100644 index e29b92836..000000000 --- a/repoze/bfg/paster_templates/alchemy/+package+/templates/model.pt +++ /dev/null @@ -1,103 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" - xmlns:tal="http://xml.zope.org/namespaces/tal"> -<head> -<meta http-equiv="content-type" content="text/html; charset=utf-8" /> -<title>${project} Application</title> -<meta name="keywords" content="python web application" /> -<meta name="description" content="repoze.bfg web application" /> -<link href="${request.application_url}/static/default.css" rel="stylesheet" type="text/css" /> -</head> -<body> -<!-- start header --> -<div id="logo"> - <h2><code>${project}</code>, a <code>repoze.bfg</code> application</h2> -</div> -<div id="header"> - <div id="menu"> - </div> -</div> -<!-- end header --> -<div id="wrapper"> - <!-- start page --> - <div id="page"> - <!-- start content --> - <div id="content"> - <div class="post"> - <h1 class="title">Welcome to <code>${project}</code>, an - application generated by the <a - href="http://bfg.repoze.org">repoze.bfg</a> web - application framework.</h1> - <p> - <b>Id:</b> ${item.id}<br /> - <b>Name:</b> ${item.name}<br /> - <b>Value:</b> ${item.value}</p> - </div> - </div> - <!-- end content --> - <!-- start sidebar --> - <div id="sidebar"> - <ul> - <li id="search"> - <h2>Search<br/> <code>repoze.bfg</code> Documentation</h2> - <form method="get" - action="http://bfg.repoze.org/searchresults"> - <fieldset> - <input type="text" id="q" name="text" value="" /> - <input type="submit" id="x" value="Search" /> - </fieldset> - </form> - </li> - <li> - <h2><code>repoze.bfg</code> links</h2> - <ul> - <li><a - href="http://docs.repoze.org/bfg/current/#narrative-documentation">Narrative - Documentation</a> - </li> - <li> - <a - href="http://docs.repoze.org/bfg/current/#api-documentation">API - Documentation</a> - </li> - <li> - <a - href="http://docs.repoze.org/bfg/current/#tutorials">Tutorials</a> - </li> - <li> - <a - href="http://docs.repoze.org/bfg/current/#change-history">Change - History</a> - </li> - <li> - <a - href="http://docs.repoze.org/bfg/current/#sample-applications">Sample - Applications</a> - </li> - <li> - <a - href="http://docs.repoze.org/bfg/current/#support-and-development">Support - and Development</a> - </li> - <li> - <a - href="irc://irc.freenode.net#repoze">IRC Channel</a> - </li> - </ul> - </li> - </ul> - </div> - <!-- end sidebar --> - <div style="clear: both;"> </div> - </div> -</div> -<!-- end page --> -<!-- start footer --> -<div id="footer"> - <p id="legal">( c ) 2008. All Rights Reserved. Template design - by <a href="http://www.freecsstemplates.org/">Free CSS - Templates</a>.</p> -</div> -<!-- end footer --> -</body> -</html> diff --git a/repoze/bfg/paster_templates/alchemy/+package+/templates/root.pt b/repoze/bfg/paster_templates/alchemy/+package+/templates/root.pt deleted file mode 100644 index 2cac6fe6e..000000000 --- a/repoze/bfg/paster_templates/alchemy/+package+/templates/root.pt +++ /dev/null @@ -1,101 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" - xmlns:tal="http://xml.zope.org/namespaces/tal"> -<head> -<meta http-equiv="content-type" content="text/html; charset=utf-8" /> -<title>${project} Application</title> -<meta name="keywords" content="python web application" /> -<meta name="description" content="repoze.bfg web application" /> -<link href="${request.application_url}/static/default.css" rel="stylesheet" type="text/css" /> -</head> -<body> -<!-- start header --> -<div id="logo"> - <h2><code>${project}</code>, a <code>repoze.bfg</code> application</h2> -</div> -<div id="header"> - <div id="menu"> - </div> -</div> -<!-- end header --> -<div id="wrapper"> - <!-- start page --> - <div id="page"> - <!-- start content --> - <div id="content"> - <div class="post"> - <h1 class="title">Welcome to <code>${project}</code>, an - application generated by the <a - href="http://bfg.repoze.org">repoze.bfg</a> web - application framework.</h1> - <p tal:repeat="item items"> - <a href="${item.id}">${item.name}</a></p> - </div> - </div> - <!-- end content --> - <!-- start sidebar --> - <div id="sidebar"> - <ul> - <li id="search"> - <h2>Search<br/> <code>repoze.bfg</code> Documentation</h2> - <form method="get" - action="http://bfg.repoze.org/searchresults"> - <fieldset> - <input type="text" id="q" name="text" value="" /> - <input type="submit" id="x" value="Search" /> - </fieldset> - </form> - </li> - <li> - <h2><code>repoze.bfg</code> links</h2> - <ul> - <li><a - href="http://docs.repoze.org/bfg/current/#narrative-documentation">Narrative - Documentation</a> - </li> - <li> - <a - href="http://docs.repoze.org/bfg/current/#api-documentation">API - Documentation</a> - </li> - <li> - <a - href="http://docs.repoze.org/bfg/current/#tutorials">Tutorials</a> - </li> - <li> - <a - href="http://docs.repoze.org/bfg/current/#change-history">Change - History</a> - </li> - <li> - <a - href="http://docs.repoze.org/bfg/current/#sample-applications">Sample - Applications</a> - </li> - <li> - <a - href="http://docs.repoze.org/bfg/current/#support-and-development">Support - and Development</a> - </li> - <li> - <a - href="irc://irc.freenode.net#repoze">IRC Channel</a> - </li> - </ul> - </li> - </ul> - </div> - <!-- end sidebar --> - <div style="clear: both;"> </div> - </div> -</div> -<!-- end page --> -<!-- start footer --> -<div id="footer"> - <p id="legal">( c ) 2008. All Rights Reserved. Template design - by <a href="http://www.freecsstemplates.org/">Free CSS - Templates</a>.</p> -</div> -<!-- end footer --> -</body> -</html> diff --git a/repoze/bfg/paster_templates/alchemy/+package+/templates/static/default.css b/repoze/bfg/paster_templates/alchemy/+package+/templates/static/default.css deleted file mode 100644 index 41b3debde..000000000 --- a/repoze/bfg/paster_templates/alchemy/+package+/templates/static/default.css +++ /dev/null @@ -1,380 +0,0 @@ -/* -Design by Free CSS Templates -http://www.freecsstemplates.org -Released for free under a Creative Commons Attribution 2.5 License -*/ - -body { - margin: 0; - padding: 0; - background: url(images/img01.gif) repeat-x left top; - font-size: 13px; - font-family: "Trebuchet MS", Georgia, "Times New Roman", Times, serif; - text-align: justify; - color: #FFFFFF; -} - -h1, h2, h3 { - margin: 0; - text-transform: lowercase; - font-weight: normal; - color: #FFFFFF; -} - -h1 { - letter-spacing: -1px; - font-size: 32px; -} - -h2 { - font-size: 23px; -} - -p, ul, ol { - margin: 0 0 2em 0; - text-align: justify; - line-height: 26px; -} - -a:link { - color: #8BD80E; -} - -a:hover, a:active { - text-decoration: none; - color: #8BD80E; -} - -a:visited { - color: #8BD80E; -} - -img { - border: none; -} - -img.left { - float: left; - margin-right: 15px; -} - -img.right { - float: right; - margin-left: 15px; -} - -/* Form */ - -form { - margin: 0; - padding: 0; -} - -fieldset { - margin: 0; - padding: 0; - border: none; -} - -legend { - display: none; -} - -input, textarea, select { - font-family: "Trebuchet MS", Arial, Helvetica, sans-serif; - font-size: 13px; - color: #333333; -} - -#wrapper { - margin: 0; - padding: 0; - background: #000000; -} - -/* Header */ - -#header { - width: 713px; - margin: 0 auto; - height: 42px; -} - -/* Menu */ - -#menu { - float: left; - width: 713px; - height: 50px; - background: url(images/img02.gif) no-repeat left top; -} - -#menu ul { - margin: 0; - padding: 0px 0 0 10px; - list-style: none; - line-height: normal; -} - -#menu li { - display: block; - float: left; -} - -#menu a { - display: block; - float: left; - background: url(images/img04.gif) no-repeat right 55%; - margin-top: 5px; - margin-right: 3px; - padding: 8px 17px; - text-decoration: none; - font-size: 13px; - color: #000000; -} - -#menu a:hover { - color: #000000; -} - -#menu .current_page_item a { - color: #000000; -} - -/** LOGO */ - -#logo { - width: 713px; - height: 80px; - margin: 0 auto; -} - -#logo h1, #logo h2 { - float: left; - margin: 0; - padding: 30px 0 0 0px; - line-height: normal; -} - -#logo h1 { - font-family: Georgia, "Times New Roman", Times, serif; - font-size:40px; -} - -#logo h1 a { - text-decoration: none; - color: #4C4C4C; -} - -#logo h1 a:hover { text-decoration: underline; } - -#logo h2 { - float: left; - padding: 45px 0 0 18px; - font: 18px Georgia, "Times New Roman", Times, serif; - color: #8BD80E; -} - -#logo p a { - text-decoration: none; - color: #8BD80E; -} - -#logo p a:hover { text-decoration: underline; } - - - -/* Page */ - -#page { - width: 663px; - margin: 0 auto; - background: #4C4C4C url(images/img03.gif) no-repeat left bottom; - padding: 0 25px; -} - -/* Content */ - -#content { - float: left; - width: 410px; - -} - -/* Post */ - -.post { - padding: 15px 0px; - margin-bottom: 20px; -} - -.post .title { - margin-bottom: 20px; - padding-bottom: 5px; -} - -.post h1 { - padding: 0px 0 0 0px; - background: url(images/img08.jpg) no-repeat left top; - font-size: 24px; - color: #FFFFFF; -} - -.post h2 { - padding: 0px 0 0 0px; - font-size: 22px; - color: #FFFFFF; -} - -.post .entry { -} - -.post .meta { - padding: 15px 15px 30px 0px; - font-family: Arial, Helvetica, sans-serif; - font-size: 11px; -} - -.post .meta p { - margin: 0; - padding-top: 15px; - line-height: normal; - color: #FFFFFF; -} - -.post .meta .byline { - float: left; -} - -.post .meta .links { - float: right; -} - -.post .meta .more { - padding: 0 10px 0 18px; -} - -.post .meta .comments { -} - -.post .meta b { - display: none; -} - - -/* Sidebar */ - -#sidebar { - width: 210px; - float: right; - margin: 0; - padding: 0; -} - -#sidebar ul { - margin: 0; - padding: 0; - list-style: none; -} - -#sidebar li { - margin-bottom: 40px; -} - -#sidebar li ul { -} - -#sidebar li li { - margin: 0; -} - -#sidebar h2 { - width: 250px; - padding: 8px 0 0 0px; - margin-bottom: 10px; - background: url(images/img07.jpg) no-repeat left top; - font-size: 20px; - color: #FFFFFF; -} - -/* Search */ - -#search { - -} - -#search h2 { - margin-bottom: 20px; -} - -#s { - width: 140px; - margin-right: 5px; - padding: 3px; - border: 1px solid #BED99C; -} - -#x { - padding: 3px; - border: none; - background: #8BD80E; - text-transform: lowercase; - font-size: 11px; - color: #FFFFFF; -} - -/* Boxes */ - -.box1 { - padding: 20px; -} - -.box2 { - color: #BABABA; -} - -.box2 h2 { - margin-bottom: 15px; - font-size: 16px; - color: #FFFFFF; -} - -.box2 ul { - margin: 0; - padding: 0; - list-style: none; -} - -.box2 a:link, .box2 a:hover, .box2 a:active, .box2 a:visited { - color: #EDEDED; -} - -/* Footer */ -#footer-wrap { -} - -#footer { - margin: 0 auto; - padding: 20px 0 10px 0; - background: #000000; -} - -html>body #footer { - height: auto; -} - -#footer p { - font-size: 11px; -} - -#legal { - clear: both; - padding-top: 17px; - text-align: center; - color: #FFFFFF; -} - -#legal a { - font-weight: normal; - color: #FFFFFF; -} diff --git a/repoze/bfg/paster_templates/alchemy/+package+/templates/static/images/img01.gif b/repoze/bfg/paster_templates/alchemy/+package+/templates/static/images/img01.gif Binary files differdeleted file mode 100644 index 5f082bd99..000000000 --- a/repoze/bfg/paster_templates/alchemy/+package+/templates/static/images/img01.gif +++ /dev/null diff --git a/repoze/bfg/paster_templates/alchemy/+package+/templates/static/images/img02.gif b/repoze/bfg/paster_templates/alchemy/+package+/templates/static/images/img02.gif Binary files differdeleted file mode 100644 index 45a3ae976..000000000 --- a/repoze/bfg/paster_templates/alchemy/+package+/templates/static/images/img02.gif +++ /dev/null diff --git a/repoze/bfg/paster_templates/alchemy/+package+/templates/static/images/img03.gif b/repoze/bfg/paster_templates/alchemy/+package+/templates/static/images/img03.gif Binary files differdeleted file mode 100644 index d92ea38f9..000000000 --- a/repoze/bfg/paster_templates/alchemy/+package+/templates/static/images/img03.gif +++ /dev/null diff --git a/repoze/bfg/paster_templates/alchemy/+package+/templates/static/images/img04.gif b/repoze/bfg/paster_templates/alchemy/+package+/templates/static/images/img04.gif Binary files differdeleted file mode 100644 index 950c4af9d..000000000 --- a/repoze/bfg/paster_templates/alchemy/+package+/templates/static/images/img04.gif +++ /dev/null diff --git a/repoze/bfg/paster_templates/alchemy/+package+/templates/static/images/spacer.gif b/repoze/bfg/paster_templates/alchemy/+package+/templates/static/images/spacer.gif Binary files differdeleted file mode 100644 index 5bfd67a2d..000000000 --- a/repoze/bfg/paster_templates/alchemy/+package+/templates/static/images/spacer.gif +++ /dev/null diff --git a/repoze/bfg/paster_templates/alchemy/+package+/templates/static/templatelicense.txt b/repoze/bfg/paster_templates/alchemy/+package+/templates/static/templatelicense.txt deleted file mode 100644 index ccb6b06ab..000000000 --- a/repoze/bfg/paster_templates/alchemy/+package+/templates/static/templatelicense.txt +++ /dev/null @@ -1,243 +0,0 @@ -Creative Commons </> - -Creative Commons Legal Code - -*Attribution 2.5* - -CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE -LEGAL SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN -ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION -ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE -INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM -ITS USE. - -/License/ - -THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE -COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY -COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS -AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED. - -BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE -TO BE BOUND BY THE TERMS OF THIS LICENSE. THE LICENSOR GRANTS YOU THE -RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS -AND CONDITIONS. - -*1. Definitions* - - 1. *"Collective Work"* means a work, such as a periodical issue, - anthology or encyclopedia, in which the Work in its entirety in - unmodified form, along with a number of other contributions, - constituting separate and independent works in themselves, are - assembled into a collective whole. A work that constitutes a - Collective Work will not be considered a Derivative Work (as - defined below) for the purposes of this License. - 2. *"Derivative Work"* means a work based upon the Work or upon the - Work and other pre-existing works, such as a translation, musical - arrangement, dramatization, fictionalization, motion picture - version, sound recording, art reproduction, abridgment, - condensation, or any other form in which the Work may be recast, - transformed, or adapted, except that a work that constitutes a - Collective Work will not be considered a Derivative Work for the - purpose of this License. For the avoidance of doubt, where the - Work is a musical composition or sound recording, the - synchronization of the Work in timed-relation with a moving image - ("synching") will be considered a Derivative Work for the purpose - of this License. - 3. *"Licensor"* means the individual or entity that offers the Work - under the terms of this License. - 4. *"Original Author"* means the individual or entity who created the - Work. - 5. *"Work"* means the copyrightable work of authorship offered under - the terms of this License. - 6. *"You"* means an individual or entity exercising rights under this - License who has not previously violated the terms of this License - with respect to the Work, or who has received express permission - from the Licensor to exercise rights under this License despite a - previous violation. - -*2. Fair Use Rights.* Nothing in this license is intended to reduce, -limit, or restrict any rights arising from fair use, first sale or other -limitations on the exclusive rights of the copyright owner under -copyright law or other applicable laws. - -*3. License Grant.* Subject to the terms and conditions of this License, -Licensor hereby grants You a worldwide, royalty-free, non-exclusive, -perpetual (for the duration of the applicable copyright) license to -exercise the rights in the Work as stated below: - - 1. to reproduce the Work, to incorporate the Work into one or more - Collective Works, and to reproduce the Work as incorporated in the - Collective Works; - 2. to create and reproduce Derivative Works; - 3. to distribute copies or phonorecords of, display publicly, perform - publicly, and perform publicly by means of a digital audio - transmission the Work including as incorporated in Collective Works; - 4. to distribute copies or phonorecords of, display publicly, perform - publicly, and perform publicly by means of a digital audio - transmission Derivative Works. - 5. - - For the avoidance of doubt, where the work is a musical composition: - - 1. *Performance Royalties Under Blanket Licenses*. Licensor - waives the exclusive right to collect, whether individually - or via a performance rights society (e.g. ASCAP, BMI, - SESAC), royalties for the public performance or public - digital performance (e.g. webcast) of the Work. - 2. *Mechanical Rights and Statutory Royalties*. Licensor waives - the exclusive right to collect, whether individually or via - a music rights agency or designated agent (e.g. Harry Fox - Agency), royalties for any phonorecord You create from the - Work ("cover version") and distribute, subject to the - compulsory license created by 17 USC Section 115 of the US - Copyright Act (or the equivalent in other jurisdictions). - 6. *Webcasting Rights and Statutory Royalties*. For the avoidance of - doubt, where the Work is a sound recording, Licensor waives the - exclusive right to collect, whether individually or via a - performance-rights society (e.g. SoundExchange), royalties for the - public digital performance (e.g. webcast) of the Work, subject to - the compulsory license created by 17 USC Section 114 of the US - Copyright Act (or the equivalent in other jurisdictions). - -The above rights may be exercised in all media and formats whether now -known or hereafter devised. The above rights include the right to make -such modifications as are technically necessary to exercise the rights -in other media and formats. All rights not expressly granted by Licensor -are hereby reserved. - -*4. Restrictions.*The license granted in Section 3 above is expressly -made subject to and limited by the following restrictions: - - 1. You may distribute, publicly display, publicly perform, or - publicly digitally perform the Work only under the terms of this - License, and You must include a copy of, or the Uniform Resource - Identifier for, this License with every copy or phonorecord of the - Work You distribute, publicly display, publicly perform, or - publicly digitally perform. You may not offer or impose any terms - on the Work that alter or restrict the terms of this License or - the recipients' exercise of the rights granted hereunder. You may - not sublicense the Work. You must keep intact all notices that - refer to this License and to the disclaimer of warranties. You may - not distribute, publicly display, publicly perform, or publicly - digitally perform the Work with any technological measures that - control access or use of the Work in a manner inconsistent with - the terms of this License Agreement. The above applies to the Work - as incorporated in a Collective Work, but this does not require - the Collective Work apart from the Work itself to be made subject - to the terms of this License. If You create a Collective Work, - upon notice from any Licensor You must, to the extent practicable, - remove from the Collective Work any credit as required by clause - 4(b), as requested. If You create a Derivative Work, upon notice - from any Licensor You must, to the extent practicable, remove from - the Derivative Work any credit as required by clause 4(b), as - requested. - 2. If you distribute, publicly display, publicly perform, or publicly - digitally perform the Work or any Derivative Works or Collective - Works, You must keep intact all copyright notices for the Work and - provide, reasonable to the medium or means You are utilizing: (i) - the name of the Original Author (or pseudonym, if applicable) if - supplied, and/or (ii) if the Original Author and/or Licensor - designate another party or parties (e.g. a sponsor institute, - publishing entity, journal) for attribution in Licensor's - copyright notice, terms of service or by other reasonable means, - the name of such party or parties; the title of the Work if - supplied; to the extent reasonably practicable, the Uniform - Resource Identifier, if any, that Licensor specifies to be - associated with the Work, unless such URI does not refer to the - copyright notice or licensing information for the Work; and in the - case of a Derivative Work, a credit identifying the use of the - Work in the Derivative Work (e.g., "French translation of the Work - by Original Author," or "Screenplay based on original Work by - Original Author"). Such credit may be implemented in any - reasonable manner; provided, however, that in the case of a - Derivative Work or Collective Work, at a minimum such credit will - appear where any other comparable authorship credit appears and in - a manner at least as prominent as such other comparable authorship - credit. - -*5. Representations, Warranties and Disclaimer* - -UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR -OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY -KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, -INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, -FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF -LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, -WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE -EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU. - -*6. Limitation on Liability.* EXCEPT TO THE EXTENT REQUIRED BY -APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL -THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY -DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF -LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - -*7. Termination* - - 1. This License and the rights granted hereunder will terminate - automatically upon any breach by You of the terms of this License. - Individuals or entities who have received Derivative Works or - Collective Works from You under this License, however, will not - have their licenses terminated provided such individuals or - entities remain in full compliance with those licenses. Sections - 1, 2, 5, 6, 7, and 8 will survive any termination of this License. - 2. Subject to the above terms and conditions, the license granted - here is perpetual (for the duration of the applicable copyright in - the Work). Notwithstanding the above, Licensor reserves the right - to release the Work under different license terms or to stop - distributing the Work at any time; provided, however that any such - election will not serve to withdraw this License (or any other - license that has been, or is required to be, granted under the - terms of this License), and this License will continue in full - force and effect unless terminated as stated above. - -*8. Miscellaneous* - - 1. Each time You distribute or publicly digitally perform the Work or - a Collective Work, the Licensor offers to the recipient a license - to the Work on the same terms and conditions as the license - granted to You under this License. - 2. Each time You distribute or publicly digitally perform a - Derivative Work, Licensor offers to the recipient a license to the - original Work on the same terms and conditions as the license - granted to You under this License. - 3. If any provision of this License is invalid or unenforceable under - applicable law, it shall not affect the validity or enforceability - of the remainder of the terms of this License, and without further - action by the parties to this agreement, such provision shall be - reformed to the minimum extent necessary to make such provision - valid and enforceable. - 4. No term or provision of this License shall be deemed waived and no - breach consented to unless such waiver or consent shall be in - writing and signed by the party to be charged with such waiver or - consent. - 5. This License constitutes the entire agreement between the parties - with respect to the Work licensed here. There are no - understandings, agreements or representations with respect to the - Work not specified here. Licensor shall not be bound by any - additional provisions that may appear in any communication from - You. This License may not be modified without the mutual written - agreement of the Licensor and You. - -Creative Commons is not a party to this License, and makes no warranty -whatsoever in connection with the Work. Creative Commons will not be -liable to You or any party on any legal theory for any damages -whatsoever, including without limitation any general, special, -incidental or consequential damages arising in connection to this -license. Notwithstanding the foregoing two (2) sentences, if Creative -Commons has expressly identified itself as the Licensor hereunder, it -shall have all rights and obligations of Licensor. - -Except for the limited purpose of indicating to the public that the Work -is licensed under the CCPL, neither party will use the trademark -"Creative Commons" or any related trademark or logo of Creative Commons -without the prior written consent of Creative Commons. Any permitted use -will be in compliance with Creative Commons' then-current trademark -usage guidelines, as may be published on its website or otherwise made -available upon request from time to time. - -Creative Commons may be contacted at http://creativecommons.org/ -<http://creativecommons.org>. - -« Back to Commons Deed <./> diff --git a/repoze/bfg/paster_templates/alchemy/+package+/views.py_tmpl b/repoze/bfg/paster_templates/alchemy/+package+/views.py_tmpl deleted file mode 100644 index 12bce138e..000000000 --- a/repoze/bfg/paster_templates/alchemy/+package+/views.py_tmpl +++ /dev/null @@ -1,5 +0,0 @@ -def view_root(context, request): - return {'items':list(context), 'project':'{{project}}'} - -def view_model(context, request): - return {'item':context, 'project':'{{project}}'} diff --git a/repoze/bfg/paster_templates/alchemy/+project+.ini_tmpl b/repoze/bfg/paster_templates/alchemy/+project+.ini_tmpl deleted file mode 100644 index 8260104d5..000000000 --- a/repoze/bfg/paster_templates/alchemy/+project+.ini_tmpl +++ /dev/null @@ -1,22 +0,0 @@ -[DEFAULT] -debug = true - -[app:sqlalchemy] -use = egg:{{package}}#app -reload_templates = true -debug_authorization = false -debug_notfound = false -debug_templates = true -default_locale_name = en -db_string = sqlite:///%(here)s/{{package}}.db -db_echo = false - -[pipeline:main] -pipeline = - egg:repoze.tm2#tm - sqlalchemy - -[server:main] -use = egg:Paste#http -host = 0.0.0.0 -port = 6543 diff --git a/repoze/bfg/paster_templates/alchemy/CHANGES.txt_tmpl b/repoze/bfg/paster_templates/alchemy/CHANGES.txt_tmpl deleted file mode 100644 index 5b34f7803..000000000 --- a/repoze/bfg/paster_templates/alchemy/CHANGES.txt_tmpl +++ /dev/null @@ -1,4 +0,0 @@ -0.1 ---- - -- Initial version diff --git a/repoze/bfg/paster_templates/alchemy/README.txt_tmpl b/repoze/bfg/paster_templates/alchemy/README.txt_tmpl deleted file mode 100644 index 0ddebfc3e..000000000 --- a/repoze/bfg/paster_templates/alchemy/README.txt_tmpl +++ /dev/null @@ -1,4 +0,0 @@ -{{project}} README - - - diff --git a/repoze/bfg/paster_templates/alchemy/setup.cfg_tmpl b/repoze/bfg/paster_templates/alchemy/setup.cfg_tmpl deleted file mode 100644 index 5bec29823..000000000 --- a/repoze/bfg/paster_templates/alchemy/setup.cfg_tmpl +++ /dev/null @@ -1,27 +0,0 @@ -[nosetests] -match=^test -nocapture=1 -cover-package={{package}} -with-coverage=1 -cover-erase=1 - -[compile_catalog] -directory = {{package}}/locale -domain = {{project}} -statistics = true - -[extract_messages] -add_comments = TRANSLATORS: -output_file = {{package}}/locale/{{project}}.pot -width = 80 - -[init_catalog] -domain = {{project}} -input_file = {{package}}/locale/{{project}}.pot -output_dir = {{package}}/locale - -[update_catalog] -domain = {{project}} -input_file = {{package}}/locale/{{project}}.pot -output_dir = {{package}}/locale -previous = true diff --git a/repoze/bfg/paster_templates/alchemy/setup.py_tmpl b/repoze/bfg/paster_templates/alchemy/setup.py_tmpl deleted file mode 100644 index 9446964e5..000000000 --- a/repoze/bfg/paster_templates/alchemy/setup.py_tmpl +++ /dev/null @@ -1,45 +0,0 @@ -import os -import sys - -from setuptools import setup, find_packages - -here = os.path.abspath(os.path.dirname(__file__)) -README = open(os.path.join(here, 'README.txt')).read() -CHANGES = open(os.path.join(here, 'CHANGES.txt')).read() - -requires = [ - 'repoze.bfg', - 'repoze.tm2', - 'sqlalchemy', - 'zope.sqlalchemy', - ] - -if sys.version_info[:3] < (2,5,0): - requires.append('pysqlite') - -setup(name='{{project}}', - version='0.0', - description='{{project}}', - long_description=README + '\n\n' + CHANGES, - classifiers=[ - "Programming Language :: Python", - "Framework :: BFG", - "Topic :: Internet :: WWW/HTTP", - "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", - ], - author='', - author_email='', - url='', - keywords='web wsgi bfg', - packages=find_packages(), - include_package_data=True, - zip_safe=False, - install_requires = requires, - tests_require = requires, - test_suite="{{package}}", - entry_points = """\ - [paste.app_factory] - app = {{package}}.run:app - """ - ) - diff --git a/repoze/bfg/paster_templates/routesalchemy/+package+/__init__.py b/repoze/bfg/paster_templates/routesalchemy/+package+/__init__.py deleted file mode 100644 index cbdfd3ac6..000000000 --- a/repoze/bfg/paster_templates/routesalchemy/+package+/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# A package - diff --git a/repoze/bfg/paster_templates/routesalchemy/+package+/configure.zcml b/repoze/bfg/paster_templates/routesalchemy/+package+/configure.zcml deleted file mode 100644 index 6d16bd089..000000000 --- a/repoze/bfg/paster_templates/routesalchemy/+package+/configure.zcml +++ /dev/null @@ -1,18 +0,0 @@ -<configure xmlns="http://namespaces.repoze.org/bfg"> - - <!-- this must be included for the view declarations to work --> - <include package="repoze.bfg.includes" /> - - <route - pattern="" - name="home" - view=".views.my_view" - view_renderer="templates/mytemplate.pt" - /> - - <static - name="static" - path="templates/static" - /> - -</configure> diff --git a/repoze/bfg/paster_templates/routesalchemy/+package+/models.py b/repoze/bfg/paster_templates/routesalchemy/+package+/models.py deleted file mode 100644 index a1726ebf4..000000000 --- a/repoze/bfg/paster_templates/routesalchemy/+package+/models.py +++ /dev/null @@ -1,44 +0,0 @@ -import transaction - -from sqlalchemy import create_engine -from sqlalchemy import Column -from sqlalchemy import Integer -from sqlalchemy import Unicode - -from sqlalchemy.exc import IntegrityError -from sqlalchemy.ext.declarative import declarative_base - -from sqlalchemy.orm import scoped_session -from sqlalchemy.orm import sessionmaker - -from zope.sqlalchemy import ZopeTransactionExtension - -DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension())) -Base = declarative_base() - -class MyModel(Base): - __tablename__ = 'models' - id = Column(Integer, primary_key=True) - name = Column(Unicode(255), unique=True) - value = Column(Integer) - - def __init__(self, name, value): - self.name = name - self.value = value - -def populate(): - session = DBSession() - model = MyModel(name=u'root',value=55) - session.add(model) - session.flush() - transaction.commit() - -def initialize_sql(db_string, db_echo=False): - engine = create_engine(db_string, echo=db_echo) - DBSession.configure(bind=engine) - Base.metadata.bind = engine - Base.metadata.create_all(engine) - try: - populate() - except IntegrityError: - pass diff --git a/repoze/bfg/paster_templates/routesalchemy/+package+/run.py_tmpl b/repoze/bfg/paster_templates/routesalchemy/+package+/run.py_tmpl deleted file mode 100644 index b85f57556..000000000 --- a/repoze/bfg/paster_templates/routesalchemy/+package+/run.py_tmpl +++ /dev/null @@ -1,23 +0,0 @@ -from repoze.bfg.configuration import Configurator -from paste.deploy.converters import asbool - -from {{package}}.models import initialize_sql - -def app(global_config, **settings): - """ This function returns a WSGI application. - - It is usually called by the PasteDeploy framework during - ``paster serve``. - """ - zcml_file = settings.get('configure_zcml', 'configure.zcml') - db_string = settings.get('db_string') - if db_string is None: - raise ValueError("No 'db_string' value in application configuration.") - db_echo = settings.get('db_echo', 'false') - initialize_sql(db_string, asbool(db_echo)) - config = Configurator(settings=settings) - config.begin() - config.load_zcml(zcml_file) - config.end() - return config.make_wsgi_app() - diff --git a/repoze/bfg/paster_templates/routesalchemy/+package+/templates/mytemplate.pt b/repoze/bfg/paster_templates/routesalchemy/+package+/templates/mytemplate.pt deleted file mode 100644 index 2aedcad9f..000000000 --- a/repoze/bfg/paster_templates/routesalchemy/+package+/templates/mytemplate.pt +++ /dev/null @@ -1,99 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" - xmlns:tal="http://xml.zope.org/namespaces/tal"> -<head> -<meta http-equiv="content-type" content="text/html; charset=utf-8" /> -<title>${project} Application</title> -<meta name="keywords" content="python web application" /> -<meta name="description" content="repoze.bfg web application" /> -<link href="${request.application_url}/static/default.css" rel="stylesheet" type="text/css" /> -</head> -<body> -<!-- start header --> -<div id="logo"> - <h2><code>${project}</code>, a <code>repoze.bfg</code> application</h2> -</div> -<div id="header"> - <div id="menu"> - </div> -</div> -<!-- end header --> -<div id="wrapper"> - <!-- start page --> - <div id="page"> - <!-- start content --> - <div id="content"> - <div class="post"> - <h1 class="title">Welcome to <code>${project}</code>, an - application generated by the <a - href="http://bfg.repoze.org">repoze.bfg</a> web - application framework.</h1> - </div> - </div> - <!-- end content --> - <!-- start sidebar --> - <div id="sidebar"> - <ul> - <li id="search"> - <h2>Search<br/> <code>repoze.bfg</code> Documentation</h2> - <form method="get" - action="http://bfg.repoze.org/searchresults"> - <fieldset> - <input type="text" id="q" name="text" value="" /> - <input type="submit" id="x" value="Search" /> - </fieldset> - </form> - </li> - <li> - <h2><code>repoze.bfg</code> links</h2> - <ul> - <li><a - href="http://docs.repoze.org/bfg/current/#narrative-documentation">Narrative - Documentation</a> - </li> - <li> - <a - href="http://docs.repoze.org/bfg/current/#api-documentation">API - Documentation</a> - </li> - <li> - <a - href="http://docs.repoze.org/bfg/current/#tutorials">Tutorials</a> - </li> - <li> - <a - href="http://docs.repoze.org/bfg/current/#change-history">Change - History</a> - </li> - <li> - <a - href="http://docs.repoze.org/bfg/current/#sample-applications">Sample - Applications</a> - </li> - <li> - <a - href="http://docs.repoze.org/bfg/current/#support-and-development">Support - and Development</a> - </li> - <li> - <a - href="irc://irc.freenode.net#repoze">IRC Channel</a> - </li> - </ul> - </li> - </ul> - </div> - <!-- end sidebar --> - <div style="clear: both;"> </div> - </div> -</div> -<!-- end page --> -<!-- start footer --> -<div id="footer"> - <p id="legal">( c ) 2008. All Rights Reserved. Template design - by <a href="http://www.freecsstemplates.org/">Free CSS - Templates</a>.</p> -</div> -<!-- end footer --> -</body> -</html> diff --git a/repoze/bfg/paster_templates/routesalchemy/+package+/templates/static/default.css b/repoze/bfg/paster_templates/routesalchemy/+package+/templates/static/default.css deleted file mode 100644 index 41b3debde..000000000 --- a/repoze/bfg/paster_templates/routesalchemy/+package+/templates/static/default.css +++ /dev/null @@ -1,380 +0,0 @@ -/* -Design by Free CSS Templates -http://www.freecsstemplates.org -Released for free under a Creative Commons Attribution 2.5 License -*/ - -body { - margin: 0; - padding: 0; - background: url(images/img01.gif) repeat-x left top; - font-size: 13px; - font-family: "Trebuchet MS", Georgia, "Times New Roman", Times, serif; - text-align: justify; - color: #FFFFFF; -} - -h1, h2, h3 { - margin: 0; - text-transform: lowercase; - font-weight: normal; - color: #FFFFFF; -} - -h1 { - letter-spacing: -1px; - font-size: 32px; -} - -h2 { - font-size: 23px; -} - -p, ul, ol { - margin: 0 0 2em 0; - text-align: justify; - line-height: 26px; -} - -a:link { - color: #8BD80E; -} - -a:hover, a:active { - text-decoration: none; - color: #8BD80E; -} - -a:visited { - color: #8BD80E; -} - -img { - border: none; -} - -img.left { - float: left; - margin-right: 15px; -} - -img.right { - float: right; - margin-left: 15px; -} - -/* Form */ - -form { - margin: 0; - padding: 0; -} - -fieldset { - margin: 0; - padding: 0; - border: none; -} - -legend { - display: none; -} - -input, textarea, select { - font-family: "Trebuchet MS", Arial, Helvetica, sans-serif; - font-size: 13px; - color: #333333; -} - -#wrapper { - margin: 0; - padding: 0; - background: #000000; -} - -/* Header */ - -#header { - width: 713px; - margin: 0 auto; - height: 42px; -} - -/* Menu */ - -#menu { - float: left; - width: 713px; - height: 50px; - background: url(images/img02.gif) no-repeat left top; -} - -#menu ul { - margin: 0; - padding: 0px 0 0 10px; - list-style: none; - line-height: normal; -} - -#menu li { - display: block; - float: left; -} - -#menu a { - display: block; - float: left; - background: url(images/img04.gif) no-repeat right 55%; - margin-top: 5px; - margin-right: 3px; - padding: 8px 17px; - text-decoration: none; - font-size: 13px; - color: #000000; -} - -#menu a:hover { - color: #000000; -} - -#menu .current_page_item a { - color: #000000; -} - -/** LOGO */ - -#logo { - width: 713px; - height: 80px; - margin: 0 auto; -} - -#logo h1, #logo h2 { - float: left; - margin: 0; - padding: 30px 0 0 0px; - line-height: normal; -} - -#logo h1 { - font-family: Georgia, "Times New Roman", Times, serif; - font-size:40px; -} - -#logo h1 a { - text-decoration: none; - color: #4C4C4C; -} - -#logo h1 a:hover { text-decoration: underline; } - -#logo h2 { - float: left; - padding: 45px 0 0 18px; - font: 18px Georgia, "Times New Roman", Times, serif; - color: #8BD80E; -} - -#logo p a { - text-decoration: none; - color: #8BD80E; -} - -#logo p a:hover { text-decoration: underline; } - - - -/* Page */ - -#page { - width: 663px; - margin: 0 auto; - background: #4C4C4C url(images/img03.gif) no-repeat left bottom; - padding: 0 25px; -} - -/* Content */ - -#content { - float: left; - width: 410px; - -} - -/* Post */ - -.post { - padding: 15px 0px; - margin-bottom: 20px; -} - -.post .title { - margin-bottom: 20px; - padding-bottom: 5px; -} - -.post h1 { - padding: 0px 0 0 0px; - background: url(images/img08.jpg) no-repeat left top; - font-size: 24px; - color: #FFFFFF; -} - -.post h2 { - padding: 0px 0 0 0px; - font-size: 22px; - color: #FFFFFF; -} - -.post .entry { -} - -.post .meta { - padding: 15px 15px 30px 0px; - font-family: Arial, Helvetica, sans-serif; - font-size: 11px; -} - -.post .meta p { - margin: 0; - padding-top: 15px; - line-height: normal; - color: #FFFFFF; -} - -.post .meta .byline { - float: left; -} - -.post .meta .links { - float: right; -} - -.post .meta .more { - padding: 0 10px 0 18px; -} - -.post .meta .comments { -} - -.post .meta b { - display: none; -} - - -/* Sidebar */ - -#sidebar { - width: 210px; - float: right; - margin: 0; - padding: 0; -} - -#sidebar ul { - margin: 0; - padding: 0; - list-style: none; -} - -#sidebar li { - margin-bottom: 40px; -} - -#sidebar li ul { -} - -#sidebar li li { - margin: 0; -} - -#sidebar h2 { - width: 250px; - padding: 8px 0 0 0px; - margin-bottom: 10px; - background: url(images/img07.jpg) no-repeat left top; - font-size: 20px; - color: #FFFFFF; -} - -/* Search */ - -#search { - -} - -#search h2 { - margin-bottom: 20px; -} - -#s { - width: 140px; - margin-right: 5px; - padding: 3px; - border: 1px solid #BED99C; -} - -#x { - padding: 3px; - border: none; - background: #8BD80E; - text-transform: lowercase; - font-size: 11px; - color: #FFFFFF; -} - -/* Boxes */ - -.box1 { - padding: 20px; -} - -.box2 { - color: #BABABA; -} - -.box2 h2 { - margin-bottom: 15px; - font-size: 16px; - color: #FFFFFF; -} - -.box2 ul { - margin: 0; - padding: 0; - list-style: none; -} - -.box2 a:link, .box2 a:hover, .box2 a:active, .box2 a:visited { - color: #EDEDED; -} - -/* Footer */ -#footer-wrap { -} - -#footer { - margin: 0 auto; - padding: 20px 0 10px 0; - background: #000000; -} - -html>body #footer { - height: auto; -} - -#footer p { - font-size: 11px; -} - -#legal { - clear: both; - padding-top: 17px; - text-align: center; - color: #FFFFFF; -} - -#legal a { - font-weight: normal; - color: #FFFFFF; -} diff --git a/repoze/bfg/paster_templates/routesalchemy/+package+/templates/static/images/img01.gif b/repoze/bfg/paster_templates/routesalchemy/+package+/templates/static/images/img01.gif Binary files differdeleted file mode 100644 index 5f082bd99..000000000 --- a/repoze/bfg/paster_templates/routesalchemy/+package+/templates/static/images/img01.gif +++ /dev/null diff --git a/repoze/bfg/paster_templates/routesalchemy/+package+/templates/static/images/img02.gif b/repoze/bfg/paster_templates/routesalchemy/+package+/templates/static/images/img02.gif Binary files differdeleted file mode 100644 index 45a3ae976..000000000 --- a/repoze/bfg/paster_templates/routesalchemy/+package+/templates/static/images/img02.gif +++ /dev/null diff --git a/repoze/bfg/paster_templates/routesalchemy/+package+/templates/static/images/img03.gif b/repoze/bfg/paster_templates/routesalchemy/+package+/templates/static/images/img03.gif Binary files differdeleted file mode 100644 index d92ea38f9..000000000 --- a/repoze/bfg/paster_templates/routesalchemy/+package+/templates/static/images/img03.gif +++ /dev/null diff --git a/repoze/bfg/paster_templates/routesalchemy/+package+/templates/static/images/img04.gif b/repoze/bfg/paster_templates/routesalchemy/+package+/templates/static/images/img04.gif Binary files differdeleted file mode 100644 index 950c4af9d..000000000 --- a/repoze/bfg/paster_templates/routesalchemy/+package+/templates/static/images/img04.gif +++ /dev/null diff --git a/repoze/bfg/paster_templates/routesalchemy/+package+/templates/static/images/spacer.gif b/repoze/bfg/paster_templates/routesalchemy/+package+/templates/static/images/spacer.gif Binary files differdeleted file mode 100644 index 5bfd67a2d..000000000 --- a/repoze/bfg/paster_templates/routesalchemy/+package+/templates/static/images/spacer.gif +++ /dev/null diff --git a/repoze/bfg/paster_templates/routesalchemy/+package+/templates/static/templatelicense.txt b/repoze/bfg/paster_templates/routesalchemy/+package+/templates/static/templatelicense.txt deleted file mode 100644 index ccb6b06ab..000000000 --- a/repoze/bfg/paster_templates/routesalchemy/+package+/templates/static/templatelicense.txt +++ /dev/null @@ -1,243 +0,0 @@ -Creative Commons </> - -Creative Commons Legal Code - -*Attribution 2.5* - -CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE -LEGAL SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN -ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION -ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE -INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM -ITS USE. - -/License/ - -THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE -COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY -COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS -AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED. - -BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE -TO BE BOUND BY THE TERMS OF THIS LICENSE. THE LICENSOR GRANTS YOU THE -RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS -AND CONDITIONS. - -*1. Definitions* - - 1. *"Collective Work"* means a work, such as a periodical issue, - anthology or encyclopedia, in which the Work in its entirety in - unmodified form, along with a number of other contributions, - constituting separate and independent works in themselves, are - assembled into a collective whole. A work that constitutes a - Collective Work will not be considered a Derivative Work (as - defined below) for the purposes of this License. - 2. *"Derivative Work"* means a work based upon the Work or upon the - Work and other pre-existing works, such as a translation, musical - arrangement, dramatization, fictionalization, motion picture - version, sound recording, art reproduction, abridgment, - condensation, or any other form in which the Work may be recast, - transformed, or adapted, except that a work that constitutes a - Collective Work will not be considered a Derivative Work for the - purpose of this License. For the avoidance of doubt, where the - Work is a musical composition or sound recording, the - synchronization of the Work in timed-relation with a moving image - ("synching") will be considered a Derivative Work for the purpose - of this License. - 3. *"Licensor"* means the individual or entity that offers the Work - under the terms of this License. - 4. *"Original Author"* means the individual or entity who created the - Work. - 5. *"Work"* means the copyrightable work of authorship offered under - the terms of this License. - 6. *"You"* means an individual or entity exercising rights under this - License who has not previously violated the terms of this License - with respect to the Work, or who has received express permission - from the Licensor to exercise rights under this License despite a - previous violation. - -*2. Fair Use Rights.* Nothing in this license is intended to reduce, -limit, or restrict any rights arising from fair use, first sale or other -limitations on the exclusive rights of the copyright owner under -copyright law or other applicable laws. - -*3. License Grant.* Subject to the terms and conditions of this License, -Licensor hereby grants You a worldwide, royalty-free, non-exclusive, -perpetual (for the duration of the applicable copyright) license to -exercise the rights in the Work as stated below: - - 1. to reproduce the Work, to incorporate the Work into one or more - Collective Works, and to reproduce the Work as incorporated in the - Collective Works; - 2. to create and reproduce Derivative Works; - 3. to distribute copies or phonorecords of, display publicly, perform - publicly, and perform publicly by means of a digital audio - transmission the Work including as incorporated in Collective Works; - 4. to distribute copies or phonorecords of, display publicly, perform - publicly, and perform publicly by means of a digital audio - transmission Derivative Works. - 5. - - For the avoidance of doubt, where the work is a musical composition: - - 1. *Performance Royalties Under Blanket Licenses*. Licensor - waives the exclusive right to collect, whether individually - or via a performance rights society (e.g. ASCAP, BMI, - SESAC), royalties for the public performance or public - digital performance (e.g. webcast) of the Work. - 2. *Mechanical Rights and Statutory Royalties*. Licensor waives - the exclusive right to collect, whether individually or via - a music rights agency or designated agent (e.g. Harry Fox - Agency), royalties for any phonorecord You create from the - Work ("cover version") and distribute, subject to the - compulsory license created by 17 USC Section 115 of the US - Copyright Act (or the equivalent in other jurisdictions). - 6. *Webcasting Rights and Statutory Royalties*. For the avoidance of - doubt, where the Work is a sound recording, Licensor waives the - exclusive right to collect, whether individually or via a - performance-rights society (e.g. SoundExchange), royalties for the - public digital performance (e.g. webcast) of the Work, subject to - the compulsory license created by 17 USC Section 114 of the US - Copyright Act (or the equivalent in other jurisdictions). - -The above rights may be exercised in all media and formats whether now -known or hereafter devised. The above rights include the right to make -such modifications as are technically necessary to exercise the rights -in other media and formats. All rights not expressly granted by Licensor -are hereby reserved. - -*4. Restrictions.*The license granted in Section 3 above is expressly -made subject to and limited by the following restrictions: - - 1. You may distribute, publicly display, publicly perform, or - publicly digitally perform the Work only under the terms of this - License, and You must include a copy of, or the Uniform Resource - Identifier for, this License with every copy or phonorecord of the - Work You distribute, publicly display, publicly perform, or - publicly digitally perform. You may not offer or impose any terms - on the Work that alter or restrict the terms of this License or - the recipients' exercise of the rights granted hereunder. You may - not sublicense the Work. You must keep intact all notices that - refer to this License and to the disclaimer of warranties. You may - not distribute, publicly display, publicly perform, or publicly - digitally perform the Work with any technological measures that - control access or use of the Work in a manner inconsistent with - the terms of this License Agreement. The above applies to the Work - as incorporated in a Collective Work, but this does not require - the Collective Work apart from the Work itself to be made subject - to the terms of this License. If You create a Collective Work, - upon notice from any Licensor You must, to the extent practicable, - remove from the Collective Work any credit as required by clause - 4(b), as requested. If You create a Derivative Work, upon notice - from any Licensor You must, to the extent practicable, remove from - the Derivative Work any credit as required by clause 4(b), as - requested. - 2. If you distribute, publicly display, publicly perform, or publicly - digitally perform the Work or any Derivative Works or Collective - Works, You must keep intact all copyright notices for the Work and - provide, reasonable to the medium or means You are utilizing: (i) - the name of the Original Author (or pseudonym, if applicable) if - supplied, and/or (ii) if the Original Author and/or Licensor - designate another party or parties (e.g. a sponsor institute, - publishing entity, journal) for attribution in Licensor's - copyright notice, terms of service or by other reasonable means, - the name of such party or parties; the title of the Work if - supplied; to the extent reasonably practicable, the Uniform - Resource Identifier, if any, that Licensor specifies to be - associated with the Work, unless such URI does not refer to the - copyright notice or licensing information for the Work; and in the - case of a Derivative Work, a credit identifying the use of the - Work in the Derivative Work (e.g., "French translation of the Work - by Original Author," or "Screenplay based on original Work by - Original Author"). Such credit may be implemented in any - reasonable manner; provided, however, that in the case of a - Derivative Work or Collective Work, at a minimum such credit will - appear where any other comparable authorship credit appears and in - a manner at least as prominent as such other comparable authorship - credit. - -*5. Representations, Warranties and Disclaimer* - -UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR -OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY -KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, -INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, -FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF -LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, -WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE -EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU. - -*6. Limitation on Liability.* EXCEPT TO THE EXTENT REQUIRED BY -APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL -THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY -DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF -LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - -*7. Termination* - - 1. This License and the rights granted hereunder will terminate - automatically upon any breach by You of the terms of this License. - Individuals or entities who have received Derivative Works or - Collective Works from You under this License, however, will not - have their licenses terminated provided such individuals or - entities remain in full compliance with those licenses. Sections - 1, 2, 5, 6, 7, and 8 will survive any termination of this License. - 2. Subject to the above terms and conditions, the license granted - here is perpetual (for the duration of the applicable copyright in - the Work). Notwithstanding the above, Licensor reserves the right - to release the Work under different license terms or to stop - distributing the Work at any time; provided, however that any such - election will not serve to withdraw this License (or any other - license that has been, or is required to be, granted under the - terms of this License), and this License will continue in full - force and effect unless terminated as stated above. - -*8. Miscellaneous* - - 1. Each time You distribute or publicly digitally perform the Work or - a Collective Work, the Licensor offers to the recipient a license - to the Work on the same terms and conditions as the license - granted to You under this License. - 2. Each time You distribute or publicly digitally perform a - Derivative Work, Licensor offers to the recipient a license to the - original Work on the same terms and conditions as the license - granted to You under this License. - 3. If any provision of this License is invalid or unenforceable under - applicable law, it shall not affect the validity or enforceability - of the remainder of the terms of this License, and without further - action by the parties to this agreement, such provision shall be - reformed to the minimum extent necessary to make such provision - valid and enforceable. - 4. No term or provision of this License shall be deemed waived and no - breach consented to unless such waiver or consent shall be in - writing and signed by the party to be charged with such waiver or - consent. - 5. This License constitutes the entire agreement between the parties - with respect to the Work licensed here. There are no - understandings, agreements or representations with respect to the - Work not specified here. Licensor shall not be bound by any - additional provisions that may appear in any communication from - You. This License may not be modified without the mutual written - agreement of the Licensor and You. - -Creative Commons is not a party to this License, and makes no warranty -whatsoever in connection with the Work. Creative Commons will not be -liable to You or any party on any legal theory for any damages -whatsoever, including without limitation any general, special, -incidental or consequential damages arising in connection to this -license. Notwithstanding the foregoing two (2) sentences, if Creative -Commons has expressly identified itself as the Licensor hereunder, it -shall have all rights and obligations of Licensor. - -Except for the limited purpose of indicating to the public that the Work -is licensed under the CCPL, neither party will use the trademark -"Creative Commons" or any related trademark or logo of Creative Commons -without the prior written consent of Creative Commons. Any permitted use -will be in compliance with Creative Commons' then-current trademark -usage guidelines, as may be published on its website or otherwise made -available upon request from time to time. - -Creative Commons may be contacted at http://creativecommons.org/ -<http://creativecommons.org>. - -« Back to Commons Deed <./> diff --git a/repoze/bfg/paster_templates/routesalchemy/+package+/tests.py_tmpl b/repoze/bfg/paster_templates/routesalchemy/+package+/tests.py_tmpl deleted file mode 100644 index ed7f1280b..000000000 --- a/repoze/bfg/paster_templates/routesalchemy/+package+/tests.py_tmpl +++ /dev/null @@ -1,24 +0,0 @@ -import unittest -from repoze.bfg.configuration import Configurator -from repoze.bfg import testing - -def _initTestingDB(): - from {{package}}.models import initialize_sql - session = initialize_sql('sqlite://') - return session - -class TestMyView(unittest.TestCase): - def setUp(self): - self.config = Configurator() - self.config.begin() - _initTestingDB() - - def tearDown(self): - self.config.end() - - def test_it(self): - from {{package}}.views import my_view - request = testing.DummyRequest() - info = my_view(request) - self.assertEqual(info['root'].name, 'root') - self.assertEqual(info['project'], '{{package}}') diff --git a/repoze/bfg/paster_templates/routesalchemy/+package+/views.py_tmpl b/repoze/bfg/paster_templates/routesalchemy/+package+/views.py_tmpl deleted file mode 100644 index 86cc02e41..000000000 --- a/repoze/bfg/paster_templates/routesalchemy/+package+/views.py_tmpl +++ /dev/null @@ -1,7 +0,0 @@ -from {{package}}.models import DBSession -from {{package}}.models import MyModel - -def my_view(request): - dbsession = DBSession() - root = dbsession.query(MyModel).filter(MyModel.name==u'root').first() - return {'root':root, 'project':'{{project}}'} diff --git a/repoze/bfg/paster_templates/routesalchemy/+project+.ini_tmpl b/repoze/bfg/paster_templates/routesalchemy/+project+.ini_tmpl deleted file mode 100644 index 8260104d5..000000000 --- a/repoze/bfg/paster_templates/routesalchemy/+project+.ini_tmpl +++ /dev/null @@ -1,22 +0,0 @@ -[DEFAULT] -debug = true - -[app:sqlalchemy] -use = egg:{{package}}#app -reload_templates = true -debug_authorization = false -debug_notfound = false -debug_templates = true -default_locale_name = en -db_string = sqlite:///%(here)s/{{package}}.db -db_echo = false - -[pipeline:main] -pipeline = - egg:repoze.tm2#tm - sqlalchemy - -[server:main] -use = egg:Paste#http -host = 0.0.0.0 -port = 6543 diff --git a/repoze/bfg/paster_templates/routesalchemy/CHANGES.txt_tmpl b/repoze/bfg/paster_templates/routesalchemy/CHANGES.txt_tmpl deleted file mode 100644 index 35a34f332..000000000 --- a/repoze/bfg/paster_templates/routesalchemy/CHANGES.txt_tmpl +++ /dev/null @@ -1,4 +0,0 @@ -0.0 ---- - -- Initial version diff --git a/repoze/bfg/paster_templates/routesalchemy/README.txt_tmpl b/repoze/bfg/paster_templates/routesalchemy/README.txt_tmpl deleted file mode 100644 index 0ddebfc3e..000000000 --- a/repoze/bfg/paster_templates/routesalchemy/README.txt_tmpl +++ /dev/null @@ -1,4 +0,0 @@ -{{project}} README - - - diff --git a/repoze/bfg/paster_templates/routesalchemy/setup.cfg_tmpl b/repoze/bfg/paster_templates/routesalchemy/setup.cfg_tmpl deleted file mode 100644 index 5bec29823..000000000 --- a/repoze/bfg/paster_templates/routesalchemy/setup.cfg_tmpl +++ /dev/null @@ -1,27 +0,0 @@ -[nosetests] -match=^test -nocapture=1 -cover-package={{package}} -with-coverage=1 -cover-erase=1 - -[compile_catalog] -directory = {{package}}/locale -domain = {{project}} -statistics = true - -[extract_messages] -add_comments = TRANSLATORS: -output_file = {{package}}/locale/{{project}}.pot -width = 80 - -[init_catalog] -domain = {{project}} -input_file = {{package}}/locale/{{project}}.pot -output_dir = {{package}}/locale - -[update_catalog] -domain = {{project}} -input_file = {{package}}/locale/{{project}}.pot -output_dir = {{package}}/locale -previous = true diff --git a/repoze/bfg/paster_templates/routesalchemy/setup.py_tmpl b/repoze/bfg/paster_templates/routesalchemy/setup.py_tmpl deleted file mode 100644 index 0ce1b8bad..000000000 --- a/repoze/bfg/paster_templates/routesalchemy/setup.py_tmpl +++ /dev/null @@ -1,45 +0,0 @@ -import os -import sys - -from setuptools import setup, find_packages - -here = os.path.abspath(os.path.dirname(__file__)) -README = open(os.path.join(here, 'README.txt')).read() -CHANGES = open(os.path.join(here, 'CHANGES.txt')).read() - -requires = [ - 'repoze.bfg', - 'SQLAlchemy', - 'transaction', - 'repoze.tm2', - 'zope.sqlalchemy', - ] - -if sys.version_info[:3] < (2,5,0): - requires.append('pysqlite') - -setup(name='{{project}}', - version='0.0', - description='{{project}}', - long_description=README + '\n\n' + CHANGES, - classifiers=[ - "Programming Language :: Python", - "Framework :: BFG", - "Topic :: Internet :: WWW/HTTP", - "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", - ], - author='', - author_email='', - url='', - keywords='web wsgi bfg', - packages=find_packages(), - include_package_data=True, - zip_safe=False, - test_suite='{{package}}', - install_requires = requires, - entry_points = """\ - [paste.app_factory] - app = {{package}}.run:app - """ - ) - diff --git a/repoze/bfg/paster_templates/starter/+package+/__init__.py b/repoze/bfg/paster_templates/starter/+package+/__init__.py deleted file mode 100644 index cbdfd3ac6..000000000 --- a/repoze/bfg/paster_templates/starter/+package+/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# A package - diff --git a/repoze/bfg/paster_templates/starter/+package+/configure.zcml b/repoze/bfg/paster_templates/starter/+package+/configure.zcml deleted file mode 100644 index e83dd3933..000000000 --- a/repoze/bfg/paster_templates/starter/+package+/configure.zcml +++ /dev/null @@ -1,17 +0,0 @@ -<configure xmlns="http://namespaces.repoze.org/bfg"> - - <!-- this must be included for the view declarations to work --> - <include package="repoze.bfg.includes" /> - - <view - context=".models.MyModel" - view=".views.my_view" - renderer="templates/mytemplate.pt" - /> - - <static - name="static" - path="templates/static" - /> - -</configure> diff --git a/repoze/bfg/paster_templates/starter/+package+/models.py b/repoze/bfg/paster_templates/starter/+package+/models.py deleted file mode 100644 index 75dec7505..000000000 --- a/repoze/bfg/paster_templates/starter/+package+/models.py +++ /dev/null @@ -1,7 +0,0 @@ -class MyModel(object): - pass - -root = MyModel() - -def get_root(request): - return root diff --git a/repoze/bfg/paster_templates/starter/+package+/run.py_tmpl b/repoze/bfg/paster_templates/starter/+package+/run.py_tmpl deleted file mode 100644 index 74876f3f4..000000000 --- a/repoze/bfg/paster_templates/starter/+package+/run.py_tmpl +++ /dev/null @@ -1,15 +0,0 @@ -from repoze.bfg.configuration import Configurator -from {{package}}.models import get_root - -def app(global_config, **settings): - """ This function returns a WSGI application. - - It is usually called by the PasteDeploy framework during - ``paster serve``. - """ - zcml_file = settings.get('configure_zcml', 'configure.zcml') - config = Configurator(root_factory=get_root, settings=settings) - config.begin() - config.load_zcml(zcml_file) - config.end() - return config.make_wsgi_app() diff --git a/repoze/bfg/paster_templates/starter/+package+/templates/mytemplate.pt b/repoze/bfg/paster_templates/starter/+package+/templates/mytemplate.pt deleted file mode 100644 index 2aedcad9f..000000000 --- a/repoze/bfg/paster_templates/starter/+package+/templates/mytemplate.pt +++ /dev/null @@ -1,99 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" - xmlns:tal="http://xml.zope.org/namespaces/tal"> -<head> -<meta http-equiv="content-type" content="text/html; charset=utf-8" /> -<title>${project} Application</title> -<meta name="keywords" content="python web application" /> -<meta name="description" content="repoze.bfg web application" /> -<link href="${request.application_url}/static/default.css" rel="stylesheet" type="text/css" /> -</head> -<body> -<!-- start header --> -<div id="logo"> - <h2><code>${project}</code>, a <code>repoze.bfg</code> application</h2> -</div> -<div id="header"> - <div id="menu"> - </div> -</div> -<!-- end header --> -<div id="wrapper"> - <!-- start page --> - <div id="page"> - <!-- start content --> - <div id="content"> - <div class="post"> - <h1 class="title">Welcome to <code>${project}</code>, an - application generated by the <a - href="http://bfg.repoze.org">repoze.bfg</a> web - application framework.</h1> - </div> - </div> - <!-- end content --> - <!-- start sidebar --> - <div id="sidebar"> - <ul> - <li id="search"> - <h2>Search<br/> <code>repoze.bfg</code> Documentation</h2> - <form method="get" - action="http://bfg.repoze.org/searchresults"> - <fieldset> - <input type="text" id="q" name="text" value="" /> - <input type="submit" id="x" value="Search" /> - </fieldset> - </form> - </li> - <li> - <h2><code>repoze.bfg</code> links</h2> - <ul> - <li><a - href="http://docs.repoze.org/bfg/current/#narrative-documentation">Narrative - Documentation</a> - </li> - <li> - <a - href="http://docs.repoze.org/bfg/current/#api-documentation">API - Documentation</a> - </li> - <li> - <a - href="http://docs.repoze.org/bfg/current/#tutorials">Tutorials</a> - </li> - <li> - <a - href="http://docs.repoze.org/bfg/current/#change-history">Change - History</a> - </li> - <li> - <a - href="http://docs.repoze.org/bfg/current/#sample-applications">Sample - Applications</a> - </li> - <li> - <a - href="http://docs.repoze.org/bfg/current/#support-and-development">Support - and Development</a> - </li> - <li> - <a - href="irc://irc.freenode.net#repoze">IRC Channel</a> - </li> - </ul> - </li> - </ul> - </div> - <!-- end sidebar --> - <div style="clear: both;"> </div> - </div> -</div> -<!-- end page --> -<!-- start footer --> -<div id="footer"> - <p id="legal">( c ) 2008. All Rights Reserved. Template design - by <a href="http://www.freecsstemplates.org/">Free CSS - Templates</a>.</p> -</div> -<!-- end footer --> -</body> -</html> diff --git a/repoze/bfg/paster_templates/starter/+package+/templates/static/default.css b/repoze/bfg/paster_templates/starter/+package+/templates/static/default.css deleted file mode 100644 index 41b3debde..000000000 --- a/repoze/bfg/paster_templates/starter/+package+/templates/static/default.css +++ /dev/null @@ -1,380 +0,0 @@ -/* -Design by Free CSS Templates -http://www.freecsstemplates.org -Released for free under a Creative Commons Attribution 2.5 License -*/ - -body { - margin: 0; - padding: 0; - background: url(images/img01.gif) repeat-x left top; - font-size: 13px; - font-family: "Trebuchet MS", Georgia, "Times New Roman", Times, serif; - text-align: justify; - color: #FFFFFF; -} - -h1, h2, h3 { - margin: 0; - text-transform: lowercase; - font-weight: normal; - color: #FFFFFF; -} - -h1 { - letter-spacing: -1px; - font-size: 32px; -} - -h2 { - font-size: 23px; -} - -p, ul, ol { - margin: 0 0 2em 0; - text-align: justify; - line-height: 26px; -} - -a:link { - color: #8BD80E; -} - -a:hover, a:active { - text-decoration: none; - color: #8BD80E; -} - -a:visited { - color: #8BD80E; -} - -img { - border: none; -} - -img.left { - float: left; - margin-right: 15px; -} - -img.right { - float: right; - margin-left: 15px; -} - -/* Form */ - -form { - margin: 0; - padding: 0; -} - -fieldset { - margin: 0; - padding: 0; - border: none; -} - -legend { - display: none; -} - -input, textarea, select { - font-family: "Trebuchet MS", Arial, Helvetica, sans-serif; - font-size: 13px; - color: #333333; -} - -#wrapper { - margin: 0; - padding: 0; - background: #000000; -} - -/* Header */ - -#header { - width: 713px; - margin: 0 auto; - height: 42px; -} - -/* Menu */ - -#menu { - float: left; - width: 713px; - height: 50px; - background: url(images/img02.gif) no-repeat left top; -} - -#menu ul { - margin: 0; - padding: 0px 0 0 10px; - list-style: none; - line-height: normal; -} - -#menu li { - display: block; - float: left; -} - -#menu a { - display: block; - float: left; - background: url(images/img04.gif) no-repeat right 55%; - margin-top: 5px; - margin-right: 3px; - padding: 8px 17px; - text-decoration: none; - font-size: 13px; - color: #000000; -} - -#menu a:hover { - color: #000000; -} - -#menu .current_page_item a { - color: #000000; -} - -/** LOGO */ - -#logo { - width: 713px; - height: 80px; - margin: 0 auto; -} - -#logo h1, #logo h2 { - float: left; - margin: 0; - padding: 30px 0 0 0px; - line-height: normal; -} - -#logo h1 { - font-family: Georgia, "Times New Roman", Times, serif; - font-size:40px; -} - -#logo h1 a { - text-decoration: none; - color: #4C4C4C; -} - -#logo h1 a:hover { text-decoration: underline; } - -#logo h2 { - float: left; - padding: 45px 0 0 18px; - font: 18px Georgia, "Times New Roman", Times, serif; - color: #8BD80E; -} - -#logo p a { - text-decoration: none; - color: #8BD80E; -} - -#logo p a:hover { text-decoration: underline; } - - - -/* Page */ - -#page { - width: 663px; - margin: 0 auto; - background: #4C4C4C url(images/img03.gif) no-repeat left bottom; - padding: 0 25px; -} - -/* Content */ - -#content { - float: left; - width: 410px; - -} - -/* Post */ - -.post { - padding: 15px 0px; - margin-bottom: 20px; -} - -.post .title { - margin-bottom: 20px; - padding-bottom: 5px; -} - -.post h1 { - padding: 0px 0 0 0px; - background: url(images/img08.jpg) no-repeat left top; - font-size: 24px; - color: #FFFFFF; -} - -.post h2 { - padding: 0px 0 0 0px; - font-size: 22px; - color: #FFFFFF; -} - -.post .entry { -} - -.post .meta { - padding: 15px 15px 30px 0px; - font-family: Arial, Helvetica, sans-serif; - font-size: 11px; -} - -.post .meta p { - margin: 0; - padding-top: 15px; - line-height: normal; - color: #FFFFFF; -} - -.post .meta .byline { - float: left; -} - -.post .meta .links { - float: right; -} - -.post .meta .more { - padding: 0 10px 0 18px; -} - -.post .meta .comments { -} - -.post .meta b { - display: none; -} - - -/* Sidebar */ - -#sidebar { - width: 210px; - float: right; - margin: 0; - padding: 0; -} - -#sidebar ul { - margin: 0; - padding: 0; - list-style: none; -} - -#sidebar li { - margin-bottom: 40px; -} - -#sidebar li ul { -} - -#sidebar li li { - margin: 0; -} - -#sidebar h2 { - width: 250px; - padding: 8px 0 0 0px; - margin-bottom: 10px; - background: url(images/img07.jpg) no-repeat left top; - font-size: 20px; - color: #FFFFFF; -} - -/* Search */ - -#search { - -} - -#search h2 { - margin-bottom: 20px; -} - -#s { - width: 140px; - margin-right: 5px; - padding: 3px; - border: 1px solid #BED99C; -} - -#x { - padding: 3px; - border: none; - background: #8BD80E; - text-transform: lowercase; - font-size: 11px; - color: #FFFFFF; -} - -/* Boxes */ - -.box1 { - padding: 20px; -} - -.box2 { - color: #BABABA; -} - -.box2 h2 { - margin-bottom: 15px; - font-size: 16px; - color: #FFFFFF; -} - -.box2 ul { - margin: 0; - padding: 0; - list-style: none; -} - -.box2 a:link, .box2 a:hover, .box2 a:active, .box2 a:visited { - color: #EDEDED; -} - -/* Footer */ -#footer-wrap { -} - -#footer { - margin: 0 auto; - padding: 20px 0 10px 0; - background: #000000; -} - -html>body #footer { - height: auto; -} - -#footer p { - font-size: 11px; -} - -#legal { - clear: both; - padding-top: 17px; - text-align: center; - color: #FFFFFF; -} - -#legal a { - font-weight: normal; - color: #FFFFFF; -} diff --git a/repoze/bfg/paster_templates/starter/+package+/templates/static/images/img01.gif b/repoze/bfg/paster_templates/starter/+package+/templates/static/images/img01.gif Binary files differdeleted file mode 100644 index 5f082bd99..000000000 --- a/repoze/bfg/paster_templates/starter/+package+/templates/static/images/img01.gif +++ /dev/null diff --git a/repoze/bfg/paster_templates/starter/+package+/templates/static/images/img02.gif b/repoze/bfg/paster_templates/starter/+package+/templates/static/images/img02.gif Binary files differdeleted file mode 100644 index 45a3ae976..000000000 --- a/repoze/bfg/paster_templates/starter/+package+/templates/static/images/img02.gif +++ /dev/null diff --git a/repoze/bfg/paster_templates/starter/+package+/templates/static/images/img03.gif b/repoze/bfg/paster_templates/starter/+package+/templates/static/images/img03.gif Binary files differdeleted file mode 100644 index d92ea38f9..000000000 --- a/repoze/bfg/paster_templates/starter/+package+/templates/static/images/img03.gif +++ /dev/null diff --git a/repoze/bfg/paster_templates/starter/+package+/templates/static/images/img04.gif b/repoze/bfg/paster_templates/starter/+package+/templates/static/images/img04.gif Binary files differdeleted file mode 100644 index 950c4af9d..000000000 --- a/repoze/bfg/paster_templates/starter/+package+/templates/static/images/img04.gif +++ /dev/null diff --git a/repoze/bfg/paster_templates/starter/+package+/templates/static/images/spacer.gif b/repoze/bfg/paster_templates/starter/+package+/templates/static/images/spacer.gif Binary files differdeleted file mode 100644 index 5bfd67a2d..000000000 --- a/repoze/bfg/paster_templates/starter/+package+/templates/static/images/spacer.gif +++ /dev/null diff --git a/repoze/bfg/paster_templates/starter/+package+/templates/static/templatelicense.txt b/repoze/bfg/paster_templates/starter/+package+/templates/static/templatelicense.txt deleted file mode 100644 index ccb6b06ab..000000000 --- a/repoze/bfg/paster_templates/starter/+package+/templates/static/templatelicense.txt +++ /dev/null @@ -1,243 +0,0 @@ -Creative Commons </> - -Creative Commons Legal Code - -*Attribution 2.5* - -CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE -LEGAL SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN -ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION -ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE -INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM -ITS USE. - -/License/ - -THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE -COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY -COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS -AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED. - -BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE -TO BE BOUND BY THE TERMS OF THIS LICENSE. THE LICENSOR GRANTS YOU THE -RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS -AND CONDITIONS. - -*1. Definitions* - - 1. *"Collective Work"* means a work, such as a periodical issue, - anthology or encyclopedia, in which the Work in its entirety in - unmodified form, along with a number of other contributions, - constituting separate and independent works in themselves, are - assembled into a collective whole. A work that constitutes a - Collective Work will not be considered a Derivative Work (as - defined below) for the purposes of this License. - 2. *"Derivative Work"* means a work based upon the Work or upon the - Work and other pre-existing works, such as a translation, musical - arrangement, dramatization, fictionalization, motion picture - version, sound recording, art reproduction, abridgment, - condensation, or any other form in which the Work may be recast, - transformed, or adapted, except that a work that constitutes a - Collective Work will not be considered a Derivative Work for the - purpose of this License. For the avoidance of doubt, where the - Work is a musical composition or sound recording, the - synchronization of the Work in timed-relation with a moving image - ("synching") will be considered a Derivative Work for the purpose - of this License. - 3. *"Licensor"* means the individual or entity that offers the Work - under the terms of this License. - 4. *"Original Author"* means the individual or entity who created the - Work. - 5. *"Work"* means the copyrightable work of authorship offered under - the terms of this License. - 6. *"You"* means an individual or entity exercising rights under this - License who has not previously violated the terms of this License - with respect to the Work, or who has received express permission - from the Licensor to exercise rights under this License despite a - previous violation. - -*2. Fair Use Rights.* Nothing in this license is intended to reduce, -limit, or restrict any rights arising from fair use, first sale or other -limitations on the exclusive rights of the copyright owner under -copyright law or other applicable laws. - -*3. License Grant.* Subject to the terms and conditions of this License, -Licensor hereby grants You a worldwide, royalty-free, non-exclusive, -perpetual (for the duration of the applicable copyright) license to -exercise the rights in the Work as stated below: - - 1. to reproduce the Work, to incorporate the Work into one or more - Collective Works, and to reproduce the Work as incorporated in the - Collective Works; - 2. to create and reproduce Derivative Works; - 3. to distribute copies or phonorecords of, display publicly, perform - publicly, and perform publicly by means of a digital audio - transmission the Work including as incorporated in Collective Works; - 4. to distribute copies or phonorecords of, display publicly, perform - publicly, and perform publicly by means of a digital audio - transmission Derivative Works. - 5. - - For the avoidance of doubt, where the work is a musical composition: - - 1. *Performance Royalties Under Blanket Licenses*. Licensor - waives the exclusive right to collect, whether individually - or via a performance rights society (e.g. ASCAP, BMI, - SESAC), royalties for the public performance or public - digital performance (e.g. webcast) of the Work. - 2. *Mechanical Rights and Statutory Royalties*. Licensor waives - the exclusive right to collect, whether individually or via - a music rights agency or designated agent (e.g. Harry Fox - Agency), royalties for any phonorecord You create from the - Work ("cover version") and distribute, subject to the - compulsory license created by 17 USC Section 115 of the US - Copyright Act (or the equivalent in other jurisdictions). - 6. *Webcasting Rights and Statutory Royalties*. For the avoidance of - doubt, where the Work is a sound recording, Licensor waives the - exclusive right to collect, whether individually or via a - performance-rights society (e.g. SoundExchange), royalties for the - public digital performance (e.g. webcast) of the Work, subject to - the compulsory license created by 17 USC Section 114 of the US - Copyright Act (or the equivalent in other jurisdictions). - -The above rights may be exercised in all media and formats whether now -known or hereafter devised. The above rights include the right to make -such modifications as are technically necessary to exercise the rights -in other media and formats. All rights not expressly granted by Licensor -are hereby reserved. - -*4. Restrictions.*The license granted in Section 3 above is expressly -made subject to and limited by the following restrictions: - - 1. You may distribute, publicly display, publicly perform, or - publicly digitally perform the Work only under the terms of this - License, and You must include a copy of, or the Uniform Resource - Identifier for, this License with every copy or phonorecord of the - Work You distribute, publicly display, publicly perform, or - publicly digitally perform. You may not offer or impose any terms - on the Work that alter or restrict the terms of this License or - the recipients' exercise of the rights granted hereunder. You may - not sublicense the Work. You must keep intact all notices that - refer to this License and to the disclaimer of warranties. You may - not distribute, publicly display, publicly perform, or publicly - digitally perform the Work with any technological measures that - control access or use of the Work in a manner inconsistent with - the terms of this License Agreement. The above applies to the Work - as incorporated in a Collective Work, but this does not require - the Collective Work apart from the Work itself to be made subject - to the terms of this License. If You create a Collective Work, - upon notice from any Licensor You must, to the extent practicable, - remove from the Collective Work any credit as required by clause - 4(b), as requested. If You create a Derivative Work, upon notice - from any Licensor You must, to the extent practicable, remove from - the Derivative Work any credit as required by clause 4(b), as - requested. - 2. If you distribute, publicly display, publicly perform, or publicly - digitally perform the Work or any Derivative Works or Collective - Works, You must keep intact all copyright notices for the Work and - provide, reasonable to the medium or means You are utilizing: (i) - the name of the Original Author (or pseudonym, if applicable) if - supplied, and/or (ii) if the Original Author and/or Licensor - designate another party or parties (e.g. a sponsor institute, - publishing entity, journal) for attribution in Licensor's - copyright notice, terms of service or by other reasonable means, - the name of such party or parties; the title of the Work if - supplied; to the extent reasonably practicable, the Uniform - Resource Identifier, if any, that Licensor specifies to be - associated with the Work, unless such URI does not refer to the - copyright notice or licensing information for the Work; and in the - case of a Derivative Work, a credit identifying the use of the - Work in the Derivative Work (e.g., "French translation of the Work - by Original Author," or "Screenplay based on original Work by - Original Author"). Such credit may be implemented in any - reasonable manner; provided, however, that in the case of a - Derivative Work or Collective Work, at a minimum such credit will - appear where any other comparable authorship credit appears and in - a manner at least as prominent as such other comparable authorship - credit. - -*5. Representations, Warranties and Disclaimer* - -UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR -OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY -KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, -INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, -FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF -LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, -WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE -EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU. - -*6. Limitation on Liability.* EXCEPT TO THE EXTENT REQUIRED BY -APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL -THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY -DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF -LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - -*7. Termination* - - 1. This License and the rights granted hereunder will terminate - automatically upon any breach by You of the terms of this License. - Individuals or entities who have received Derivative Works or - Collective Works from You under this License, however, will not - have their licenses terminated provided such individuals or - entities remain in full compliance with those licenses. Sections - 1, 2, 5, 6, 7, and 8 will survive any termination of this License. - 2. Subject to the above terms and conditions, the license granted - here is perpetual (for the duration of the applicable copyright in - the Work). Notwithstanding the above, Licensor reserves the right - to release the Work under different license terms or to stop - distributing the Work at any time; provided, however that any such - election will not serve to withdraw this License (or any other - license that has been, or is required to be, granted under the - terms of this License), and this License will continue in full - force and effect unless terminated as stated above. - -*8. Miscellaneous* - - 1. Each time You distribute or publicly digitally perform the Work or - a Collective Work, the Licensor offers to the recipient a license - to the Work on the same terms and conditions as the license - granted to You under this License. - 2. Each time You distribute or publicly digitally perform a - Derivative Work, Licensor offers to the recipient a license to the - original Work on the same terms and conditions as the license - granted to You under this License. - 3. If any provision of this License is invalid or unenforceable under - applicable law, it shall not affect the validity or enforceability - of the remainder of the terms of this License, and without further - action by the parties to this agreement, such provision shall be - reformed to the minimum extent necessary to make such provision - valid and enforceable. - 4. No term or provision of this License shall be deemed waived and no - breach consented to unless such waiver or consent shall be in - writing and signed by the party to be charged with such waiver or - consent. - 5. This License constitutes the entire agreement between the parties - with respect to the Work licensed here. There are no - understandings, agreements or representations with respect to the - Work not specified here. Licensor shall not be bound by any - additional provisions that may appear in any communication from - You. This License may not be modified without the mutual written - agreement of the Licensor and You. - -Creative Commons is not a party to this License, and makes no warranty -whatsoever in connection with the Work. Creative Commons will not be -liable to You or any party on any legal theory for any damages -whatsoever, including without limitation any general, special, -incidental or consequential damages arising in connection to this -license. Notwithstanding the foregoing two (2) sentences, if Creative -Commons has expressly identified itself as the Licensor hereunder, it -shall have all rights and obligations of Licensor. - -Except for the limited purpose of indicating to the public that the Work -is licensed under the CCPL, neither party will use the trademark -"Creative Commons" or any related trademark or logo of Creative Commons -without the prior written consent of Creative Commons. Any permitted use -will be in compliance with Creative Commons' then-current trademark -usage guidelines, as may be published on its website or otherwise made -available upon request from time to time. - -Creative Commons may be contacted at http://creativecommons.org/ -<http://creativecommons.org>. - -« Back to Commons Deed <./> diff --git a/repoze/bfg/paster_templates/starter/+package+/tests.py_tmpl b/repoze/bfg/paster_templates/starter/+package+/tests.py_tmpl deleted file mode 100644 index 578a58d35..000000000 --- a/repoze/bfg/paster_templates/starter/+package+/tests.py_tmpl +++ /dev/null @@ -1,20 +0,0 @@ -import unittest - -from repoze.bfg.configuration import Configurator -from repoze.bfg import testing - -class ViewTests(unittest.TestCase): - def setUp(self): - self.config = Configurator() - self.config.begin() - - def tearDown(self): - self.config.end() - - def test_my_view(self): - from {{package}}.views import my_view - request = testing.DummyRequest() - info = my_view(request) - self.assertEqual(info['project'], '{{project}}') - - diff --git a/repoze/bfg/paster_templates/starter/+package+/views.py_tmpl b/repoze/bfg/paster_templates/starter/+package+/views.py_tmpl deleted file mode 100644 index 12ed8832d..000000000 --- a/repoze/bfg/paster_templates/starter/+package+/views.py_tmpl +++ /dev/null @@ -1,2 +0,0 @@ -def my_view(request): - return {'project':'{{project}}'} diff --git a/repoze/bfg/paster_templates/starter/+project+.ini_tmpl b/repoze/bfg/paster_templates/starter/+project+.ini_tmpl deleted file mode 100644 index 9bdeec1ae..000000000 --- a/repoze/bfg/paster_templates/starter/+project+.ini_tmpl +++ /dev/null @@ -1,15 +0,0 @@ -[DEFAULT] -debug = true - -[app:main] -use = egg:{{project}}#app -reload_templates = true -debug_authorization = false -debug_notfound = false -debug_templates = true -default_locale_name = en - -[server:main] -use = egg:Paste#http -host = 0.0.0.0 -port = 6543 diff --git a/repoze/bfg/paster_templates/starter/CHANGES.txt_tmpl b/repoze/bfg/paster_templates/starter/CHANGES.txt_tmpl deleted file mode 100644 index 35a34f332..000000000 --- a/repoze/bfg/paster_templates/starter/CHANGES.txt_tmpl +++ /dev/null @@ -1,4 +0,0 @@ -0.0 ---- - -- Initial version diff --git a/repoze/bfg/paster_templates/starter/README.txt_tmpl b/repoze/bfg/paster_templates/starter/README.txt_tmpl deleted file mode 100644 index 0ddebfc3e..000000000 --- a/repoze/bfg/paster_templates/starter/README.txt_tmpl +++ /dev/null @@ -1,4 +0,0 @@ -{{project}} README - - - diff --git a/repoze/bfg/paster_templates/starter/setup.cfg_tmpl b/repoze/bfg/paster_templates/starter/setup.cfg_tmpl deleted file mode 100644 index 5bec29823..000000000 --- a/repoze/bfg/paster_templates/starter/setup.cfg_tmpl +++ /dev/null @@ -1,27 +0,0 @@ -[nosetests] -match=^test -nocapture=1 -cover-package={{package}} -with-coverage=1 -cover-erase=1 - -[compile_catalog] -directory = {{package}}/locale -domain = {{project}} -statistics = true - -[extract_messages] -add_comments = TRANSLATORS: -output_file = {{package}}/locale/{{project}}.pot -width = 80 - -[init_catalog] -domain = {{project}} -input_file = {{package}}/locale/{{project}}.pot -output_dir = {{package}}/locale - -[update_catalog] -domain = {{project}} -input_file = {{package}}/locale/{{project}}.pot -output_dir = {{package}}/locale -previous = true diff --git a/repoze/bfg/paster_templates/starter/setup.py_tmpl b/repoze/bfg/paster_templates/starter/setup.py_tmpl deleted file mode 100644 index df1206c1e..000000000 --- a/repoze/bfg/paster_templates/starter/setup.py_tmpl +++ /dev/null @@ -1,36 +0,0 @@ -import os - -from setuptools import setup, find_packages - -here = os.path.abspath(os.path.dirname(__file__)) -README = open(os.path.join(here, 'README.txt')).read() -CHANGES = open(os.path.join(here, 'CHANGES.txt')).read() - -requires = ['repoze.bfg'] - -setup(name='{{project}}', - version='0.0', - description='{{project}}', - long_description=README + '\n\n' + CHANGES, - classifiers=[ - "Programming Language :: Python", - "Framework :: BFG", - "Topic :: Internet :: WWW/HTTP", - "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", - ], - author='', - author_email='', - url='', - keywords='web wsgi bfg', - packages=find_packages(), - include_package_data=True, - zip_safe=False, - install_requires=requires, - tests_require=requires, - test_suite="{{package}}", - entry_points = """\ - [paste.app_factory] - app = {{package}}.run:app - """ - ) - diff --git a/repoze/bfg/paster_templates/zodb/+package+/__init__.py b/repoze/bfg/paster_templates/zodb/+package+/__init__.py deleted file mode 100644 index cbdfd3ac6..000000000 --- a/repoze/bfg/paster_templates/zodb/+package+/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# A package - diff --git a/repoze/bfg/paster_templates/zodb/+package+/configure.zcml b/repoze/bfg/paster_templates/zodb/+package+/configure.zcml deleted file mode 100644 index e83dd3933..000000000 --- a/repoze/bfg/paster_templates/zodb/+package+/configure.zcml +++ /dev/null @@ -1,17 +0,0 @@ -<configure xmlns="http://namespaces.repoze.org/bfg"> - - <!-- this must be included for the view declarations to work --> - <include package="repoze.bfg.includes" /> - - <view - context=".models.MyModel" - view=".views.my_view" - renderer="templates/mytemplate.pt" - /> - - <static - name="static" - path="templates/static" - /> - -</configure> diff --git a/repoze/bfg/paster_templates/zodb/+package+/models.py b/repoze/bfg/paster_templates/zodb/+package+/models.py deleted file mode 100644 index 8dd0f5a49..000000000 --- a/repoze/bfg/paster_templates/zodb/+package+/models.py +++ /dev/null @@ -1,12 +0,0 @@ -from persistent.mapping import PersistentMapping - -class MyModel(PersistentMapping): - __parent__ = __name__ = None - -def appmaker(zodb_root): - if not 'app_root' in zodb_root: - app_root = MyModel() - zodb_root['app_root'] = app_root - import transaction - transaction.commit() - return zodb_root['app_root'] diff --git a/repoze/bfg/paster_templates/zodb/+package+/run.py_tmpl b/repoze/bfg/paster_templates/zodb/+package+/run.py_tmpl deleted file mode 100644 index c0a245089..000000000 --- a/repoze/bfg/paster_templates/zodb/+package+/run.py_tmpl +++ /dev/null @@ -1,23 +0,0 @@ -from repoze.bfg.configuration import Configurator -from repoze.zodbconn.finder import PersistentApplicationFinder -from {{package}}.models import appmaker - -def app(global_config, **settings): - """ This function returns a WSGI application. - - It is usually called by the PasteDeploy framework during - ``paster serve``. - """ - zodb_uri = settings.get('zodb_uri') - zcml_file = settings.get('configure_zcml', 'configure.zcml') - if zodb_uri is None: - raise ValueError("No 'zodb_uri' in application configuration.") - - finder = PersistentApplicationFinder(zodb_uri, appmaker) - def get_root(request): - return finder(request.environ) - config = Configurator(root_factory=get_root, settings=settings) - config.begin() - config.load_zcml(zcml_file) - config.end() - return config.make_wsgi_app() diff --git a/repoze/bfg/paster_templates/zodb/+package+/templates/mytemplate.pt b/repoze/bfg/paster_templates/zodb/+package+/templates/mytemplate.pt deleted file mode 100644 index 2aedcad9f..000000000 --- a/repoze/bfg/paster_templates/zodb/+package+/templates/mytemplate.pt +++ /dev/null @@ -1,99 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" - xmlns:tal="http://xml.zope.org/namespaces/tal"> -<head> -<meta http-equiv="content-type" content="text/html; charset=utf-8" /> -<title>${project} Application</title> -<meta name="keywords" content="python web application" /> -<meta name="description" content="repoze.bfg web application" /> -<link href="${request.application_url}/static/default.css" rel="stylesheet" type="text/css" /> -</head> -<body> -<!-- start header --> -<div id="logo"> - <h2><code>${project}</code>, a <code>repoze.bfg</code> application</h2> -</div> -<div id="header"> - <div id="menu"> - </div> -</div> -<!-- end header --> -<div id="wrapper"> - <!-- start page --> - <div id="page"> - <!-- start content --> - <div id="content"> - <div class="post"> - <h1 class="title">Welcome to <code>${project}</code>, an - application generated by the <a - href="http://bfg.repoze.org">repoze.bfg</a> web - application framework.</h1> - </div> - </div> - <!-- end content --> - <!-- start sidebar --> - <div id="sidebar"> - <ul> - <li id="search"> - <h2>Search<br/> <code>repoze.bfg</code> Documentation</h2> - <form method="get" - action="http://bfg.repoze.org/searchresults"> - <fieldset> - <input type="text" id="q" name="text" value="" /> - <input type="submit" id="x" value="Search" /> - </fieldset> - </form> - </li> - <li> - <h2><code>repoze.bfg</code> links</h2> - <ul> - <li><a - href="http://docs.repoze.org/bfg/current/#narrative-documentation">Narrative - Documentation</a> - </li> - <li> - <a - href="http://docs.repoze.org/bfg/current/#api-documentation">API - Documentation</a> - </li> - <li> - <a - href="http://docs.repoze.org/bfg/current/#tutorials">Tutorials</a> - </li> - <li> - <a - href="http://docs.repoze.org/bfg/current/#change-history">Change - History</a> - </li> - <li> - <a - href="http://docs.repoze.org/bfg/current/#sample-applications">Sample - Applications</a> - </li> - <li> - <a - href="http://docs.repoze.org/bfg/current/#support-and-development">Support - and Development</a> - </li> - <li> - <a - href="irc://irc.freenode.net#repoze">IRC Channel</a> - </li> - </ul> - </li> - </ul> - </div> - <!-- end sidebar --> - <div style="clear: both;"> </div> - </div> -</div> -<!-- end page --> -<!-- start footer --> -<div id="footer"> - <p id="legal">( c ) 2008. All Rights Reserved. Template design - by <a href="http://www.freecsstemplates.org/">Free CSS - Templates</a>.</p> -</div> -<!-- end footer --> -</body> -</html> diff --git a/repoze/bfg/paster_templates/zodb/+package+/templates/static/default.css b/repoze/bfg/paster_templates/zodb/+package+/templates/static/default.css deleted file mode 100644 index 41b3debde..000000000 --- a/repoze/bfg/paster_templates/zodb/+package+/templates/static/default.css +++ /dev/null @@ -1,380 +0,0 @@ -/* -Design by Free CSS Templates -http://www.freecsstemplates.org -Released for free under a Creative Commons Attribution 2.5 License -*/ - -body { - margin: 0; - padding: 0; - background: url(images/img01.gif) repeat-x left top; - font-size: 13px; - font-family: "Trebuchet MS", Georgia, "Times New Roman", Times, serif; - text-align: justify; - color: #FFFFFF; -} - -h1, h2, h3 { - margin: 0; - text-transform: lowercase; - font-weight: normal; - color: #FFFFFF; -} - -h1 { - letter-spacing: -1px; - font-size: 32px; -} - -h2 { - font-size: 23px; -} - -p, ul, ol { - margin: 0 0 2em 0; - text-align: justify; - line-height: 26px; -} - -a:link { - color: #8BD80E; -} - -a:hover, a:active { - text-decoration: none; - color: #8BD80E; -} - -a:visited { - color: #8BD80E; -} - -img { - border: none; -} - -img.left { - float: left; - margin-right: 15px; -} - -img.right { - float: right; - margin-left: 15px; -} - -/* Form */ - -form { - margin: 0; - padding: 0; -} - -fieldset { - margin: 0; - padding: 0; - border: none; -} - -legend { - display: none; -} - -input, textarea, select { - font-family: "Trebuchet MS", Arial, Helvetica, sans-serif; - font-size: 13px; - color: #333333; -} - -#wrapper { - margin: 0; - padding: 0; - background: #000000; -} - -/* Header */ - -#header { - width: 713px; - margin: 0 auto; - height: 42px; -} - -/* Menu */ - -#menu { - float: left; - width: 713px; - height: 50px; - background: url(images/img02.gif) no-repeat left top; -} - -#menu ul { - margin: 0; - padding: 0px 0 0 10px; - list-style: none; - line-height: normal; -} - -#menu li { - display: block; - float: left; -} - -#menu a { - display: block; - float: left; - background: url(images/img04.gif) no-repeat right 55%; - margin-top: 5px; - margin-right: 3px; - padding: 8px 17px; - text-decoration: none; - font-size: 13px; - color: #000000; -} - -#menu a:hover { - color: #000000; -} - -#menu .current_page_item a { - color: #000000; -} - -/** LOGO */ - -#logo { - width: 713px; - height: 80px; - margin: 0 auto; -} - -#logo h1, #logo h2 { - float: left; - margin: 0; - padding: 30px 0 0 0px; - line-height: normal; -} - -#logo h1 { - font-family: Georgia, "Times New Roman", Times, serif; - font-size:40px; -} - -#logo h1 a { - text-decoration: none; - color: #4C4C4C; -} - -#logo h1 a:hover { text-decoration: underline; } - -#logo h2 { - float: left; - padding: 45px 0 0 18px; - font: 18px Georgia, "Times New Roman", Times, serif; - color: #8BD80E; -} - -#logo p a { - text-decoration: none; - color: #8BD80E; -} - -#logo p a:hover { text-decoration: underline; } - - - -/* Page */ - -#page { - width: 663px; - margin: 0 auto; - background: #4C4C4C url(images/img03.gif) no-repeat left bottom; - padding: 0 25px; -} - -/* Content */ - -#content { - float: left; - width: 410px; - -} - -/* Post */ - -.post { - padding: 15px 0px; - margin-bottom: 20px; -} - -.post .title { - margin-bottom: 20px; - padding-bottom: 5px; -} - -.post h1 { - padding: 0px 0 0 0px; - background: url(images/img08.jpg) no-repeat left top; - font-size: 24px; - color: #FFFFFF; -} - -.post h2 { - padding: 0px 0 0 0px; - font-size: 22px; - color: #FFFFFF; -} - -.post .entry { -} - -.post .meta { - padding: 15px 15px 30px 0px; - font-family: Arial, Helvetica, sans-serif; - font-size: 11px; -} - -.post .meta p { - margin: 0; - padding-top: 15px; - line-height: normal; - color: #FFFFFF; -} - -.post .meta .byline { - float: left; -} - -.post .meta .links { - float: right; -} - -.post .meta .more { - padding: 0 10px 0 18px; -} - -.post .meta .comments { -} - -.post .meta b { - display: none; -} - - -/* Sidebar */ - -#sidebar { - width: 210px; - float: right; - margin: 0; - padding: 0; -} - -#sidebar ul { - margin: 0; - padding: 0; - list-style: none; -} - -#sidebar li { - margin-bottom: 40px; -} - -#sidebar li ul { -} - -#sidebar li li { - margin: 0; -} - -#sidebar h2 { - width: 250px; - padding: 8px 0 0 0px; - margin-bottom: 10px; - background: url(images/img07.jpg) no-repeat left top; - font-size: 20px; - color: #FFFFFF; -} - -/* Search */ - -#search { - -} - -#search h2 { - margin-bottom: 20px; -} - -#s { - width: 140px; - margin-right: 5px; - padding: 3px; - border: 1px solid #BED99C; -} - -#x { - padding: 3px; - border: none; - background: #8BD80E; - text-transform: lowercase; - font-size: 11px; - color: #FFFFFF; -} - -/* Boxes */ - -.box1 { - padding: 20px; -} - -.box2 { - color: #BABABA; -} - -.box2 h2 { - margin-bottom: 15px; - font-size: 16px; - color: #FFFFFF; -} - -.box2 ul { - margin: 0; - padding: 0; - list-style: none; -} - -.box2 a:link, .box2 a:hover, .box2 a:active, .box2 a:visited { - color: #EDEDED; -} - -/* Footer */ -#footer-wrap { -} - -#footer { - margin: 0 auto; - padding: 20px 0 10px 0; - background: #000000; -} - -html>body #footer { - height: auto; -} - -#footer p { - font-size: 11px; -} - -#legal { - clear: both; - padding-top: 17px; - text-align: center; - color: #FFFFFF; -} - -#legal a { - font-weight: normal; - color: #FFFFFF; -} diff --git a/repoze/bfg/paster_templates/zodb/+package+/templates/static/images/img01.gif b/repoze/bfg/paster_templates/zodb/+package+/templates/static/images/img01.gif Binary files differdeleted file mode 100644 index 5f082bd99..000000000 --- a/repoze/bfg/paster_templates/zodb/+package+/templates/static/images/img01.gif +++ /dev/null diff --git a/repoze/bfg/paster_templates/zodb/+package+/templates/static/images/img02.gif b/repoze/bfg/paster_templates/zodb/+package+/templates/static/images/img02.gif Binary files differdeleted file mode 100644 index 45a3ae976..000000000 --- a/repoze/bfg/paster_templates/zodb/+package+/templates/static/images/img02.gif +++ /dev/null diff --git a/repoze/bfg/paster_templates/zodb/+package+/templates/static/images/img03.gif b/repoze/bfg/paster_templates/zodb/+package+/templates/static/images/img03.gif Binary files differdeleted file mode 100644 index d92ea38f9..000000000 --- a/repoze/bfg/paster_templates/zodb/+package+/templates/static/images/img03.gif +++ /dev/null diff --git a/repoze/bfg/paster_templates/zodb/+package+/templates/static/images/img04.gif b/repoze/bfg/paster_templates/zodb/+package+/templates/static/images/img04.gif Binary files differdeleted file mode 100644 index 950c4af9d..000000000 --- a/repoze/bfg/paster_templates/zodb/+package+/templates/static/images/img04.gif +++ /dev/null diff --git a/repoze/bfg/paster_templates/zodb/+package+/templates/static/images/spacer.gif b/repoze/bfg/paster_templates/zodb/+package+/templates/static/images/spacer.gif Binary files differdeleted file mode 100644 index 5bfd67a2d..000000000 --- a/repoze/bfg/paster_templates/zodb/+package+/templates/static/images/spacer.gif +++ /dev/null diff --git a/repoze/bfg/paster_templates/zodb/+package+/templates/static/templatelicense.txt b/repoze/bfg/paster_templates/zodb/+package+/templates/static/templatelicense.txt deleted file mode 100644 index ccb6b06ab..000000000 --- a/repoze/bfg/paster_templates/zodb/+package+/templates/static/templatelicense.txt +++ /dev/null @@ -1,243 +0,0 @@ -Creative Commons </> - -Creative Commons Legal Code - -*Attribution 2.5* - -CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE -LEGAL SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN -ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION -ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE -INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM -ITS USE. - -/License/ - -THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE -COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY -COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS -AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED. - -BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE -TO BE BOUND BY THE TERMS OF THIS LICENSE. THE LICENSOR GRANTS YOU THE -RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS -AND CONDITIONS. - -*1. Definitions* - - 1. *"Collective Work"* means a work, such as a periodical issue, - anthology or encyclopedia, in which the Work in its entirety in - unmodified form, along with a number of other contributions, - constituting separate and independent works in themselves, are - assembled into a collective whole. A work that constitutes a - Collective Work will not be considered a Derivative Work (as - defined below) for the purposes of this License. - 2. *"Derivative Work"* means a work based upon the Work or upon the - Work and other pre-existing works, such as a translation, musical - arrangement, dramatization, fictionalization, motion picture - version, sound recording, art reproduction, abridgment, - condensation, or any other form in which the Work may be recast, - transformed, or adapted, except that a work that constitutes a - Collective Work will not be considered a Derivative Work for the - purpose of this License. For the avoidance of doubt, where the - Work is a musical composition or sound recording, the - synchronization of the Work in timed-relation with a moving image - ("synching") will be considered a Derivative Work for the purpose - of this License. - 3. *"Licensor"* means the individual or entity that offers the Work - under the terms of this License. - 4. *"Original Author"* means the individual or entity who created the - Work. - 5. *"Work"* means the copyrightable work of authorship offered under - the terms of this License. - 6. *"You"* means an individual or entity exercising rights under this - License who has not previously violated the terms of this License - with respect to the Work, or who has received express permission - from the Licensor to exercise rights under this License despite a - previous violation. - -*2. Fair Use Rights.* Nothing in this license is intended to reduce, -limit, or restrict any rights arising from fair use, first sale or other -limitations on the exclusive rights of the copyright owner under -copyright law or other applicable laws. - -*3. License Grant.* Subject to the terms and conditions of this License, -Licensor hereby grants You a worldwide, royalty-free, non-exclusive, -perpetual (for the duration of the applicable copyright) license to -exercise the rights in the Work as stated below: - - 1. to reproduce the Work, to incorporate the Work into one or more - Collective Works, and to reproduce the Work as incorporated in the - Collective Works; - 2. to create and reproduce Derivative Works; - 3. to distribute copies or phonorecords of, display publicly, perform - publicly, and perform publicly by means of a digital audio - transmission the Work including as incorporated in Collective Works; - 4. to distribute copies or phonorecords of, display publicly, perform - publicly, and perform publicly by means of a digital audio - transmission Derivative Works. - 5. - - For the avoidance of doubt, where the work is a musical composition: - - 1. *Performance Royalties Under Blanket Licenses*. Licensor - waives the exclusive right to collect, whether individually - or via a performance rights society (e.g. ASCAP, BMI, - SESAC), royalties for the public performance or public - digital performance (e.g. webcast) of the Work. - 2. *Mechanical Rights and Statutory Royalties*. Licensor waives - the exclusive right to collect, whether individually or via - a music rights agency or designated agent (e.g. Harry Fox - Agency), royalties for any phonorecord You create from the - Work ("cover version") and distribute, subject to the - compulsory license created by 17 USC Section 115 of the US - Copyright Act (or the equivalent in other jurisdictions). - 6. *Webcasting Rights and Statutory Royalties*. For the avoidance of - doubt, where the Work is a sound recording, Licensor waives the - exclusive right to collect, whether individually or via a - performance-rights society (e.g. SoundExchange), royalties for the - public digital performance (e.g. webcast) of the Work, subject to - the compulsory license created by 17 USC Section 114 of the US - Copyright Act (or the equivalent in other jurisdictions). - -The above rights may be exercised in all media and formats whether now -known or hereafter devised. The above rights include the right to make -such modifications as are technically necessary to exercise the rights -in other media and formats. All rights not expressly granted by Licensor -are hereby reserved. - -*4. Restrictions.*The license granted in Section 3 above is expressly -made subject to and limited by the following restrictions: - - 1. You may distribute, publicly display, publicly perform, or - publicly digitally perform the Work only under the terms of this - License, and You must include a copy of, or the Uniform Resource - Identifier for, this License with every copy or phonorecord of the - Work You distribute, publicly display, publicly perform, or - publicly digitally perform. You may not offer or impose any terms - on the Work that alter or restrict the terms of this License or - the recipients' exercise of the rights granted hereunder. You may - not sublicense the Work. You must keep intact all notices that - refer to this License and to the disclaimer of warranties. You may - not distribute, publicly display, publicly perform, or publicly - digitally perform the Work with any technological measures that - control access or use of the Work in a manner inconsistent with - the terms of this License Agreement. The above applies to the Work - as incorporated in a Collective Work, but this does not require - the Collective Work apart from the Work itself to be made subject - to the terms of this License. If You create a Collective Work, - upon notice from any Licensor You must, to the extent practicable, - remove from the Collective Work any credit as required by clause - 4(b), as requested. If You create a Derivative Work, upon notice - from any Licensor You must, to the extent practicable, remove from - the Derivative Work any credit as required by clause 4(b), as - requested. - 2. If you distribute, publicly display, publicly perform, or publicly - digitally perform the Work or any Derivative Works or Collective - Works, You must keep intact all copyright notices for the Work and - provide, reasonable to the medium or means You are utilizing: (i) - the name of the Original Author (or pseudonym, if applicable) if - supplied, and/or (ii) if the Original Author and/or Licensor - designate another party or parties (e.g. a sponsor institute, - publishing entity, journal) for attribution in Licensor's - copyright notice, terms of service or by other reasonable means, - the name of such party or parties; the title of the Work if - supplied; to the extent reasonably practicable, the Uniform - Resource Identifier, if any, that Licensor specifies to be - associated with the Work, unless such URI does not refer to the - copyright notice or licensing information for the Work; and in the - case of a Derivative Work, a credit identifying the use of the - Work in the Derivative Work (e.g., "French translation of the Work - by Original Author," or "Screenplay based on original Work by - Original Author"). Such credit may be implemented in any - reasonable manner; provided, however, that in the case of a - Derivative Work or Collective Work, at a minimum such credit will - appear where any other comparable authorship credit appears and in - a manner at least as prominent as such other comparable authorship - credit. - -*5. Representations, Warranties and Disclaimer* - -UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR -OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY -KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, -INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, -FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF -LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, -WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE -EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU. - -*6. Limitation on Liability.* EXCEPT TO THE EXTENT REQUIRED BY -APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL -THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY -DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF -LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - -*7. Termination* - - 1. This License and the rights granted hereunder will terminate - automatically upon any breach by You of the terms of this License. - Individuals or entities who have received Derivative Works or - Collective Works from You under this License, however, will not - have their licenses terminated provided such individuals or - entities remain in full compliance with those licenses. Sections - 1, 2, 5, 6, 7, and 8 will survive any termination of this License. - 2. Subject to the above terms and conditions, the license granted - here is perpetual (for the duration of the applicable copyright in - the Work). Notwithstanding the above, Licensor reserves the right - to release the Work under different license terms or to stop - distributing the Work at any time; provided, however that any such - election will not serve to withdraw this License (or any other - license that has been, or is required to be, granted under the - terms of this License), and this License will continue in full - force and effect unless terminated as stated above. - -*8. Miscellaneous* - - 1. Each time You distribute or publicly digitally perform the Work or - a Collective Work, the Licensor offers to the recipient a license - to the Work on the same terms and conditions as the license - granted to You under this License. - 2. Each time You distribute or publicly digitally perform a - Derivative Work, Licensor offers to the recipient a license to the - original Work on the same terms and conditions as the license - granted to You under this License. - 3. If any provision of this License is invalid or unenforceable under - applicable law, it shall not affect the validity or enforceability - of the remainder of the terms of this License, and without further - action by the parties to this agreement, such provision shall be - reformed to the minimum extent necessary to make such provision - valid and enforceable. - 4. No term or provision of this License shall be deemed waived and no - breach consented to unless such waiver or consent shall be in - writing and signed by the party to be charged with such waiver or - consent. - 5. This License constitutes the entire agreement between the parties - with respect to the Work licensed here. There are no - understandings, agreements or representations with respect to the - Work not specified here. Licensor shall not be bound by any - additional provisions that may appear in any communication from - You. This License may not be modified without the mutual written - agreement of the Licensor and You. - -Creative Commons is not a party to this License, and makes no warranty -whatsoever in connection with the Work. Creative Commons will not be -liable to You or any party on any legal theory for any damages -whatsoever, including without limitation any general, special, -incidental or consequential damages arising in connection to this -license. Notwithstanding the foregoing two (2) sentences, if Creative -Commons has expressly identified itself as the Licensor hereunder, it -shall have all rights and obligations of Licensor. - -Except for the limited purpose of indicating to the public that the Work -is licensed under the CCPL, neither party will use the trademark -"Creative Commons" or any related trademark or logo of Creative Commons -without the prior written consent of Creative Commons. Any permitted use -will be in compliance with Creative Commons' then-current trademark -usage guidelines, as may be published on its website or otherwise made -available upon request from time to time. - -Creative Commons may be contacted at http://creativecommons.org/ -<http://creativecommons.org>. - -« Back to Commons Deed <./> diff --git a/repoze/bfg/paster_templates/zodb/+package+/tests.py_tmpl b/repoze/bfg/paster_templates/zodb/+package+/tests.py_tmpl deleted file mode 100644 index 30da5c9b3..000000000 --- a/repoze/bfg/paster_templates/zodb/+package+/tests.py_tmpl +++ /dev/null @@ -1,19 +0,0 @@ -import unittest - -from repoze.bfg.configuration import Configurator -from repoze.bfg import testing - -class ViewTests(unittest.TestCase): - def setUp(self): - self.config = Configurator() - self.config.begin() - - def tearDown(self): - self.config.end() - - def test_my_view(self): - from {{package}}.views import my_view - request = testing.DummyRequest() - info = my_view(request) - self.assertEqual(info['project'], '{{project}}') - diff --git a/repoze/bfg/paster_templates/zodb/+package+/views.py_tmpl b/repoze/bfg/paster_templates/zodb/+package+/views.py_tmpl deleted file mode 100644 index 12ed8832d..000000000 --- a/repoze/bfg/paster_templates/zodb/+package+/views.py_tmpl +++ /dev/null @@ -1,2 +0,0 @@ -def my_view(request): - return {'project':'{{project}}'} diff --git a/repoze/bfg/paster_templates/zodb/+project+.ini_tmpl b/repoze/bfg/paster_templates/zodb/+project+.ini_tmpl deleted file mode 100644 index 993cec596..000000000 --- a/repoze/bfg/paster_templates/zodb/+project+.ini_tmpl +++ /dev/null @@ -1,22 +0,0 @@ -[DEFAULT] -debug = true - -[app:zodb] -use = egg:{{project}}#app -reload_templates = true -debug_authorization = false -debug_notfound = false -debug_templates = true -default_locale_name = en -zodb_uri = file://%(here)s/Data.fs?connection_cache_size=20000 - -[pipeline:main] -pipeline = - egg:repoze.zodbconn#closer - egg:repoze.tm#tm - zodb - -[server:main] -use = egg:Paste#http -host = 0.0.0.0 -port = 6543 diff --git a/repoze/bfg/paster_templates/zodb/CHANGES.txt_tmpl b/repoze/bfg/paster_templates/zodb/CHANGES.txt_tmpl deleted file mode 100644 index 35a34f332..000000000 --- a/repoze/bfg/paster_templates/zodb/CHANGES.txt_tmpl +++ /dev/null @@ -1,4 +0,0 @@ -0.0 ---- - -- Initial version diff --git a/repoze/bfg/paster_templates/zodb/README.txt_tmpl b/repoze/bfg/paster_templates/zodb/README.txt_tmpl deleted file mode 100644 index 0ddebfc3e..000000000 --- a/repoze/bfg/paster_templates/zodb/README.txt_tmpl +++ /dev/null @@ -1,4 +0,0 @@ -{{project}} README - - - diff --git a/repoze/bfg/paster_templates/zodb/setup.cfg_tmpl b/repoze/bfg/paster_templates/zodb/setup.cfg_tmpl deleted file mode 100644 index 5bec29823..000000000 --- a/repoze/bfg/paster_templates/zodb/setup.cfg_tmpl +++ /dev/null @@ -1,27 +0,0 @@ -[nosetests] -match=^test -nocapture=1 -cover-package={{package}} -with-coverage=1 -cover-erase=1 - -[compile_catalog] -directory = {{package}}/locale -domain = {{project}} -statistics = true - -[extract_messages] -add_comments = TRANSLATORS: -output_file = {{package}}/locale/{{project}}.pot -width = 80 - -[init_catalog] -domain = {{project}} -input_file = {{package}}/locale/{{project}}.pot -output_dir = {{package}}/locale - -[update_catalog] -domain = {{project}} -input_file = {{package}}/locale/{{project}}.pot -output_dir = {{package}}/locale -previous = true diff --git a/repoze/bfg/paster_templates/zodb/setup.py_tmpl b/repoze/bfg/paster_templates/zodb/setup.py_tmpl deleted file mode 100644 index dba0e4ac7..000000000 --- a/repoze/bfg/paster_templates/zodb/setup.py_tmpl +++ /dev/null @@ -1,41 +0,0 @@ -import os - -from setuptools import setup, find_packages - -here = os.path.abspath(os.path.dirname(__file__)) -README = open(os.path.join(here, 'README.txt')).read() -CHANGES = open(os.path.join(here, 'CHANGES.txt')).read() - -requires = [ - 'repoze.bfg', - 'repoze.zodbconn', - 'repoze.tm', - 'ZODB3', - ] - -setup(name='{{project}}', - version='0.0', - description='{{project}}', - long_description=README + '\n\n' + CHANGES, - classifiers=[ - "Programming Language :: Python", - "Framework :: BFG", - "Topic :: Internet :: WWW/HTTP", - "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", - ], - author='', - author_email='', - url='', - keywords='web wsgi bfg', - packages=find_packages(), - include_package_data=True, - zip_safe=False, - install_requires = requires, - tests_require= requires, - test_suite="{{package}}", - entry_points = """\ - [paste.app_factory] - app = {{package}}.run:app - """ - ) - diff --git a/repoze/bfg/path.py b/repoze/bfg/path.py deleted file mode 100644 index b5850968f..000000000 --- a/repoze/bfg/path.py +++ /dev/null @@ -1,69 +0,0 @@ -import os -import pkg_resources -import sys -import imp - -ignore_types = [ imp.C_EXTENSION, imp.C_BUILTIN ] -init_names = [ '__init__%s' % x[0] for x in imp.get_suffixes() if - x[0] and x[2] not in ignore_types ] - -def caller_path(path, level=2): - if not os.path.isabs(path): - module = caller_module(level+1) - prefix = package_path(module) - path = os.path.join(prefix, path) - return path - -def caller_module(level=2): - module_globals = sys._getframe(level).f_globals - module_name = module_globals['__name__'] - module = sys.modules[module_name] - return module - -def package_name(pkg_or_module): - """ If this function is passed a module, return the dotted Python - package name of the package in which the module lives. If this - function is passed a package, return the dotted Python package - name of the package itself.""" - if pkg_or_module is None: - return '__main__' - pkg_filename = pkg_or_module.__file__ - pkg_name = pkg_or_module.__name__ - splitted = os.path.split(pkg_filename) - if splitted[-1] in init_names: - # it's a package - return pkg_name - return pkg_name.rsplit('.', 1)[0] - -def package_of(pkg_or_module): - """ Return the package of a module or return the package itself """ - pkg_name = package_name(pkg_or_module) - __import__(pkg_name) - return sys.modules[pkg_name] - -def caller_package(level=2, caller_module=caller_module): - # caller_module in arglist for tests - module = caller_module(level+1) - if '__init__.py' in getattr(module, '__file__', ''): # empty at >>> - # Module is a package - return module - # Go up one level to get package - package_name = module.__name__.rsplit('.', 1)[0] - return sys.modules[package_name] - -def package_path(package): - # computing the abspath is actually kinda expensive so we memoize - # the result - prefix = getattr(package, '__bfg_abspath__', None) - if prefix is None: - prefix = pkg_resources.resource_filename(package.__name__, '') - # pkg_resources doesn't care whether we feed it a package - # name or a module name within the package, the result - # will be the same: a directory name to the package itself - try: - package.__bfg_abspath__ = prefix - except: - # this is only an optimization, ignore any error - pass - return prefix - diff --git a/repoze/bfg/registry.py b/repoze/bfg/registry.py deleted file mode 100644 index e935ac165..000000000 --- a/repoze/bfg/registry.py +++ /dev/null @@ -1,24 +0,0 @@ -from zope.component.registry import Components - -class Registry(Components, dict): - - # for optimization purposes, if no listeners are listening, don't try - # to notify them - has_listeners = False - - def registerSubscriptionAdapter(self, *arg, **kw): - result = Components.registerSubscriptionAdapter(self, *arg, **kw) - self.has_listeners = True - return result - - def registerHandler(self, *arg, **kw): - result = Components.registerHandler(self, *arg, **kw) - self.has_listeners = True - return result - - def notify(self, *events): - if self.has_listeners: - # iterating over subscribers assures they get executed - [ _ for _ in self.subscribers(events, None) ] - -global_registry = Registry('global') diff --git a/repoze/bfg/renderers.py b/repoze/bfg/renderers.py deleted file mode 100644 index 00413e3fe..000000000 --- a/repoze/bfg/renderers.py +++ /dev/null @@ -1,320 +0,0 @@ -import os -import pkg_resources -import threading - -from webob import Response - -from zope.deprecation import deprecated - -from repoze.bfg.interfaces import IRendererGlobalsFactory -from repoze.bfg.interfaces import IRendererFactory -from repoze.bfg.interfaces import IResponseFactory -from repoze.bfg.interfaces import ITemplateRenderer - -from repoze.bfg.compat import json -from repoze.bfg.path import caller_package -from repoze.bfg.settings import get_settings -from repoze.bfg.threadlocal import get_current_registry -from repoze.bfg.resource import resolve_resource_spec -from repoze.bfg.decorator import reify - -# API - -def render(renderer_name, value, request=None, package=None): - """ Using the renderer specified as ``renderer_name`` (a template - or a static renderer) render the value (or set of values) present - in ``value``. Return the result of the renderer's ``__call__`` - method (usually a string or Unicode). - - If the renderer name refers to a file on disk (such as when the - renderer is a template), it's usually best to supply the name as a - :term:`resource specification` - (e.g. ``packagename:path/to/template.pt``). - - You may supply a relative resource spec as ``renderer_name``. If - the ``package`` argument is supplied, a relative renderer path - will be converted to an absolute resource specification by - combining the package supplied as ``package`` with the relative - resource specification supplied as ``renderer_name``. If you do - not supply a ``package`` (or ``package`` is ``None``) the package - name of the *caller* of this function will be used as the package. - - The ``value`` provided will be supplied as the input to the - renderer. Usually, for template renderings, this should be a - dictionary. For other renderers, this will need to be whatever - sort of value the renderer expects. - - The 'system' values supplied to the renderer will include a basic - set of top-level system names, such as ``request``, ``context``, - and ``renderer_name``. If :term:`renderer globals` have been - specified, these will also be used to agument the value. - - Supply a ``request`` parameter in order to provide the renderer - with the most correct 'system' values (``request`` and ``context`` - in particular). - - .. note:: This API is new in :mod:`repoze.bfg` 1.3. - - """ - try: - registry = request.registry - except AttributeError: - registry = None - if package is None: - package = caller_package() - renderer = RendererHelper(renderer_name, package=package, registry=registry) - return renderer.render(value, None, request=request) - -def render_to_response(renderer_name, value, request=None, package=None): - """ Using the renderer specified as ``renderer_name`` (a template - or a static renderer) render the value (or set of values) using - the result of the renderer's ``__call__`` method (usually a string - or Unicode) as the response body. - - If the renderer name refers to a file on disk (such as when the - renderer is a template), it's usually best to supply the name as a - :term:`resource specification`. - - You may supply a relative resource spec as ``renderer_name``. If - the ``package`` argument is supplied, a relative renderer name - will be converted to an absolute resource specification by - combining the package supplied as ``package`` with the relative - resource specification supplied as ``renderer_name``. If you do - not supply a ``package`` (or ``package`` is ``None``) the package - name of the *caller* of this function will be used as the package. - - The ``value`` provided will be supplied as the input to the - renderer. Usually, for template renderings, this should be a - dictionary. For other renderers, this will need to be whatever - sort of value the renderer expects. - - The 'system' values supplied to the renderer will include a basic - set of top-level system names, such as ``request``, ``context``, - and ``renderer_name``. If :term:`renderer globals` have been - specified, these will also be used to agument the value. - - Supply a ``request`` parameter in order to provide the renderer - with the most correct 'system' values (``request`` and ``context`` - in particular). - - .. note:: This API is new in :mod:`repoze.bfg` 1.3. - - """ - try: - registry = request.registry - except AttributeError: - registry = None - if package is None: - package = caller_package() - renderer = RendererHelper(renderer_name, package=package, registry=registry) - return renderer.render_to_response(value, None, request=request) - -def get_renderer(renderer_name, package=None): - """ Return the renderer object for the renderer named as - ``renderer_name``. - - You may supply a relative resource spec as ``renderer_name``. If - the ``package`` argument is supplied, a relative renderer name - will be converted to an absolute resource specification by - combining the package supplied as ``package`` with the relative - resource specification supplied as ``renderer_name``. If you do - not supply a ``package`` (or ``package`` is ``None``) the package - name of the *caller* of this function will be used as the package. - """ - if package is None: - package = caller_package() - renderer = RendererHelper(renderer_name, package=package) - return renderer.get_renderer() - - -# concrete renderer factory implementations (also API) - -def json_renderer_factory(name): - def _render(value, system): - request = system.get('request') - if request is not None: - if not hasattr(request, 'response_content_type'): - request.response_content_type = 'application/json' - return json.dumps(value) - return _render - -def string_renderer_factory(name): - def _render(value, system): - if not isinstance(value, basestring): - value = str(value) - request = system.get('request') - if request is not None: - if not hasattr(request, 'response_content_type'): - request.response_content_type = 'text/plain' - return value - return _render - -# utility functions, not API - -# Lock to prevent simultaneous registry writes; used in -# template_renderer_factory. template_renderer_factory may be called -# at runtime, from more than a single thread. -registry_lock = threading.Lock() - -def template_renderer_factory(spec, impl, lock=registry_lock): - reg = get_current_registry() - if os.path.isabs(spec): - # 'spec' is an absolute filename - if not os.path.exists(spec): - raise ValueError('Missing template file: %s' % spec) - renderer = reg.queryUtility(ITemplateRenderer, name=spec) - if renderer is None: - renderer = impl(spec) - # cache the template - try: - lock.acquire() - reg.registerUtility(renderer, ITemplateRenderer, name=spec) - finally: - lock.release() - else: - # spec is a package:relpath resource spec - renderer = reg.queryUtility(ITemplateRenderer, name=spec) - if renderer is None: - try: - package_name, filename = spec.split(':', 1) - except ValueError: # pragma: no cover - # somehow we were passed a relative pathname; this - # should die - package_name = caller_package(4).__name__ - filename = spec - abspath = pkg_resources.resource_filename(package_name, filename) - if not pkg_resources.resource_exists(package_name, filename): - raise ValueError( - 'Missing template resource: %s (%s)' % (spec, abspath)) - renderer = impl(abspath) - if not _reload_resources(): - # cache the template - try: - lock.acquire() - reg.registerUtility(renderer, ITemplateRenderer, name=spec) - finally: - lock.release() - - return renderer - -def _reload_resources(): - settings = get_settings() - return settings and settings.get('reload_resources') - -def renderer_from_name(path, package=None): - return RendererHelper(path, package=package).get_renderer() - -def rendered_response(renderer, result, view, context, request, renderer_name): - # XXX: deprecated, left here only to not break old code; use - # render_to_response instead - if ( hasattr(result, 'app_iter') and hasattr(result, 'headerlist') - and hasattr(result, 'status') ): - return result - - system = {'view':view, 'renderer_name':renderer_name, - 'context':context, 'request':request} - - helper = RendererHelper(renderer_name) - helper.renderer = renderer - return helper.render_to_response(result, system, request=request) - -deprecated('rendered_response', - "('repoze.bfg.renderers.rendered_response' is not a public API; it is " - "officially deprecated as of repoze.bfg 1.3; " - "use repoze.bfg.renderers.render_to_response instead')", - ) - -class RendererHelper(object): - def __init__(self, renderer_name, registry=None, package=None): - if registry is None: - registry = get_current_registry() - self.registry = registry - self.package = package - if renderer_name is None: - factory = registry.queryUtility(IRendererFactory) - renderer_type = None - else: - if '.' in renderer_name: - renderer_type = os.path.splitext(renderer_name)[1] - renderer_name = self.resolve_spec(renderer_name) - else: - renderer_type = renderer_name - renderer_name = renderer_name - factory = registry.queryUtility(IRendererFactory, - name=renderer_type) - self.renderer_name = renderer_name - self.renderer_type = renderer_type - self.factory = factory - - @reify - def renderer(self): - if self.factory is None: - raise ValueError('No such renderer factory %s' % str(self.renderer_type)) - return self.factory(self.renderer_name) - - def resolve_spec(self, path_or_spec): - if path_or_spec is None: - return path_or_spec - - package, filename = resolve_resource_spec(path_or_spec, - self.package) - if package is None: - return filename # absolute filename - return '%s:%s' % (package, filename) - - def get_renderer(self): - return self.renderer - - def render(self, value, system_values, request=None): - renderer = self.renderer - if system_values is None: - system_values = { - 'view':None, - 'renderer_name':self.renderer_name, - 'context':getattr(request, 'context', None), - 'request':request, - } - - registry = self.registry - globals_factory = registry.queryUtility(IRendererGlobalsFactory) - - if globals_factory is not None: - renderer_globals = globals_factory(system_values) - if renderer_globals: - system_values.update(renderer_globals) - - result = renderer(value, system_values) - return result - - def render_to_response(self, value, system_values, request=None): - result = self.render(value, system_values, request=request) - return self._make_response(result, request) - - def _make_response(self, result, request): - registry = self.registry - response_factory = registry.queryUtility(IResponseFactory, - default=Response) - - response = response_factory(result) - - if request is not None: - attrs = request.__dict__ - content_type = attrs.get('response_content_type', None) - if content_type is not None: - response.content_type = content_type - headerlist = attrs.get('response_headerlist', None) - if headerlist is not None: - for k, v in headerlist: - response.headers.add(k, v) - status = attrs.get('response_status', None) - if status is not None: - response.status = status - charset = attrs.get('response_charset', None) - if charset is not None: - response.charset = charset - cache_for = attrs.get('response_cache_for', None) - if cache_for is not None: - response.cache_expires = cache_for - - return response - diff --git a/repoze/bfg/request.py b/repoze/bfg/request.py deleted file mode 100644 index f32a7a40c..000000000 --- a/repoze/bfg/request.py +++ /dev/null @@ -1,229 +0,0 @@ -from zope.deprecation import deprecated -from zope.interface import implements -from zope.interface.interface import InterfaceClass - -from webob import Request as WebobRequest - -from repoze.bfg.interfaces import IRequest - -class Request(WebobRequest): - """ - A subclass of the :term:`WebOb` Request class. An instance of - this class is created by the :term:`router` and is provided to a - view callable (and to other subsystems) as the ``request`` - argument. - - The documentation below (save for the ``add_response_callback`` - and ''add_finished_callback`` methods, which are defined in this - subclass itself, and the attributes ``context``, ``registry``, - ``root``, ``subpath``, ``traversed``, ``view_name``, - ``virtual_root`` , and ``virtual_root_path``, each of which is - added to the request at by the :term:`router` at request ingress - time) are autogenerated from the WebOb source code used when this - documentation was generated. - - Due to technical constraints, we can't yet display the WebOb - version number from which this documentation is autogenerated, but - it will be the 'prevailing WebOb version' at the time of the - release of this :mod:`repoze.bfg` version. See - http://http://pythonpaste.org/webob/ for further information. - """ - implements(IRequest) - response_callbacks = () - finished_callbacks = () - exception = None - - def add_response_callback(self, callback): - """ - Add a callback to the set of callbacks to be called by the - :term:`router` at a point after a :term:`response` object is - successfully created. :mod:`repoze.bfg` does not have a - global response object: this functionality allows an - application to register an action to be performed against the - response once one is created. - - A 'callback' is a callable which accepts two positional - parameters: ``request`` and ``response``. For example: - - .. code-block:: python - :linenos: - - def cache_callback(request, response): - 'Set the cache_control max_age for the response' - response.cache_control.max_age = 360 - request.add_response_callback(cache_callback) - - Response callbacks are called in the order they're added - (first-to-most-recently-added). No response callback is - called if an exception happens in application code, or if the - response object returned by :term:`view` code is invalid. - - All response callbacks are called *after* the - :class:`repoze.bfg.interfaces.INewResponse` event is sent. - - Errors raised by callbacks are not handled specially. They - will be propagated to the caller of the :mod:`repoze.bfg` - router application. - - .. note: ``add_response_callback`` is new in :mod:`repoze.bfg` - 1.3. - - See also: :ref:`using_response_callbacks`. - """ - - callbacks = self.response_callbacks - if not callbacks: - callbacks = [] - callbacks.append(callback) - self.response_callbacks = callbacks - - def _process_response_callbacks(self, response): - callbacks = self.response_callbacks - while callbacks: - callback = callbacks.pop(0) - callback(self, response) - - def add_finished_callback(self, callback): - """ - Add a callback to the set of callbacks to be called - unconditionally by the :term:`router` at the very end of - request processing. - - ``callback`` is a callable which accepts a single positional - parameter: ``request``. For example: - - .. code-block:: python - :linenos: - - import transaction - - def commit_callback(request): - '''commit or abort the transaction associated with request''' - if request.exception is not None: - transaction.abort() - else: - transaction.commit() - request.add_finished_callback(commit_callback) - - Finished callbacks are called in the order they're added ( - first- to most-recently- added). Finished callbacks (unlike - response callbacks) are *always* called, even if an exception - happens in application code that prevents a response from - being generated. - - The set of finished callbacks associated with a request are - called *very late* in the processing of that request; they are - essentially the last thing called by the :term:`router`. They - are called after response processing has already occurred in a - top-level ``finally:`` block within the router request - processing code. As a result, mutations performed to the - ``request`` provided to a finished callback will have no - meaningful effect, because response processing will have - already occurred, and the request's scope will expire almost - immediately after all finished callbacks have been processed. - - Errors raised by finished callbacks are not handled specially. - They will be propagated to the caller of the :mod:`repoze.bfg` - router application. - - .. note: ``add_finished_callback`` is new in :mod:`repoze.bfg` - 1.3. - - See also: :ref:`using_finished_callbacks`. - """ - - callbacks = self.finished_callbacks - if not callbacks: - callbacks = [] - callbacks.append(callback) - self.finished_callbacks = callbacks - - def _process_finished_callbacks(self): - callbacks = self.finished_callbacks - while callbacks: - callback = callbacks.pop(0) - callback(self) - - # override default WebOb "environ['adhoc_attr']" mutation behavior - __getattr__ = object.__getattribute__ - __setattr__ = object.__setattr__ - __delattr__ = object.__delattr__ - - # b/c dict interface for "root factory" code that expects a bare - # environ. Explicitly omitted dict methods: clear (unnecessary), - # copy (implemented by WebOb), fromkeys (unnecessary) - - def __contains__(self, k): - return self.environ.__contains__(k) - - def __delitem__(self, k): - return self.environ.__delitem__(k) - - def __getitem__(self, k): - return self.environ.__getitem__(k) - - def __iter__(self): - return iter(self.environ) - - def __setitem__(self, k, v): - self.environ[k] = v - - def get(self, k, default=None): - return self.environ.get(k, default) - - def has_key(self, k): - return self.environ.has_key(k) - - def items(self): - return self.environ.items() - - def iteritems(self): - return self.environ.iteritems() - - def iterkeys(self): - return self.environ.iterkeys() - - def itervalues(self): - return self.environ.itervalues() - - def keys(self): - return self.environ.keys() - - def pop(self, k): - return self.environ.pop(k) - - def popitem(self): - return self.environ.popitem() - - def setdefault(self, v, default): - return self.environ.setdefault(v, default) - - def update(self, v, **kw): - return self.environ.update(v, **kw) - - def values(self): - return self.environ.values() - -def route_request_iface(name, bases=()): - iface = InterfaceClass('%s_IRequest' % name, bases=bases) - # for exception view lookups - iface.combined = InterfaceClass('%s_combined_IRequest' % name, - bases=(iface, IRequest)) - return iface - -def add_global_response_headers(request, headerlist): - def add_headers(request, response): - for k, v in headerlist: - response.headerlist.append((k, v)) - request.add_response_callback(add_headers) - -from repoze.bfg.threadlocal import get_current_request as get_request # b/c - -get_request # prevent PyFlakes complaints - -deprecated('get_request', - 'As of repoze.bfg 1.0, any import of get_request from' - '``repoze.bfg.request`` is ' - 'deprecated. Use ``from repoze.bfg.threadlocal import ' - 'get_current_request instead.') - diff --git a/repoze/bfg/resource.py b/repoze/bfg/resource.py deleted file mode 100644 index da49f16ec..000000000 --- a/repoze/bfg/resource.py +++ /dev/null @@ -1,201 +0,0 @@ -import os -import pkg_resources - -from zope.interface import implements - -from repoze.bfg.interfaces import IPackageOverrides - -from repoze.bfg.path import package_path -from repoze.bfg.path import package_name -from repoze.bfg.threadlocal import get_current_registry - -class OverrideProvider(pkg_resources.DefaultProvider): - def __init__(self, module): - pkg_resources.DefaultProvider.__init__(self, module) - self.module_name = module.__name__ - - def _get_overrides(self): - reg = get_current_registry() - overrides = reg.queryUtility(IPackageOverrides, self.module_name) - return overrides - - def get_resource_filename(self, manager, resource_name): - """ Return a true filesystem path for resource_name, - co-ordinating the extraction with manager, if the resource - must be unpacked to the filesystem. - """ - overrides = self._get_overrides() - if overrides is not None: - filename = overrides.get_filename(resource_name) - if filename is not None: - return filename - return pkg_resources.DefaultProvider.get_resource_filename( - self, manager, resource_name) - - def get_resource_stream(self, manager, resource_name): - """ Return a readable file-like object for resource_name.""" - overrides = self._get_overrides() - if overrides is not None: - stream = overrides.get_stream(resource_name) - if stream is not None: - return stream - return pkg_resources.DefaultProvider.get_resource_stream( - self, manager, resource_name) - - def get_resource_string(self, manager, resource_name): - """ Return a string containing the contents of resource_name.""" - overrides = self._get_overrides() - if overrides is not None: - string = overrides.get_string(resource_name) - if string is not None: - return string - return pkg_resources.DefaultProvider.get_resource_string( - self, manager, resource_name) - - def has_resource(self, resource_name): - overrides = self._get_overrides() - if overrides is not None: - result = overrides.has_resource(resource_name) - if result is not None: - return result - return pkg_resources.DefaultProvider.has_resource( - self, resource_name) - - def resource_isdir(self, resource_name): - overrides = self._get_overrides() - if overrides is not None: - result = overrides.isdir(resource_name) - if result is not None: - return result - return pkg_resources.DefaultProvider.resource_isdir( - self, resource_name) - - def resource_listdir(self, resource_name): - overrides = self._get_overrides() - if overrides is not None: - result = overrides.listdir(resource_name) - if result is not None: - return result - return pkg_resources.DefaultProvider.resource_listdir( - self, resource_name) - -class PackageOverrides: - implements(IPackageOverrides) - # pkg_resources arg in kw args below for testing - def __init__(self, package, pkg_resources=pkg_resources): - if hasattr(package, '__loader__') and not isinstance(package.__loader__, - self.__class__): - raise TypeError('Package %s already has a non-%s __loader__ ' - '(probably a module in a zipped egg)' % - (package, self.__class__)) - # We register ourselves as a __loader__ *only* to support the - # setuptools _find_adapter adapter lookup; this class doesn't - # actually support the PEP 302 loader "API". This is - # excusable due to the following statement in the spec: - # ... Loader objects are not - # required to offer any useful functionality (any such functionality, - # such as the zipimport get_data() method mentioned above, is - # optional)... - # A __loader__ attribute is basically metadata, and setuptools - # uses it as such. - package.__loader__ = self - # we call register_loader_type for every instantiation of this - # class; that's OK, it's idempotent to do it more than once. - pkg_resources.register_loader_type(self.__class__, OverrideProvider) - self.overrides = [] - self.overridden_package_name = package.__name__ - - def insert(self, path, package, prefix): - if not path or path.endswith('/'): - override = DirectoryOverride(path, package, prefix) - else: - override = FileOverride(path, package, prefix) - self.overrides.insert(0, override) - return override - - def search_path(self, resource_name): - for override in self.overrides: - o = override(resource_name) - if o is not None: - package, name = o - yield package, name - - def get_filename(self, resource_name): - for package, rname in self.search_path(resource_name): - if pkg_resources.resource_exists(package, rname): - return pkg_resources.resource_filename(package, rname) - - def get_stream(self, resource_name): - for package, rname in self.search_path(resource_name): - if pkg_resources.resource_exists(package, rname): - return pkg_resources.resource_stream(package, rname) - - def get_string(self, resource_name): - for package, rname in self.search_path(resource_name): - if pkg_resources.resource_exists(package, rname): - return pkg_resources.resource_string(package, rname) - - def has_resource(self, resource_name): - for package, rname in self.search_path(resource_name): - if pkg_resources.resource_exists(package, rname): - return True - - def isdir(self, resource_name): - for package, rname in self.search_path(resource_name): - if pkg_resources.resource_exists(package, rname): - return pkg_resources.resource_isdir(package, rname) - - def listdir(self, resource_name): - for package, rname in self.search_path(resource_name): - if pkg_resources.resource_exists(package, rname): - return pkg_resources.resource_listdir(package, rname) - - -class DirectoryOverride: - def __init__(self, path, package, prefix): - self.path = path - self.package = package - self.prefix = prefix - self.pathlen = len(self.path) - - def __call__(self, resource_name): - if resource_name.startswith(self.path): - name = '%s%s' % (self.prefix, resource_name[self.pathlen:]) - return self.package, name - -class FileOverride: - def __init__(self, path, package, prefix): - self.path = path - self.package = package - self.prefix = prefix - - def __call__(self, resource_name): - if resource_name == self.path: - return self.package, self.prefix - -def resolve_resource_spec(spec, pname='__main__'): - if pname and not isinstance(pname, basestring): - pname = pname.__name__ # as package - if os.path.isabs(spec): - return None, spec - filename = spec - if ':' in spec: - pname, filename = spec.split(':', 1) - elif pname is None: - pname, filename = None, spec - return pname, filename - -def resource_spec_from_abspath(abspath, package): - """ Try to convert an absolute path to a resource in a package to - a resource specification if possible; otherwise return the - absolute path. """ - if getattr(package, '__name__', None) == '__main__': - return abspath - pp = package_path(package) + os.path.sep - if abspath.startswith(pp): - relpath = abspath[len(pp):] - return '%s:%s' % (package_name(package), - relpath.replace(os.path.sep, '/')) - return abspath - - diff --git a/repoze/bfg/router.py b/repoze/bfg/router.py deleted file mode 100644 index 7b3bcb75e..000000000 --- a/repoze/bfg/router.py +++ /dev/null @@ -1,189 +0,0 @@ -from zope.interface import implements -from zope.interface import providedBy - -from repoze.bfg.interfaces import IDebugLogger -from repoze.bfg.interfaces import IExceptionViewClassifier -from repoze.bfg.interfaces import IRequest -from repoze.bfg.interfaces import IRootFactory -from repoze.bfg.interfaces import IRouteRequest -from repoze.bfg.interfaces import IRouter -from repoze.bfg.interfaces import IRequestFactory -from repoze.bfg.interfaces import IRoutesMapper -from repoze.bfg.interfaces import ISettings -from repoze.bfg.interfaces import ITraverser -from repoze.bfg.interfaces import IView -from repoze.bfg.interfaces import IViewClassifier - -from repoze.bfg.configuration import make_app # b/c import -from repoze.bfg.events import ContextFound -from repoze.bfg.events import NewRequest -from repoze.bfg.events import NewResponse -from repoze.bfg.exceptions import NotFound -from repoze.bfg.request import Request -from repoze.bfg.threadlocal import manager -from repoze.bfg.traversal import DefaultRootFactory -from repoze.bfg.traversal import ModelGraphTraverser - -make_app # prevent pyflakes from complaining - -class Router(object): - implements(IRouter) - - debug_notfound = False - threadlocal_manager = manager - - def __init__(self, registry): - q = registry.queryUtility - self.logger = q(IDebugLogger) - self.root_factory = q(IRootFactory, default=DefaultRootFactory) - self.routes_mapper = q(IRoutesMapper) - self.request_factory = q(IRequestFactory, default=Request) - self.root_policy = self.root_factory # b/w compat - self.registry = registry - settings = q(ISettings) - if settings is not None: - self.debug_notfound = settings['debug_notfound'] - - def __call__(self, environ, start_response): - """ - Accept ``environ`` and ``start_response``; create a - :term:`request` and route the request to a :mod:`repoze.bfg` - view based on introspection of :term:`view configuration` - within the application registry; call ``start_response`` and - return an iterable. - """ - registry = self.registry - adapters = registry.adapters - has_listeners = registry.has_listeners - logger = self.logger - manager = self.threadlocal_manager - request = None - threadlocals = {'registry':registry, 'request':request} - manager.push(threadlocals) - - try: # matches finally: manager.pop() - - try: # matches finally: ... call request finished callbacks ... - - # create the request - request = self.request_factory(environ) - context = None - threadlocals['request'] = request - attrs = request.__dict__ - attrs['registry'] = registry - has_listeners and registry.notify(NewRequest(request)) - request_iface = IRequest - - try: - # find the root object - root_factory = self.root_factory - if self.routes_mapper is not None: - info = self.routes_mapper(request) - match, route = info['match'], info['route'] - if route is not None: - # TODO: kill off bfg.routes.* environ keys - # when traverser requires request arg, and - # cant cope with environ anymore (likely 1.4+) - environ['bfg.routes.route'] = route - environ['bfg.routes.matchdict'] = match - attrs['matchdict'] = match - attrs['matched_route'] = route - request_iface = registry.queryUtility( - IRouteRequest, - name=route.name, - default=IRequest) - root_factory = route.factory or self.root_factory - - root = root_factory(request) - attrs['root'] = root - - # find a context - traverser = adapters.queryAdapter(root, ITraverser) - if traverser is None: - traverser = ModelGraphTraverser(root) - tdict = traverser(request) - context, view_name, subpath, traversed, vroot, vroot_path =( - tdict['context'], tdict['view_name'], tdict['subpath'], - tdict['traversed'], tdict['virtual_root'], - tdict['virtual_root_path']) - attrs.update(tdict) - has_listeners and registry.notify(ContextFound(request)) - - # find a view callable - context_iface = providedBy(context) - view_callable = adapters.lookup( - (IViewClassifier, request_iface, context_iface), - IView, name=view_name, default=None) - - # invoke the view callable - if view_callable is None: - if self.debug_notfound: - msg = ( - 'debug_notfound of url %s; path_info: %r, ' - 'context: %r, view_name: %r, subpath: %r, ' - 'traversed: %r, root: %r, vroot: %r, ' - 'vroot_path: %r' % ( - request.url, request.path_info, context, - view_name, - subpath, traversed, root, vroot, vroot_path) - ) - logger and logger.debug(msg) - else: - msg = request.path_info - # XXX repoze.bfg.message should be deprecated - environ['repoze.bfg.message'] = msg - raise NotFound(msg) - else: - response = view_callable(context, request) - - # handle exceptions raised during root finding and view-exec - except Exception, why: - attrs['exception'] = why - - for_ = (IExceptionViewClassifier, - request_iface.combined, - providedBy(why)) - view_callable = adapters.lookup(for_, IView, default=None) - - if view_callable is None: - raise - - # XXX r.b.message should be deprecated - try: - msg = why[0] - except: - msg = '' - environ['repoze.bfg.message'] = msg - - response = view_callable(why, request) - - # process the response - - has_listeners and registry.notify(NewResponse(request,response)) - - if request.response_callbacks: - request._process_response_callbacks(response) - - try: - headers = response.headerlist - app_iter = response.app_iter - status = response.status - except AttributeError: - raise ValueError( - 'Non-response object returned from view named %s ' - '(and no renderer): %r' % (view_name, response)) - - finally: - if request is not None and request.finished_callbacks: - request._process_finished_callbacks() - - start_response(status, headers) - return app_iter - - finally: - manager.pop() - - - - - diff --git a/repoze/bfg/scripting.py b/repoze/bfg/scripting.py deleted file mode 100644 index ca0bea597..000000000 --- a/repoze/bfg/scripting.py +++ /dev/null @@ -1,25 +0,0 @@ -from repoze.bfg.request import Request -from repoze.bfg.interfaces import IRequestFactory - -def get_root(app, request=None): - """ Return a tuple composed of ``(root, closer)`` when provided a - :term:`router` instance as the ``app`` argument. The ``root`` - returned is the application root object. The ``closer`` returned - is a callable (accepting no arguments) that should be called when - your scripting application is finished using the root. If - ``request`` is not None, it is used as the request passed to the - :mod:`repoze.bfg` application root factory. A request is - constructed and passed to the root factory if ``request`` is None.""" - registry = app.registry - if request is None: - request_factory = registry.queryUtility( - IRequestFactory, default=Request) - request = request_factory.blank('/') - request.registry = registry - threadlocals = {'registry':registry, 'request':request} - app.threadlocal_manager.push(threadlocals) - def closer(request=request): # keep request alive via this function default - app.threadlocal_manager.pop() - root = app.root_factory(request) - return root, closer - diff --git a/repoze/bfg/security.py b/repoze/bfg/security.py deleted file mode 100644 index cd1bae9a5..000000000 --- a/repoze/bfg/security.py +++ /dev/null @@ -1,270 +0,0 @@ -from zope.interface import providedBy - -from zope.deprecation import deprecated - -from repoze.bfg.interfaces import IAuthenticationPolicy -from repoze.bfg.interfaces import IAuthorizationPolicy -from repoze.bfg.interfaces import ISecuredView -from repoze.bfg.interfaces import IViewClassifier - -from repoze.bfg.exceptions import Forbidden as Unauthorized # b/c import -from repoze.bfg.threadlocal import get_current_registry - -Unauthorized # prevent PyFlakes from complaining - -deprecated('Unauthorized', - "('from repoze.bfg.security import Unauthorized' was " - "deprecated as of repoze.bfg 1.1; instead use 'from " - "repoze.bfg.exceptions import Forbidden')", - ) - -Everyone = 'system.Everyone' -Authenticated = 'system.Authenticated' -Allow = 'Allow' -Deny = 'Deny' - -class AllPermissionsList(object): - """ Stand in 'permission list' to represent all permissions """ - def __iter__(self): - return () - def __contains__(self, other): - return True - def __eq__(self, other): - return isinstance(other, self.__class__) - -ALL_PERMISSIONS = AllPermissionsList() -DENY_ALL = (Deny, Everyone, ALL_PERMISSIONS) - -def has_permission(permission, context, request): - """ Provided a permission (a string or unicode object), a context - (a :term:`model` instance) and a request object, return an - instance of :data:`repoze.bfg.security.Allowed` if the permission - is granted in this context to the user implied by the - request. Return an instance of :mod:`repoze.bfg.security.Denied` - if this permission is not granted in this context to this user. - This function delegates to the current authentication and - authorization policies. Return - :data:`repoze.bfg.security.Allowed` unconditionally if no - authentication policy has been configured in this application.""" - try: - reg = request.registry - except AttributeError: - reg = get_current_registry() # b/c - authn_policy = reg.queryUtility(IAuthenticationPolicy) - if authn_policy is None: - return Allowed('No authentication policy in use.') - - authz_policy = reg.queryUtility(IAuthorizationPolicy) - if authz_policy is None: - raise ValueError('Authentication policy registered without ' - 'authorization policy') # should never happen - principals = authn_policy.effective_principals(request) - return authz_policy.permits(context, principals, permission) - -def authenticated_userid(request): - """ Return the userid of the currently authenticated user or - ``None`` if there is no :term:`authentication policy` in effect or - there is no currently authenticated user.""" - try: - reg = request.registry - except AttributeError: - reg = get_current_registry() # b/c - - policy = reg.queryUtility(IAuthenticationPolicy) - if policy is None: - return None - return policy.authenticated_userid(request) - -def effective_principals(request): - """ Return the list of 'effective' :term:`principal` identifiers - for the ``request``. This will include the userid of the - currently authenticated user if a user is currently - authenticated. If no :term:`authentication policy` is in effect, - this will return an empty sequence.""" - try: - reg = request.registry - except AttributeError: - reg = get_current_registry() # b/c - - policy = reg.queryUtility(IAuthenticationPolicy) - if policy is None: - return [] - return policy.effective_principals(request) - -def principals_allowed_by_permission(context, permission): - """ Provided a ``context`` (a model object), and a ``permission`` - (a string or unicode object), if a :term:`authorization policy` is - in effect, return a sequence of :term:`principal` ids that possess - the permission in the ``context``. If no authorization policy is - in effect, this will return a sequence with the single value - :mod:`repoze.bfg.security.Everyone` (the special principal - identifier representing all principals). - - .. note:: even if an :term:`authorization policy` is in effect, - some (exotic) authorization policies may not implement the - required machinery for this function; those will cause a - :exc:`NotImplementedError` exception to be raised when this - function is invoked. - """ - reg = get_current_registry() - policy = reg.queryUtility(IAuthorizationPolicy) - if policy is None: - return [Everyone] - return policy.principals_allowed_by_permission(context, permission) - -def view_execution_permitted(context, request, name=''): - """ If the view specified by ``context`` and ``name`` is protected - by a :term:`permission`, check the permission associated with the - view using the effective authentication/authorization policies and - the ``request``. Return a boolean result. If no - :term:`authorization policy` is in effect, or if the view is not - protected by a permission, return ``True``.""" - try: - reg = request.registry - except AttributeError: - reg = get_current_registry() # b/c - provides = [IViewClassifier] + map(providedBy, (request, context)) - view = reg.adapters.lookup(provides, ISecuredView, name=name) - if view is None: - return Allowed( - 'Allowed: view name %r in context %r (no permission defined)' % - (name, context)) - return view.__permitted__(context, request) - -def remember(request, principal, **kw): - """ Return a sequence of header tuples (e.g. ``[('Set-Cookie', - 'foo=abc')]``) suitable for 'remembering' a set of credentials - implied by the data passed as ``principal`` and ``*kw`` using the - current :term:`authentication policy`. Common usage might look - like so within the body of a view function (``response`` is - assumed to be an :term:`WebOb` -style :term:`response` object - computed previously by the view code):: - - from repoze.bfg.security import remember - headers = remember(request, 'chrism', password='123', max_age='86400') - response.headerlist.extend(headers) - return response - - If no :term:`authentication policy` is in use, this function will - always return an empty sequence. If used, the composition and - meaning of ``**kw`` must be agreed upon by the calling code and - the effective authentication policy.""" - try: - reg = request.registry - except AttributeError: - reg = get_current_registry() # b/c - policy = reg.queryUtility(IAuthenticationPolicy) - if policy is None: - return [] - else: - return policy.remember(request, principal, **kw) - -def forget(request): - """ Return a sequence of header tuples (e.g. ``[('Set-Cookie', - 'foo=abc')]``) suitable for 'forgetting' the set of credentials - possessed by the currently authenticated user. A common usage - might look like so within the body of a view function - (``response`` is assumed to be an :term:`WebOb` -style - :term:`response` object computed previously by the view code):: - - from repoze.bfg.security import forget - headers = forget(request) - response.headerlist.extend(headers) - return response - - If no :term:`authentication policy` is in use, this function will - always return an empty sequence.""" - try: - reg = request.registry - except AttributeError: - reg = get_current_registry() # b/c - policy = reg.queryUtility(IAuthenticationPolicy) - if policy is None: - return [] - else: - return policy.forget(request) - -class PermitsResult(int): - def __new__(cls, s, *args): - inst = int.__new__(cls, cls.boolval) - inst.s = s - inst.args = args - return inst - - @property - def msg(self): - return self.s % self.args - - def __str__(self): - return self.msg - - def __repr__(self): - return '<%s instance at %s with msg %r>' % (self.__class__.__name__, - id(self), - self.msg) - -class Denied(PermitsResult): - """ An instance of ``Denied`` is returned when a security-related - API or other :mod:`repoze.bfg` code denies an action unrelated to - an ACL check. It evaluates equal to all boolean false types. It - has an attribute named ``msg`` describing the circumstances for - the deny.""" - boolval = 0 - -class Allowed(PermitsResult): - """ An instance of ``Allowed`` is returned when a security-related - API or other :mod:`repoze.bfg` code allows an action unrelated to - an ACL check. It evaluates equal to all boolean true types. It - has an attribute named ``msg`` describing the circumstances for - the allow.""" - boolval = 1 - -class ACLPermitsResult(int): - def __new__(cls, ace, acl, permission, principals, context): - inst = int.__new__(cls, cls.boolval) - inst.permission = permission - inst.ace = ace - inst.acl = acl - inst.principals = principals - inst.context = context - return inst - - @property - def msg(self): - s = ('%s permission %r via ACE %r in ACL %r on context %r for ' - 'principals %r') - return s % (self.__class__.__name__, - self.permission, - self.ace, - self.acl, - self.context, - self.principals) - - def __str__(self): - return self.msg - - def __repr__(self): - return '<%s instance at %s with msg %r>' % (self.__class__.__name__, - id(self), - self.msg) - -class ACLDenied(ACLPermitsResult): - """ An instance of ``ACLDenied`` represents that a security check - made explicitly against ACL was denied. It evaluates equal to all - boolean false types. It also has attributes which indicate which - acl, ace, permission, principals, and context were involved in the - request. Its __str__ method prints a summary of these attributes - for debugging purposes. The same summary is available as the - ``msg`` attribute.""" - boolval = 0 - -class ACLAllowed(ACLPermitsResult): - """ An instance of ``ACLAllowed`` represents that a security check - made explicitly against ACL was allowed. It evaluates equal to - all boolean true types. It also has attributes which indicate - which acl, ace, permission, principals, and context were involved - in the request. Its __str__ method prints a summary of these - attributes for debugging purposes. The same summary is available - as the ``msg`` attribute.""" - boolval = 1 - diff --git a/repoze/bfg/settings.py b/repoze/bfg/settings.py deleted file mode 100644 index 5e1181809..000000000 --- a/repoze/bfg/settings.py +++ /dev/null @@ -1,85 +0,0 @@ -import os - -from zope.interface import implements - -from repoze.bfg.interfaces import ISettings - -from repoze.bfg.threadlocal import get_current_registry - -class Settings(dict): - """ Deployment settings. Update application settings (usually - from PasteDeploy keywords) with framework-specific key/value pairs - (e.g. find ``BFG_DEBUG_AUTHORIZATION`` in os.environ and jam into - keyword args).""" - implements(ISettings) - # _environ_ is dep inj for testing - def __init__(self, d=None, _environ_=os.environ, **kw): - if d is None: - d = {} - dict.__init__(self, d, **kw) - eget = _environ_.get - config_debug_all = self.get('debug_all', '') - eff_debug_all = asbool(eget('BFG_DEBUG_ALL', config_debug_all)) - config_reload_all = self.get('reload_all', '') - eff_reload_all = asbool(eget('BFG_RELOAD_ALL',config_reload_all)) - config_debug_auth = self.get('debug_authorization', '') - eff_debug_auth = asbool(eget('BFG_DEBUG_AUTHORIZATION', - config_debug_auth)) - config_debug_notfound = self.get('debug_notfound', '') - eff_debug_notfound = asbool(eget('BFG_DEBUG_NOTFOUND', - config_debug_notfound)) - config_debug_templates = self.get('debug_templates', '') - eff_debug_templates = asbool(eget('BFG_DEBUG_TEMPLATES', - config_debug_templates)) - config_reload_templates = self.get('reload_templates', '') - eff_reload_templates = asbool(eget('BFG_RELOAD_TEMPLATES', - config_reload_templates)) - config_reload_resources = self.get('reload_resources', '') - eff_reload_resources = asbool(eget('BFG_RELOAD_RESOURCES', - config_reload_resources)) - configure_zcml = self.get('configure_zcml', '') - eff_configure_zcml = eget('BFG_CONFIGURE_ZCML', configure_zcml) - locale_name = self.get('default_locale_name', 'en') - eff_locale_name = eget('BFG_DEFAULT_LOCALE_NAME', locale_name) - - update = { - 'debug_authorization': eff_debug_all or eff_debug_auth, - 'debug_notfound': eff_debug_all or eff_debug_notfound, - 'debug_templates': eff_debug_all or eff_debug_templates, - 'reload_templates': eff_reload_all or eff_reload_templates, - 'reload_resources':eff_reload_all or eff_reload_resources, - 'configure_zcml':eff_configure_zcml, - 'default_locale_name':eff_locale_name, - } - - self.update(update) - - def __getattr__(self, name): - # backwards compatibility - try: - return self[name] - except KeyError: - raise AttributeError(name) - -def get_settings(): - """ - Return a 'settings' object for the current application. A - 'settings' object is a dictionary-like object that contains - key/value pairs based on the dictionary passed as the ``settings`` - argument to the :class:`repoze.bfg.configuration.Configurator` - constructor or the :func:`repoze.bfg.router.make_app` API. - - .. note:: For backwards compatibility, dictionary keys can also be - looked up as attributes of the settings object. - - .. note:: the - :class:`repoze.bfg.configuration.Configurator.get_settings` method - performs the same duty. - """ - reg = get_current_registry() - return reg.queryUtility(ISettings) - -def asbool(s): - s = str(s).strip() - return s.lower() in ('t', 'true', 'y', 'yes', 'on', '1') - diff --git a/repoze/bfg/static.py b/repoze/bfg/static.py deleted file mode 100644 index 71db132b7..000000000 --- a/repoze/bfg/static.py +++ /dev/null @@ -1,213 +0,0 @@ -import os -import pkg_resources -from urlparse import urljoin -from urlparse import urlparse - -from paste import httpexceptions -from paste import request -from paste.httpheaders import ETAG -from paste.urlparser import StaticURLParser - -from zope.interface import implements - -from repoze.bfg.interfaces import IStaticURLInfo -from repoze.bfg.path import caller_package -from repoze.bfg.resource import resolve_resource_spec -from repoze.bfg.url import route_url - -class PackageURLParser(StaticURLParser): - """ This probably won't work with zipimported resources """ - def __init__(self, package_name, resource_name, root_resource=None, - cache_max_age=None): - self.package_name = package_name - self.resource_name = os.path.normpath(resource_name) - if root_resource is None: - root_resource = self.resource_name - self.root_resource = root_resource - self.cache_max_age = cache_max_age - - def __call__(self, environ, start_response): - path_info = environ.get('PATH_INFO', '') - if not path_info: - return self.add_slash(environ, start_response) - if path_info == '/': - # @@: This should obviously be configurable - filename = 'index.html' - else: - filename = request.path_info_pop(environ) - resource = os.path.normcase(os.path.normpath( - self.resource_name + '/' + filename)) - if ( (self.root_resource is not None) and - (not resource.startswith(self.root_resource)) ): - # Out of bounds - return self.not_found(environ, start_response) - if not pkg_resources.resource_exists(self.package_name, resource): - return self.not_found(environ, start_response) - if pkg_resources.resource_isdir(self.package_name, resource): - # @@: Cache? - child_root = (self.root_resource is not None and - self.root_resource or self.resource_name) - return self.__class__( - self.package_name, resource, root_resource=child_root, - cache_max_age=self.cache_max_age)(environ, start_response) - if (environ.get('PATH_INFO') - and environ.get('PATH_INFO') != '/'): # pragma: no cover - return self.error_extra_path(environ, start_response) - full = pkg_resources.resource_filename(self.package_name, resource) - if_none_match = environ.get('HTTP_IF_NONE_MATCH') - if if_none_match: - mytime = os.stat(full).st_mtime - if str(mytime) == if_none_match: - headers = [] - ETAG.update(headers, mytime) - start_response('304 Not Modified', headers) - return [''] # empty body - - fa = self.make_app(full) - if self.cache_max_age: - fa.cache_control(max_age=self.cache_max_age) - return fa(environ, start_response) - - def not_found(self, environ, start_response, debug_message=None): - comment=('SCRIPT_NAME=%r; PATH_INFO=%r; looking in package %s; ' - 'subdir %s ;debug: %s' % (environ.get('SCRIPT_NAME'), - environ.get('PATH_INFO'), - self.package_name, - self.resource_name, - debug_message or '(none)')) - exc = httpexceptions.HTTPNotFound( - 'The resource at %s could not be found' - % request.construct_url(environ), - comment=comment) - return exc.wsgi_application(environ, start_response) - - def __repr__(self): - return '<%s %s:%s at %s>' % (self.__class__.__name__, self.package_name, - self.root_resource, id(self)) - -class StaticURLInfo(object): - implements(IStaticURLInfo) - - route_url = staticmethod(route_url) # for testing only - - def __init__(self, config): - self.config = config - self.registrations = [] - - def generate(self, path, request, **kw): - for (name, spec, is_url) in self.registrations: - if path.startswith(spec): - subpath = path[len(spec):] - if is_url: - return urljoin(name, subpath) - else: - kw['subpath'] = subpath - return self.route_url(name, request, **kw) - - raise ValueError('No static URL definition matching %s' % path) - - def add(self, name, spec, **extra): - # This feature only allows for the serving of a directory and - # the files contained within, not of a single resource; - # appending a slash here if the spec doesn't have one is - # required for proper prefix matching done in ``generate`` - # (``subpath = path[len(spec):]``). - if not spec.endswith('/'): - spec = spec + '/' - - # we also make sure the name ends with a slash, purely as a - # convenience: a name that is a url is required to end in a - # slash, so that ``urljoin(name, subpath))`` will work above - # when the name is a URL, and it doesn't hurt things for it to - # have a name that ends in a slash if it's used as a route - # name instead of a URL. - if not name.endswith('/'): - # make sure it ends with a slash - name = name + '/' - - names = [ t[0] for t in self.registrations ] - - if name in names: - idx = names.index(name) - self.registrations.pop(idx) - - if urlparse(name)[0]: - # it's a URL - self.registrations.append((name, spec, True)) - else: - # it's a view name - _info = extra.pop('_info', None) - cache_max_age = extra.pop('cache_max_age', None) - view = static_view(spec, cache_max_age=cache_max_age) - # register a route using this view - self.config.add_route( - name, - "%s*subpath" % name, # name already ends with slash - view=view, - view_for=self.__class__, - factory=lambda *x: self, - _info=_info - ) - self.registrations.append((name, spec, False)) - -class static_view(object): - """ An instance of this class is a callable which can act as a - :mod:`repoze.bfg` :term:`view callable`; this view will serve - static files from a directory on disk based on the ``root_dir`` - you provide to its constructor. - - The directory may contain subdirectories (recursively); the static - view implementation will descend into these directories as - necessary based on the components of the URL in order to resolve a - path into a response. - - You may pass an absolute or relative filesystem path or a - :term:`resource specification` representing the directory - containing static files as the ``root_dir`` argument to this - class' constructor. - - If the ``root_dir`` path is relative, and the ``package_name`` - argument is ``None``, ``root_dir`` will be considered relative to - the directory in which the Python file which *calls* ``static`` - resides. If the ``package_name`` name argument is provided, and a - relative ``root_dir`` is provided, the ``root_dir`` will be - considered relative to the Python :term:`package` specified by - ``package_name`` (a dotted path to a Python package). - - ``cache_max_age`` influences the ``Expires`` and ``Max-Age`` - response headers returned by the view (default is 3600 seconds or - five minutes). - - .. note:: If the ``root_dir`` is relative to a :term:`package`, or - is a :term:`resource specification` the :mod:`repoze.bfg` - ``resource`` ZCML directive or - :class:`repoze.bfg.configuration.Configurator` method can be - used to override resources within the named ``root_dir`` - package-relative directory. However, if the ``root_dir`` is - absolute, the ``resource`` directive will not be able to - override the resources it contains. """ - - def __init__(self, root_dir, cache_max_age=3600, package_name=None): - # package_name is for bw compat; it is preferred to pass in a - # package-relative path as root_dir - # (e.g. ``anotherpackage:foo/static``). - caller_package_name = caller_package().__name__ - package_name = package_name or caller_package_name - package_name, root_dir = resolve_resource_spec(root_dir, package_name) - if package_name is None: - app = StaticURLParser(root_dir, cache_max_age=cache_max_age) - else: - app = PackageURLParser( - package_name, root_dir, cache_max_age=cache_max_age) - self.app = app - - def __call__(self, context, request): - subpath = '/'.join(request.subpath) - request_copy = request.copy() - # Fix up PATH_INFO to get rid of everything but the "subpath" - # (the actual path to the file relative to the root dir). - request_copy.environ['PATH_INFO'] = '/' + subpath - # Zero out SCRIPT_NAME for good measure. - request_copy.environ['SCRIPT_NAME'] = '' - return request_copy.get_response(self.app) - diff --git a/repoze/bfg/testing.py b/repoze/bfg/testing.py deleted file mode 100644 index c99ba8706..000000000 --- a/repoze/bfg/testing.py +++ /dev/null @@ -1,818 +0,0 @@ -import copy -import types - -from webob import Response - -from zope.configuration.xmlconfig import _clearContext - -from zope.deprecation import deprecated - -from zope.interface import implements -from zope.interface import Interface -from zope.interface import alsoProvides - -from repoze.bfg.interfaces import IRequest -from repoze.bfg.interfaces import IRoutesMapper -from repoze.bfg.interfaces import ISecuredView -from repoze.bfg.interfaces import IView -from repoze.bfg.interfaces import IViewClassifier -from repoze.bfg.interfaces import IViewPermission - -from repoze.bfg.configuration import Configurator -from repoze.bfg.exceptions import Forbidden -from repoze.bfg.registry import Registry -from repoze.bfg.security import Allowed -from repoze.bfg.security import Authenticated -from repoze.bfg.security import Denied -from repoze.bfg.security import Everyone -from repoze.bfg.security import has_permission -from repoze.bfg.threadlocal import get_current_registry -from repoze.bfg.threadlocal import manager -from repoze.bfg.urldispatch import RoutesMapper -from repoze.bfg.zcml import zcml_configure # API - -zcml_configure # prevent pyflakes from complaining - -_marker = object() - -def registerDummySecurityPolicy(userid=None, groupids=(), permissive=True): - """ 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 - :meth:`repoze.bfg.configuration.Configurator.testing_securitypolicy` - method in your unit and integration tests. - """ - registry = get_current_registry() - config = Configurator(registry=registry) - return config.testing_securitypolicy(userid=userid, groupids=groupids, - permissive=permissive) - -def registerModels(models): - """ 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 - :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=None): - """ Registers an :term:`event` listener (aka :term:`subscriber`) - 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 - :meth:`repoze.bfg.configuration.Configurator.testing_add_subscriber` - method in your unit and integration tests. - """ - registry = get_current_registry() - config = Configurator(registry=registry) - return config.testing_add_subscriber(event_iface) - -def registerTemplateRenderer(path, renderer=None): - """ Register a template renderer 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.renderers.render` function or - :func:`repoze.bfg.renderers.render_to_response` function or any - other ``render_*`` or ``get_*`` API of the - :mod:`repoze.bfg.renderers` module. - - .. warning:: This API is deprecated as of :mod:`repoze.bfg` 1.2. - Instead use the - :meth:`repoze.bfg.configuration.Configurator.testing_add_template`` - method in your unit and integration tests. - - """ - registry = get_current_registry() - config = Configurator(registry=registry) - return config.testing_add_template(path, renderer) - -# registerDummyRenderer is a deprecated alias that should never be removed -# (too much usage in the wild) -registerDummyRenderer = registerTemplateRenderer - -def registerView(name, result='', view=None, for_=(Interface, Interface), - permission=None): - """ 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 - :meth:`repoze.bfg.configuration.Configurator.add_view`` - method in your unit and integration tests. - """ - for_ = (IViewClassifier, ) + for_ - if view is None: - def view(context, request): - return Response(result) - if permission is None: - return registerAdapter(view, for_, IView, name) - else: - def _secure(context, request): - if not has_permission(permission, context, request): - raise Forbidden('no permission') - else: - return view(context, request) - _secure.__call_permissive__ = view - def permitted(context, request): - return has_permission(permission, context, request) - _secure.__permitted__ = permitted - return registerAdapter(_secure, for_, ISecuredView, name) - -def registerViewPermission(name, result=True, viewpermission=None, - for_=(Interface, Interface)): - """ 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+. - """ - if result is True: - result = Allowed('message') - else: - result = Denied('message') - if viewpermission is None: - def viewpermission(context, request): - return result - return registerAdapter(viewpermission, for_, IViewPermission, name) - -deprecated('registerViewPermission', - 'registerViewPermission has been deprecated. As of repoze.bfg ' - 'version 1.1, view functions are now responsible for protecting ' - 'their own execution. A call to this function won\'t prevent a ' - 'view from being executed by the repoze.bfg router, nor ' - 'will the ``repoze.bfg.security.view_execution_permitted`` function ' - 'use the permission registered with this function. Instead,' - 'to register a view permission during testing, use the ' - '``repoze.bfg.testing.registerView`` directive with a ' - '``permission`` argument.') - -def registerUtility(impl, iface=Interface, name=''): - """ Register a ZCA utility component. - - 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 <http://www.muthukadan.net/docs/zca.html>`_ for - more information about ZCA utilities. - - .. warning:: This API is deprecated as of :mod:`repoze.bfg` 1.2. - Instead use the :meth:`repoze.bfg.Registry.registerUtility` - method. The ``registry`` attribute of a :term:`Configurator` - in your unit and integration tests is an instance 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 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. - - 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 <http://www.muthukadan.net/docs/zca.html>`_ for - more information about ZCA adapters. - - .. warning:: This API is deprecated as of :mod:`repoze.bfg` 1.2. - Instead use the :meth:`repoze.bfg.Registry.registerAdapter` - method. The ``registry`` attribute of a :term:`Configurator` - in your unit and integration tests is an instance of the - :class:`repoze.bfg.Registry` class. - """ - reg = get_current_registry() - if not isinstance(for_, (tuple, list)): - for_ = (for_,) - reg.registerAdapter(impl, for_, provides, name=name) - return impl - -def registerSubscriber(subscriber, iface=Interface): - """ Register a ZCA subscriber component. - - The ``subscriber`` argument specifies the implementation of the - subscriber component (often a function). - - 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 <http://www.muthukadan.net/docs/zca.html>`_ for - more information about ZCA subscribers. - - .. warning:: This API is deprecated as of :mod:`repoze.bfg` 1.2. - Instead use the - :meth:`repoze.bfg.configuration.Configurator.add_subscriber` - method in your unit and integration tests. - """ - registry = get_current_registry() - config = Configurator(registry) - return config.add_subscriber(subscriber, iface=iface) - -def registerRoute(pattern, name, factory=None): - """ Register a new :term:`route` using a pattern - (e.g. ``:pagename``), a name (e.g. ``home``), and an optional root - factory. - - The ``pattern`` argument implies the route pattern. 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 - :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, pattern, factory=factory) - -def registerRoutesMapper(root_factory=None): - """ Register a routes 'mapper' object. - - .. note:: This API was added in :mod:`repoze.bfg` version 1.1. - - .. 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 - 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:: - - registerSettings({'external_uri':'http://example.com'}) - - Or a set of key/value pairs:: - - registerSettings(external_uri='http://example.com') - - Use of this function is required 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 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 - :meth:`repoze.bfg.configuration.Configurator.add_settings` - method in your unit and integration tests. - """ - registry = get_current_registry() - config = Configurator(registry=registry) - config.add_settings(dictarg, **kw) - -class DummyRootFactory(object): - __parent__ = None - __name__ = None - def __init__(self, request): - if 'bfg.routes.matchdict' in request: - self.__dict__.update(request['bfg.routes.matchdict']) - -class DummySecurityPolicy(object): - """ A standin for both an IAuthentication and IAuthorization policy """ - def __init__(self, userid=None, groupids=(), permissive=True): - self.userid = userid - self.groupids = groupids - self.permissive = permissive - - def authenticated_userid(self, request): - return self.userid - - def effective_principals(self, request): - effective_principals = [Everyone] - if self.userid: - effective_principals.append(Authenticated) - effective_principals.append(self.userid) - effective_principals.extend(self.groupids) - return effective_principals - - def remember(self, request, principal, **kw): - return [] - - def forget(self, request): - return [] - - def permits(self, context, principals, permission): - return self.permissive - - def principals_allowed_by_permission(self, context, permission): - return self.effective_principals(None) - -class DummyTemplateRenderer(object): - """ - An instance of this class is returned from - :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=''): - self._received = {} - self._string_response = string_response - self._implementation = MockTemplate(string_response) - - # For in-the-wild test code that doesn't create its own renderer, - # but mutates our internals instead. When all you read is the - # source code, *everything* is an API! - def _get_string_response(self): - return self._string_response - def _set_string_response(self, response): - self._string_response = response - self._implementation.response = response - string_response = property(_get_string_response, _set_string_response) - - def implementation(self): - return self._implementation - - def __call__(self, kw, system=None): - if system: - self._received.update(system) - self._received.update(kw) - return self.string_response - - def __getattr__(self, k): - """ Backwards compatibility """ - val = self._received.get(k, _marker) - if val is _marker: - val = self._implementation._received.get(k, _marker) - if val is _marker: - raise AttributeError(k) - return val - - def assert_(self, **kw): - """ Accept an arbitrary set of assertion key/value pairs. For - each assertion key/value pair assert that the renderer - (eg. :func:`repoze.bfg.renderer.render_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: - myval = self._implementation._received.get(k, _marker) - if myval is _marker: - raise AssertionError( - 'A value for key "%s" was not passed to the renderer' - % k) - - if myval != v: - raise AssertionError( - '\nasserted value for %s: %r\nactual value: %r' % ( - v, k, myval)) - return True - -class DummyModel: - """ A dummy :mod:`repoze.bfg` :term:`model` object.""" - def __init__(self, __name__=None, __parent__=None, __provides__=None, - **kw): - """ 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: - alsoProvides(self, __provides__) - self.kw = kw - self.__dict__.update(**kw) - self.subs = {} - - def __setitem__(self, name, val): - """ When the ``__setitem__`` method is called, the object - passed in as ``val`` will be decorated with a ``__parent__`` - attribute pointing at the dummy model and a ``__name__`` - attribute that is the value of ``name``. The value will then - be returned when dummy model's ``__getitem__`` is called with - the name ``name```.""" - val.__name__ = name - val.__parent__ = self - self.subs[name] = val - - def __getitem__(self, name): - """ Return a named subobject (see ``__setitem__``)""" - ob = self.subs[name] - return ob - - def __delitem__(self, name): - del self.subs[name] - - def get(self, name, default=None): - return self.subs.get(name, default) - - def values(self): - """ Return the values set by __setitem__ """ - return self.subs.values() - - def items(self): - """ Return the items set by __setitem__ """ - return self.subs.items() - - def keys(self): - """ Return the keys set by __setitem__ """ - return self.subs.keys() - - __iter__ = keys - - def __nonzero__(self): - return True - - def __len__(self): - return len(self.subs) - - def __contains__(self, name): - return name in self.subs - - def clone(self, __name__=_marker, __parent__=_marker, **kw): - """ Create a clone of the model object. If ``__name__`` or - ``__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`` - argument, 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) - inst.subs = copy.deepcopy(self.subs) - if __name__ is not _marker: - inst.__name__ = __name__ - if __parent__ is not _marker: - inst.__parent__ = __parent__ - return inst - -class DummyRequest(object): - """ A dummy request object (imitates a :term:`request` object). - - The ``params``, ``environ``, ``headers``, ``path``, and - ``cookies`` arguments correspond to their :term`WebOb` - equivalents. - - The ``post`` argument, if passed, populates the request's - ``POST`` attribute, but *not* ``params``, in order to allow testing - that the app accepts data for a given view only from POST requests. - This argument also sets ``self.method`` to "POST". - - Extra keyword arguments are assigned as attributes of the request - itself. - """ - implements(IRequest) - method = 'GET' - application_url = 'http://example.com' - host = 'example.com:80' - content_length = 0 - response_callbacks = () - def __init__(self, params=None, environ=None, headers=None, path='/', - cookies=None, post=None, **kw): - if environ is None: - environ = {} - if params is None: - params = {} - if headers is None: - headers = {} - if cookies is None: - cookies = {} - self.environ = environ - self.headers = headers - self.params = params - self.cookies = cookies - self.matchdict = {} - self.GET = params - if post is not None: - self.method = 'POST' - self.POST = post - else: - self.POST = params - self.host_url = self.application_url - self.path_url = self.application_url - self.url = self.application_url - self.path = path - self.path_info = path - self.script_name = '' - self.path_qs = '' - self.body = '' - self.view_name = '' - self.subpath = () - self.traversed = () - self.virtual_root_path = () - self.context = None - self.root = None - self.virtual_root = None - self.marshalled = params # repoze.monty - self.registry = get_current_registry() - self.__dict__.update(kw) - - def add_response_callback(self, callback): - if not self.response_callbacks: - self.response_callbacks = [] - self.response_callbacks.append(callback) - -def setUp(registry=None, request=None, hook_zca=True): - """ - 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. - - Use this function in the ``setUp`` method of a unittest test case - which directly or indirectly uses: - - - 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 :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``, - :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 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 - :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. - - 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. :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. - - .. 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 preferred to using - ``repoze.bfg.testing.setUp`` and - ``repoze.bfg.testing.tearDown``. See - :ref:`unittesting_chapter` for more information. - """ - manager.clear() - if registry is None: - registry = Registry('testing') - config = Configurator(registry=registry) - if hasattr(registry, 'registerUtility'): - # Sometimes nose calls us with a non-registry object because - # it thinks this function is module test setup. Likewise, - # someone may be passing us an esoteric "dummy" registry, and - # the below won't succeed if it doesn't have a registerUtility - # method. - from repoze.bfg.configuration import DEFAULT_RENDERERS - for name, renderer in DEFAULT_RENDERERS: - # Cause the default renderers to be registered because - # in-the-wild test code relies on being able to call - # e.g. ``repoze.bfg.chameleon_zpt.render_template`` - # without registering a .pt renderer, expecting the "real" - # template to be rendered. This is a holdover from when - # individual template system renderers weren't indirected - # by the ``repoze.bfg.renderers`` machinery, and - # ``render_template`` and friends went behind the back of - # any existing renderer factory lookup system. - config.add_renderer(name, renderer) - hook_zca and config.hook_zca() - config.begin(request=request) - return config - -def tearDown(unhook_zca=True): - """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 - :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. - - .. warning:: Although this method of tearing a test setup down - will never disappear, after :mod:`repoze.bfg` 1.2a6, - using the ``begin`` and ``end`` methods of a - ``Configurator`` are preferred to using - ``repoze.bfg.testing.setUp`` and - ``repoze.bfg.testing.tearDown``. See - :ref:`unittesting_chapter` for more information. - - """ - if unhook_zca: - try: - from zope.component import getSiteManager - getSiteManager.reset() - except ImportError: # pragma: no cover - pass - info = manager.pop() - manager.clear() - if info is not None: - registry = info['registry'] - if hasattr(registry, '__init__') and hasattr(registry, '__name__'): - try: - registry.__init__(registry.__name__) - except TypeError: - # calling __init__ is largely for the benefit of - # people who want to use the global ZCA registry; - # however maybe somebody's using a registry we don't - # understand, let's not blow up - pass - _clearContext() # XXX why? - -def cleanUp(*arg, **kw): - """ :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.""" - return setUp(*arg, **kw) - -class DummyRendererFactory(object): - """ Registered by - ``repoze.bfg.configuration.Configurator.testing_add_renderer`` as - a dummy renderer factory. The indecision about what to use as a - key (a spec vs. a relative name) is caused by test suites in the - wild believing they can register either. The ``factory`` argument - passed to this constructor is usually the *real* template renderer - factory, found when ``testing_add_renderer`` is called.""" - def __init__(self, name, factory): - self.name = name - self.factory = factory # the "real" renderer factory reg'd previously - self.renderers = {} - - def add(self, spec, renderer): - self.renderers[spec] = renderer - if ':' in spec: - package, relative = spec.split(':', 1) - self.renderers[relative] = renderer - - def __call__(self, spec): - renderer = self.renderers.get(spec) - if renderer is None: - if ':' in spec: - package, relative = spec.split(':', 1) - renderer = self.renderers.get(relative) - if renderer is None: - if self.factory: - renderer = self.factory(spec) - else: - raise KeyError('No testing renderer registered for %r' % - spec) - return renderer - - -class MockTemplate(object): - def __init__(self, response): - self._received = {} - self.response = response - def __getattr__(self, attrname): - return self - def __getitem__(self, attrname): - return self - def __call__(self, *arg, **kw): - self._received.update(kw) - return self.response diff --git a/repoze/bfg/tests/__init__.py b/repoze/bfg/tests/__init__.py deleted file mode 100644 index 5bb534f79..000000000 --- a/repoze/bfg/tests/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# package diff --git a/repoze/bfg/tests/ccbugapp/__init__.py b/repoze/bfg/tests/ccbugapp/__init__.py deleted file mode 100644 index 546616b2c..000000000 --- a/repoze/bfg/tests/ccbugapp/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# fixture application diff --git a/repoze/bfg/tests/ccbugapp/configure.zcml b/repoze/bfg/tests/ccbugapp/configure.zcml deleted file mode 100644 index cb9ca6f1d..000000000 --- a/repoze/bfg/tests/ccbugapp/configure.zcml +++ /dev/null @@ -1,15 +0,0 @@ -<configure xmlns="http://namespaces.repoze.org/bfg"> - - <include package="repoze.bfg.includes" /> - - <route - view=".views.rdf_view" - path="licenses/:license_code/:license_version/rdf" - name="rdf" /> - - <route - view=".views.juri_view" - path="licenses/:license_code/:license_version/:jurisdiction" - name="juri" /> - -</configure> diff --git a/repoze/bfg/tests/ccbugapp/views.py b/repoze/bfg/tests/ccbugapp/views.py deleted file mode 100644 index 4a6939ac2..000000000 --- a/repoze/bfg/tests/ccbugapp/views.py +++ /dev/null @@ -1,10 +0,0 @@ -from webob import Response - -def rdf_view(request): - """ """ - return Response('rdf') - -def juri_view(request): - """ """ - return Response('juri') - diff --git a/repoze/bfg/tests/exceptionviewapp/__init__.py b/repoze/bfg/tests/exceptionviewapp/__init__.py deleted file mode 100644 index ef5fe8b12..000000000 --- a/repoze/bfg/tests/exceptionviewapp/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# a package diff --git a/repoze/bfg/tests/exceptionviewapp/configure.zcml b/repoze/bfg/tests/exceptionviewapp/configure.zcml deleted file mode 100644 index 680e065a6..000000000 --- a/repoze/bfg/tests/exceptionviewapp/configure.zcml +++ /dev/null @@ -1,44 +0,0 @@ -<configure xmlns="http://namespaces.repoze.org/bfg"> - - <include package="repoze.bfg.includes" /> - - <view view=".views.maybe"/> - - <view context=".models.NotAnException" - view=".views.no"/> - - <view context=".models.AnException" - view=".views.yes"/> - - <view name="raise_exception" - view=".views.raise_exception"/> - - <route name="route_raise_exception" - path="route_raise_exception" - view=".views.raise_exception"/> - - <route name="route_raise_exception2" - path="route_raise_exception2" - view=".views.raise_exception" - factory=".models.route_factory"/> - - <route name="route_raise_exception3" - path="route_raise_exception3" - view=".views.raise_exception" - factory=".models.route_factory2"/> - - <view context=".models.AnException" - route_name="route_raise_exception3" - view=".views.whoa"/> - - <route name="route_raise_exception4" - path="route_raise_exception4" - view=".views.raise_exception"/> - - <view context=".models.AnException" - route_name="route_raise_exception4" - view=".views.whoa"/> - -</configure> - - diff --git a/repoze/bfg/tests/exceptionviewapp/models.py b/repoze/bfg/tests/exceptionviewapp/models.py deleted file mode 100644 index fe407badc..000000000 --- a/repoze/bfg/tests/exceptionviewapp/models.py +++ /dev/null @@ -1,18 +0,0 @@ - -class NotAnException(object): - pass - -class AnException(Exception): - pass - -class RouteContext(object): - pass - -class RouteContext2(object): - pass - -def route_factory(*arg): - return RouteContext() - -def route_factory2(*arg): - return RouteContext2() diff --git a/repoze/bfg/tests/exceptionviewapp/views.py b/repoze/bfg/tests/exceptionviewapp/views.py deleted file mode 100644 index 1432618cf..000000000 --- a/repoze/bfg/tests/exceptionviewapp/views.py +++ /dev/null @@ -1,17 +0,0 @@ -from webob import Response -from models import AnException - -def no(request): - return Response('no') - -def yes(request): - return Response('yes') - -def maybe(request): - return Response('maybe') - -def whoa(request): - return Response('whoa') - -def raise_exception(request): - raise AnException() diff --git a/repoze/bfg/tests/fixtureapp/__init__.py b/repoze/bfg/tests/fixtureapp/__init__.py deleted file mode 100644 index 546616b2c..000000000 --- a/repoze/bfg/tests/fixtureapp/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# fixture application diff --git a/repoze/bfg/tests/fixtureapp/another.zcml b/repoze/bfg/tests/fixtureapp/another.zcml deleted file mode 100644 index f8678bad7..000000000 --- a/repoze/bfg/tests/fixtureapp/another.zcml +++ /dev/null @@ -1,10 +0,0 @@ -<configure xmlns="http://namespaces.repoze.org/bfg"> - - <include package="repoze.bfg.includes" /> - - <view - view=".views.fixture_view" - name="another.html" - /> - -</configure> diff --git a/repoze/bfg/tests/fixtureapp/configure.zcml b/repoze/bfg/tests/fixtureapp/configure.zcml deleted file mode 100644 index e3470d47a..000000000 --- a/repoze/bfg/tests/fixtureapp/configure.zcml +++ /dev/null @@ -1,37 +0,0 @@ -<configure xmlns="http://namespaces.repoze.org/bfg"> - - <include package="repoze.bfg.includes" /> - - <view - view=".views.fixture_view" - /> - - <view - view=".views.exception_view" - for="RuntimeError" - /> - - <view - view=".views.protected_view" - name="protected.html" - /> - - <view - view=".views.erroneous_view" - name="error.html" - /> - - <view - view=".views.fixture_view" - name="dummyskin.html" - request_type=".views.IDummy" - /> - - <utility - component=".models.fixture" - provides=".models.IFixture" - /> - - <include file="another.zcml"/> - -</configure> diff --git a/repoze/bfg/tests/fixtureapp/models.py b/repoze/bfg/tests/fixtureapp/models.py deleted file mode 100644 index d80d14bb3..000000000 --- a/repoze/bfg/tests/fixtureapp/models.py +++ /dev/null @@ -1,8 +0,0 @@ -from zope.interface import Interface - -class IFixture(Interface): - pass - -def fixture(): - """ """ - diff --git a/repoze/bfg/tests/fixtureapp/subpackage/__init__.py b/repoze/bfg/tests/fixtureapp/subpackage/__init__.py deleted file mode 100644 index d3173e636..000000000 --- a/repoze/bfg/tests/fixtureapp/subpackage/__init__.py +++ /dev/null @@ -1 +0,0 @@ -#package diff --git a/repoze/bfg/tests/fixtureapp/subpackage/templates/bar.pt b/repoze/bfg/tests/fixtureapp/subpackage/templates/bar.pt deleted file mode 100644 index 90531a4b3..000000000 --- a/repoze/bfg/tests/fixtureapp/subpackage/templates/bar.pt +++ /dev/null @@ -1,2 +0,0 @@ -<html> -</html> diff --git a/repoze/bfg/tests/fixtureapp/subpackage/yetanother.zcml b/repoze/bfg/tests/fixtureapp/subpackage/yetanother.zcml deleted file mode 100644 index 464163477..000000000 --- a/repoze/bfg/tests/fixtureapp/subpackage/yetanother.zcml +++ /dev/null @@ -1,8 +0,0 @@ -<configure xmlns="http://namespaces.repoze.org/bfg"> - - <include package="repoze.bfg.includes" /> - - <include package="repoze.bfg.tests.fixtureapp" file="another.zcml"/> - -</configure> - diff --git a/repoze/bfg/tests/fixtureapp/templates/fixture.pt b/repoze/bfg/tests/fixtureapp/templates/fixture.pt deleted file mode 100644 index 06dd4e2b1..000000000 --- a/repoze/bfg/tests/fixtureapp/templates/fixture.pt +++ /dev/null @@ -1,6 +0,0 @@ -<html xmlns="http://www.w3.org/1999/xhtml" - xmlns:tal="http://xml.zope.org/namespaces/tal"> -<head></head> -<body> -</body> -</html> diff --git a/repoze/bfg/tests/fixtureapp/views.py b/repoze/bfg/tests/fixtureapp/views.py deleted file mode 100644 index 862046d43..000000000 --- a/repoze/bfg/tests/fixtureapp/views.py +++ /dev/null @@ -1,22 +0,0 @@ -from zope.interface import Interface -from webob import Response -from repoze.bfg.exceptions import Forbidden - -def fixture_view(context, request): - """ """ - return Response('fixture') - -def erroneous_view(context, request): - """ """ - raise RuntimeError() - -def exception_view(context, request): - """ """ - return Response('supressed') - -def protected_view(context, request): - """ """ - raise Forbidden() - -class IDummy(Interface): - pass diff --git a/repoze/bfg/tests/fixtures/minimal.pt b/repoze/bfg/tests/fixtures/minimal.pt deleted file mode 100644 index 693d155ef..000000000 --- a/repoze/bfg/tests/fixtures/minimal.pt +++ /dev/null @@ -1,3 +0,0 @@ -<div xmlns="http://www.w3.org/1999/xhtml" - xmlns:tal="http://xml.zope.org/namespaces/tal"> -</div> diff --git a/repoze/bfg/tests/fixtures/minimal.txt b/repoze/bfg/tests/fixtures/minimal.txt deleted file mode 100644 index 18832d351..000000000 --- a/repoze/bfg/tests/fixtures/minimal.txt +++ /dev/null @@ -1 +0,0 @@ -Hello. diff --git a/repoze/bfg/tests/fixtures/nonminimal.txt b/repoze/bfg/tests/fixtures/nonminimal.txt deleted file mode 100644 index 9de95ec92..000000000 --- a/repoze/bfg/tests/fixtures/nonminimal.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, ${name}! diff --git a/repoze/bfg/tests/fixtures/pp.pt b/repoze/bfg/tests/fixtures/pp.pt deleted file mode 100644 index 9df7d22da..000000000 --- a/repoze/bfg/tests/fixtures/pp.pt +++ /dev/null @@ -1,3 +0,0 @@ -<p xmlns="http://www.w3.org/1999/xhtml" - xmlns:tal="http://xml.zope.org/namespaces/tal" - tal:content="wrapped">WRAPPED</p> diff --git a/repoze/bfg/tests/fixtures/static/index.html b/repoze/bfg/tests/fixtures/static/index.html deleted file mode 100644 index 6498787a5..000000000 --- a/repoze/bfg/tests/fixtures/static/index.html +++ /dev/null @@ -1 +0,0 @@ -<html>static</html> diff --git a/repoze/bfg/tests/fixtures/static/subdir/index.html b/repoze/bfg/tests/fixtures/static/subdir/index.html deleted file mode 100644 index bb84fad04..000000000 --- a/repoze/bfg/tests/fixtures/static/subdir/index.html +++ /dev/null @@ -1 +0,0 @@ -<html>subdir</html> diff --git a/repoze/bfg/tests/grokkedapp/__init__.py b/repoze/bfg/tests/grokkedapp/__init__.py deleted file mode 100644 index 5d2843885..000000000 --- a/repoze/bfg/tests/grokkedapp/__init__.py +++ /dev/null @@ -1,90 +0,0 @@ -from repoze.bfg.view import bfg_view - -@bfg_view() -def grokked(context, request): - return 'grokked' - -@bfg_view(request_method='POST') -def grokked_post(context, request): - return 'grokked_post' - -@bfg_view(name='stacked2') -@bfg_view(name='stacked1') -def stacked(context, request): - return 'stacked' - -class stacked_class(object): - def __init__(self, context, request): - self.context = context - self.request = request - - def __call__(self): - return 'stacked_class' - -stacked_class = bfg_view(name='stacked_class1')(stacked_class) -stacked_class = bfg_view(name='stacked_class2')(stacked_class) - -class oldstyle_grokked_class: - def __init__(self, context, request): - self.context = context - self.request = request - - def __call__(self): - return 'oldstyle_grokked_class' - -oldstyle_grokked_class = bfg_view(name='oldstyle_grokked_class')( - oldstyle_grokked_class) - -class grokked_class(object): - def __init__(self, context, request): - self.context = context - self.request = request - - def __call__(self): - return 'grokked_class' - -grokked_class = bfg_view(name='grokked_class')(grokked_class) - -class Foo(object): - def __call__(self, context, request): - return 'grokked_instance' - -grokked_instance = Foo() -grokked_instance = bfg_view(name='grokked_instance')(grokked_instance) - -class Base(object): - @bfg_view(name='basemethod') - def basemethod(self): - """ """ - -class MethodViews(Base): - def __init__(self, context, request): - self.context = context - self.request = request - - @bfg_view(name='method1') - def method1(self): - return 'method1' - - @bfg_view(name='method2') - def method2(self): - return 'method2' - - @bfg_view(name='stacked_method2') - @bfg_view(name='stacked_method1') - def stacked(self): - return 'stacked_method' - -# ungrokkable - -A = 1 -B = {} - -def stuff(): - """ """ - -class Whatever(object): - pass - -class Whatever2: - pass diff --git a/repoze/bfg/tests/grokkedapp/another.py b/repoze/bfg/tests/grokkedapp/another.py deleted file mode 100644 index 7dda1d579..000000000 --- a/repoze/bfg/tests/grokkedapp/another.py +++ /dev/null @@ -1,62 +0,0 @@ -from repoze.bfg.view import bfg_view - -@bfg_view(name='another') -def grokked(context, request): - return 'another_grokked' - -@bfg_view(request_method='POST', name='another') -def grokked_post(context, request): - return 'another_grokked_post' - -@bfg_view(name='another_stacked2') -@bfg_view(name='another_stacked1') -def stacked(context, request): - return 'another_stacked' - -class stacked_class(object): - def __init__(self, context, request): - self.context = context - self.request = request - - def __call__(self): - return 'another_stacked_class' - -stacked_class = bfg_view(name='another_stacked_class1')(stacked_class) -stacked_class = bfg_view(name='another_stacked_class2')(stacked_class) - -class oldstyle_grokked_class: - def __init__(self, context, request): - self.context = context - self.request = request - - def __call__(self): - return 'another_oldstyle_grokked_class' - -oldstyle_grokked_class = bfg_view(name='another_oldstyle_grokked_class')( - oldstyle_grokked_class) - -class grokked_class(object): - def __init__(self, context, request): - self.context = context - self.request = request - - def __call__(self): - return 'another_grokked_class' - -grokked_class = bfg_view(name='another_grokked_class')(grokked_class) - -class Foo(object): - def __call__(self, context, request): - return 'another_grokked_instance' - -grokked_instance = Foo() -grokked_instance = bfg_view(name='another_grokked_instance')(grokked_instance) - -# ungrokkable - -A = 1 -B = {} - -def stuff(): - """ """ - diff --git a/repoze/bfg/tests/grokkedapp/configure.zcml b/repoze/bfg/tests/grokkedapp/configure.zcml deleted file mode 100644 index 6867046df..000000000 --- a/repoze/bfg/tests/grokkedapp/configure.zcml +++ /dev/null @@ -1,6 +0,0 @@ -<configure xmlns="http://namespaces.repoze.org/bfg"> - - <include package="repoze.bfg.includes" /> - <scan package="."/> - -</configure> diff --git a/repoze/bfg/tests/grokkedapp/pod/notinit.py b/repoze/bfg/tests/grokkedapp/pod/notinit.py deleted file mode 100644 index ca0538123..000000000 --- a/repoze/bfg/tests/grokkedapp/pod/notinit.py +++ /dev/null @@ -1,5 +0,0 @@ -from repoze.bfg.view import bfg_view - -@bfg_view(name='pod_notinit') -def subpackage_notinit(context, request): - return 'pod_notinit' diff --git a/repoze/bfg/tests/grokkedapp/subpackage/__init__.py b/repoze/bfg/tests/grokkedapp/subpackage/__init__.py deleted file mode 100644 index bdbe54e13..000000000 --- a/repoze/bfg/tests/grokkedapp/subpackage/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -from repoze.bfg.view import bfg_view - -@bfg_view(name='subpackage_init') -def subpackage_init(context, request): - return 'subpackage_init' diff --git a/repoze/bfg/tests/grokkedapp/subpackage/notinit.py b/repoze/bfg/tests/grokkedapp/subpackage/notinit.py deleted file mode 100644 index 84de6503d..000000000 --- a/repoze/bfg/tests/grokkedapp/subpackage/notinit.py +++ /dev/null @@ -1,5 +0,0 @@ -from repoze.bfg.view import bfg_view - -@bfg_view(name='subpackage_notinit') -def subpackage_notinit(context, request): - return 'subpackage_notinit' diff --git a/repoze/bfg/tests/grokkedapp/subpackage/subsubpackage/__init__.py b/repoze/bfg/tests/grokkedapp/subpackage/subsubpackage/__init__.py deleted file mode 100644 index a83be850b..000000000 --- a/repoze/bfg/tests/grokkedapp/subpackage/subsubpackage/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -from repoze.bfg.view import bfg_view - -@bfg_view(name='subsubpackage_init') -def subpackage_init(context, request): - return 'subsubpackage_init' diff --git a/repoze/bfg/tests/hybridapp/__init__.py b/repoze/bfg/tests/hybridapp/__init__.py deleted file mode 100644 index 5bb534f79..000000000 --- a/repoze/bfg/tests/hybridapp/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# package diff --git a/repoze/bfg/tests/hybridapp/configure.zcml b/repoze/bfg/tests/hybridapp/configure.zcml deleted file mode 100644 index a94409e26..000000000 --- a/repoze/bfg/tests/hybridapp/configure.zcml +++ /dev/null @@ -1,117 +0,0 @@ -<configure xmlns="http://namespaces.repoze.org/bfg"> - - <include package="repoze.bfg.includes" /> - - <!-- we want this view to "win" --> - <route - view=".views.route_view" - path="abc" - name="route" /> - - <!-- .. even though this one has a more specific context --> - <view - view=".views.global_view" - context="repoze.bfg.traversal.DefaultRootFactory" - /> - - <view - name="global2" - view=".views.global2_view" - context="repoze.bfg.traversal.DefaultRootFactory" - /> - - <route - path="def" - name="route2" - /> - - <!-- we want this view to win for route2 even though global view with - context is more specific --> - <view - route_name="route2" - view=".views.route2_view" - /> - - <!-- the global view should be found for this route --> - <route - path="ghi" - name="route3" - use_global_views="True" - /> - - <!-- the global view should not be found for this route --> - <route - path="jkl" - name="route4" - /> - - <!-- the global view should not be found for this route (/global2) --> - <route - path="mno/*traverse" - name="route5" - /> - - <!-- the global view should be found for this route (/global2) --> - <route - path="pqr/*traverse" - name="route6" - use_global_views="True" - /> - - <route - path="error" - name="route7" - /> - - <view - route_name="route7" - view=".views.erroneous_view" - /> - - <route - path="error2" - name="route8" - /> - - <view - route_name="route8" - view=".views.erroneous_view" - /> - - <!-- we want this view to "win" for route7 as exception view --> - <view - view=".views.exception_view" - for="RuntimeError" - /> - - <!-- we want this view to "win" for route8 as exception view--> - <view - route_name="route8" - view=".views.exception2_view" - for="RuntimeError" - /> - - <route - path="error_sub" - name="route9" - /> - - <view - route_name="route9" - view=".views.erroneous_sub_view" - /> - - <!-- we want this view to "win" for route9 as exception view... --> - <view - route_name="route9" - view=".views.exception2_view" - for=".views.SuperException" - /> - - <!-- ...even if we have more context-specialized view for raised exception --> - <view - view=".views.exception_view" - for=".views.SubException" - /> - -</configure> diff --git a/repoze/bfg/tests/hybridapp/views.py b/repoze/bfg/tests/hybridapp/views.py deleted file mode 100644 index 135ef8290..000000000 --- a/repoze/bfg/tests/hybridapp/views.py +++ /dev/null @@ -1,39 +0,0 @@ -from webob import Response - -def route_view(request): - """ """ - return Response('route') - -def global_view(request): - """ """ - return Response('global') - -def global2_view(request): - """ """ - return Response('global2') - -def route2_view(request): - """ """ - return Response('route2') - -def exception_view(request): - """ """ - return Response('supressed') - -def exception2_view(request): - """ """ - return Response('supressed2') - -def erroneous_view(request): - """ """ - raise RuntimeError() - -def erroneous_sub_view(request): - """ """ - raise SubException() - -class SuperException(Exception): - """ """ - -class SubException(SuperException): - """ """ diff --git a/repoze/bfg/tests/localeapp/__init__.py b/repoze/bfg/tests/localeapp/__init__.py deleted file mode 100644 index 1a35cdb4a..000000000 --- a/repoze/bfg/tests/localeapp/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# a file diff --git a/repoze/bfg/tests/localeapp/locale/GARBAGE b/repoze/bfg/tests/localeapp/locale/GARBAGE deleted file mode 100644 index 032c55584..000000000 --- a/repoze/bfg/tests/localeapp/locale/GARBAGE +++ /dev/null @@ -1 +0,0 @@ -Garbage file. diff --git a/repoze/bfg/tests/localeapp/locale/be/LC_MESSAGES b/repoze/bfg/tests/localeapp/locale/be/LC_MESSAGES deleted file mode 100644 index 909cf6a3b..000000000 --- a/repoze/bfg/tests/localeapp/locale/be/LC_MESSAGES +++ /dev/null @@ -1 +0,0 @@ -busted. diff --git a/repoze/bfg/tests/localeapp/locale/de/LC_MESSAGES/deformsite.mo b/repoze/bfg/tests/localeapp/locale/de/LC_MESSAGES/deformsite.mo Binary files differdeleted file mode 100644 index 2924a5eb5..000000000 --- a/repoze/bfg/tests/localeapp/locale/de/LC_MESSAGES/deformsite.mo +++ /dev/null diff --git a/repoze/bfg/tests/localeapp/locale/de/LC_MESSAGES/deformsite.po b/repoze/bfg/tests/localeapp/locale/de/LC_MESSAGES/deformsite.po deleted file mode 100644 index 17f87bc19..000000000 --- a/repoze/bfg/tests/localeapp/locale/de/LC_MESSAGES/deformsite.po +++ /dev/null @@ -1,31 +0,0 @@ -# German translations for deformsite. -# Copyright (C) 2010 ORGANIZATION -# This file is distributed under the same license as the deformsite project. -# FIRST AUTHOR <EMAIL@ADDRESS>, 2010. -# -msgid "" -msgstr "" -"Project-Id-Version: deformsite 0.0\n" -"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2010-04-22 14:17+0400\n" -"PO-Revision-Date: 2010-04-22 14:17-0400\n" -"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" -"Language-Team: de <LL@li.org>\n" -"Plural-Forms: nplurals=2; plural=(n != 1)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 0.9.5\n" - -#: deformsite/__init__.py:458 -msgid "Approve" -msgstr "Genehmigen" - -#: deformsite/__init__.py:459 -msgid "Show approval" -msgstr "Zeigen Genehmigung" - -#: deformsite/__init__.py:466 -msgid "Submit" -msgstr "Beugen" - diff --git a/repoze/bfg/tests/localeapp/locale/en/LC_MESSAGES/deformsite.mo b/repoze/bfg/tests/localeapp/locale/en/LC_MESSAGES/deformsite.mo Binary files differdeleted file mode 100644 index 2924a5eb5..000000000 --- a/repoze/bfg/tests/localeapp/locale/en/LC_MESSAGES/deformsite.mo +++ /dev/null diff --git a/repoze/bfg/tests/localeapp/locale/en/LC_MESSAGES/deformsite.po b/repoze/bfg/tests/localeapp/locale/en/LC_MESSAGES/deformsite.po deleted file mode 100644 index 17f87bc19..000000000 --- a/repoze/bfg/tests/localeapp/locale/en/LC_MESSAGES/deformsite.po +++ /dev/null @@ -1,31 +0,0 @@ -# German translations for deformsite. -# Copyright (C) 2010 ORGANIZATION -# This file is distributed under the same license as the deformsite project. -# FIRST AUTHOR <EMAIL@ADDRESS>, 2010. -# -msgid "" -msgstr "" -"Project-Id-Version: deformsite 0.0\n" -"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2010-04-22 14:17+0400\n" -"PO-Revision-Date: 2010-04-22 14:17-0400\n" -"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" -"Language-Team: de <LL@li.org>\n" -"Plural-Forms: nplurals=2; plural=(n != 1)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 0.9.5\n" - -#: deformsite/__init__.py:458 -msgid "Approve" -msgstr "Genehmigen" - -#: deformsite/__init__.py:459 -msgid "Show approval" -msgstr "Zeigen Genehmigung" - -#: deformsite/__init__.py:466 -msgid "Submit" -msgstr "Beugen" - diff --git a/repoze/bfg/tests/restbugapp/__init__.py b/repoze/bfg/tests/restbugapp/__init__.py deleted file mode 100644 index 5bb534f79..000000000 --- a/repoze/bfg/tests/restbugapp/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# package diff --git a/repoze/bfg/tests/restbugapp/configure.zcml b/repoze/bfg/tests/restbugapp/configure.zcml deleted file mode 100644 index 67954b892..000000000 --- a/repoze/bfg/tests/restbugapp/configure.zcml +++ /dev/null @@ -1,25 +0,0 @@ -<configure xmlns="http://namespaces.repoze.org/bfg"> - - <include package="repoze.bfg.includes"/> - - <route - path="/pet" - name="gameactions_pet_get_pets" - view=".views.PetRESTView" - view_attr="GET" - request_method="GET" - permission="view" - renderer="json" - /> - - <route - path="/pet" - name="gameactions_pet_care_for_pet" - view=".views.PetRESTView" - view_attr="POST" - request_method="POST" - permission="view" - renderer="json" - /> - -</configure> diff --git a/repoze/bfg/tests/restbugapp/views.py b/repoze/bfg/tests/restbugapp/views.py deleted file mode 100644 index b94851099..000000000 --- a/repoze/bfg/tests/restbugapp/views.py +++ /dev/null @@ -1,15 +0,0 @@ -from webob import Response - -class BaseRESTView(object): - def __init__(self, context, request): - self.context = context - self.request = request - -class PetRESTView(BaseRESTView): - """ REST Controller to control action of an avatar """ - def __init__(self, context, request): - super(PetRESTView, self).__init__(context, request) - - def GET(self): - return Response('gotten') - diff --git a/repoze/bfg/tests/routesapp/__init__.py b/repoze/bfg/tests/routesapp/__init__.py deleted file mode 100644 index 546616b2c..000000000 --- a/repoze/bfg/tests/routesapp/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# fixture application diff --git a/repoze/bfg/tests/routesapp/configure.zcml b/repoze/bfg/tests/routesapp/configure.zcml deleted file mode 100644 index 01062b6d4..000000000 --- a/repoze/bfg/tests/routesapp/configure.zcml +++ /dev/null @@ -1,12 +0,0 @@ -<configure xmlns="http://namespaces.repoze.org/bfg"> - - <include package="repoze.bfg.includes" /> - - <route - path=":id" - name="default" - view=".views.fixture_view" - permission="repoze.view" - /> - -</configure> diff --git a/repoze/bfg/tests/routesapp/models.py b/repoze/bfg/tests/routesapp/models.py deleted file mode 100644 index a57b06308..000000000 --- a/repoze/bfg/tests/routesapp/models.py +++ /dev/null @@ -1,5 +0,0 @@ -from zope.interface import Interface - -class IFixture(Interface): - pass - diff --git a/repoze/bfg/tests/routesapp/templates/fixture.pt b/repoze/bfg/tests/routesapp/templates/fixture.pt deleted file mode 100644 index 06dd4e2b1..000000000 --- a/repoze/bfg/tests/routesapp/templates/fixture.pt +++ /dev/null @@ -1,6 +0,0 @@ -<html xmlns="http://www.w3.org/1999/xhtml" - xmlns:tal="http://xml.zope.org/namespaces/tal"> -<head></head> -<body> -</body> -</html> diff --git a/repoze/bfg/tests/routesapp/views.py b/repoze/bfg/tests/routesapp/views.py deleted file mode 100644 index f805b88c9..000000000 --- a/repoze/bfg/tests/routesapp/views.py +++ /dev/null @@ -1,8 +0,0 @@ -from zope.interface import Interface - -def fixture_view(context, request): - """ """ - -class IDummy(Interface): - pass - diff --git a/repoze/bfg/tests/test_authentication.py b/repoze/bfg/tests/test_authentication.py deleted file mode 100644 index d020a11a6..000000000 --- a/repoze/bfg/tests/test_authentication.py +++ /dev/null @@ -1,664 +0,0 @@ -import unittest - -class TestRepozeWho1AuthenticationPolicy(unittest.TestCase): - def _getTargetClass(self): - from repoze.bfg.authentication import RepozeWho1AuthenticationPolicy - return RepozeWho1AuthenticationPolicy - - def _makeOne(self, identifier_name='auth_tkt', callback=None): - return self._getTargetClass()(identifier_name, callback) - - def test_class_implements_IAuthenticationPolicy(self): - from zope.interface.verify import verifyClass - from repoze.bfg.interfaces import IAuthenticationPolicy - verifyClass(IAuthenticationPolicy, self._getTargetClass()) - - def test_instance_implements_IAuthenticationPolicy(self): - from zope.interface.verify import verifyObject - from repoze.bfg.interfaces import IAuthenticationPolicy - verifyObject(IAuthenticationPolicy, self._makeOne()) - - def test_authenticated_userid_None(self): - request = DummyRequest({}) - policy = self._makeOne() - self.assertEqual(policy.authenticated_userid(request), None) - - def test_authenticated_userid(self): - request = DummyRequest( - {'repoze.who.identity':{'repoze.who.userid':'fred'}}) - policy = self._makeOne() - self.assertEqual(policy.authenticated_userid(request), 'fred') - - def test_authenticated_userid_with_callback_returns_None(self): - request = DummyRequest( - {'repoze.who.identity':{'repoze.who.userid':'fred'}}) - def callback(identity, request): - return None - policy = self._makeOne(callback=callback) - self.assertEqual(policy.authenticated_userid(request), None) - - def test_authenticated_userid_with_callback_returns_something(self): - request = DummyRequest( - {'repoze.who.identity':{'repoze.who.userid':'fred'}}) - def callback(identity, request): - return ['agroup'] - policy = self._makeOne(callback=callback) - self.assertEqual(policy.authenticated_userid(request), 'fred') - - def test_effective_principals_None(self): - from repoze.bfg.security import Everyone - request = DummyRequest({}) - policy = self._makeOne() - self.assertEqual(policy.effective_principals(request), [Everyone]) - - def test_effective_principals_userid_only(self): - from repoze.bfg.security import Everyone - from repoze.bfg.security import Authenticated - request = DummyRequest( - {'repoze.who.identity':{'repoze.who.userid':'fred'}}) - policy = self._makeOne() - self.assertEqual(policy.effective_principals(request), - [Everyone, Authenticated, 'fred']) - - def test_effective_principals_userid_and_groups(self): - from repoze.bfg.security import Everyone - from repoze.bfg.security import Authenticated - request = DummyRequest( - {'repoze.who.identity':{'repoze.who.userid':'fred', - 'groups':['quux', 'biz']}}) - def callback(identity, request): - return identity['groups'] - policy = self._makeOne(callback=callback) - self.assertEqual(policy.effective_principals(request), - [Everyone, Authenticated, 'fred', 'quux', 'biz']) - - def test_effective_principals_userid_callback_returns_None(self): - from repoze.bfg.security import Everyone - request = DummyRequest( - {'repoze.who.identity':{'repoze.who.userid':'fred', - 'groups':['quux', 'biz']}}) - def callback(identity, request): - return None - policy = self._makeOne(callback=callback) - self.assertEqual(policy.effective_principals(request), [Everyone]) - - def test_remember_no_plugins(self): - request = DummyRequest({}) - policy = self._makeOne() - result = policy.remember(request, 'fred') - self.assertEqual(result, []) - - def test_remember(self): - authtkt = DummyWhoPlugin() - request = DummyRequest( - {'repoze.who.plugins':{'auth_tkt':authtkt}}) - policy = self._makeOne() - result = policy.remember(request, 'fred') - self.assertEqual(result[0], request.environ) - self.assertEqual(result[1], {'repoze.who.userid':'fred'}) - - def test_forget_no_plugins(self): - request = DummyRequest({}) - policy = self._makeOne() - result = policy.forget(request) - self.assertEqual(result, []) - - def test_forget(self): - authtkt = DummyWhoPlugin() - request = DummyRequest( - {'repoze.who.plugins':{'auth_tkt':authtkt}, - 'repoze.who.identity':{'repoze.who.userid':'fred'}, - }) - policy = self._makeOne() - result = policy.forget(request) - self.assertEqual(result[0], request.environ) - self.assertEqual(result[1], request.environ['repoze.who.identity']) - -class TestRemoteUserAuthenticationPolicy(unittest.TestCase): - def _getTargetClass(self): - from repoze.bfg.authentication import RemoteUserAuthenticationPolicy - return RemoteUserAuthenticationPolicy - - def _makeOne(self, environ_key='REMOTE_USER', callback=None): - return self._getTargetClass()(environ_key, callback) - - def test_class_implements_IAuthenticationPolicy(self): - from zope.interface.verify import verifyClass - from repoze.bfg.interfaces import IAuthenticationPolicy - verifyClass(IAuthenticationPolicy, self._getTargetClass()) - - def test_instance_implements_IAuthenticationPolicy(self): - from zope.interface.verify import verifyObject - from repoze.bfg.interfaces import IAuthenticationPolicy - verifyObject(IAuthenticationPolicy, self._makeOne()) - - def test_authenticated_userid_None(self): - request = DummyRequest({}) - policy = self._makeOne() - self.assertEqual(policy.authenticated_userid(request), None) - - def test_authenticated_userid(self): - request = DummyRequest({'REMOTE_USER':'fred'}) - policy = self._makeOne() - self.assertEqual(policy.authenticated_userid(request), 'fred') - - def test_effective_principals_None(self): - from repoze.bfg.security import Everyone - request = DummyRequest({}) - policy = self._makeOne() - self.assertEqual(policy.effective_principals(request), [Everyone]) - - def test_effective_principals(self): - from repoze.bfg.security import Everyone - from repoze.bfg.security import Authenticated - request = DummyRequest({'REMOTE_USER':'fred'}) - policy = self._makeOne() - self.assertEqual(policy.effective_principals(request), - [Everyone, Authenticated, 'fred']) - - def test_remember(self): - request = DummyRequest({'REMOTE_USER':'fred'}) - policy = self._makeOne() - result = policy.remember(request, 'fred') - self.assertEqual(result, []) - - def test_forget(self): - request = DummyRequest({'REMOTE_USER':'fred'}) - policy = self._makeOne() - result = policy.forget(request) - self.assertEqual(result, []) - -class TestAutkTktAuthenticationPolicy(unittest.TestCase): - def _getTargetClass(self): - from repoze.bfg.authentication import AuthTktAuthenticationPolicy - return AuthTktAuthenticationPolicy - - def _makeOne(self, callback, cookieidentity, **kw): - inst = self._getTargetClass()('secret', callback, **kw) - inst.cookie = DummyCookieHelper(cookieidentity) - return inst - - def test_allargs(self): - # pass all known args - inst = self._getTargetClass()( - 'secret', callback=None, cookie_name=None, secure=False, - include_ip=False, timeout=None, reissue_time=None, - ) - self.assertEqual(inst.callback, None) - - def test_class_implements_IAuthenticationPolicy(self): - from zope.interface.verify import verifyClass - from repoze.bfg.interfaces import IAuthenticationPolicy - verifyClass(IAuthenticationPolicy, self._getTargetClass()) - - def test_instance_implements_IAuthenticationPolicy(self): - from zope.interface.verify import verifyObject - from repoze.bfg.interfaces import IAuthenticationPolicy - verifyObject(IAuthenticationPolicy, self._makeOne(None, None)) - - def test_authenticated_userid_no_cookie_identity(self): - request = DummyRequest({}) - policy = self._makeOne(None, None) - self.assertEqual(policy.authenticated_userid(request), None) - - def test_authenticated_userid_callback_returns_None(self): - request = DummyRequest({}) - def callback(userid, request): - return None - policy = self._makeOne(callback, {'userid':'fred'}) - self.assertEqual(policy.authenticated_userid(request), None) - - def test_authenticated_userid(self): - request = DummyRequest({}) - def callback(userid, request): - return True - policy = self._makeOne(callback, {'userid':'fred'}) - self.assertEqual(policy.authenticated_userid(request), 'fred') - - def test_effective_principals_no_cookie_identity(self): - from repoze.bfg.security import Everyone - request = DummyRequest({}) - policy = self._makeOne(None, None) - self.assertEqual(policy.effective_principals(request), [Everyone]) - - def test_effective_principals_callback_returns_None(self): - from repoze.bfg.security import Everyone - request = DummyRequest({}) - def callback(userid, request): - return None - policy = self._makeOne(callback, {'userid':'fred'}) - self.assertEqual(policy.effective_principals(request), [Everyone]) - - def test_effective_principals(self): - from repoze.bfg.security import Everyone - from repoze.bfg.security import Authenticated - request = DummyRequest({}) - def callback(userid, request): - return ['group.foo'] - policy = self._makeOne(callback, {'userid':'fred'}) - self.assertEqual(policy.effective_principals(request), - [Everyone, Authenticated, 'fred', 'group.foo']) - - def test_remember(self): - request = DummyRequest({}) - policy = self._makeOne(None, None) - result = policy.remember(request, 'fred') - self.assertEqual(result, []) - - def test_remember_with_extra_kargs(self): - request = DummyRequest({}) - policy = self._makeOne(None, None) - result = policy.remember(request, 'fred', a=1, b=2) - self.assertEqual(policy.cookie.kw, {'a':1, 'b':2}) - self.assertEqual(result, []) - - def test_forget(self): - request = DummyRequest({}) - policy = self._makeOne(None, None) - result = policy.forget(request) - self.assertEqual(result, []) - -class TestAuthTktCookieHelper(unittest.TestCase): - def _getTargetClass(self): - from repoze.bfg.authentication import AuthTktCookieHelper - return AuthTktCookieHelper - - def _makeOne(self, *arg, **kw): - plugin = self._getTargetClass()(*arg, **kw) - plugin.auth_tkt = DummyAuthTktModule() - return plugin - - def _makeRequest(self, kw=None): - environ = {'wsgi.version': (1,0)} - if kw is not None: - environ.update(kw) - environ['REMOTE_ADDR'] = '1.1.1.1' - environ['SERVER_NAME'] = 'localhost' - return DummyRequest(environ) - - def _cookieValue(self, cookie): - return eval(cookie.value) - - def _parseHeaders(self, headers): - return [ self._parseHeader(header) for header in headers ] - - def _parseHeader(self, header): - cookie = self._parseCookie(header[1]) - return cookie - - def _parseCookie(self, cookie): - from Cookie import SimpleCookie - cookies = SimpleCookie() - cookies.load(cookie) - return cookies.get('auth_tkt') - - def test_identify_nocookie(self): - plugin = self._makeOne('secret') - request = self._makeRequest() - result = plugin.identify(request) - self.assertEqual(result, None) - - def test_identify_good_cookie_include_ip(self): - plugin = self._makeOne('secret', include_ip=True) - request = self._makeRequest({'HTTP_COOKIE':'auth_tkt=ticket'}) - result = plugin.identify(request) - self.assertEqual(len(result), 4) - self.assertEqual(result['tokens'], ()) - self.assertEqual(result['userid'], 'userid') - self.assertEqual(result['userdata'], '') - self.assertEqual(result['timestamp'], 0) - self.assertEqual(plugin.auth_tkt.value, 'ticket') - self.assertEqual(plugin.auth_tkt.remote_addr, '1.1.1.1') - self.assertEqual(plugin.auth_tkt.secret, 'secret') - environ = request.environ - self.assertEqual(environ['REMOTE_USER_TOKENS'], ()) - self.assertEqual(environ['REMOTE_USER_DATA'],'') - self.assertEqual(environ['AUTH_TYPE'],'cookie') - - def test_identify_good_cookie_dont_include_ip(self): - plugin = self._makeOne('secret', include_ip=False) - request = self._makeRequest({'HTTP_COOKIE':'auth_tkt=ticket'}) - result = plugin.identify(request) - self.assertEqual(len(result), 4) - self.assertEqual(result['tokens'], ()) - self.assertEqual(result['userid'], 'userid') - self.assertEqual(result['userdata'], '') - self.assertEqual(result['timestamp'], 0) - self.assertEqual(plugin.auth_tkt.value, 'ticket') - self.assertEqual(plugin.auth_tkt.remote_addr, '0.0.0.0') - self.assertEqual(plugin.auth_tkt.secret, 'secret') - environ = request.environ - self.assertEqual(environ['REMOTE_USER_TOKENS'], ()) - self.assertEqual(environ['REMOTE_USER_DATA'],'') - self.assertEqual(environ['AUTH_TYPE'],'cookie') - - def test_identify_good_cookie_int_useridtype(self): - plugin = self._makeOne('secret', include_ip=False) - plugin.auth_tkt.userid = '1' - plugin.auth_tkt.user_data = 'userid_type:int' - request = self._makeRequest({'HTTP_COOKIE':'auth_tkt=ticket'}) - result = plugin.identify(request) - self.assertEqual(len(result), 4) - self.assertEqual(result['tokens'], ()) - self.assertEqual(result['userid'], 1) - self.assertEqual(result['userdata'], 'userid_type:int') - self.assertEqual(result['timestamp'], 0) - environ = request.environ - self.assertEqual(environ['REMOTE_USER_TOKENS'], ()) - self.assertEqual(environ['REMOTE_USER_DATA'],'userid_type:int') - self.assertEqual(environ['AUTH_TYPE'],'cookie') - - def test_identify_good_cookie_unknown_useridtype(self): - plugin = self._makeOne('secret', include_ip=False) - plugin.auth_tkt.userid = 'abc' - plugin.auth_tkt.user_data = 'userid_type:unknown' - request = self._makeRequest({'HTTP_COOKIE':'auth_tkt=ticket'}) - result = plugin.identify(request) - self.assertEqual(len(result), 4) - self.assertEqual(result['tokens'], ()) - self.assertEqual(result['userid'], 'abc') - self.assertEqual(result['userdata'], 'userid_type:unknown') - self.assertEqual(result['timestamp'], 0) - environ = request.environ - self.assertEqual(environ['REMOTE_USER_TOKENS'], ()) - self.assertEqual(environ['REMOTE_USER_DATA'],'userid_type:unknown') - self.assertEqual(environ['AUTH_TYPE'],'cookie') - - def test_identify_good_cookie_b64str_useridtype(self): - plugin = self._makeOne('secret', include_ip=False) - plugin.auth_tkt.userid = 'encoded'.encode('base64').strip() - plugin.auth_tkt.user_data = 'userid_type:b64str' - request = self._makeRequest({'HTTP_COOKIE':'auth_tkt=ticket'}) - result = plugin.identify(request) - self.assertEqual(len(result), 4) - self.assertEqual(result['tokens'], ()) - self.assertEqual(result['userid'], 'encoded') - self.assertEqual(result['userdata'], 'userid_type:b64str') - self.assertEqual(result['timestamp'], 0) - environ = request.environ - self.assertEqual(environ['REMOTE_USER_TOKENS'], ()) - self.assertEqual(environ['REMOTE_USER_DATA'],'userid_type:b64str') - self.assertEqual(environ['AUTH_TYPE'],'cookie') - - def test_identify_good_cookie_b64unicode_useridtype(self): - plugin = self._makeOne('secret', include_ip=False) - plugin.auth_tkt.userid = '\xc3\xa9ncoded'.encode('base64').strip() - plugin.auth_tkt.user_data = 'userid_type:b64unicode' - request = self._makeRequest({'HTTP_COOKIE':'auth_tkt=ticket'}) - result = plugin.identify(request) - self.assertEqual(len(result), 4) - self.assertEqual(result['tokens'], ()) - self.assertEqual(result['userid'], unicode('\xc3\xa9ncoded', 'utf-8')) - self.assertEqual(result['userdata'], 'userid_type:b64unicode') - self.assertEqual(result['timestamp'], 0) - environ = request.environ - self.assertEqual(environ['REMOTE_USER_TOKENS'], ()) - self.assertEqual(environ['REMOTE_USER_DATA'],'userid_type:b64unicode') - self.assertEqual(environ['AUTH_TYPE'],'cookie') - - def test_identify_bad_cookie(self): - plugin = self._makeOne('secret', include_ip=True) - plugin.auth_tkt.parse_raise = True - request = self._makeRequest({'HTTP_COOKIE':'auth_tkt=bogus'}) - result = plugin.identify(request) - self.assertEqual(result, None) - - def test_identify_cookie_timed_out(self): - plugin = self._makeOne('secret', timeout=1) - request = self._makeRequest({'HTTP_COOKIE':'auth_tkt=bogus'}) - result = plugin.identify(request) - self.assertEqual(result, None) - - def test_identify_cookie_reissue(self): - import time - plugin = self._makeOne('secret', timeout=5, reissue_time=0) - plugin.auth_tkt.timestamp = time.time() - request = self._makeRequest({'HTTP_COOKIE':'auth_tkt=bogus'}) - result = plugin.identify(request) - self.failUnless(result) - self.assertEqual(len(request.callbacks), 1) - response = DummyResponse() - request.callbacks[0](None, response) - self.assertEqual(len(response.headerlist), 3) - self.assertEqual(response.headerlist[0][0], 'Set-Cookie') - - def test_remember(self): - plugin = self._makeOne('secret') - request = self._makeRequest() - result = plugin.remember(request, 'userid') - self.assertEqual(len(result), 3) - - self.assertEqual(result[0][0], 'Set-Cookie') - self.failUnless(result[0][1].endswith('; Path=/')) - self.failUnless(result[0][1].startswith('auth_tkt=')) - - self.assertEqual(result[1][0], 'Set-Cookie') - self.failUnless(result[1][1].endswith('; Path=/; Domain=localhost')) - self.failUnless(result[1][1].startswith('auth_tkt=')) - - self.assertEqual(result[2][0], 'Set-Cookie') - self.failUnless(result[2][1].endswith('; Path=/; Domain=.localhost')) - self.failUnless(result[2][1].startswith('auth_tkt=')) - - def test_remember_include_ip(self): - plugin = self._makeOne('secret', include_ip=True) - request = self._makeRequest() - result = plugin.remember(request, 'other') - self.assertEqual(len(result), 3) - - self.assertEqual(result[0][0], 'Set-Cookie') - self.failUnless(result[0][1].endswith('; Path=/')) - self.failUnless(result[0][1].startswith('auth_tkt=')) - - self.assertEqual(result[1][0], 'Set-Cookie') - self.failUnless(result[1][1].endswith('; Path=/; Domain=localhost')) - self.failUnless(result[1][1].startswith('auth_tkt=')) - - self.assertEqual(result[2][0], 'Set-Cookie') - self.failUnless(result[2][1].endswith('; Path=/; Domain=.localhost')) - self.failUnless(result[2][1].startswith('auth_tkt=')) - - def test_remember_path(self): - plugin = self._makeOne('secret', include_ip=True, - path="/cgi-bin/bfg.cgi/") - request = self._makeRequest() - result = plugin.remember(request, 'other') - self.assertEqual(len(result), 3) - - self.assertEqual(result[0][0], 'Set-Cookie') - self.failUnless(result[0][1].endswith('; Path=/cgi-bin/bfg.cgi/')) - self.failUnless(result[0][1].startswith('auth_tkt=')) - - self.assertEqual(result[1][0], 'Set-Cookie') - self.failUnless(result[1][1].endswith( - '; Path=/cgi-bin/bfg.cgi/; Domain=localhost')) - self.failUnless(result[1][1].startswith('auth_tkt=')) - - self.assertEqual(result[2][0], 'Set-Cookie') - self.failUnless(result[2][1].endswith( - '; Path=/cgi-bin/bfg.cgi/; Domain=.localhost')) - self.failUnless(result[2][1].startswith('auth_tkt=')) - - def test_remember_http_only(self): - plugin = self._makeOne('secret', include_ip=True, http_only=True) - request = self._makeRequest() - result = plugin.remember(request, 'other') - self.assertEqual(len(result), 3) - - self.assertEqual(result[0][0], 'Set-Cookie') - self.failUnless(result[0][1].endswith('; HttpOnly')) - self.failUnless(result[0][1].startswith('auth_tkt=')) - - self.assertEqual(result[1][0], 'Set-Cookie') - self.failUnless(result[1][1].endswith('; HttpOnly')) - self.failUnless(result[1][1].startswith('auth_tkt=')) - - self.assertEqual(result[2][0], 'Set-Cookie') - self.failUnless(result[2][1].endswith('; HttpOnly')) - self.failUnless(result[2][1].startswith('auth_tkt=')) - - def test_remember_secure(self): - plugin = self._makeOne('secret', include_ip=True, secure=True) - request = self._makeRequest() - result = plugin.remember(request, 'other') - self.assertEqual(len(result), 3) - - self.assertEqual(result[0][0], 'Set-Cookie') - self.failUnless('; Secure' in result[0][1]) - self.failUnless(result[0][1].startswith('auth_tkt=')) - - self.assertEqual(result[1][0], 'Set-Cookie') - self.failUnless('; Secure' in result[1][1]) - self.failUnless(result[1][1].startswith('auth_tkt=')) - - self.assertEqual(result[2][0], 'Set-Cookie') - self.failUnless('; Secure' in result[2][1]) - self.failUnless(result[2][1].startswith('auth_tkt=')) - - def test_remember_string_userid(self): - plugin = self._makeOne('secret') - request = self._makeRequest() - result = plugin.remember(request, 'userid') - values = self._parseHeaders(result) - self.assertEqual(len(result), 3) - val = self._cookieValue(values[0]) - self.assertEqual(val['userid'], 'userid'.encode('base64').strip()) - self.assertEqual(val['user_data'], 'userid_type:b64str') - - def test_remember_int_userid(self): - plugin = self._makeOne('secret') - request = self._makeRequest() - result = plugin.remember(request, 1) - values = self._parseHeaders(result) - self.assertEqual(len(result), 3) - val = self._cookieValue(values[0]) - self.assertEqual(val['userid'], '1') - self.assertEqual(val['user_data'], 'userid_type:int') - - def test_remember_long_userid(self): - plugin = self._makeOne('secret') - request = self._makeRequest() - result = plugin.remember(request, long(1)) - values = self._parseHeaders(result) - self.assertEqual(len(result), 3) - val = self._cookieValue(values[0]) - self.assertEqual(val['userid'], '1') - self.assertEqual(val['user_data'], 'userid_type:int') - - def test_remember_unicode_userid(self): - plugin = self._makeOne('secret') - request = self._makeRequest() - userid = unicode('\xc2\xa9', 'utf-8') - result = plugin.remember(request, userid) - values = self._parseHeaders(result) - self.assertEqual(len(result), 3) - val = self._cookieValue(values[0]) - self.assertEqual(val['userid'], - userid.encode('utf-8').encode('base64').strip()) - self.assertEqual(val['user_data'], 'userid_type:b64unicode') - - def test_remember_max_age(self): - plugin = self._makeOne('secret') - request = self._makeRequest() - result = plugin.remember(request, 'userid', max_age='500') - values = self._parseHeaders(result) - self.assertEqual(len(result), 3) - - self.assertEqual(values[0]['max-age'], '500') - self.failUnless(values[0]['expires']) - - def test_forget(self): - plugin = self._makeOne('secret') - request = self._makeRequest() - headers = plugin.forget(request) - self.assertEqual(len(headers), 3) - name, value = headers[0] - self.assertEqual(name, 'Set-Cookie') - self.assertEqual(value, - 'auth_tkt=""; Path=/; Max-Age=0; Expires=Wed, 31-Dec-97 23:59:59 GMT') - name, value = headers[1] - self.assertEqual(name, 'Set-Cookie') - self.assertEqual(value, - 'auth_tkt=""; Path=/; Domain=localhost; Max-Age=0; ' - 'Expires=Wed, 31-Dec-97 23:59:59 GMT') - name, value = headers[2] - self.assertEqual(name, 'Set-Cookie') - self.assertEqual(value, - 'auth_tkt=""; Path=/; Domain=.localhost; Max-Age=0; ' - 'Expires=Wed, 31-Dec-97 23:59:59 GMT') - - def test_timeout_lower_than_reissue(self): - self.assertRaises(ValueError, self._makeOne, 'userid', timeout=1, - reissue_time=2) - -class DummyContext: - pass - -class DummyRequest: - def __init__(self, environ): - self.environ = environ - self.callbacks = [] - - def add_response_callback(self, callback): - self.callbacks.append(callback) - -class DummyWhoPlugin: - def remember(self, environ, identity): - return environ, identity - - def forget(self, environ, identity): - return environ, identity - -class DummyCookieHelper: - def __init__(self, result): - self.result = result - - def identify(self, *arg, **kw): - return self.result - - def remember(self, *arg, **kw): - self.kw = kw - return [] - - def forget(self, *arg): - return [] - -class DummyAuthTktModule(object): - def __init__(self, timestamp=0, userid='userid', tokens=(), user_data='', - parse_raise=False): - self.timestamp = timestamp - self.userid = userid - self.tokens = tokens - self.user_data = user_data - self.parse_raise = parse_raise - def parse_ticket(secret, value, remote_addr): - self.secret = secret - self.value = value - self.remote_addr = remote_addr - if self.parse_raise: - raise self.BadTicket() - return self.timestamp, self.userid, self.tokens, self.user_data - self.parse_ticket = parse_ticket - - class AuthTicket(object): - def __init__(self, secret, userid, remote_addr, **kw): - self.secret = secret - self.userid = userid - self.remote_addr = remote_addr - self.kw = kw - - def cookie_value(self): - result = {'secret':self.secret, 'userid':self.userid, - 'remote_addr':self.remote_addr} - result.update(self.kw) - result = repr(result) - return result - self.AuthTicket = AuthTicket - - class BadTicket(Exception): - pass - -class DummyResponse: - def __init__(self): - self.headerlist = [] - diff --git a/repoze/bfg/tests/test_authorization.py b/repoze/bfg/tests/test_authorization.py deleted file mode 100644 index 6b8c8293a..000000000 --- a/repoze/bfg/tests/test_authorization.py +++ /dev/null @@ -1,189 +0,0 @@ -import unittest - -from repoze.bfg.testing import cleanUp - -class TestACLAuthorizationPolicy(unittest.TestCase): - def setUp(self): - cleanUp() - - def tearDown(self): - cleanUp() - - def _getTargetClass(self): - from repoze.bfg.authorization import ACLAuthorizationPolicy - return ACLAuthorizationPolicy - - def _makeOne(self): - return self._getTargetClass()() - - def test_class_implements_IAuthorizationPolicy(self): - from zope.interface.verify import verifyClass - from repoze.bfg.interfaces import IAuthorizationPolicy - verifyClass(IAuthorizationPolicy, self._getTargetClass()) - - def test_instance_implements_IAuthorizationPolicy(self): - from zope.interface.verify import verifyObject - from repoze.bfg.interfaces import IAuthorizationPolicy - verifyObject(IAuthorizationPolicy, self._makeOne()) - - def test_permits_no_acl(self): - context = DummyContext() - policy = self._makeOne() - self.assertEqual(policy.permits(context, [], 'view'), False) - - def test_permits(self): - from repoze.bfg.security import Deny - from repoze.bfg.security import Allow - from repoze.bfg.security import Everyone - from repoze.bfg.security import Authenticated - from repoze.bfg.security import ALL_PERMISSIONS - from repoze.bfg.security import DENY_ALL - root = DummyContext() - community = DummyContext(__name__='community', __parent__=root) - blog = DummyContext(__name__='blog', __parent__=community) - root.__acl__ = [ - (Allow, Authenticated, VIEW), - ] - community.__acl__ = [ - (Allow, 'fred', ALL_PERMISSIONS), - (Allow, 'wilma', VIEW), - DENY_ALL, - ] - blog.__acl__ = [ - (Allow, 'barney', MEMBER_PERMS), - (Allow, 'wilma', VIEW), - ] - - policy = self._makeOne() - - result = policy.permits(blog, [Everyone, Authenticated, 'wilma'], - 'view') - self.assertEqual(result, True) - self.assertEqual(result.context, blog) - self.assertEqual(result.ace, (Allow, 'wilma', VIEW)) - self.assertEqual(result.acl, blog.__acl__) - - result = policy.permits(blog, [Everyone, Authenticated, 'wilma'], - 'delete') - self.assertEqual(result, False) - self.assertEqual(result.context, community) - self.assertEqual(result.ace, (Deny, Everyone, ALL_PERMISSIONS)) - self.assertEqual(result.acl, community.__acl__) - - result = policy.permits(blog, [Everyone, Authenticated, 'fred'], 'view') - self.assertEqual(result, True) - self.assertEqual(result.context, community) - self.assertEqual(result.ace, (Allow, 'fred', ALL_PERMISSIONS)) - result = policy.permits(blog, [Everyone, Authenticated, 'fred'], - 'doesntevenexistyet') - self.assertEqual(result, True) - self.assertEqual(result.context, community) - self.assertEqual(result.ace, (Allow, 'fred', ALL_PERMISSIONS)) - self.assertEqual(result.acl, community.__acl__) - - result = policy.permits(blog, [Everyone, Authenticated, 'barney'], - 'view') - self.assertEqual(result, True) - self.assertEqual(result.context, blog) - self.assertEqual(result.ace, (Allow, 'barney', MEMBER_PERMS)) - result = policy.permits(blog, [Everyone, Authenticated, 'barney'], - 'administer') - self.assertEqual(result, False) - self.assertEqual(result.context, community) - self.assertEqual(result.ace, (Deny, Everyone, ALL_PERMISSIONS)) - self.assertEqual(result.acl, community.__acl__) - - result = policy.permits(root, [Everyone, Authenticated, 'someguy'], - 'view') - self.assertEqual(result, True) - self.assertEqual(result.context, root) - self.assertEqual(result.ace, (Allow, Authenticated, VIEW)) - result = policy.permits(blog, - [Everyone, Authenticated, 'someguy'], 'view') - self.assertEqual(result, False) - self.assertEqual(result.context, community) - self.assertEqual(result.ace, (Deny, Everyone, ALL_PERMISSIONS)) - self.assertEqual(result.acl, community.__acl__) - - result = policy.permits(root, [Everyone], 'view') - self.assertEqual(result, False) - self.assertEqual(result.context, root) - self.assertEqual(result.ace, '<default deny>') - self.assertEqual(result.acl, root.__acl__) - - context = DummyContext() - result = policy.permits(context, [Everyone], 'view') - self.assertEqual(result, False) - self.assertEqual(result.ace, '<default deny>') - self.assertEqual( - result.acl, - '<No ACL found on any object in model lineage>') - - def test_principals_allowed_by_permission_direct(self): - from repoze.bfg.security import Allow - from repoze.bfg.security import DENY_ALL - context = DummyContext() - acl = [ (Allow, 'chrism', ('read', 'write')), - DENY_ALL, - (Allow, 'other', 'read') ] - context.__acl__ = acl - policy = self._makeOne() - result = sorted( - policy.principals_allowed_by_permission(context, 'read')) - self.assertEqual(result, ['chrism']) - - def test_principals_allowed_by_permission(self): - from repoze.bfg.security import Allow - from repoze.bfg.security import Deny - from repoze.bfg.security import DENY_ALL - from repoze.bfg.security import ALL_PERMISSIONS - root = DummyContext(__name__='', __parent__=None) - community = DummyContext(__name__='community', __parent__=root) - blog = DummyContext(__name__='blog', __parent__=community) - root.__acl__ = [ (Allow, 'chrism', ('read', 'write')), - (Allow, 'other', ('read',)), - (Allow, 'jim', ALL_PERMISSIONS)] - community.__acl__ = [ (Deny, 'flooz', 'read'), - (Allow, 'flooz', 'read'), - (Allow, 'mork', 'read'), - (Deny, 'jim', 'read'), - (Allow, 'someguy', 'manage')] - blog.__acl__ = [ (Allow, 'fred', 'read'), - DENY_ALL] - - policy = self._makeOne() - - result = sorted(policy.principals_allowed_by_permission(blog, 'read')) - self.assertEqual(result, ['fred']) - result = sorted(policy.principals_allowed_by_permission(community, - 'read')) - self.assertEqual(result, ['chrism', 'mork', 'other']) - result = sorted(policy.principals_allowed_by_permission(community, - 'read')) - result = sorted(policy.principals_allowed_by_permission(root, 'read')) - self.assertEqual(result, ['chrism', 'jim', 'other']) - - def test_principals_allowed_by_permission_no_acls(self): - context = DummyContext() - policy = self._makeOne() - result = sorted(policy.principals_allowed_by_permission(context,'read')) - self.assertEqual(result, []) - -class DummyContext: - def __init__(self, *arg, **kw): - self.__dict__.update(kw) - - -VIEW = 'view' -EDIT = 'edit' -CREATE = 'create' -DELETE = 'delete' -MODERATE = 'moderate' -ADMINISTER = 'administer' -COMMENT = 'comment' - -GUEST_PERMS = (VIEW, COMMENT) -MEMBER_PERMS = GUEST_PERMS + (EDIT, CREATE, DELETE) -MODERATOR_PERMS = MEMBER_PERMS + (MODERATE,) -ADMINISTRATOR_PERMS = MODERATOR_PERMS + (ADMINISTER,) - diff --git a/repoze/bfg/tests/test_chameleon_text.py b/repoze/bfg/tests/test_chameleon_text.py deleted file mode 100644 index d9cefbd67..000000000 --- a/repoze/bfg/tests/test_chameleon_text.py +++ /dev/null @@ -1,198 +0,0 @@ -import unittest - -from repoze.bfg.testing import cleanUp - -class Base: - def setUp(self): - cleanUp() - import os - try: - # avoid spew from chameleon logger? - os.unlink(self._getTemplatePath('minimal.txt.py')) - except: - pass - - def tearDown(self): - cleanUp() - - def _getTemplatePath(self, name): - import os - here = os.path.abspath(os.path.dirname(__file__)) - return os.path.join(here, 'fixtures', name) - - def _registerUtility(self, utility, iface, name=''): - from repoze.bfg.threadlocal import get_current_registry - reg = get_current_registry() - reg.registerUtility(utility, iface, name=name) - return reg - - -class TextTemplateRendererTests(Base, unittest.TestCase): - def setUp(self): - from repoze.bfg.configuration import Configurator - from repoze.bfg.registry import Registry - registry = Registry() - self.config = Configurator(registry=registry) - self.config.begin() - - def tearDown(self): - self.config.end() - - def _getTargetClass(self): - from repoze.bfg.chameleon_text import TextTemplateRenderer - return TextTemplateRenderer - - def _makeOne(self, *arg, **kw): - klass = self._getTargetClass() - return klass(*arg, **kw) - - def test_instance_implements_ITemplate(self): - from zope.interface.verify import verifyObject - from repoze.bfg.interfaces import ITemplateRenderer - path = self._getTemplatePath('minimal.txt') - verifyObject(ITemplateRenderer, self._makeOne(path)) - - def test_class_implements_ITemplate(self): - from zope.interface.verify import verifyClass - from repoze.bfg.interfaces import ITemplateRenderer - verifyClass(ITemplateRenderer, self._getTargetClass()) - - def test_template_reified(self): - minimal = self._getTemplatePath('minimal.txt') - instance = self._makeOne(minimal) - self.failIf('template' in instance.__dict__) - template = instance.template - self.assertEqual(template, instance.__dict__['template']) - - def test_template_with_ichameleon_translate(self): - from repoze.bfg.interfaces import IChameleonTranslate - def ct(): pass - self.config.registry.registerUtility(ct, IChameleonTranslate) - minimal = self._getTemplatePath('minimal.txt') - instance = self._makeOne(minimal) - self.failIf('template' in instance.__dict__) - template = instance.template - self.assertEqual(template.translate, ct) - - def test_template_with_debug_templates(self): - self.config.add_settings({'debug_templates':True}) - minimal = self._getTemplatePath('minimal.txt') - instance = self._makeOne(minimal) - self.failIf('template' in instance.__dict__) - template = instance.template - self.assertEqual(template.debug, True) - - def test_template_with_reload_templates(self): - self.config.add_settings({'reload_templates':True}) - minimal = self._getTemplatePath('minimal.txt') - instance = self._makeOne(minimal) - self.failIf('template' in instance.__dict__) - template = instance.template - self.assertEqual(template.auto_reload, True) - - def test_template_with_emptydict(self): - from repoze.bfg.interfaces import ISettings - self.config.registry.registerUtility({}, ISettings) - minimal = self._getTemplatePath('minimal.txt') - instance = self._makeOne(minimal) - self.failIf('template' in instance.__dict__) - template = instance.template - self.assertEqual(template.auto_reload, False) - self.assertEqual(template.debug, False) - - def test_call(self): - minimal = self._getTemplatePath('minimal.txt') - instance = self._makeOne(minimal) - result = instance({}, {}) - self.failUnless(isinstance(result, str)) - self.assertEqual(result, 'Hello.\n') - - def test_call_with_nondict_value(self): - minimal = self._getTemplatePath('minimal.txt') - instance = self._makeOne(minimal) - self.assertRaises(ValueError, instance, None, {}) - - def test_call_nonminimal(self): - nonminimal = self._getTemplatePath('nonminimal.txt') - instance = self._makeOne(nonminimal) - result = instance({'name':'Chris'}, {}) - self.failUnless(isinstance(result, str)) - self.assertEqual(result, 'Hello, Chris!\n') - - def test_implementation(self): - minimal = self._getTemplatePath('minimal.txt') - instance = self._makeOne(minimal) - result = instance.implementation()() - self.failUnless(isinstance(result, str)) - self.assertEqual(result, 'Hello.\n') - -class RenderTemplateTests(Base, unittest.TestCase): - def _callFUT(self, name, **kw): - from repoze.bfg.chameleon_text import render_template - return render_template(name, **kw) - - def test_it(self): - minimal = self._getTemplatePath('minimal.txt') - result = self._callFUT(minimal) - self.failUnless(isinstance(result, str)) - self.assertEqual(result, 'Hello.\n') - -class RenderTemplateToResponseTests(Base, unittest.TestCase): - def _callFUT(self, name, **kw): - from repoze.bfg.chameleon_text import render_template_to_response - return render_template_to_response(name, **kw) - - def test_minimal(self): - minimal = self._getTemplatePath('minimal.txt') - result = self._callFUT(minimal) - from webob import Response - self.failUnless(isinstance(result, Response)) - self.assertEqual(result.app_iter, ['Hello.\n']) - self.assertEqual(result.status, '200 OK') - self.assertEqual(len(result.headerlist), 2) - - def test_iresponsefactory_override(self): - from webob import Response - class Response2(Response): - pass - from repoze.bfg.interfaces import IResponseFactory - self._registerUtility(Response2, IResponseFactory) - minimal = self._getTemplatePath('minimal.txt') - result = self._callFUT(minimal) - self.failUnless(isinstance(result, Response2)) - -class GetRendererTests(Base, unittest.TestCase): - def _callFUT(self, name): - from repoze.bfg.chameleon_text import get_renderer - return get_renderer(name) - - def test_it(self): - from repoze.bfg.interfaces import IRendererFactory - class Dummy: - template = object() - def implementation(self): pass - renderer = Dummy() - def rf(spec): - return renderer - self._registerUtility(rf, IRendererFactory, name='foo') - result = self._callFUT('foo') - self.failUnless(result is renderer) - -class GetTemplateTests(Base, unittest.TestCase): - def _callFUT(self, name): - from repoze.bfg.chameleon_text import get_template - return get_template(name) - - def test_it(self): - from repoze.bfg.interfaces import IRendererFactory - class Dummy: - template = object() - def implementation(self): - return self.template - renderer = Dummy() - def rf(spec): - return renderer - self._registerUtility(rf, IRendererFactory, name='foo') - result = self._callFUT('foo') - self.failUnless(result is renderer.template) - diff --git a/repoze/bfg/tests/test_chameleon_zpt.py b/repoze/bfg/tests/test_chameleon_zpt.py deleted file mode 100644 index a0f01701a..000000000 --- a/repoze/bfg/tests/test_chameleon_zpt.py +++ /dev/null @@ -1,194 +0,0 @@ -import unittest - -from repoze.bfg.testing import cleanUp - -class Base(object): - def setUp(self): - cleanUp() - - def tearDown(self): - cleanUp() - - def _getTemplatePath(self, name): - import os - here = os.path.abspath(os.path.dirname(__file__)) - return os.path.join(here, 'fixtures', name) - - def _registerUtility(self, utility, iface, name=''): - from repoze.bfg.threadlocal import get_current_registry - reg = get_current_registry() - reg.registerUtility(utility, iface, name=name) - return reg - -class ZPTTemplateRendererTests(Base, unittest.TestCase): - def setUp(self): - from repoze.bfg.configuration import Configurator - from repoze.bfg.registry import Registry - registry = Registry() - self.config = Configurator(registry=registry) - self.config.begin() - - def tearDown(self): - self.config.end() - - def _getTargetClass(self): - from repoze.bfg.chameleon_zpt import ZPTTemplateRenderer - return ZPTTemplateRenderer - - def _makeOne(self, *arg, **kw): - klass = self._getTargetClass() - return klass(*arg, **kw) - - def test_instance_implements_ITemplate(self): - from zope.interface.verify import verifyObject - from repoze.bfg.interfaces import ITemplateRenderer - path = self._getTemplatePath('minimal.pt') - verifyObject(ITemplateRenderer, self._makeOne(path)) - - def test_class_implements_ITemplate(self): - from zope.interface.verify import verifyClass - from repoze.bfg.interfaces import ITemplateRenderer - verifyClass(ITemplateRenderer, self._getTargetClass()) - - def test_call(self): - minimal = self._getTemplatePath('minimal.pt') - instance = self._makeOne(minimal) - result = instance({}, {}) - self.failUnless(isinstance(result, unicode)) - self.assertEqual(result, - '<div xmlns="http://www.w3.org/1999/xhtml">\n</div>') - - def test_template_reified(self): - minimal = self._getTemplatePath('minimal.pt') - instance = self._makeOne(minimal) - self.failIf('template' in instance.__dict__) - template = instance.template - self.assertEqual(template, instance.__dict__['template']) - - def test_template_with_ichameleon_translate(self): - from repoze.bfg.interfaces import IChameleonTranslate - def ct(): pass - self.config.registry.registerUtility(ct, IChameleonTranslate) - minimal = self._getTemplatePath('minimal.pt') - instance = self._makeOne(minimal) - self.failIf('template' in instance.__dict__) - template = instance.template - self.assertEqual(template.translate, ct) - - def test_template_with_debug_templates(self): - self.config.add_settings({'debug_templates':True}) - minimal = self._getTemplatePath('minimal.pt') - instance = self._makeOne(minimal) - self.failIf('template' in instance.__dict__) - template = instance.template - self.assertEqual(template.debug, True) - - def test_template_with_reload_templates(self): - self.config.add_settings({'reload_templates':True}) - minimal = self._getTemplatePath('minimal.pt') - instance = self._makeOne(minimal) - self.failIf('template' in instance.__dict__) - template = instance.template - self.assertEqual(template.auto_reload, True) - - def test_template_with_emptydict(self): - from repoze.bfg.interfaces import ISettings - self.config.registry.registerUtility({}, ISettings) - minimal = self._getTemplatePath('minimal.pt') - instance = self._makeOne(minimal) - self.failIf('template' in instance.__dict__) - template = instance.template - self.assertEqual(template.auto_reload, False) - self.assertEqual(template.debug, False) - - def test_call_with_nondict_value(self): - minimal = self._getTemplatePath('minimal.pt') - instance = self._makeOne(minimal) - self.assertRaises(ValueError, instance, None, {}) - - def test_implementation(self): - minimal = self._getTemplatePath('minimal.pt') - instance = self._makeOne(minimal) - result = instance.implementation()() - self.failUnless(isinstance(result, unicode)) - self.assertEqual(result, - '<div xmlns="http://www.w3.org/1999/xhtml">\n</div>') - - -class RenderTemplateTests(Base, unittest.TestCase): - def _callFUT(self, name, **kw): - from repoze.bfg.chameleon_zpt import render_template - return render_template(name, **kw) - - def test_it(self): - minimal = self._getTemplatePath('minimal.pt') - result = self._callFUT(minimal) - self.failUnless(isinstance(result, unicode)) - self.assertEqual(result, - '<div xmlns="http://www.w3.org/1999/xhtml">\n</div>') - -class RenderTemplateToResponseTests(Base, unittest.TestCase): - def setUp(self): - cleanUp() - - def tearDown(self): - cleanUp() - - def _callFUT(self, name, **kw): - from repoze.bfg.chameleon_zpt import render_template_to_response - return render_template_to_response(name, **kw) - - def test_it(self): - minimal = self._getTemplatePath('minimal.pt') - result = self._callFUT(minimal) - from webob import Response - self.failUnless(isinstance(result, Response)) - self.assertEqual(result.app_iter, - ['<div xmlns="http://www.w3.org/1999/xhtml">\n</div>']) - self.assertEqual(result.status, '200 OK') - self.assertEqual(len(result.headerlist), 2) - - def test_iresponsefactory_override(self): - from webob import Response - class Response2(Response): - pass - from repoze.bfg.interfaces import IResponseFactory - self._registerUtility(Response2, IResponseFactory) - minimal = self._getTemplatePath('minimal.pt') - result = self._callFUT(minimal) - self.failUnless(isinstance(result, Response2)) - -class GetRendererTests(Base, unittest.TestCase): - def _callFUT(self, name): - from repoze.bfg.chameleon_zpt import get_renderer - return get_renderer(name) - - def test_it(self): - from repoze.bfg.interfaces import IRendererFactory - class Dummy: - template = object() - def implementation(self): pass - renderer = Dummy() - def rf(spec): - return renderer - self._registerUtility(rf, IRendererFactory, name='foo') - result = self._callFUT('foo') - self.failUnless(result is renderer) - -class GetTemplateTests(Base, unittest.TestCase): - def _callFUT(self, name): - from repoze.bfg.chameleon_zpt import get_template - return get_template(name) - - def test_it(self): - from repoze.bfg.interfaces import IRendererFactory - class Dummy: - template = object() - def implementation(self): - return self.template - renderer = Dummy() - def rf(spec): - return renderer - self._registerUtility(rf, IRendererFactory, name='foo') - result = self._callFUT('foo') - self.failUnless(result is renderer.template) diff --git a/repoze/bfg/tests/test_compat.py b/repoze/bfg/tests/test_compat.py deleted file mode 100644 index 66ea61860..000000000 --- a/repoze/bfg/tests/test_compat.py +++ /dev/null @@ -1,9 +0,0 @@ -import unittest - -class TestAliases(unittest.TestCase): - def test_all(self): - from repoze.bfg.compat import all - self.assertEqual(all([True, True]), True) - self.assertEqual(all([False, False]), False) - self.assertEqual(all([False, True]), False) - diff --git a/repoze/bfg/tests/test_configuration.py b/repoze/bfg/tests/test_configuration.py deleted file mode 100644 index 47649d6ba..000000000 --- a/repoze/bfg/tests/test_configuration.py +++ /dev/null @@ -1,4335 +0,0 @@ -import unittest - -from repoze.bfg import testing - -class ConfiguratorTests(unittest.TestCase): - def _makeOne(self, *arg, **kw): - from repoze.bfg.configuration import Configurator - return Configurator(*arg, **kw) - - def _registerRenderer(self, config, name='.txt'): - from repoze.bfg.interfaces import IRendererFactory - from repoze.bfg.interfaces import ITemplateRenderer - from zope.interface import implements - class Renderer: - implements(ITemplateRenderer) - def __init__(self, path): - self.__class__.path = path - def __call__(self, *arg): - return 'Hello!' - config.registry.registerUtility(Renderer, IRendererFactory, name=name) - return Renderer - - def _getViewCallable(self, config, ctx_iface=None, request_iface=None, - name='', exception_view=False): - from zope.interface import Interface - from repoze.bfg.interfaces import IRequest - from repoze.bfg.interfaces import IView - from repoze.bfg.interfaces import IViewClassifier - from repoze.bfg.interfaces import IExceptionViewClassifier - if exception_view: - classifier = IExceptionViewClassifier - else: - classifier = IViewClassifier - if ctx_iface is None: - ctx_iface = Interface - if request_iface is None: - request_iface = IRequest - return config.registry.adapters.lookup( - (classifier, request_iface, ctx_iface), IView, name=name, - default=None) - - def _getRouteRequestIface(self, config, name): - from repoze.bfg.interfaces import IRouteRequest - iface = config.registry.getUtility(IRouteRequest, name) - return iface - - def _assertNotFound(self, wrapper, *arg): - from repoze.bfg.exceptions import NotFound - self.assertRaises(NotFound, wrapper, *arg) - - def _registerEventListener(self, config, event_iface=None): - if event_iface is None: # pragma: no cover - from zope.interface import Interface - event_iface = Interface - L = [] - def subscriber(*event): - L.extend(event) - config.registry.registerHandler(subscriber, (event_iface,)) - return L - - def _registerLogger(self, config): - from repoze.bfg.interfaces import IDebugLogger - logger = DummyLogger() - config.registry.registerUtility(logger, IDebugLogger) - return logger - - def _makeRequest(self, config): - request = DummyRequest() - request.registry = config.registry - return request - - def _registerSecurityPolicy(self, config, permissive): - from repoze.bfg.interfaces import IAuthenticationPolicy - from repoze.bfg.interfaces import IAuthorizationPolicy - policy = DummySecurityPolicy(permissive) - config.registry.registerUtility(policy, IAuthenticationPolicy) - config.registry.registerUtility(policy, IAuthorizationPolicy) - - def _registerSettings(self, config, **settings): - from repoze.bfg.interfaces import ISettings - config.registry.registerUtility(settings, ISettings) - - def test_ctor_no_registry(self): - import sys - from repoze.bfg.interfaces import ISettings - from repoze.bfg.configuration import Configurator - from repoze.bfg.interfaces import IRendererFactory - config = Configurator() - this_pkg = sys.modules['repoze.bfg.tests'] - self.failUnless(config.registry.getUtility(ISettings)) - self.assertEqual(config.package, this_pkg) - self.failUnless(config.registry.getUtility(IRendererFactory, 'json')) - self.failUnless(config.registry.getUtility(IRendererFactory, 'string')) - self.failUnless(config.registry.getUtility(IRendererFactory, '.pt')) - self.failUnless(config.registry.getUtility(IRendererFactory, '.txt')) - - def test_begin(self): - from repoze.bfg.configuration import Configurator - config = Configurator() - manager = DummyThreadLocalManager() - config.manager = manager - config.begin() - self.assertEqual(manager.pushed, - {'registry':config.registry, 'request':None}) - self.assertEqual(manager.popped, False) - - def test_begin_with_request(self): - from repoze.bfg.configuration import Configurator - config = Configurator() - request = object() - manager = DummyThreadLocalManager() - config.manager = manager - config.begin(request=request) - self.assertEqual(manager.pushed, - {'registry':config.registry, 'request':request}) - self.assertEqual(manager.popped, False) - - def test_end(self): - from repoze.bfg.configuration import Configurator - config = Configurator() - manager = DummyThreadLocalManager() - config.manager = manager - config.end() - self.assertEqual(manager.pushed, None) - self.assertEqual(manager.popped, True) - - def test_ctor_with_package_registry(self): - import sys - from repoze.bfg.configuration import Configurator - bfg_pkg = sys.modules['repoze.bfg'] - config = Configurator(package=bfg_pkg) - self.assertEqual(config.package, bfg_pkg) - - def test_ctor_noreg_custom_settings(self): - from repoze.bfg.interfaces import ISettings - settings = {'reload_templates':True, - 'mysetting':True} - config = self._makeOne(settings=settings) - settings = config.registry.getUtility(ISettings) - self.assertEqual(settings['reload_templates'], True) - self.assertEqual(settings['debug_authorization'], False) - self.assertEqual(settings['mysetting'], True) - - def test_ctor_noreg_debug_logger_None_default(self): - from repoze.bfg.interfaces import IDebugLogger - config = self._makeOne() - logger = config.registry.getUtility(IDebugLogger) - self.assertEqual(logger.name, 'repoze.bfg.debug') - - def test_ctor_noreg_debug_logger_non_None(self): - from repoze.bfg.interfaces import IDebugLogger - logger = object() - config = self._makeOne(debug_logger=logger) - result = config.registry.getUtility(IDebugLogger) - self.assertEqual(logger, result) - - def test_ctor_authentication_policy(self): - from repoze.bfg.interfaces import IAuthenticationPolicy - policy = object() - config = self._makeOne(authentication_policy=policy) - result = config.registry.getUtility(IAuthenticationPolicy) - self.assertEqual(policy, result) - - def test_ctor_authorization_policy_only(self): - from repoze.bfg.exceptions import ConfigurationError - policy = object() - self.assertRaises(ConfigurationError, - self._makeOne, authorization_policy=policy) - - def test_ctor_no_root_factory(self): - from repoze.bfg.interfaces import IRootFactory - config = self._makeOne() - self.failUnless(config.registry.getUtility(IRootFactory)) - - def test_ctor_alternate_renderers(self): - from repoze.bfg.interfaces import IRendererFactory - renderer = object() - config = self._makeOne(renderers=[('yeah', renderer)]) - self.assertEqual(config.registry.getUtility(IRendererFactory, 'yeah'), - renderer) - - def test_ctor_default_permission(self): - from repoze.bfg.interfaces import IDefaultPermission - config = self._makeOne(default_permission='view') - self.assertEqual(config.registry.getUtility(IDefaultPermission), 'view') - - def test_with_package_module(self): - from repoze.bfg.tests import test_configuration - import repoze.bfg.tests - config = self._makeOne() - newconfig = config.with_package(test_configuration) - self.assertEqual(newconfig.package, repoze.bfg.tests) - - def test_with_package_package(self): - import repoze.bfg.tests - config = self._makeOne() - newconfig = config.with_package(repoze.bfg.tests) - self.assertEqual(newconfig.package, repoze.bfg.tests) - - def test_maybe_dotted_string_success(self): - import repoze.bfg.tests - config = self._makeOne() - result = config.maybe_dotted('repoze.bfg.tests') - self.assertEqual(result, repoze.bfg.tests) - - def test_maybe_dotted_string_fail(self): - from repoze.bfg.configuration import ConfigurationError - config = self._makeOne() - self.assertRaises(ConfigurationError, - config.maybe_dotted, 'cant.be.found') - - def test_maybe_dotted_notstring_success(self): - import repoze.bfg.tests - config = self._makeOne() - result = config.maybe_dotted(repoze.bfg.tests) - self.assertEqual(result, repoze.bfg.tests) - - def test_absolute_resource_spec_already_absolute(self): - import repoze.bfg.tests - config = self._makeOne(package=repoze.bfg.tests) - result = config.absolute_resource_spec('already:absolute') - self.assertEqual(result, 'already:absolute') - - def test_absolute_resource_spec_notastring(self): - import repoze.bfg.tests - config = self._makeOne(package=repoze.bfg.tests) - result = config.absolute_resource_spec(None) - self.assertEqual(result, None) - - def test_absolute_resource_spec_relative(self): - import repoze.bfg.tests - config = self._makeOne(package=repoze.bfg.tests) - result = config.absolute_resource_spec('templates') - self.assertEqual(result, 'repoze.bfg.tests:templates') - - def test_setup_registry_fixed(self): - class DummyRegistry(object): - def subscribers(self, events, name): - self.events = events - return events - def registerUtility(self, *arg, **kw): - pass - reg = DummyRegistry() - config = self._makeOne(reg) - config.add_view = lambda *arg, **kw: False - config.setup_registry() - self.assertEqual(reg.has_listeners, True) - self.assertEqual(reg.notify(1), None) - self.assertEqual(reg.events, (1,)) - - def test_setup_registry_registers_default_exceptionresponse_view(self): - from repoze.bfg.interfaces import IExceptionResponse - from repoze.bfg.view import default_exceptionresponse_view - class DummyRegistry(object): - def registerUtility(self, *arg, **kw): - pass - reg = DummyRegistry() - config = self._makeOne(reg) - views = [] - config.add_view = lambda *arg, **kw: views.append((arg, kw)) - config.setup_registry() - self.assertEqual(views[0], ((default_exceptionresponse_view,), - {'context':IExceptionResponse})) - - def test_setup_registry_explicit_notfound_trumps_iexceptionresponse(self): - from zope.interface import implementedBy - from repoze.bfg.interfaces import IRequest - from repoze.bfg.exceptions import NotFound - from repoze.bfg.registry import Registry - reg = Registry() - config = self._makeOne(reg) - config.setup_registry() # registers IExceptionResponse default view - def myview(context, request): - return 'OK' - config.add_view(myview, context=NotFound) - request = self._makeRequest(config) - view = self._getViewCallable(config, ctx_iface=implementedBy(NotFound), - request_iface=IRequest) - result = view(None, request) - self.assertEqual(result, 'OK') - - def test_setup_registry_custom_settings(self): - from repoze.bfg.registry import Registry - from repoze.bfg.interfaces import ISettings - settings = {'reload_templates':True, - 'mysetting':True} - reg = Registry() - config = self._makeOne(reg) - config.setup_registry(settings=settings) - settings = reg.getUtility(ISettings) - self.assertEqual(settings['reload_templates'], True) - self.assertEqual(settings['debug_authorization'], False) - self.assertEqual(settings['mysetting'], True) - - def test_setup_registry_debug_logger_None_default(self): - from repoze.bfg.registry import Registry - from repoze.bfg.interfaces import IDebugLogger - reg = Registry() - config = self._makeOne(reg) - config.setup_registry() - logger = reg.getUtility(IDebugLogger) - self.assertEqual(logger.name, 'repoze.bfg.debug') - - def test_setup_registry_debug_logger_non_None(self): - from repoze.bfg.registry import Registry - from repoze.bfg.interfaces import IDebugLogger - logger = object() - reg = Registry() - config = self._makeOne(reg) - config.setup_registry(debug_logger=logger) - result = reg.getUtility(IDebugLogger) - self.assertEqual(logger, result) - - def test_setup_registry_debug_logger_dottedname(self): - from repoze.bfg.registry import Registry - from repoze.bfg.interfaces import IDebugLogger - reg = Registry() - config = self._makeOne(reg) - config.setup_registry(debug_logger='repoze.bfg.tests') - result = reg.getUtility(IDebugLogger) - import repoze.bfg.tests - self.assertEqual(result, repoze.bfg.tests) - - def test_setup_registry_authentication_policy(self): - from repoze.bfg.registry import Registry - from repoze.bfg.interfaces import IAuthenticationPolicy - policy = object() - reg = Registry() - config = self._makeOne(reg) - config.setup_registry(authentication_policy=policy) - result = reg.getUtility(IAuthenticationPolicy) - self.assertEqual(policy, result) - - def test_setup_registry_authentication_policy_dottedname(self): - from repoze.bfg.registry import Registry - from repoze.bfg.interfaces import IAuthenticationPolicy - reg = Registry() - config = self._makeOne(reg) - config.setup_registry(authentication_policy='repoze.bfg.tests') - result = reg.getUtility(IAuthenticationPolicy) - import repoze.bfg.tests - self.assertEqual(result, repoze.bfg.tests) - - def test_setup_registry_authorization_policy_dottedname(self): - from repoze.bfg.registry import Registry - from repoze.bfg.interfaces import IAuthorizationPolicy - reg = Registry() - config = self._makeOne(reg) - dummy = object() - config.setup_registry(authentication_policy=dummy, - authorization_policy='repoze.bfg.tests') - result = reg.getUtility(IAuthorizationPolicy) - import repoze.bfg.tests - self.assertEqual(result, repoze.bfg.tests) - - def test_setup_registry_authorization_policy_only(self): - from repoze.bfg.registry import Registry - from repoze.bfg.exceptions import ConfigurationError - policy = object() - reg = Registry() - config = self._makeOne(reg) - config = self.assertRaises(ConfigurationError, - config.setup_registry, - authorization_policy=policy) - - def test_setup_registry_default_root_factory(self): - from repoze.bfg.registry import Registry - from repoze.bfg.interfaces import IRootFactory - reg = Registry() - config = self._makeOne(reg) - config.setup_registry() - self.failUnless(reg.getUtility(IRootFactory)) - - def test_setup_registry_dottedname_root_factory(self): - from repoze.bfg.registry import Registry - from repoze.bfg.interfaces import IRootFactory - reg = Registry() - config = self._makeOne(reg) - import repoze.bfg.tests - config.setup_registry(root_factory='repoze.bfg.tests') - self.assertEqual(reg.getUtility(IRootFactory), repoze.bfg.tests) - - def test_setup_registry_locale_negotiator_dottedname(self): - from repoze.bfg.registry import Registry - from repoze.bfg.interfaces import ILocaleNegotiator - reg = Registry() - config = self._makeOne(reg) - import repoze.bfg.tests - config.setup_registry(locale_negotiator='repoze.bfg.tests') - utility = reg.getUtility(ILocaleNegotiator) - self.assertEqual(utility, repoze.bfg.tests) - - def test_setup_registry_locale_negotiator(self): - from repoze.bfg.registry import Registry - from repoze.bfg.interfaces import ILocaleNegotiator - reg = Registry() - config = self._makeOne(reg) - negotiator = object() - config.setup_registry(locale_negotiator=negotiator) - utility = reg.getUtility(ILocaleNegotiator) - self.assertEqual(utility, negotiator) - - def test_setup_registry_request_factory(self): - from repoze.bfg.registry import Registry - from repoze.bfg.interfaces import IRequestFactory - reg = Registry() - config = self._makeOne(reg) - factory = object() - config.setup_registry(request_factory=factory) - utility = reg.getUtility(IRequestFactory) - self.assertEqual(utility, factory) - - def test_setup_registry_request_factory_dottedname(self): - from repoze.bfg.registry import Registry - from repoze.bfg.interfaces import IRequestFactory - reg = Registry() - config = self._makeOne(reg) - import repoze.bfg.tests - config.setup_registry(request_factory='repoze.bfg.tests') - utility = reg.getUtility(IRequestFactory) - self.assertEqual(utility, repoze.bfg.tests) - - def test_setup_registry_renderer_globals_factory(self): - from repoze.bfg.registry import Registry - from repoze.bfg.interfaces import IRendererGlobalsFactory - reg = Registry() - config = self._makeOne(reg) - factory = object() - config.setup_registry(renderer_globals_factory=factory) - utility = reg.getUtility(IRendererGlobalsFactory) - self.assertEqual(utility, factory) - - def test_setup_registry_renderer_globals_factory_dottedname(self): - from repoze.bfg.registry import Registry - from repoze.bfg.interfaces import IRendererGlobalsFactory - reg = Registry() - config = self._makeOne(reg) - import repoze.bfg.tests - config.setup_registry(renderer_globals_factory='repoze.bfg.tests') - utility = reg.getUtility(IRendererGlobalsFactory) - self.assertEqual(utility, repoze.bfg.tests) - - def test_setup_registry_alternate_renderers(self): - from repoze.bfg.registry import Registry - from repoze.bfg.interfaces import IRendererFactory - renderer = object() - reg = Registry() - config = self._makeOne(reg) - config.setup_registry(renderers=[('yeah', renderer)]) - self.assertEqual(reg.getUtility(IRendererFactory, 'yeah'), - renderer) - - def test_setup_registry_default_permission(self): - from repoze.bfg.registry import Registry - from repoze.bfg.interfaces import IDefaultPermission - reg = Registry() - config = self._makeOne(reg) - config.setup_registry(default_permission='view') - self.assertEqual(reg.getUtility(IDefaultPermission), 'view') - - def test_get_settings_nosettings(self): - from repoze.bfg.registry import Registry - reg = Registry() - config = self._makeOne(reg) - self.assertEqual(config.get_settings(), None) - - def test_get_settings_withsettings(self): - from repoze.bfg.interfaces import ISettings - settings = {'a':1} - config = self._makeOne() - config.registry.registerUtility(settings, ISettings) - self.assertEqual(config.get_settings(), settings) - - def test_add_settings_settings_already_registered(self): - from repoze.bfg.registry import Registry - from repoze.bfg.interfaces import ISettings - reg = Registry() - config = self._makeOne(reg) - config._set_settings({'a':1}) - config.add_settings({'b':2}) - settings = reg.getUtility(ISettings) - self.assertEqual(settings['a'], 1) - self.assertEqual(settings['b'], 2) - - def test_add_settings_settings_not_yet_registered(self): - from repoze.bfg.registry import Registry - from repoze.bfg.interfaces import ISettings - reg = Registry() - config = self._makeOne(reg) - config.add_settings({'a':1}) - settings = reg.getUtility(ISettings) - self.assertEqual(settings['a'], 1) - - def test_add_subscriber_defaults(self): - from zope.interface import implements - from zope.interface import Interface - class IEvent(Interface): - pass - class Event: - implements(IEvent) - L = [] - def subscriber(event): - L.append(event) - config = self._makeOne() - config.add_subscriber(subscriber) - event = Event() - config.registry.notify(event) - self.assertEqual(len(L), 1) - self.assertEqual(L[0], event) - config.registry.notify(object()) - self.assertEqual(len(L), 2) - - def test_add_subscriber_iface_specified(self): - from zope.interface import implements - from zope.interface import Interface - class IEvent(Interface): - pass - class Event: - implements(IEvent) - L = [] - def subscriber(event): - L.append(event) - config = self._makeOne() - config.add_subscriber(subscriber, IEvent) - event = Event() - config.registry.notify(event) - self.assertEqual(len(L), 1) - self.assertEqual(L[0], event) - config.registry.notify(object()) - self.assertEqual(len(L), 1) - - def test_add_subscriber_dottednames(self): - import repoze.bfg.tests - from repoze.bfg.interfaces import INewRequest - config = self._makeOne() - config.add_subscriber('repoze.bfg.tests', - 'repoze.bfg.interfaces.INewRequest') - handlers = list(config.registry.registeredHandlers()) - self.assertEqual(len(handlers), 1) - handler = handlers[0] - self.assertEqual(handler.handler, repoze.bfg.tests) - self.assertEqual(handler.required, (INewRequest,)) - - def test_add_object_event_subscriber(self): - from zope.interface import implements - from zope.interface import Interface - class IEvent(Interface): - pass - class Event: - object = 'foo' - implements(IEvent) - event = Event() - L = [] - def subscriber(object, event): - L.append(event) - config = self._makeOne() - config.add_subscriber(subscriber, (Interface, IEvent)) - config.registry.subscribers((event.object, event), None) - self.assertEqual(len(L), 1) - self.assertEqual(L[0], event) - config.registry.subscribers((event.object, IDummy), None) - self.assertEqual(len(L), 1) - - def test_make_wsgi_app(self): - from repoze.bfg.router import Router - from repoze.bfg.interfaces import IApplicationCreated - manager = DummyThreadLocalManager() - config = self._makeOne() - subscriber = self._registerEventListener(config, IApplicationCreated) - config.manager = manager - app = config.make_wsgi_app() - self.assertEqual(app.__class__, Router) - self.assertEqual(manager.pushed['registry'], config.registry) - self.assertEqual(manager.pushed['request'], None) - self.failUnless(manager.popped) - self.assertEqual(len(subscriber), 1) - self.failUnless(IApplicationCreated.providedBy(subscriber[0])) - - def test_load_zcml_default(self): - import repoze.bfg.tests.fixtureapp - config = self._makeOne(package=repoze.bfg.tests.fixtureapp) - registry = config.load_zcml() - from repoze.bfg.tests.fixtureapp.models import IFixture - self.failUnless(registry.queryUtility(IFixture)) # only in c.zcml - - def test_load_zcml_routesapp(self): - from repoze.bfg.interfaces import IRoutesMapper - config = self._makeOne() - config.load_zcml('repoze.bfg.tests.routesapp:configure.zcml') - self.failUnless(config.registry.getUtility(IRoutesMapper)) - - def test_load_zcml_fixtureapp(self): - from repoze.bfg.tests.fixtureapp.models import IFixture - config = self._makeOne() - config.load_zcml('repoze.bfg.tests.fixtureapp:configure.zcml') - self.failUnless(config.registry.queryUtility(IFixture)) # only in c.zcml - - def test_load_zcml_as_relative_filename(self): - import repoze.bfg.tests.fixtureapp - config = self._makeOne(package=repoze.bfg.tests.fixtureapp) - registry = config.load_zcml('configure.zcml') - from repoze.bfg.tests.fixtureapp.models import IFixture - self.failUnless(registry.queryUtility(IFixture)) # only in c.zcml - - def test_load_zcml_as_absolute_filename(self): - import os - import repoze.bfg.tests.fixtureapp - config = self._makeOne(package=repoze.bfg.tests.fixtureapp) - dn = os.path.dirname(repoze.bfg.tests.fixtureapp.__file__) - c_z = os.path.join(dn, 'configure.zcml') - registry = config.load_zcml(c_z) - from repoze.bfg.tests.fixtureapp.models import IFixture - self.failUnless(registry.queryUtility(IFixture)) # only in c.zcml - - def test_load_zcml_lock_and_unlock(self): - config = self._makeOne() - dummylock = DummyLock() - config.load_zcml( - 'repoze.bfg.tests.fixtureapp:configure.zcml', - lock=dummylock) - self.assertEqual(dummylock.acquired, True) - self.assertEqual(dummylock.released, True) - - def test_add_view_view_callable_None_no_renderer(self): - from repoze.bfg.exceptions import ConfigurationError - config = self._makeOne() - self.assertRaises(ConfigurationError, config.add_view) - - def test_add_view_with_request_type_and_route_name(self): - from repoze.bfg.exceptions import ConfigurationError - config = self._makeOne() - view = lambda *arg: 'OK' - self.assertRaises(ConfigurationError, config.add_view, view, '', None, - None, True, True) - - def test_add_view_with_request_type_methodname_string(self): - view = lambda *arg: 'OK' - config = self._makeOne() - config.add_view(view=view, request_type='GET') - wrapper = self._getViewCallable(config) - request = DummyRequest() - request.method = 'POST' - self._assertNotFound(wrapper, None, request) - request = DummyRequest() - request.method = 'GET' - result = wrapper(None, request) - self.assertEqual(result, 'OK') - - def test_add_view_with_request_type(self): - from zope.interface import directlyProvides - from repoze.bfg.interfaces import IRequest - view = lambda *arg: 'OK' - config = self._makeOne() - config.add_view(view=view, - request_type='repoze.bfg.interfaces.IRequest') - wrapper = self._getViewCallable(config) - request = DummyRequest() - self._assertNotFound(wrapper, None, request) - directlyProvides(request, IRequest) - result = wrapper(None, request) - self.assertEqual(result, 'OK') - - def test_add_view_view_callable_None_with_renderer(self): - config = self._makeOne() - self._registerRenderer(config, name='dummy') - config.add_view(renderer='dummy') - view = self._getViewCallable(config) - self.failUnless('Hello!' in view(None, None).body) - - def test_add_view_wrapped_view_is_decorated(self): - def view(request): # request-only wrapper - """ """ - config = self._makeOne() - config.add_view(view=view) - wrapper = self._getViewCallable(config) - self.assertEqual(wrapper.__module__, view.__module__) - self.assertEqual(wrapper.__name__, view.__name__) - self.assertEqual(wrapper.__doc__, view.__doc__) - - def test_add_view_view_callable_dottedname(self): - config = self._makeOne() - config.add_view(view='repoze.bfg.tests.test_configuration.dummy_view') - wrapper = self._getViewCallable(config) - self.assertEqual(wrapper(None, None), 'OK') - - def test_add_view_with_function_callable(self): - view = lambda *arg: 'OK' - config = self._makeOne() - config.add_view(view=view) - wrapper = self._getViewCallable(config) - result = wrapper(None, None) - self.assertEqual(result, 'OK') - - def test_add_view_with_function_callable_requestonly(self): - def view(request): - return 'OK' - config = self._makeOne() - config.add_view(view=view) - wrapper = self._getViewCallable(config) - result = wrapper(None, None) - self.assertEqual(result, 'OK') - - def test_add_view_as_instance(self): - class AView: - def __call__(self, context, request): - """ """ - return 'OK' - view = AView() - config = self._makeOne() - config.add_view(view=view) - wrapper = self._getViewCallable(config) - result = wrapper(None, None) - self.assertEqual(result, 'OK') - - def test_add_view_as_instance_requestonly(self): - class AView: - def __call__(self, request): - """ """ - return 'OK' - view = AView() - config = self._makeOne() - config.add_view(view=view) - wrapper = self._getViewCallable(config) - result = wrapper(None, None) - self.assertEqual(result, 'OK') - - def test_add_view_as_oldstyle_class(self): - class view: - def __init__(self, context, request): - self.context = context - self.request = request - - def __call__(self): - return 'OK' - config = self._makeOne() - config.add_view(view=view) - wrapper = self._getViewCallable(config) - result = wrapper(None, None) - self.assertEqual(result, 'OK') - - def test_add_view_as_oldstyle_class_requestonly(self): - class view: - def __init__(self, request): - self.request = request - - def __call__(self): - return 'OK' - config = self._makeOne() - config.add_view(view=view) - wrapper = self._getViewCallable(config) - result = wrapper(None, None) - self.assertEqual(result, 'OK') - - def test_add_view_context_as_class(self): - from zope.interface import implementedBy - view = lambda *arg: 'OK' - class Foo: - pass - config = self._makeOne() - config.add_view(context=Foo, view=view) - foo = implementedBy(Foo) - wrapper = self._getViewCallable(config, foo) - self.assertEqual(wrapper, view) - - def test_add_view_context_as_iface(self): - view = lambda *arg: 'OK' - config = self._makeOne() - config.add_view(context=IDummy, view=view) - wrapper = self._getViewCallable(config, IDummy) - self.assertEqual(wrapper, view) - - def test_add_view_context_as_dottedname(self): - view = lambda *arg: 'OK' - config = self._makeOne() - config.add_view(context='repoze.bfg.tests.test_configuration.IDummy', - view=view) - wrapper = self._getViewCallable(config, IDummy) - self.assertEqual(wrapper, view) - - def test_add_view_for__as_dottedname(self): - view = lambda *arg: 'OK' - config = self._makeOne() - config.add_view(for_='repoze.bfg.tests.test_configuration.IDummy', - view=view) - wrapper = self._getViewCallable(config, IDummy) - self.assertEqual(wrapper, view) - - def test_add_view_for_as_class(self): - # ``for_`` is older spelling for ``context`` - from zope.interface import implementedBy - view = lambda *arg: 'OK' - class Foo: - pass - config = self._makeOne() - config.add_view(for_=Foo, view=view) - foo = implementedBy(Foo) - wrapper = self._getViewCallable(config, foo) - self.assertEqual(wrapper, view) - - def test_add_view_for_as_iface(self): - # ``for_`` is older spelling for ``context`` - view = lambda *arg: 'OK' - config = self._makeOne() - config.add_view(for_=IDummy, view=view) - wrapper = self._getViewCallable(config, IDummy) - self.assertEqual(wrapper, view) - - def test_add_view_context_trumps_for(self): - # ``for_`` is older spelling for ``context`` - view = lambda *arg: 'OK' - config = self._makeOne() - class Foo: - pass - config.add_view(context=IDummy, for_=Foo, view=view) - wrapper = self._getViewCallable(config, IDummy) - self.assertEqual(wrapper, view) - - def test_add_view_register_secured_view(self): - from zope.interface import Interface - from repoze.bfg.interfaces import IRequest - from repoze.bfg.interfaces import ISecuredView - from repoze.bfg.interfaces import IViewClassifier - view = lambda *arg: 'OK' - view.__call_permissive__ = view - config = self._makeOne() - config.add_view(view=view) - wrapper = config.registry.adapters.lookup( - (IViewClassifier, IRequest, Interface), - ISecuredView, name='', default=None) - self.assertEqual(wrapper, view) - - def test_add_view_exception_register_secured_view(self): - from zope.interface import implementedBy - from repoze.bfg.interfaces import IRequest - from repoze.bfg.interfaces import IView - from repoze.bfg.interfaces import IExceptionViewClassifier - view = lambda *arg: 'OK' - view.__call_permissive__ = view - config = self._makeOne() - config.add_view(view=view, context=RuntimeError) - wrapper = config.registry.adapters.lookup( - (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)), - IView, name='', default=None) - self.assertEqual(wrapper, view) - - def test_add_view_same_phash_overrides_existing_single_view(self): - from repoze.bfg.compat import md5 - from zope.interface import Interface - from repoze.bfg.interfaces import IRequest - from repoze.bfg.interfaces import IView - from repoze.bfg.interfaces import IViewClassifier - from repoze.bfg.interfaces import IMultiView - phash = md5() - phash.update('xhr:True') - view = lambda *arg: 'NOT OK' - view.__phash__ = phash.hexdigest() - config = self._makeOne() - config.registry.registerAdapter( - view, (IViewClassifier, IRequest, Interface), IView, name='') - def newview(context, request): - return 'OK' - config.add_view(view=newview, xhr=True) - wrapper = self._getViewCallable(config) - self.failIf(IMultiView.providedBy(wrapper)) - request = DummyRequest() - request.is_xhr = True - self.assertEqual(wrapper(None, request), 'OK') - - def test_add_view_exc_same_phash_overrides_existing_single_view(self): - from repoze.bfg.compat import md5 - from zope.interface import implementedBy - from repoze.bfg.interfaces import IRequest - from repoze.bfg.interfaces import IView - from repoze.bfg.interfaces import IExceptionViewClassifier - from repoze.bfg.interfaces import IMultiView - phash = md5() - phash.update('xhr:True') - view = lambda *arg: 'NOT OK' - view.__phash__ = phash.hexdigest() - config = self._makeOne() - config.registry.registerAdapter( - view, - (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)), - IView, name='') - def newview(context, request): - return 'OK' - config.add_view(view=newview, xhr=True, - context=RuntimeError) - wrapper = self._getViewCallable( - config, ctx_iface=implementedBy(RuntimeError), exception_view=True) - self.failIf(IMultiView.providedBy(wrapper)) - request = DummyRequest() - request.is_xhr = True - self.assertEqual(wrapper(None, request), 'OK') - - def test_add_view_default_phash_overrides_no_phash(self): - from zope.interface import Interface - from repoze.bfg.interfaces import IRequest - from repoze.bfg.interfaces import IView - from repoze.bfg.interfaces import IViewClassifier - from repoze.bfg.interfaces import IMultiView - view = lambda *arg: 'NOT OK' - config = self._makeOne() - config.registry.registerAdapter( - view, (IViewClassifier, IRequest, Interface), IView, name='') - def newview(context, request): - return 'OK' - config.add_view(view=newview) - wrapper = self._getViewCallable(config) - self.failIf(IMultiView.providedBy(wrapper)) - request = DummyRequest() - request.is_xhr = True - self.assertEqual(wrapper(None, request), 'OK') - - def test_add_view_exc_default_phash_overrides_no_phash(self): - from zope.interface import implementedBy - from repoze.bfg.interfaces import IRequest - from repoze.bfg.interfaces import IView - from repoze.bfg.interfaces import IExceptionViewClassifier - from repoze.bfg.interfaces import IMultiView - view = lambda *arg: 'NOT OK' - config = self._makeOne() - config.registry.registerAdapter( - view, - (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)), - IView, name='') - def newview(context, request): - return 'OK' - config.add_view(view=newview, context=RuntimeError) - wrapper = self._getViewCallable( - config, ctx_iface=implementedBy(RuntimeError), exception_view=True) - self.failIf(IMultiView.providedBy(wrapper)) - request = DummyRequest() - request.is_xhr = True - self.assertEqual(wrapper(None, request), 'OK') - - def test_add_view_default_phash_overrides_default_phash(self): - from repoze.bfg.configuration import DEFAULT_PHASH - from zope.interface import Interface - from repoze.bfg.interfaces import IRequest - from repoze.bfg.interfaces import IView - from repoze.bfg.interfaces import IViewClassifier - from repoze.bfg.interfaces import IMultiView - view = lambda *arg: 'NOT OK' - view.__phash__ = DEFAULT_PHASH - config = self._makeOne() - config.registry.registerAdapter( - view, (IViewClassifier, IRequest, Interface), IView, name='') - def newview(context, request): - return 'OK' - config.add_view(view=newview) - wrapper = self._getViewCallable(config) - self.failIf(IMultiView.providedBy(wrapper)) - request = DummyRequest() - request.is_xhr = True - self.assertEqual(wrapper(None, request), 'OK') - - def test_add_view_exc_default_phash_overrides_default_phash(self): - from repoze.bfg.configuration import DEFAULT_PHASH - from zope.interface import implementedBy - from repoze.bfg.interfaces import IRequest - from repoze.bfg.interfaces import IView - from repoze.bfg.interfaces import IExceptionViewClassifier - from repoze.bfg.interfaces import IMultiView - view = lambda *arg: 'NOT OK' - view.__phash__ = DEFAULT_PHASH - config = self._makeOne() - config.registry.registerAdapter( - view, - (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)), - IView, name='') - def newview(context, request): - return 'OK' - config.add_view(view=newview, context=RuntimeError) - wrapper = self._getViewCallable( - config, ctx_iface=implementedBy(RuntimeError), exception_view=True) - self.failIf(IMultiView.providedBy(wrapper)) - request = DummyRequest() - request.is_xhr = True - self.assertEqual(wrapper(None, request), 'OK') - - def test_add_view_multiview_replaces_existing_view(self): - from zope.interface import Interface - from repoze.bfg.interfaces import IRequest - from repoze.bfg.interfaces import IView - from repoze.bfg.interfaces import IViewClassifier - from repoze.bfg.interfaces import IMultiView - view = lambda *arg: 'OK' - view.__phash__ = 'abc' - config = self._makeOne() - config.registry.registerAdapter( - view, (IViewClassifier, IRequest, Interface), IView, name='') - config.add_view(view=view) - wrapper = self._getViewCallable(config) - self.failUnless(IMultiView.providedBy(wrapper)) - self.assertEqual(wrapper(None, None), 'OK') - - def test_add_view_exc_multiview_replaces_existing_view(self): - from zope.interface import implementedBy - from repoze.bfg.interfaces import IRequest - from repoze.bfg.interfaces import IView - from repoze.bfg.interfaces import IExceptionViewClassifier - from repoze.bfg.interfaces import IViewClassifier - from repoze.bfg.interfaces import IMultiView - view = lambda *arg: 'OK' - view.__phash__ = 'abc' - config = self._makeOne() - config.registry.registerAdapter( - view, - (IViewClassifier, IRequest, implementedBy(RuntimeError)), - IView, name='') - config.registry.registerAdapter( - view, - (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)), - IView, name='') - config.add_view(view=view, context=RuntimeError) - wrapper = self._getViewCallable( - config, ctx_iface=implementedBy(RuntimeError), exception_view=True) - self.failUnless(IMultiView.providedBy(wrapper)) - self.assertEqual(wrapper(None, None), 'OK') - - def test_add_view_multiview_replaces_existing_securedview(self): - from zope.interface import Interface - from repoze.bfg.interfaces import IRequest - from repoze.bfg.interfaces import ISecuredView - from repoze.bfg.interfaces import IMultiView - from repoze.bfg.interfaces import IViewClassifier - view = lambda *arg: 'OK' - view.__phash__ = 'abc' - config = self._makeOne() - config.registry.registerAdapter( - view, (IViewClassifier, IRequest, Interface), - ISecuredView, name='') - config.add_view(view=view) - wrapper = self._getViewCallable(config) - self.failUnless(IMultiView.providedBy(wrapper)) - self.assertEqual(wrapper(None, None), 'OK') - - def test_add_view_exc_multiview_replaces_existing_securedview(self): - from zope.interface import implementedBy - from repoze.bfg.interfaces import IRequest - from repoze.bfg.interfaces import ISecuredView - from repoze.bfg.interfaces import IMultiView - from repoze.bfg.interfaces import IViewClassifier - from repoze.bfg.interfaces import IExceptionViewClassifier - view = lambda *arg: 'OK' - view.__phash__ = 'abc' - config = self._makeOne() - config.registry.registerAdapter( - view, - (IViewClassifier, IRequest, implementedBy(RuntimeError)), - ISecuredView, name='') - config.registry.registerAdapter( - view, - (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)), - ISecuredView, name='') - config.add_view(view=view, context=RuntimeError) - wrapper = self._getViewCallable( - config, ctx_iface=implementedBy(RuntimeError), exception_view=True) - self.failUnless(IMultiView.providedBy(wrapper)) - self.assertEqual(wrapper(None, None), 'OK') - - def test_add_view_with_accept_multiview_replaces_existing_view(self): - from zope.interface import Interface - from repoze.bfg.interfaces import IRequest - from repoze.bfg.interfaces import IView - from repoze.bfg.interfaces import IMultiView - from repoze.bfg.interfaces import IViewClassifier - def view(context, request): - return 'OK' - def view2(context, request): - return 'OK2' - config = self._makeOne() - config.registry.registerAdapter( - view, (IViewClassifier, IRequest, Interface), IView, name='') - config.add_view(view=view2, accept='text/html') - wrapper = self._getViewCallable(config) - self.failUnless(IMultiView.providedBy(wrapper)) - self.assertEqual(len(wrapper.views), 1) - self.assertEqual(len(wrapper.media_views), 1) - self.assertEqual(wrapper(None, None), 'OK') - request = DummyRequest() - request.accept = DummyAccept('text/html', 'text/html') - self.assertEqual(wrapper(None, request), 'OK2') - - def test_add_view_exc_with_accept_multiview_replaces_existing_view(self): - from zope.interface import implementedBy - from repoze.bfg.interfaces import IRequest - from repoze.bfg.interfaces import IView - from repoze.bfg.interfaces import IMultiView - from repoze.bfg.interfaces import IViewClassifier - from repoze.bfg.interfaces import IExceptionViewClassifier - def view(context, request): - return 'OK' - def view2(context, request): - return 'OK2' - config = self._makeOne() - config.registry.registerAdapter( - view, - (IViewClassifier, IRequest, implementedBy(RuntimeError)), - IView, name='') - config.registry.registerAdapter( - view, - (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)), - IView, name='') - config.add_view(view=view2, accept='text/html', context=RuntimeError) - wrapper = self._getViewCallable( - config, ctx_iface=implementedBy(RuntimeError), exception_view=True) - self.failUnless(IMultiView.providedBy(wrapper)) - self.assertEqual(len(wrapper.views), 1) - self.assertEqual(len(wrapper.media_views), 1) - self.assertEqual(wrapper(None, None), 'OK') - request = DummyRequest() - request.accept = DummyAccept('text/html', 'text/html') - self.assertEqual(wrapper(None, request), 'OK2') - - def test_add_view_multiview_replaces_existing_view_with___accept__(self): - from zope.interface import Interface - from repoze.bfg.interfaces import IRequest - from repoze.bfg.interfaces import IView - from repoze.bfg.interfaces import IMultiView - from repoze.bfg.interfaces import IViewClassifier - def view(context, request): - return 'OK' - def view2(context, request): - return 'OK2' - view.__accept__ = 'text/html' - view.__phash__ = 'abc' - config = self._makeOne() - config.registry.registerAdapter( - view, (IViewClassifier, IRequest, Interface), IView, name='') - config.add_view(view=view2) - wrapper = self._getViewCallable(config) - self.failUnless(IMultiView.providedBy(wrapper)) - self.assertEqual(len(wrapper.views), 1) - self.assertEqual(len(wrapper.media_views), 1) - self.assertEqual(wrapper(None, None), 'OK2') - request = DummyRequest() - request.accept = DummyAccept('text/html') - self.assertEqual(wrapper(None, request), 'OK') - - def test_add_view_exc_mulview_replaces_existing_view_with___accept__(self): - from zope.interface import implementedBy - from repoze.bfg.interfaces import IRequest - from repoze.bfg.interfaces import IView - from repoze.bfg.interfaces import IMultiView - from repoze.bfg.interfaces import IViewClassifier - from repoze.bfg.interfaces import IExceptionViewClassifier - def view(context, request): - return 'OK' - def view2(context, request): - return 'OK2' - view.__accept__ = 'text/html' - view.__phash__ = 'abc' - config = self._makeOne() - config.registry.registerAdapter( - view, - (IViewClassifier, IRequest, implementedBy(RuntimeError)), - IView, name='') - config.registry.registerAdapter( - view, - (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)), - IView, name='') - config.add_view(view=view2, context=RuntimeError) - wrapper = self._getViewCallable( - config, ctx_iface=implementedBy(RuntimeError), exception_view=True) - self.failUnless(IMultiView.providedBy(wrapper)) - self.assertEqual(len(wrapper.views), 1) - self.assertEqual(len(wrapper.media_views), 1) - self.assertEqual(wrapper(None, None), 'OK2') - request = DummyRequest() - request.accept = DummyAccept('text/html') - self.assertEqual(wrapper(None, request), 'OK') - - def test_add_view_multiview_replaces_multiview(self): - from zope.interface import Interface - from repoze.bfg.interfaces import IRequest - from repoze.bfg.interfaces import IMultiView - from repoze.bfg.interfaces import IViewClassifier - view = DummyMultiView() - config = self._makeOne() - config.registry.registerAdapter( - view, (IViewClassifier, IRequest, Interface), - IMultiView, name='') - view2 = lambda *arg: 'OK2' - config.add_view(view=view2) - wrapper = self._getViewCallable(config) - self.failUnless(IMultiView.providedBy(wrapper)) - self.assertEqual([x[:2] for x in wrapper.views], [(view2, None)]) - self.assertEqual(wrapper(None, None), 'OK1') - - def test_add_view_exc_multiview_replaces_multiview(self): - from zope.interface import implementedBy - from repoze.bfg.interfaces import IRequest - from repoze.bfg.interfaces import IMultiView - from repoze.bfg.interfaces import IViewClassifier - from repoze.bfg.interfaces import IExceptionViewClassifier - view = DummyMultiView() - config = self._makeOne() - config.registry.registerAdapter( - view, - (IViewClassifier, IRequest, implementedBy(RuntimeError)), - IMultiView, name='') - config.registry.registerAdapter( - view, - (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)), - IMultiView, name='') - view2 = lambda *arg: 'OK2' - config.add_view(view=view2, context=RuntimeError) - wrapper = self._getViewCallable( - config, ctx_iface=implementedBy(RuntimeError), exception_view=True) - self.failUnless(IMultiView.providedBy(wrapper)) - self.assertEqual([x[:2] for x in wrapper.views], [(view2, None)]) - self.assertEqual(wrapper(None, None), 'OK1') - - def test_add_view_multiview_context_superclass_then_subclass(self): - from zope.interface import Interface - from repoze.bfg.interfaces import IRequest - from repoze.bfg.interfaces import IView - from repoze.bfg.interfaces import IMultiView - from repoze.bfg.interfaces import IViewClassifier - class ISuper(Interface): - pass - class ISub(ISuper): - pass - view = lambda *arg: 'OK' - view2 = lambda *arg: 'OK2' - config = self._makeOne() - config.registry.registerAdapter( - view, (IViewClassifier, IRequest, ISuper), IView, name='') - config.add_view(view=view2, for_=ISub) - wrapper = self._getViewCallable(config, ISuper, IRequest) - self.failIf(IMultiView.providedBy(wrapper)) - self.assertEqual(wrapper(None, None), 'OK') - wrapper = self._getViewCallable(config, ISub, IRequest) - self.failIf(IMultiView.providedBy(wrapper)) - self.assertEqual(wrapper(None, None), 'OK2') - - def test_add_view_multiview_exception_superclass_then_subclass(self): - from zope.interface import implementedBy - from repoze.bfg.interfaces import IRequest - from repoze.bfg.interfaces import IView - from repoze.bfg.interfaces import IMultiView - from repoze.bfg.interfaces import IViewClassifier - from repoze.bfg.interfaces import IExceptionViewClassifier - class Super(Exception): - pass - class Sub(Super): - pass - view = lambda *arg: 'OK' - view2 = lambda *arg: 'OK2' - config = self._makeOne() - config.registry.registerAdapter( - view, (IViewClassifier, IRequest, Super), IView, name='') - config.registry.registerAdapter( - view, (IExceptionViewClassifier, IRequest, Super), IView, name='') - config.add_view(view=view2, for_=Sub) - wrapper = self._getViewCallable( - config, implementedBy(Super), IRequest) - wrapper_exc_view = self._getViewCallable( - config, implementedBy(Super), IRequest, exception_view=True) - self.assertEqual(wrapper_exc_view, wrapper) - self.failIf(IMultiView.providedBy(wrapper_exc_view)) - self.assertEqual(wrapper_exc_view(None, None), 'OK') - wrapper = self._getViewCallable( - config, implementedBy(Sub), IRequest) - wrapper_exc_view = self._getViewCallable( - config, implementedBy(Sub), IRequest, exception_view=True) - self.assertEqual(wrapper_exc_view, wrapper) - self.failIf(IMultiView.providedBy(wrapper_exc_view)) - self.assertEqual(wrapper_exc_view(None, None), 'OK2') - - def test_add_view_multiview_call_ordering(self): - from zope.interface import directlyProvides - def view1(context, request): return 'view1' - def view2(context, request): return 'view2' - def view3(context, request): return 'view3' - def view4(context, request): return 'view4' - def view5(context, request): return 'view5' - def view6(context, request): return 'view6' - def view7(context, request): return 'view7' - def view8(context, request): return 'view8' - config = self._makeOne() - config.add_view(view=view1) - config.add_view(view=view2, request_method='POST') - config.add_view(view=view3,request_param='param') - config.add_view(view=view4, containment=IDummy) - config.add_view(view=view5, request_method='POST',request_param='param') - config.add_view(view=view6, request_method='POST', containment=IDummy) - config.add_view(view=view7, request_param='param', containment=IDummy) - config.add_view(view=view8, request_method='POST',request_param='param', - containment=IDummy) - - wrapper = self._getViewCallable(config) - - ctx = DummyContext() - request = self._makeRequest(config) - request.method = 'GET' - request.params = {} - self.assertEqual(wrapper(ctx, request), 'view1') - - ctx = DummyContext() - request = self._makeRequest(config) - request.params = {} - request.method = 'POST' - self.assertEqual(wrapper(ctx, request), 'view2') - - ctx = DummyContext() - request = self._makeRequest(config) - request.params = {'param':'1'} - request.method = 'GET' - self.assertEqual(wrapper(ctx, request), 'view3') - - ctx = DummyContext() - directlyProvides(ctx, IDummy) - request = self._makeRequest(config) - request.method = 'GET' - request.params = {} - self.assertEqual(wrapper(ctx, request), 'view4') - - ctx = DummyContext() - request = self._makeRequest(config) - request.method = 'POST' - request.params = {'param':'1'} - self.assertEqual(wrapper(ctx, request), 'view5') - - ctx = DummyContext() - directlyProvides(ctx, IDummy) - request = self._makeRequest(config) - request.params = {} - request.method = 'POST' - self.assertEqual(wrapper(ctx, request), 'view6') - - ctx = DummyContext() - directlyProvides(ctx, IDummy) - request = self._makeRequest(config) - request.method = 'GET' - request.params = {'param':'1'} - self.assertEqual(wrapper(ctx, request), 'view7') - - ctx = DummyContext() - directlyProvides(ctx, IDummy) - request = self._makeRequest(config) - request.method = 'POST' - request.params = {'param':'1'} - self.assertEqual(wrapper(ctx, request), 'view8') - - def test_add_view_with_template_renderer(self): - class view(object): - def __init__(self, context, request): - self.request = request - self.context = context - - def __call__(self): - return {'a':'1'} - config = self._makeOne() - renderer = self._registerRenderer(config) - fixture = 'repoze.bfg.tests:fixtures/minimal.txt' - config.add_view(view=view, renderer=fixture) - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - result = wrapper(None, request) - self.assertEqual(result.body, 'Hello!') - self.assertEqual(renderer.path, 'repoze.bfg.tests:fixtures/minimal.txt') - - def test_add_view_with_template_renderer_no_callable(self): - config = self._makeOne() - renderer = self._registerRenderer(config) - fixture = 'repoze.bfg.tests:fixtures/minimal.txt' - config.add_view(view=None, renderer=fixture) - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - result = wrapper(None, request) - self.assertEqual(result.body, 'Hello!') - self.assertEqual(renderer.path, 'repoze.bfg.tests:fixtures/minimal.txt') - - def test_add_view_with_request_type_as_iface(self): - from zope.interface import directlyProvides - def view(context, request): - return 'OK' - config = self._makeOne() - config.add_view(request_type=IDummy, view=view) - wrapper = self._getViewCallable(config, None) - request = self._makeRequest(config) - directlyProvides(request, IDummy) - result = wrapper(None, request) - self.assertEqual(result, 'OK') - - def test_add_view_with_request_type_as_noniface(self): - from repoze.bfg.exceptions import ConfigurationError - view = lambda *arg: 'OK' - config = self._makeOne() - self.assertRaises(ConfigurationError, - config.add_view, view, '', None, None, object) - - def test_add_view_with_route_name(self): - from zope.component import ComponentLookupError - view = lambda *arg: 'OK' - config = self._makeOne() - config.add_view(view=view, route_name='foo') - self.assertEqual(len(config.registry.deferred_route_views), 1) - infos = config.registry.deferred_route_views['foo'] - self.assertEqual(len(infos), 1) - info = infos[0] - self.assertEqual(info['route_name'], 'foo') - self.assertEqual(info['view'], view) - self.assertRaises(ComponentLookupError, - self._getRouteRequestIface, config, 'foo') - wrapper = self._getViewCallable(config, None) - self.assertEqual(wrapper, None) - config.add_route('foo', '/a/b') - request_iface = self._getRouteRequestIface(config, 'foo') - self.failIfEqual(request_iface, None) - wrapper = self._getViewCallable(config, request_iface=request_iface) - self.failIfEqual(wrapper, None) - self.assertEqual(wrapper(None, None), 'OK') - - def test_deferred_route_views_retains_custom_predicates(self): - view = lambda *arg: 'OK' - config = self._makeOne() - config.add_view(view=view, route_name='foo', custom_predicates=('123',)) - self.assertEqual(len(config.registry.deferred_route_views), 1) - infos = config.registry.deferred_route_views['foo'] - self.assertEqual(len(infos), 1) - info = infos[0] - self.assertEqual(info['route_name'], 'foo') - self.assertEqual(info['custom_predicates'], ('123',)) - - def test_add_view_with_route_name_exception(self): - from zope.interface import implementedBy - from zope.component import ComponentLookupError - view = lambda *arg: 'OK' - config = self._makeOne() - config.add_view(view=view, route_name='foo', context=RuntimeError) - self.assertEqual(len(config.registry.deferred_route_views), 1) - infos = config.registry.deferred_route_views['foo'] - self.assertEqual(len(infos), 1) - info = infos[0] - self.assertEqual(info['route_name'], 'foo') - self.assertEqual(info['view'], view) - self.assertRaises(ComponentLookupError, - self._getRouteRequestIface, config, 'foo') - wrapper_exc_view = self._getViewCallable( - config, ctx_iface=implementedBy(RuntimeError), - exception_view=True) - self.assertEqual(wrapper_exc_view, None) - config.add_route('foo', '/a/b') - request_iface = self._getRouteRequestIface(config, 'foo') - self.failIfEqual(request_iface, None) - wrapper_exc_view = self._getViewCallable( - config, ctx_iface=implementedBy(RuntimeError), - request_iface=request_iface, exception_view=True) - self.failIfEqual(wrapper_exc_view, None) - wrapper = self._getViewCallable( - config, ctx_iface=implementedBy(RuntimeError), - request_iface=request_iface) - self.assertEqual(wrapper_exc_view, wrapper) - self.assertEqual(wrapper_exc_view(None, None), 'OK') - - def test_add_view_with_request_method_true(self): - view = lambda *arg: 'OK' - config = self._makeOne() - config.add_view(view=view, request_method='POST') - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - request.method = 'POST' - self.assertEqual(wrapper(None, request), 'OK') - - def test_add_view_with_request_method_false(self): - view = lambda *arg: 'OK' - config = self._makeOne() - config.add_view(view=view, request_method='POST') - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - request.method = 'GET' - self._assertNotFound(wrapper, None, request) - - def test_add_view_with_request_param_noval_true(self): - view = lambda *arg: 'OK' - config = self._makeOne() - config.add_view(view=view, request_param='abc') - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - request.params = {'abc':''} - self.assertEqual(wrapper(None, request), 'OK') - - def test_add_view_with_request_param_noval_false(self): - view = lambda *arg: 'OK' - config = self._makeOne() - config.add_view(view=view, request_param='abc') - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - request.params = {} - self._assertNotFound(wrapper, None, request) - - def test_add_view_with_request_param_val_true(self): - view = lambda *arg: 'OK' - config = self._makeOne() - config.add_view(view=view, request_param='abc=123') - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - request.params = {'abc':'123'} - self.assertEqual(wrapper(None, request), 'OK') - - def test_add_view_with_request_param_val_false(self): - view = lambda *arg: 'OK' - config = self._makeOne() - config.add_view(view=view, request_param='abc=123') - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - request.params = {'abc':''} - self._assertNotFound(wrapper, None, request) - - def test_add_view_with_xhr_true(self): - view = lambda *arg: 'OK' - config = self._makeOne() - config.add_view(view=view, xhr=True) - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - request.is_xhr = True - self.assertEqual(wrapper(None, request), 'OK') - - def test_add_view_with_xhr_false(self): - view = lambda *arg: 'OK' - config = self._makeOne() - config.add_view(view=view, xhr=True) - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - request.is_xhr = False - self._assertNotFound(wrapper, None, request) - - def test_add_view_with_header_badregex(self): - from repoze.bfg.exceptions import ConfigurationError - view = lambda *arg: 'OK' - config = self._makeOne() - self.assertRaises(ConfigurationError, - config.add_view, view=view, header='Host:a\\') - - def test_add_view_with_header_noval_match(self): - view = lambda *arg: 'OK' - config = self._makeOne() - config.add_view(view=view, header='Host') - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - request.headers = {'Host':'whatever'} - self.assertEqual(wrapper(None, request), 'OK') - - def test_add_view_with_header_noval_nomatch(self): - view = lambda *arg: 'OK' - config = self._makeOne() - config.add_view(view=view, header='Host') - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - request.headers = {'NotHost':'whatever'} - self._assertNotFound(wrapper, None, request) - - def test_add_view_with_header_val_match(self): - view = lambda *arg: 'OK' - config = self._makeOne() - config.add_view(view=view, header=r'Host:\d') - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - request.headers = {'Host':'1'} - self.assertEqual(wrapper(None, request), 'OK') - - def test_add_view_with_header_val_nomatch(self): - view = lambda *arg: 'OK' - config = self._makeOne() - config.add_view(view=view, header=r'Host:\d') - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - request.headers = {'Host':'abc'} - self._assertNotFound(wrapper, None, request) - - def test_add_view_with_header_val_missing(self): - from repoze.bfg.exceptions import NotFound - view = lambda *arg: 'OK' - config = self._makeOne() - config.add_view(view=view, header=r'Host:\d') - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - request.headers = {'NoHost':'1'} - self.assertRaises(NotFound, wrapper, None, request) - - def test_add_view_with_accept_match(self): - view = lambda *arg: 'OK' - config = self._makeOne() - config.add_view(view=view, accept='text/xml') - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - request.accept = ['text/xml'] - self.assertEqual(wrapper(None, request), 'OK') - - def test_add_view_with_accept_nomatch(self): - view = lambda *arg: 'OK' - config = self._makeOne() - config.add_view(view=view, accept='text/xml') - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - request.accept = ['text/html'] - self._assertNotFound(wrapper, None, request) - - def test_add_view_with_containment_true(self): - from zope.interface import directlyProvides - view = lambda *arg: 'OK' - config = self._makeOne() - config.add_view(view=view, containment=IDummy) - wrapper = self._getViewCallable(config) - context = DummyContext() - directlyProvides(context, IDummy) - self.assertEqual(wrapper(context, None), 'OK') - - def test_add_view_with_containment_false(self): - view = lambda *arg: 'OK' - config = self._makeOne() - config.add_view(view=view, containment=IDummy) - wrapper = self._getViewCallable(config) - context = DummyContext() - self._assertNotFound(wrapper, context, None) - - def test_add_view_with_containment_dottedname(self): - from zope.interface import directlyProvides - view = lambda *arg: 'OK' - config = self._makeOne() - config.add_view( - view=view, - containment='repoze.bfg.tests.test_configuration.IDummy') - wrapper = self._getViewCallable(config) - context = DummyContext() - directlyProvides(context, IDummy) - self.assertEqual(wrapper(context, None), 'OK') - - def test_add_view_with_path_info_badregex(self): - from repoze.bfg.exceptions import ConfigurationError - view = lambda *arg: 'OK' - config = self._makeOne() - self.assertRaises(ConfigurationError, - config.add_view, view=view, path_info='\\') - - def test_add_view_with_path_info_match(self): - view = lambda *arg: 'OK' - config = self._makeOne() - config.add_view(view=view, path_info='/foo') - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - request.path_info = '/foo' - self.assertEqual(wrapper(None, request), 'OK') - - def test_add_view_with_path_info_nomatch(self): - view = lambda *arg: 'OK' - config = self._makeOne() - config.add_view(view=view, path_info='/foo') - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - request.path_info = '/' - self._assertNotFound(wrapper, None, request) - - def test_add_view_with_custom_predicates_match(self): - view = lambda *arg: 'OK' - config = self._makeOne() - def pred1(context, request): - return True - def pred2(context, request): - return True - predicates = (pred1, pred2) - config.add_view(view=view, custom_predicates=predicates) - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - self.assertEqual(wrapper(None, request), 'OK') - - def test_add_view_with_custom_predicates_nomatch(self): - view = lambda *arg: 'OK' - config = self._makeOne() - def pred1(context, request): - return True - def pred2(context, request): - return False - predicates = (pred1, pred2) - config.add_view(view=view, custom_predicates=predicates) - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - self._assertNotFound(wrapper, None, request) - - def test_add_view_custom_predicate_bests_standard_predicate(self): - view = lambda *arg: 'OK' - view2 = lambda *arg: 'NOT OK' - config = self._makeOne() - def pred1(context, request): - return True - config.add_view(view=view, custom_predicates=(pred1,)) - config.add_view(view=view2, request_method='GET') - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - request.method = 'GET' - self.assertEqual(wrapper(None, request), 'OK') - - def test_add_view_custom_more_preds_first_bests_fewer_preds_last(self): - view = lambda *arg: 'OK' - view2 = lambda *arg: 'NOT OK' - config = self._makeOne() - config.add_view(view=view, request_method='GET', xhr=True) - config.add_view(view=view2, request_method='GET') - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - request.method = 'GET' - request.is_xhr = True - self.assertEqual(wrapper(None, request), 'OK') - - def test_add_view_same_predicates(self): - view2 = lambda *arg: 'second' - view1 = lambda *arg: 'first' - config = self._makeOne() - config.add_view(view=view1) - config.add_view(view=view2) - view = self._getViewCallable(config) - request = self._makeRequest(config) - self.assertEqual(view(None, request), 'second') - - def test_add_view_with_permission(self): - view1 = lambda *arg: 'OK' - outerself = self - class DummyPolicy(object): - def effective_principals(self, r): - outerself.assertEqual(r, request) - return ['abc'] - def permits(self, context, principals, permission): - outerself.assertEqual(context, None) - outerself.assertEqual(principals, ['abc']) - outerself.assertEqual(permission, 'view') - return True - policy = DummyPolicy() - config = self._makeOne(authorization_policy=policy, - authentication_policy=policy) - config.add_view(view=view1, permission='view') - view = self._getViewCallable(config) - request = self._makeRequest(config) - self.assertEqual(view(None, request), 'OK') - - def test_add_view_with_default_permission_no_explicit_permission(self): - view1 = lambda *arg: 'OK' - outerself = self - class DummyPolicy(object): - def effective_principals(self, r): - outerself.assertEqual(r, request) - return ['abc'] - def permits(self, context, principals, permission): - outerself.assertEqual(context, None) - outerself.assertEqual(principals, ['abc']) - outerself.assertEqual(permission, 'view') - return True - policy = DummyPolicy() - config = self._makeOne(authorization_policy=policy, - authentication_policy=policy, - default_permission='view') - config.add_view(view=view1) - view = self._getViewCallable(config) - request = self._makeRequest(config) - self.assertEqual(view(None, request), 'OK') - - def test_add_view_with_no_default_permission_no_explicit_permission(self): - view1 = lambda *arg: 'OK' - class DummyPolicy(object): pass # wont be called - policy = DummyPolicy() - config = self._makeOne(authorization_policy=policy, - authentication_policy=policy) - config.add_view(view=view1) - view = self._getViewCallable(config) - request = self._makeRequest(config) - self.assertEqual(view(None, request), 'OK') - - def _assertRoute(self, config, name, path, num_predicates=0): - from repoze.bfg.interfaces import IRoutesMapper - mapper = config.registry.getUtility(IRoutesMapper) - routes = mapper.get_routes() - route = routes[0] - self.assertEqual(len(routes), 1) - self.assertEqual(route.name, name) - self.assertEqual(route.path, path) - self.assertEqual(len(routes[0].predicates), num_predicates) - return route - - def test_get_routes_mapper_not_yet_registered(self): - config = self._makeOne() - mapper = config.get_routes_mapper() - self.assertEqual(mapper.routelist, []) - - def test_get_routes_mapper_already_registered(self): - from repoze.bfg.interfaces import IRoutesMapper - config = self._makeOne() - mapper = object() - config.registry.registerUtility(mapper, IRoutesMapper) - result = config.get_routes_mapper() - self.assertEqual(result, mapper) - - def test_add_route_defaults(self): - config = self._makeOne() - route = config.add_route('name', 'path') - self._assertRoute(config, 'name', 'path') - self.assertEqual(route.name, 'name') - - def test_add_route_with_factory(self): - config = self._makeOne() - factory = object() - route = config.add_route('name', 'path', factory=factory) - self.assertEqual(route.factory, factory) - - def test_add_route_with_factory_dottedname(self): - config = self._makeOne() - route = config.add_route( - 'name', 'path', - factory='repoze.bfg.tests.test_configuration.dummyfactory') - self.assertEqual(route.factory, dummyfactory) - - def test_add_route_with_xhr(self): - config = self._makeOne() - config.add_route('name', 'path', xhr=True) - route = self._assertRoute(config, 'name', 'path', 1) - predicate = route.predicates[0] - request = self._makeRequest(config) - request.is_xhr = True - self.assertEqual(predicate(None, request), True) - request = self._makeRequest(config) - request.is_xhr = False - self.assertEqual(predicate(None, request), False) - - def test_add_route_with_request_method(self): - config = self._makeOne() - config.add_route('name', 'path', request_method='GET') - route = self._assertRoute(config, 'name', 'path', 1) - predicate = route.predicates[0] - request = self._makeRequest(config) - request.method = 'GET' - self.assertEqual(predicate(None, request), True) - request = self._makeRequest(config) - request.method = 'POST' - self.assertEqual(predicate(None, request), False) - - def test_add_route_with_path_info(self): - config = self._makeOne() - config.add_route('name', 'path', path_info='/foo') - route = self._assertRoute(config, 'name', 'path', 1) - predicate = route.predicates[0] - request = self._makeRequest(config) - request.path_info = '/foo' - self.assertEqual(predicate(None, request), True) - request = self._makeRequest(config) - request.path_info = '/' - self.assertEqual(predicate(None, request), False) - - def test_add_route_with_request_param(self): - config = self._makeOne() - config.add_route('name', 'path', request_param='abc') - route = self._assertRoute(config, 'name', 'path', 1) - predicate = route.predicates[0] - request = self._makeRequest(config) - request.params = {'abc':'123'} - self.assertEqual(predicate(None, request), True) - request = self._makeRequest(config) - request.params = {} - self.assertEqual(predicate(None, request), False) - - def test_add_route_with_custom_predicates(self): - config = self._makeOne() - def pred1(context, request): pass - def pred2(context, request): pass - config.add_route('name', 'path', custom_predicates=(pred1, pred2)) - route = self._assertRoute(config, 'name', 'path', 2) - self.assertEqual(route.predicates, [pred1, pred2]) - - def test_add_route_with_header(self): - config = self._makeOne() - config.add_route('name', 'path', header='Host') - route = self._assertRoute(config, 'name', 'path', 1) - predicate = route.predicates[0] - request = self._makeRequest(config) - request.headers = {'Host':'example.com'} - self.assertEqual(predicate(None, request), True) - request = self._makeRequest(config) - request.headers = {} - self.assertEqual(predicate(None, request), False) - - def test_add_route_with_accept(self): - config = self._makeOne() - config.add_route('name', 'path', accept='text/xml') - route = self._assertRoute(config, 'name', 'path', 1) - predicate = route.predicates[0] - request = self._makeRequest(config) - request.accept = ['text/xml'] - self.assertEqual(predicate(None, request), True) - request = self._makeRequest(config) - request.accept = ['text/html'] - self.assertEqual(predicate(None, request), False) - - def test_add_route_with_view(self): - config = self._makeOne() - view = lambda *arg: 'OK' - config.add_route('name', 'path', view=view) - request_type = self._getRouteRequestIface(config, 'name') - wrapper = self._getViewCallable(config, None, request_type) - self.assertEqual(wrapper(None, None), 'OK') - self._assertRoute(config, 'name', 'path') - - def test_add_route_with_view_context(self): - config = self._makeOne() - view = lambda *arg: 'OK' - config.add_route('name', 'path', view=view, view_context=IDummy) - request_type = self._getRouteRequestIface(config, 'name') - wrapper = self._getViewCallable(config, IDummy, request_type) - self.assertEqual(wrapper(None, None), 'OK') - self._assertRoute(config, 'name', 'path') - wrapper = self._getViewCallable(config, IOther, request_type) - self.assertEqual(wrapper, None) - - def test_add_route_with_view_exception(self): - from zope.interface import implementedBy - config = self._makeOne() - view = lambda *arg: 'OK' - config.add_route('name', 'path', view=view, view_context=RuntimeError) - request_type = self._getRouteRequestIface(config, 'name') - wrapper = self._getViewCallable( - config, ctx_iface=implementedBy(RuntimeError), - request_iface=request_type, exception_view=True) - self.assertEqual(wrapper(None, None), 'OK') - self._assertRoute(config, 'name', 'path') - wrapper = self._getViewCallable( - config, ctx_iface=IOther, - request_iface=request_type, exception_view=True) - self.assertEqual(wrapper, None) - - def test_add_route_with_view_for(self): - config = self._makeOne() - view = lambda *arg: 'OK' - config.add_route('name', 'path', view=view, view_for=IDummy) - request_type = self._getRouteRequestIface(config, 'name') - wrapper = self._getViewCallable(config, IDummy, request_type) - self.assertEqual(wrapper(None, None), 'OK') - self._assertRoute(config, 'name', 'path') - wrapper = self._getViewCallable(config, IOther, request_type) - self.assertEqual(wrapper, None) - - def test_add_route_with_for_(self): - config = self._makeOne() - view = lambda *arg: 'OK' - config.add_route('name', 'path', view=view, for_=IDummy) - request_type = self._getRouteRequestIface(config, 'name') - wrapper = self._getViewCallable(config, IDummy, request_type) - self.assertEqual(wrapper(None, None), 'OK') - self._assertRoute(config, 'name', 'path') - wrapper = self._getViewCallable(config, IOther, request_type) - self.assertEqual(wrapper, None) - - def test_add_route_with_view_renderer(self): - config = self._makeOne() - self._registerRenderer(config) - view = lambda *arg: 'OK' - config.add_route('name', 'path', view=view, - view_renderer='fixtures/minimal.txt') - request_type = self._getRouteRequestIface(config, 'name') - wrapper = self._getViewCallable(config, None, request_type) - self._assertRoute(config, 'name', 'path') - self.assertEqual(wrapper(None, None).body, 'Hello!') - - def test_add_route_with_view_attr(self): - config = self._makeOne() - self._registerRenderer(config) - class View(object): - def __init__(self, context, request): - pass - def alt(self): - return 'OK' - config.add_route('name', 'path', view=View, view_attr='alt') - request_type = self._getRouteRequestIface(config, 'name') - wrapper = self._getViewCallable(config, None, request_type) - self._assertRoute(config, 'name', 'path') - self.assertEqual(wrapper(None, None), 'OK') - - def test_add_route_with_view_renderer_alias(self): - config = self._makeOne() - self._registerRenderer(config) - view = lambda *arg: 'OK' - config.add_route('name', 'path', view=view, - renderer='fixtures/minimal.txt') - request_type = self._getRouteRequestIface(config, 'name') - wrapper = self._getViewCallable(config, None, request_type) - self._assertRoute(config, 'name', 'path') - self.assertEqual(wrapper(None, None).body, 'Hello!') - - def test_add_route_with_view_permission(self): - from repoze.bfg.interfaces import IAuthenticationPolicy - from repoze.bfg.interfaces import IAuthorizationPolicy - config = self._makeOne() - policy = lambda *arg: None - config.registry.registerUtility(policy, IAuthenticationPolicy) - config.registry.registerUtility(policy, IAuthorizationPolicy) - view = lambda *arg: 'OK' - config.add_route('name', 'path', view=view, view_permission='edit') - request_type = self._getRouteRequestIface(config, 'name') - wrapper = self._getViewCallable(config, None, request_type) - self._assertRoute(config, 'name', 'path') - self.failUnless(hasattr(wrapper, '__call_permissive__')) - - def test_add_route_with_view_permission_alias(self): - from repoze.bfg.interfaces import IAuthenticationPolicy - from repoze.bfg.interfaces import IAuthorizationPolicy - config = self._makeOne() - policy = lambda *arg: None - config.registry.registerUtility(policy, IAuthenticationPolicy) - config.registry.registerUtility(policy, IAuthorizationPolicy) - view = lambda *arg: 'OK' - config.add_route('name', 'path', view=view, permission='edit') - request_type = self._getRouteRequestIface(config, 'name') - wrapper = self._getViewCallable(config, None, request_type) - self._assertRoute(config, 'name', 'path') - self.failUnless(hasattr(wrapper, '__call_permissive__')) - - def test_add_route_no_pattern_with_path(self): - config = self._makeOne() - route = config.add_route('name', path='path') - self._assertRoute(config, 'name', 'path') - self.assertEqual(route.name, 'name') - - def test_add_route_no_path_no_pattern(self): - from repoze.bfg.exceptions import ConfigurationError - config = self._makeOne() - self.assertRaises(ConfigurationError, config.add_route, 'name') - - def test_add_route_with_pregenerator(self): - config = self._makeOne() - route = config.add_route('name', 'pattern', pregenerator='123') - self.assertEqual(route.pregenerator, '123') - - def test__override_not_yet_registered(self): - from repoze.bfg.interfaces import IPackageOverrides - package = DummyPackage('package') - opackage = DummyPackage('opackage') - config = self._makeOne() - config._override(package, 'path', opackage, 'oprefix', - PackageOverrides=DummyOverrides) - overrides = config.registry.queryUtility(IPackageOverrides, - name='package') - self.assertEqual(overrides.inserted, [('path', 'opackage', 'oprefix')]) - self.assertEqual(overrides.package, package) - - def test__override_already_registered(self): - from repoze.bfg.interfaces import IPackageOverrides - package = DummyPackage('package') - opackage = DummyPackage('opackage') - overrides = DummyOverrides(package) - config = self._makeOne() - config.registry.registerUtility(overrides, IPackageOverrides, - name='package') - config._override(package, 'path', opackage, 'oprefix', - PackageOverrides=DummyOverrides) - self.assertEqual(overrides.inserted, [('path', 'opackage', 'oprefix')]) - self.assertEqual(overrides.package, package) - - def test_add_static_here_no_utility_registered(self): - from repoze.bfg.static import PackageURLParser - from zope.interface import implementedBy - from repoze.bfg.static import StaticURLInfo - from repoze.bfg.interfaces import IView - from repoze.bfg.interfaces import IViewClassifier - config = self._makeOne() - config.add_static_view('static', 'fixtures/static') - request_type = self._getRouteRequestIface(config, 'static/') - route = self._assertRoute(config, 'static/', 'static/*subpath') - self.assertEqual(route.factory.__class__, type(lambda x: x)) - iface = implementedBy(StaticURLInfo) - wrapped = config.registry.adapters.lookup( - (IViewClassifier, request_type, iface), IView, name='') - request = self._makeRequest(config) - self.assertEqual(wrapped(None, request).__class__, PackageURLParser) - - def test_add_static_view_package_relative(self): - from repoze.bfg.interfaces import IStaticURLInfo - info = DummyStaticURLInfo() - config = self._makeOne() - config.registry.registerUtility(info, IStaticURLInfo) - config.add_static_view('static', 'repoze.bfg.tests:fixtures/static') - self.assertEqual(info.added, - [('static', 'repoze.bfg.tests:fixtures/static', {})]) - - def test_add_static_view_package_here_relative(self): - from repoze.bfg.interfaces import IStaticURLInfo - info = DummyStaticURLInfo() - config = self._makeOne() - config.registry.registerUtility(info, IStaticURLInfo) - config.add_static_view('static', 'fixtures/static') - self.assertEqual(info.added, - [('static', 'repoze.bfg.tests:fixtures/static', {})]) - - def test_add_static_view_absolute(self): - import os - from repoze.bfg.interfaces import IStaticURLInfo - info = DummyStaticURLInfo() - config = self._makeOne() - config.registry.registerUtility(info, IStaticURLInfo) - here = os.path.dirname(__file__) - static_path = os.path.join(here, 'fixtures', 'static') - config.add_static_view('static', static_path) - self.assertEqual(info.added, - [('static', static_path, {})]) - - def test_set_notfound_view(self): - from zope.interface import implementedBy - from repoze.bfg.interfaces import IRequest - from repoze.bfg.exceptions import NotFound - config = self._makeOne() - view = lambda *arg: arg - config.set_notfound_view(view) - request = self._makeRequest(config) - view = self._getViewCallable(config, ctx_iface=implementedBy(NotFound), - request_iface=IRequest) - result = view(None, request) - self.assertEqual(result, (None, request)) - - def test_set_notfound_view_request_has_context(self): - from zope.interface import implementedBy - from repoze.bfg.interfaces import IRequest - from repoze.bfg.exceptions import NotFound - config = self._makeOne() - view = lambda *arg: arg - config.set_notfound_view(view) - request = self._makeRequest(config) - request.context = 'abc' - view = self._getViewCallable(config, ctx_iface=implementedBy(NotFound), - request_iface=IRequest) - result = view(None, request) - self.assertEqual(result, ('abc', request)) - - def test_set_forbidden_view(self): - from zope.interface import implementedBy - from repoze.bfg.interfaces import IRequest - from repoze.bfg.exceptions import Forbidden - config = self._makeOne() - view = lambda *arg: 'OK' - config.set_forbidden_view(view) - request = self._makeRequest(config) - view = self._getViewCallable(config, ctx_iface=implementedBy(Forbidden), - request_iface=IRequest) - result = view(None, request) - self.assertEqual(result, 'OK') - - def test_set_forbidden_view_request_has_context(self): - from zope.interface import implementedBy - from repoze.bfg.interfaces import IRequest - from repoze.bfg.exceptions import Forbidden - config = self._makeOne() - view = lambda *arg: arg - config.set_forbidden_view(view) - request = self._makeRequest(config) - request.context = 'abc' - view = self._getViewCallable(config, ctx_iface=implementedBy(Forbidden), - request_iface=IRequest) - result = view(None, request) - self.assertEqual(result, ('abc', request)) - - def test__set_authentication_policy(self): - from repoze.bfg.interfaces import IAuthenticationPolicy - config = self._makeOne() - policy = object() - config._set_authentication_policy(policy) - self.assertEqual( - config.registry.getUtility(IAuthenticationPolicy), policy) - - def test__set_authorization_policy(self): - from repoze.bfg.interfaces import IAuthorizationPolicy - config = self._makeOne() - policy = object() - config._set_authorization_policy(policy) - self.assertEqual( - config.registry.getUtility(IAuthorizationPolicy), policy) - - def test_set_locale_negotiator(self): - from repoze.bfg.interfaces import ILocaleNegotiator - config = self._makeOne() - def negotiator(request): pass - config.set_locale_negotiator(negotiator) - self.assertEqual(config.registry.getUtility(ILocaleNegotiator), - negotiator) - - def test_set_locale_negotiator_dottedname(self): - from repoze.bfg.interfaces import ILocaleNegotiator - config = self._makeOne() - config.set_locale_negotiator( - 'repoze.bfg.tests.test_configuration.dummyfactory') - self.assertEqual(config.registry.getUtility(ILocaleNegotiator), - dummyfactory) - - def test_set_request_factory(self): - from repoze.bfg.interfaces import IRequestFactory - config = self._makeOne() - factory = object() - config.set_request_factory(factory) - self.assertEqual(config.registry.getUtility(IRequestFactory), factory) - - def test_set_request_factory_dottedname(self): - from repoze.bfg.interfaces import IRequestFactory - config = self._makeOne() - config.set_request_factory( - 'repoze.bfg.tests.test_configuration.dummyfactory') - self.assertEqual(config.registry.getUtility(IRequestFactory), - dummyfactory) - - def test_set_renderer_globals_factory(self): - from repoze.bfg.interfaces import IRendererGlobalsFactory - config = self._makeOne() - factory = object() - config.set_renderer_globals_factory(factory) - self.assertEqual(config.registry.getUtility(IRendererGlobalsFactory), - factory) - - def test_set_renderer_globals_factory_dottedname(self): - from repoze.bfg.interfaces import IRendererGlobalsFactory - config = self._makeOne() - config.set_renderer_globals_factory( - 'repoze.bfg.tests.test_configuration.dummyfactory') - self.assertEqual(config.registry.getUtility(IRendererGlobalsFactory), - dummyfactory) - - def test_set_default_permission(self): - from repoze.bfg.interfaces import IDefaultPermission - config = self._makeOne() - config.set_default_permission('view') - self.assertEqual(config.registry.getUtility(IDefaultPermission), - 'view') - - def test_add_translation_dirs_missing_dir(self): - from repoze.bfg.exceptions import ConfigurationError - config = self._makeOne() - self.assertRaises(ConfigurationError, - config.add_translation_dirs, - '/wont/exist/on/my/system') - - def test_add_translation_dirs_resource_spec(self): - import os - from repoze.bfg.interfaces import ITranslationDirectories - config = self._makeOne() - config.add_translation_dirs('repoze.bfg.tests.localeapp:locale') - here = os.path.dirname(__file__) - locale = os.path.join(here, 'localeapp', 'locale') - self.assertEqual(config.registry.getUtility(ITranslationDirectories), - [locale]) - - def test_add_translation_dirs_registers_chameleon_translate(self): - from repoze.bfg.interfaces import IChameleonTranslate - from repoze.bfg.threadlocal import manager - request = DummyRequest() - config = self._makeOne() - manager.push({'request':request, 'registry':config.registry}) - try: - config.add_translation_dirs('repoze.bfg.tests.localeapp:locale') - translate = config.registry.getUtility(IChameleonTranslate) - self.assertEqual(translate('Approve'), u'Approve') - finally: - manager.pop() - - def test_add_translation_dirs_abspath(self): - import os - from repoze.bfg.interfaces import ITranslationDirectories - config = self._makeOne() - here = os.path.dirname(__file__) - locale = os.path.join(here, 'localeapp', 'locale') - config.add_translation_dirs(locale) - self.assertEqual(config.registry.getUtility(ITranslationDirectories), - [locale]) - - def test_derive_view_function(self): - def view(request): - return 'OK' - config = self._makeOne() - result = config.derive_view(view) - self.failIf(result is view) - self.assertEqual(result(None, None), 'OK') - - def test_derive_view_dottedname(self): - config = self._makeOne() - result = config.derive_view( - 'repoze.bfg.tests.test_configuration.dummy_view') - self.failIf(result is dummy_view) - self.assertEqual(result(None, None), 'OK') - - def test_derive_view_with_renderer(self): - def view(request): - return 'OK' - config = self._makeOne() - class moo(object): - def __init__(self, *arg, **kw): - pass - def __call__(self, *arg, **kw): - return 'moo' - config.add_renderer('moo', moo) - result = config.derive_view(view, renderer='moo') - self.failIf(result is view) - self.assertEqual(result(None, None).body, 'moo') - - def test_derive_view_class_without_attr(self): - class View(object): - def __init__(self, request): - pass - def __call__(self): - return 'OK' - config = self._makeOne() - result = config.derive_view(View) - self.assertEqual(result(None, None), 'OK') - - def test_derive_view_class_with_attr(self): - class View(object): - def __init__(self, request): - pass - def another(self): - return 'OK' - config = self._makeOne() - result = config.derive_view(View, attr='another') - self.assertEqual(result(None, None), 'OK') - - def test__derive_view_as_function_context_and_request(self): - def view(context, request): - return 'OK' - config = self._makeOne() - result = config._derive_view(view) - self.failUnless(result is view) - self.failIf(hasattr(result, '__call_permissive__')) - self.assertEqual(view(None, None), 'OK') - - def test__derive_view_as_function_requestonly(self): - def view(request): - return 'OK' - config = self._makeOne() - result = config._derive_view(view) - self.failIf(result is view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.failIf(hasattr(result, '__call_permissive__')) - self.assertEqual(result(None, None), 'OK') - - def test__derive_view_as_newstyle_class_context_and_request(self): - class view(object): - def __init__(self, context, request): - pass - def __call__(self): - return 'OK' - config = self._makeOne() - result = config._derive_view(view) - self.failIf(result is view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.failIf(hasattr(result, '__call_permissive__')) - self.assertEqual(result(None, None), 'OK') - - def test__derive_view_as_newstyle_class_requestonly(self): - class view(object): - def __init__(self, context, request): - pass - def __call__(self): - return 'OK' - config = self._makeOne() - result = config._derive_view(view) - self.failIf(result is view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.failIf(hasattr(result, '__call_permissive__')) - self.assertEqual(result(None, None), 'OK') - - def test__derive_view_as_oldstyle_class_context_and_request(self): - class view: - def __init__(self, context, request): - pass - def __call__(self): - return 'OK' - config = self._makeOne() - result = config._derive_view(view) - self.failIf(result is view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.failIf(hasattr(result, '__call_permissive__')) - self.assertEqual(result(None, None), 'OK') - - def test__derive_view_as_oldstyle_class_requestonly(self): - class view: - def __init__(self, context, request): - pass - def __call__(self): - return 'OK' - config = self._makeOne() - result = config._derive_view(view) - self.failIf(result is view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.failIf(hasattr(result, '__call_permissive__')) - self.assertEqual(result(None, None), 'OK') - - def test__derive_view_as_instance_context_and_request(self): - class View: - def __call__(self, context, request): - return 'OK' - view = View() - config = self._makeOne() - result = config._derive_view(view) - self.failUnless(result is view) - self.failIf(hasattr(result, '__call_permissive__')) - self.assertEqual(result(None, None), 'OK') - - def test__derive_view_as_instance_requestonly(self): - class View: - def __call__(self, request): - return 'OK' - view = View() - config = self._makeOne() - result = config._derive_view(view) - self.failIf(result is view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.failUnless('instance' in result.__name__) - self.failIf(hasattr(result, '__call_permissive__')) - self.assertEqual(result(None, None), 'OK') - - def test__derive_view_with_debug_authorization_no_authpol(self): - view = lambda *arg: 'OK' - config = self._makeOne() - self._registerSettings(config, - debug_authorization=True, reload_templates=True) - logger = self._registerLogger(config) - result = config._derive_view(view, permission='view') - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.failIf(hasattr(result, '__call_permissive__')) - request = self._makeRequest(config) - request.view_name = 'view_name' - request.url = 'url' - self.assertEqual(result(None, request), 'OK') - self.assertEqual(len(logger.messages), 1) - self.assertEqual(logger.messages[0], - "debug_authorization of url url (view name " - "'view_name' against context None): Allowed " - "(no authorization policy in use)") - - def test__derive_view_with_debug_authorization_no_permission(self): - view = lambda *arg: 'OK' - config = self._makeOne() - self._registerSettings(config, - debug_authorization=True, reload_templates=True) - self._registerSecurityPolicy(config, True) - logger = self._registerLogger(config) - result = config._derive_view(view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.failIf(hasattr(result, '__call_permissive__')) - request = self._makeRequest(config) - request.view_name = 'view_name' - request.url = 'url' - self.assertEqual(result(None, request), 'OK') - self.assertEqual(len(logger.messages), 1) - self.assertEqual(logger.messages[0], - "debug_authorization of url url (view name " - "'view_name' against context None): Allowed (" - "no permission registered)") - - def test__derive_view_debug_auth_permission_authpol_permitted(self): - view = lambda *arg: 'OK' - config = self._makeOne() - self._registerSettings(config, debug_authorization=True, - reload_templates=True) - logger = self._registerLogger(config) - self._registerSecurityPolicy(config, True) - result = config._derive_view(view, permission='view') - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.assertEqual(result.__call_permissive__, view) - request = self._makeRequest(config) - request.view_name = 'view_name' - request.url = 'url' - self.assertEqual(result(None, request), 'OK') - self.assertEqual(len(logger.messages), 1) - self.assertEqual(logger.messages[0], - "debug_authorization of url url (view name " - "'view_name' against context None): True") - - def test__derive_view_debug_auth_permission_authpol_denied(self): - from repoze.bfg.exceptions import Forbidden - view = lambda *arg: 'OK' - config = self._makeOne() - self._registerSettings(config, - debug_authorization=True, reload_templates=True) - logger = self._registerLogger(config) - self._registerSecurityPolicy(config, False) - result = config._derive_view(view, permission='view') - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.assertEqual(result.__call_permissive__, view) - request = self._makeRequest(config) - request.view_name = 'view_name' - request.url = 'url' - self.assertRaises(Forbidden, result, None, request) - self.assertEqual(len(logger.messages), 1) - self.assertEqual(logger.messages[0], - "debug_authorization of url url (view name " - "'view_name' against context None): False") - - def test__derive_view_debug_auth_permission_authpol_denied2(self): - view = lambda *arg: 'OK' - config = self._makeOne() - self._registerSettings(config, - debug_authorization=True, reload_templates=True) - self._registerLogger(config) - self._registerSecurityPolicy(config, False) - result = config._derive_view(view, permission='view') - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - request = self._makeRequest(config) - request.view_name = 'view_name' - request.url = 'url' - permitted = result.__permitted__(None, None) - self.assertEqual(permitted, False) - - def test__derive_view_with_predicates_all(self): - view = lambda *arg: 'OK' - predicates = [] - def predicate1(context, request): - predicates.append(True) - return True - def predicate2(context, request): - predicates.append(True) - return True - config = self._makeOne() - result = config._derive_view(view, predicates=[predicate1, predicate2]) - request = self._makeRequest(config) - request.method = 'POST' - next = result(None, None) - self.assertEqual(next, 'OK') - self.assertEqual(predicates, [True, True]) - - def test__derive_view_with_predicates_checker(self): - view = lambda *arg: 'OK' - predicates = [] - def predicate1(context, request): - predicates.append(True) - return True - def predicate2(context, request): - predicates.append(True) - return True - config = self._makeOne() - result = config._derive_view(view, predicates=[predicate1, predicate2]) - request = self._makeRequest(config) - request.method = 'POST' - next = result.__predicated__(None, None) - self.assertEqual(next, True) - self.assertEqual(predicates, [True, True]) - - def test__derive_view_with_predicates_notall(self): - from repoze.bfg.exceptions import NotFound - view = lambda *arg: 'OK' - predicates = [] - def predicate1(context, request): - predicates.append(True) - return True - def predicate2(context, request): - predicates.append(True) - return False - config = self._makeOne() - result = config._derive_view(view, predicates=[predicate1, predicate2]) - request = self._makeRequest(config) - request.method = 'POST' - self.assertRaises(NotFound, result, None, None) - self.assertEqual(predicates, [True, True]) - - def test__derive_view_with_wrapper_viewname(self): - from webob import Response - from repoze.bfg.interfaces import IView - from repoze.bfg.interfaces import IViewClassifier - inner_response = Response('OK') - def inner_view(context, request): - return inner_response - def outer_view(context, request): - self.assertEqual(request.wrapped_response, inner_response) - self.assertEqual(request.wrapped_body, inner_response.body) - self.assertEqual(request.wrapped_view, inner_view) - return Response('outer ' + request.wrapped_body) - config = self._makeOne() - config.registry.registerAdapter( - outer_view, (IViewClassifier, None, None), IView, 'owrap') - result = config._derive_view(inner_view, viewname='inner', - wrapper_viewname='owrap') - self.failIf(result is inner_view) - self.assertEqual(inner_view.__module__, result.__module__) - self.assertEqual(inner_view.__doc__, result.__doc__) - request = self._makeRequest(config) - request.registry = config.registry - response = result(None, request) - self.assertEqual(response.body, 'outer OK') - - def test__derive_view_with_wrapper_viewname_notfound(self): - from webob import Response - inner_response = Response('OK') - def inner_view(context, request): - return inner_response - config = self._makeOne() - request = self._makeRequest(config) - request.registry = config.registry - wrapped = config._derive_view( - inner_view, viewname='inner', wrapper_viewname='owrap') - self.assertRaises(ValueError, wrapped, None, request) - - def test_override_resource_samename(self): - from repoze.bfg.exceptions import ConfigurationError - config = self._makeOne() - self.assertRaises(ConfigurationError, config.override_resource,'a', 'a') - - def test_override_resource_directory_with_file(self): - from repoze.bfg.exceptions import ConfigurationError - config = self._makeOne() - self.assertRaises(ConfigurationError, config.override_resource, - 'a:foo/', 'a:foo.pt') - - def test_override_resource_file_with_directory(self): - from repoze.bfg.exceptions import ConfigurationError - config = self._makeOne() - self.assertRaises(ConfigurationError, config.override_resource, - 'a:foo.pt', 'a:foo/') - - def test_override_resource_success(self): - config = self._makeOne() - override = DummyUnderOverride() - config.override_resource( - 'repoze.bfg.tests.fixtureapp:templates/foo.pt', - 'repoze.bfg.tests.fixtureapp.subpackage:templates/bar.pt', - _override=override) - from repoze.bfg.tests import fixtureapp - from repoze.bfg.tests.fixtureapp import subpackage - self.assertEqual(override.package, fixtureapp) - self.assertEqual(override.path, 'templates/foo.pt') - self.assertEqual(override.override_package, subpackage) - self.assertEqual(override.override_prefix, 'templates/bar.pt') - - def test_add_renderer(self): - from repoze.bfg.interfaces import IRendererFactory - config = self._makeOne() - renderer = object() - config.add_renderer('name', renderer) - self.assertEqual(config.registry.getUtility(IRendererFactory, 'name'), - renderer) - - def test_add_renderer_dottedname_factory(self): - from repoze.bfg.interfaces import IRendererFactory - config = self._makeOne() - import repoze.bfg.tests - config.add_renderer('name', 'repoze.bfg.tests') - self.assertEqual(config.registry.getUtility(IRendererFactory, 'name'), - repoze.bfg.tests) - - def test_scan_integration(self): - from zope.interface import alsoProvides - from repoze.bfg.interfaces import IRequest - from repoze.bfg.view import render_view_to_response - import repoze.bfg.tests.grokkedapp as package - config = self._makeOne() - config.scan(package) - - ctx = DummyContext() - req = DummyRequest() - alsoProvides(req, IRequest) - req.registry = config.registry - - req.method = 'GET' - result = render_view_to_response(ctx, req, '') - self.assertEqual(result, 'grokked') - - req.method = 'POST' - result = render_view_to_response(ctx, req, '') - self.assertEqual(result, 'grokked_post') - - result= render_view_to_response(ctx, req, 'grokked_class') - self.assertEqual(result, 'grokked_class') - - result= render_view_to_response(ctx, req, 'grokked_instance') - self.assertEqual(result, 'grokked_instance') - - result= render_view_to_response(ctx, req, 'oldstyle_grokked_class') - self.assertEqual(result, 'oldstyle_grokked_class') - - req.method = 'GET' - result = render_view_to_response(ctx, req, 'another') - self.assertEqual(result, 'another_grokked') - - req.method = 'POST' - result = render_view_to_response(ctx, req, 'another') - self.assertEqual(result, 'another_grokked_post') - - result= render_view_to_response(ctx, req, 'another_grokked_class') - self.assertEqual(result, 'another_grokked_class') - - result= render_view_to_response(ctx, req, 'another_grokked_instance') - self.assertEqual(result, 'another_grokked_instance') - - result= render_view_to_response(ctx, req, - 'another_oldstyle_grokked_class') - self.assertEqual(result, 'another_oldstyle_grokked_class') - - result = render_view_to_response(ctx, req, 'stacked1') - self.assertEqual(result, 'stacked') - - result = render_view_to_response(ctx, req, 'stacked2') - self.assertEqual(result, 'stacked') - - result = render_view_to_response(ctx, req, 'another_stacked1') - self.assertEqual(result, 'another_stacked') - - result = render_view_to_response(ctx, req, 'another_stacked2') - self.assertEqual(result, 'another_stacked') - - result = render_view_to_response(ctx, req, 'stacked_class1') - self.assertEqual(result, 'stacked_class') - - result = render_view_to_response(ctx, req, 'stacked_class2') - self.assertEqual(result, 'stacked_class') - - result = render_view_to_response(ctx, req, 'another_stacked_class1') - self.assertEqual(result, 'another_stacked_class') - - result = render_view_to_response(ctx, req, 'another_stacked_class2') - self.assertEqual(result, 'another_stacked_class') - - self.assertRaises(TypeError, - render_view_to_response, ctx, req, 'basemethod') - - result = render_view_to_response(ctx, req, 'method1') - self.assertEqual(result, 'method1') - - result = render_view_to_response(ctx, req, 'method2') - self.assertEqual(result, 'method2') - - result = render_view_to_response(ctx, req, 'stacked_method1') - self.assertEqual(result, 'stacked_method') - - result = render_view_to_response(ctx, req, 'stacked_method2') - self.assertEqual(result, 'stacked_method') - - result = render_view_to_response(ctx, req, 'subpackage_init') - self.assertEqual(result, 'subpackage_init') - - result = render_view_to_response(ctx, req, 'subpackage_notinit') - self.assertEqual(result, 'subpackage_notinit') - - result = render_view_to_response(ctx, req, 'subsubpackage_init') - self.assertEqual(result, 'subsubpackage_init') - - result = render_view_to_response(ctx, req, 'pod_notinit') - self.assertEqual(result, None) - - def test_scan_integration_dottedname_package(self): - from zope.interface import alsoProvides - from repoze.bfg.interfaces import IRequest - from repoze.bfg.view import render_view_to_response - config = self._makeOne() - config.scan('repoze.bfg.tests.grokkedapp') - - ctx = DummyContext() - req = DummyRequest() - alsoProvides(req, IRequest) - req.registry = config.registry - - req.method = 'GET' - result = render_view_to_response(ctx, req, '') - self.assertEqual(result, 'grokked') - - def test_testing_securitypolicy(self): - from repoze.bfg.testing import DummySecurityPolicy - config = self._makeOne() - config.testing_securitypolicy('user', ('group1', 'group2'), - permissive=False) - from repoze.bfg.interfaces import IAuthenticationPolicy - from repoze.bfg.interfaces import IAuthorizationPolicy - ut = config.registry.getUtility(IAuthenticationPolicy) - self.failUnless(isinstance(ut, DummySecurityPolicy)) - ut = config.registry.getUtility(IAuthorizationPolicy) - self.assertEqual(ut.userid, 'user') - self.assertEqual(ut.groupids, ('group1', 'group2')) - self.assertEqual(ut.permissive, False) - - def test_testing_models(self): - from repoze.bfg.traversal import find_model - from repoze.bfg.interfaces import ITraverser - ob1 = object() - ob2 = object() - models = {'/ob1':ob1, '/ob2':ob2} - config = self._makeOne() - config.testing_models(models) - adapter = config.registry.getAdapter(None, ITraverser) - result = adapter({'PATH_INFO':'/ob1'}) - self.assertEqual(result['context'], ob1) - self.assertEqual(result['view_name'], '') - self.assertEqual(result['subpath'], ()) - self.assertEqual(result['traversed'], (u'ob1',)) - self.assertEqual(result['virtual_root'], ob1) - self.assertEqual(result['virtual_root_path'], ()) - result = adapter({'PATH_INFO':'/ob2'}) - self.assertEqual(result['context'], ob2) - self.assertEqual(result['view_name'], '') - self.assertEqual(result['subpath'], ()) - self.assertEqual(result['traversed'], (u'ob2',)) - self.assertEqual(result['virtual_root'], ob2) - self.assertEqual(result['virtual_root_path'], ()) - self.assertRaises(KeyError, adapter, {'PATH_INFO':'/ob3'}) - try: - config.begin() - self.assertEqual(find_model(None, '/ob1'), ob1) - finally: - config.end() - - def test_testing_add_subscriber_single(self): - config = self._makeOne() - L = config.testing_add_subscriber(IDummy) - event = DummyEvent() - config.registry.notify(event) - self.assertEqual(len(L), 1) - self.assertEqual(L[0], event) - config.registry.notify(object()) - self.assertEqual(len(L), 1) - - def test_testing_add_subscriber_dottedname(self): - config = self._makeOne() - L = config.testing_add_subscriber( - 'repoze.bfg.tests.test_configuration.IDummy') - event = DummyEvent() - config.registry.notify(event) - self.assertEqual(len(L), 1) - self.assertEqual(L[0], event) - config.registry.notify(object()) - self.assertEqual(len(L), 1) - - def test_testing_add_subscriber_multiple(self): - config = self._makeOne() - L = config.testing_add_subscriber((Interface, IDummy)) - event = DummyEvent() - event.object = 'foo' - # the below is the equivalent of z.c.event.objectEventNotify(event) - config.registry.subscribers((event.object, event), None) - self.assertEqual(len(L), 2) - self.assertEqual(L[0], 'foo') - self.assertEqual(L[1], event) - - def test_testing_add_subscriber_defaults(self): - config = self._makeOne() - L = config.testing_add_subscriber() - event = object() - config.registry.notify(event) - self.assertEqual(L[-1], event) - event2 = object() - config.registry.notify(event2) - self.assertEqual(L[-1], event2) - - def test_hook_zca(self): - from repoze.bfg.threadlocal import get_current_registry - gsm = DummyGetSiteManager() - config = self._makeOne() - config.hook_zca(getSiteManager=gsm) - self.assertEqual(gsm.hook, get_current_registry) - - def test_unhook_zca(self): - gsm = DummyGetSiteManager() - config = self._makeOne() - config.unhook_zca(getSiteManager=gsm) - self.assertEqual(gsm.unhooked, True) - - def test_testing_add_renderer(self): - config = self._makeOne() - renderer = config.testing_add_renderer('templates/foo.pt') - from repoze.bfg.testing import DummyTemplateRenderer - self.failUnless(isinstance(renderer, DummyTemplateRenderer)) - from repoze.bfg.renderers import render_to_response - # must provide request to pass in registry (this is a functest) - request = DummyRequest() - request.registry = config.registry - render_to_response( - 'templates/foo.pt', {'foo':1, 'bar':2}, request=request) - renderer.assert_(foo=1) - renderer.assert_(bar=2) - renderer.assert_(request=request) - - def test_testing_add_renderer_explicitrenderer(self): - config = self._makeOne() - class E(Exception): pass - def renderer(kw, system): - self.assertEqual(kw, {'foo':1, 'bar':2}) - raise E - renderer = config.testing_add_renderer('templates/foo.pt', renderer) - from repoze.bfg.renderers import render_to_response - # must provide request to pass in registry (this is a functest) - request = DummyRequest() - request.registry = config.registry - try: - render_to_response( - 'templates/foo.pt', {'foo':1, 'bar':2}, request=request) - except E: - pass - else: # pragma: no cover - raise AssertionError - - def test_testing_add_template(self): - config = self._makeOne() - renderer = config.testing_add_template('templates/foo.pt') - from repoze.bfg.testing import DummyTemplateRenderer - self.failUnless(isinstance(renderer, DummyTemplateRenderer)) - from repoze.bfg.renderers import render_to_response - # must provide request to pass in registry (this is a functest) - request = DummyRequest() - request.registry = config.registry - render_to_response('templates/foo.pt', dict(foo=1, bar=2), - request=request) - renderer.assert_(foo=1) - renderer.assert_(bar=2) - renderer.assert_(request=request) - -class Test__map_view(unittest.TestCase): - def setUp(self): - from repoze.bfg.registry import Registry - self.registry = Registry() - testing.setUp(registry=self.registry) - - def tearDown(self): - del self.registry - testing.tearDown() - - def _registerRenderer(self, typ='.txt'): - from repoze.bfg.interfaces import IRendererFactory - from repoze.bfg.interfaces import ITemplateRenderer - from zope.interface import implements - class Renderer: - implements(ITemplateRenderer) - spec = 'abc' + typ - def __init__(self, path): - self.__class__.path = path - def __call__(self, *arg): - return 'Hello!' - self.registry.registerUtility(Renderer, IRendererFactory, name=typ) - return Renderer - - def _makeRequest(self): - request = DummyRequest() - request.registry = self.registry - return request - - def _callFUT(self, *arg, **kw): - from repoze.bfg.configuration import _map_view - return _map_view(*arg, **kw) - - def test__map_view_as_function_context_and_request(self): - def view(context, request): - return 'OK' - result = self._callFUT(view) - self.failUnless(result is view) - self.assertEqual(result(None, None), 'OK') - - def test__map_view_as_function_with_attr(self): - def view(context, request): - """ """ - result = self._callFUT(view, attr='__name__') - self.failIf(result is view) - self.assertRaises(TypeError, result, None, None) - - def test__map_view_as_function_with_attr_and_renderer(self): - renderer = self._registerRenderer() - view = lambda *arg: 'OK' - result = self._callFUT(view, attr='__name__', - renderer_name=renderer.spec) - self.failIf(result is view) - self.assertRaises(TypeError, result, None, None) - - def test__map_view_as_function_requestonly(self): - def view(request): - return 'OK' - result = self._callFUT(view) - self.failIf(result is view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.assertEqual(result(None, None), 'OK') - - def test__map_view_as_function_requestonly_with_attr(self): - def view(request): - """ """ - result = self._callFUT(view, attr='__name__') - self.failIf(result is view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.assertRaises(TypeError, result, None, None) - - def test__map_view_as_newstyle_class_context_and_request(self): - class view(object): - def __init__(self, context, request): - pass - def __call__(self): - return 'OK' - result = self._callFUT(view) - self.failIf(result is view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.assertEqual(result(None, None), 'OK') - - def test__map_view_as_newstyle_class_context_and_request_with_attr(self): - class view(object): - def __init__(self, context, request): - pass - def index(self): - return 'OK' - result = self._callFUT(view, attr='index') - self.failIf(result is view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.assertEqual(result(None, None), 'OK') - - def test__map_view_as_newstyle_class_context_and_request_attr_and_renderer( - self): - renderer = self._registerRenderer() - class view(object): - def __init__(self, context, request): - pass - def index(self): - return {'a':'1'} - result = self._callFUT(view, attr='index', renderer_name=renderer.spec) - self.failIf(result is view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - request = self._makeRequest() - self.assertEqual(result(None, request).body, 'Hello!') - - def test__map_view_as_newstyle_class_requestonly(self): - class view(object): - def __init__(self, request): - pass - def __call__(self): - return 'OK' - result = self._callFUT(view) - self.failIf(result is view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.assertEqual(result(None, None), 'OK') - - def test__map_view_as_newstyle_class_requestonly_with_attr(self): - class view(object): - def __init__(self, request): - pass - def index(self): - return 'OK' - result = self._callFUT(view, attr='index') - self.failIf(result is view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.assertEqual(result(None, None), 'OK') - - def test__map_view_as_newstyle_class_requestonly_attr_and_renderer(self): - renderer = self._registerRenderer() - class view(object): - def __init__(self, request): - pass - def index(self): - return {'a':'1'} - result = self._callFUT(view, attr='index', renderer_name=renderer.spec) - self.failIf(result is view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - request = self._makeRequest() - self.assertEqual(result(None, request).body, 'Hello!') - - def test__map_view_as_oldstyle_class_context_and_request(self): - class view: - def __init__(self, context, request): - pass - def __call__(self): - return 'OK' - result = self._callFUT(view) - self.failIf(result is view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.assertEqual(result(None, None), 'OK') - - def test__map_view_as_oldstyle_class_context_and_request_with_attr(self): - class view: - def __init__(self, context, request): - pass - def index(self): - return 'OK' - result = self._callFUT(view, attr='index') - self.failIf(result is view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.assertEqual(result(None, None), 'OK') - - def test__map_view_as_oldstyle_cls_context_request_attr_and_renderer(self): - renderer = self._registerRenderer() - class view: - def __init__(self, context, request): - pass - def index(self): - return {'a':'1'} - result = self._callFUT(view, attr='index', renderer_name=renderer.spec) - self.failIf(result is view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - request = self._makeRequest() - self.assertEqual(result(None, request).body, 'Hello!') - - def test__map_view_as_oldstyle_class_requestonly(self): - class view: - def __init__(self, request): - pass - def __call__(self): - return 'OK' - result = self._callFUT(view) - self.failIf(result is view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.assertEqual(result(None, None), 'OK') - - def test__map_view_as_oldstyle_class_requestonly_with_attr(self): - class view: - def __init__(self, request): - pass - def index(self): - return 'OK' - result = self._callFUT(view, attr='index') - self.failIf(result is view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.assertEqual(result(None, None), 'OK') - - def test__map_view_as_oldstyle_class_requestonly_attr_and_renderer(self): - renderer = self._registerRenderer() - class view: - def __init__(self, request): - pass - def index(self): - return {'a':'1'} - result = self._callFUT(view, attr='index', renderer_name=renderer.spec) - self.failIf(result is view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - request = self._makeRequest() - self.assertEqual(result(None, request).body, 'Hello!') - - def test__map_view_as_instance_context_and_request(self): - class View: - def __call__(self, context, request): - return 'OK' - view = View() - result = self._callFUT(view) - self.failUnless(result is view) - self.assertEqual(result(None, None), 'OK') - - def test__map_view_as_instance_context_and_request_and_attr(self): - class View: - def index(self, context, request): - return 'OK' - view = View() - result = self._callFUT(view, attr='index') - self.failIf(result is view) - self.assertEqual(result(None, None), 'OK') - - def test__map_view_as_instance_context_and_request_attr_and_renderer(self): - renderer = self._registerRenderer() - class View: - def index(self, context, request): - return {'a':'1'} - view = View() - result = self._callFUT(view, attr='index', renderer_name=renderer.spec) - self.failIf(result is view) - request = self._makeRequest() - self.assertEqual(result(None, request).body, 'Hello!') - - def test__map_view_as_instance_requestonly(self): - class View: - def __call__(self, request): - return 'OK' - view = View() - result = self._callFUT(view) - self.failIf(result is view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.failUnless('instance' in result.__name__) - self.assertEqual(result(None, None), 'OK') - - def test__map_view_as_instance_requestonly_with_attr(self): - class View: - def index(self, request): - return 'OK' - view = View() - result = self._callFUT(view, attr='index') - self.failIf(result is view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.failUnless('instance' in result.__name__) - self.assertEqual(result(None, None), 'OK') - - def test__map_view_as_instance_requestonly_with_attr_and_renderer(self): - renderer = self._registerRenderer() - class View: - def index(self, request): - return {'a':'1'} - view = View() - result = self._callFUT(view, attr='index', renderer_name=renderer.spec) - self.failIf(result is view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.failUnless('instance' in result.__name__) - request = self._makeRequest() - self.assertEqual(result(None, request).body, 'Hello!') - - def test__map_view_rendereronly(self): - renderer = self._registerRenderer() - def view(context, request): - return {'a':'1'} - result = self._callFUT(view, renderer_name=renderer.spec) - self.failIf(result is view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - request = self._makeRequest() - self.assertEqual(result(None, request).body, 'Hello!') - - def test__map_view_with_registry(self): - renderer = self._registerRenderer() - def view(context, request): - return {'a':'1'} - result = self._callFUT(view, renderer_name=renderer.spec, - registry=self.registry) - self.failIf(result is view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - request = self._makeRequest() - self.assertEqual(result(None, request).body, 'Hello!') - - def test__map_view_with_package(self): - renderer = self._registerRenderer() - def view(context, request): - return {'a':'1'} - result = self._callFUT(view, renderer_name=renderer.spec, - package='repoze.bfg') - self.failIf(result is view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - request = self._makeRequest() - self.assertEqual(result(None, request).body, 'Hello!') - self.assertEqual(renderer.path, 'repoze.bfg:abc.txt') - -class Test_decorate_view(unittest.TestCase): - def _callFUT(self, wrapped, original): - from repoze.bfg.configuration import decorate_view - return decorate_view(wrapped, original) - - def test_it_same(self): - def view(context, request): - """ """ - result = self._callFUT(view, view) - self.assertEqual(result, False) - - def test_it_different(self): - class DummyView1: - """ 1 """ - __name__ = '1' - __module__ = '1' - def __call__(self, context, request): - """ """ - def __call_permissive__(self, context, reuqest): - """ """ - def __predicated__(self, context, reuqest): - """ """ - def __permitted__(self, context, request): - """ """ - class DummyView2: - """ 2 """ - __name__ = '2' - __module__ = '2' - def __call__(self, context, request): - """ """ - def __call_permissive__(self, context, reuqest): - """ """ - def __predicated__(self, context, reuqest): - """ """ - def __permitted__(self, context, request): - """ """ - view1 = DummyView1() - view2 = DummyView2() - result = self._callFUT(view1, view2) - self.assertEqual(result, True) - self.failUnless(view1.__doc__ is view2.__doc__) - self.failUnless(view1.__module__ is view2.__module__) - self.failUnless(view1.__name__ is view2.__name__) - self.failUnless(view1.__call_permissive__.im_func is - view2.__call_permissive__.im_func) - self.failUnless(view1.__permitted__.im_func is - view2.__permitted__.im_func) - self.failUnless(view1.__predicated__.im_func is - view2.__predicated__.im_func) - -class Test__make_predicates(unittest.TestCase): - def _callFUT(self, **kw): - from repoze.bfg.configuration import _make_predicates - return _make_predicates(**kw) - - def test_ordering_xhr_and_request_method_trump_only_containment(self): - order1, _, _ = self._callFUT(xhr=True, request_method='GET') - order2, _, _ = self._callFUT(containment=True) - self.failUnless(order1 < order2) - - def test_ordering_number_of_predicates(self): - order1, _, _ = self._callFUT( - xhr='xhr', - request_method='request_method', - path_info='path_info', - request_param='param', - header='header', - accept='accept', - containment='containment', - request_type='request_type', - custom=('a',) - ) - order2, _, _ = self._callFUT( - xhr='xhr', - request_method='request_method', - path_info='path_info', - request_param='param', - header='header', - accept='accept', - containment='containment', - request_type='request_type', - custom=('a',) - ) - order3, _, _ = self._callFUT( - xhr='xhr', - request_method='request_method', - path_info='path_info', - request_param='param', - header='header', - accept='accept', - containment='containment', - request_type='request_type', - ) - order4, _, _ = self._callFUT( - xhr='xhr', - request_method='request_method', - path_info='path_info', - request_param='param', - header='header', - accept='accept', - containment='containment', - ) - order5, _, _ = self._callFUT( - xhr='xhr', - request_method='request_method', - path_info='path_info', - request_param='param', - header='header', - accept='accept', - ) - order6, _, _ = self._callFUT( - xhr='xhr', - request_method='request_method', - path_info='path_info', - request_param='param', - header='header', - ) - order7, _, _ = self._callFUT( - xhr='xhr', - request_method='request_method', - path_info='path_info', - request_param='param', - ) - order8, _, _ = self._callFUT( - xhr='xhr', - request_method='request_method', - path_info='path_info', - ) - order9, _, _ = self._callFUT( - xhr='xhr', - request_method='request_method', - ) - order10, _, _ = self._callFUT( - xhr='xhr', - ) - order11, _, _ = self._callFUT( - ) - self.assertEqual(order1, order2) - self.failUnless(order3 > order2) - self.failUnless(order4 > order3) - self.failUnless(order5 > order4) - self.failUnless(order6 > order5) - self.failUnless(order7 > order6) - self.failUnless(order8 > order7) - self.failUnless(order9 > order8) - self.failUnless(order10 > order9) - self.failUnless(order11 > order10) - - def test_ordering_importance_of_predicates(self): - order1, _, _ = self._callFUT( - xhr='xhr', - ) - order2, _, _ = self._callFUT( - request_method='request_method', - ) - order3, _, _ = self._callFUT( - path_info='path_info', - ) - order4, _, _ = self._callFUT( - request_param='param', - ) - order5, _, _ = self._callFUT( - header='header', - ) - order6, _, _ = self._callFUT( - accept='accept', - ) - order7, _, _ = self._callFUT( - containment='containment', - ) - order8, _, _ = self._callFUT( - request_type='request_type', - ) - order9, _, _ = self._callFUT( - custom=('a',), - ) - self.failUnless(order1 > order2) - self.failUnless(order2 > order3) - self.failUnless(order3 > order4) - self.failUnless(order4 > order5) - self.failUnless(order5 > order6) - self.failUnless(order6 > order7) - self.failUnless(order7 > order8) - self.failUnless(order8 > order9) - - def test_ordering_importance_and_number(self): - order1, _, _ = self._callFUT( - xhr='xhr', - request_method='request_method', - ) - order2, _, _ = self._callFUT( - custom=('a',), - ) - self.failUnless(order1 < order2) - - order1, _, _ = self._callFUT( - xhr='xhr', - request_method='request_method', - ) - order2, _, _ = self._callFUT( - request_method='request_method', - custom=('a',), - ) - self.failUnless(order1 > order2) - - order1, _, _ = self._callFUT( - xhr='xhr', - request_method='request_method', - path_info='path_info', - ) - order2, _, _ = self._callFUT( - request_method='request_method', - custom=('a',), - ) - self.failUnless(order1 < order2) - - order1, _, _ = self._callFUT( - xhr='xhr', - request_method='request_method', - path_info='path_info', - ) - order2, _, _ = self._callFUT( - xhr='xhr', - request_method='request_method', - custom=('a',), - ) - self.failUnless(order1 > order2) - - def test_different_custom_predicates_with_same_hash(self): - class PredicateWithHash(object): - def __hash__(self): - return 1 - a = PredicateWithHash() - b = PredicateWithHash() - _, _, a_phash = self._callFUT(custom=(a,)) - _, _, b_phash = self._callFUT(custom=(b,)) - self.assertEqual(a_phash, b_phash) - - def test_traverse_has_remainder_already(self): - order, predicates, phash = self._callFUT(traverse='/1/:a/:b') - self.assertEqual(len(predicates), 1) - pred = predicates[0] - info = {'traverse':'abc'} - request = DummyRequest() - result = pred(info, request) - self.assertEqual(result, True) - self.assertEqual(info, {'traverse':'abc'}) - - def test_traverse_matches(self): - order, predicates, phash = self._callFUT(traverse='/1/:a/:b') - self.assertEqual(len(predicates), 1) - pred = predicates[0] - info = {'match':{'a':'a', 'b':'b'}} - request = DummyRequest() - result = pred(info, request) - self.assertEqual(result, True) - self.assertEqual(info, {'match': - {'a':'a', 'b':'b', 'traverse':('1', 'a', 'b')}}) - -class TestMultiView(unittest.TestCase): - def _getTargetClass(self): - from repoze.bfg.configuration import MultiView - return MultiView - - def _makeOne(self, name='name'): - return self._getTargetClass()(name) - - def test_class_implements_ISecuredView(self): - from zope.interface.verify import verifyClass - from repoze.bfg.interfaces import ISecuredView - verifyClass(ISecuredView, self._getTargetClass()) - - def test_instance_implements_ISecuredView(self): - from zope.interface.verify import verifyObject - from repoze.bfg.interfaces import ISecuredView - verifyObject(ISecuredView, self._makeOne()) - - def test_add(self): - mv = self._makeOne() - mv.add('view', 100) - self.assertEqual(mv.views, [(100, 'view', None)]) - mv.add('view2', 99) - self.assertEqual(mv.views, [(99, 'view2', None), (100, 'view', None)]) - mv.add('view3', 100, 'text/html') - self.assertEqual(mv.media_views['text/html'], [(100, 'view3', None)]) - mv.add('view4', 99, 'text/html') - self.assertEqual(mv.media_views['text/html'], - [(99, 'view4', None), (100, 'view3', None)]) - mv.add('view5', 100, 'text/xml') - self.assertEqual(mv.media_views['text/xml'], [(100, 'view5', None)]) - self.assertEqual(set(mv.accepts), set(['text/xml', 'text/html'])) - self.assertEqual(mv.views, [(99, 'view2', None), (100, 'view', None)]) - mv.add('view6', 98, 'text/*') - self.assertEqual(mv.views, [(98, 'view6', None), - (99, 'view2', None), - (100, 'view', None)]) - - def test_add_with_phash(self): - mv = self._makeOne() - mv.add('view', 100, phash='abc') - self.assertEqual(mv.views, [(100, 'view', 'abc')]) - mv.add('view', 100, phash='abc') - self.assertEqual(mv.views, [(100, 'view', 'abc')]) - mv.add('view', 100, phash='def') - self.assertEqual(mv.views, [(100, 'view', 'abc'), (100, 'view', 'def')]) - mv.add('view', 100, phash='abc') - self.assertEqual(mv.views, [(100, 'view', 'abc'), (100, 'view', 'def')]) - - def test_get_views_request_has_no_accept(self): - request = DummyRequest() - mv = self._makeOne() - mv.views = [(99, lambda *arg: None)] - self.assertEqual(mv.get_views(request), mv.views) - - def test_get_views_no_self_accepts(self): - request = DummyRequest() - request.accept = True - mv = self._makeOne() - mv.accepts = [] - mv.views = [(99, lambda *arg: None)] - self.assertEqual(mv.get_views(request), mv.views) - - def test_get_views(self): - request = DummyRequest() - request.accept = DummyAccept('text/html') - mv = self._makeOne() - mv.accepts = ['text/html'] - mv.views = [(99, lambda *arg: None)] - html_views = [(98, lambda *arg: None)] - mv.media_views['text/html'] = html_views - self.assertEqual(mv.get_views(request), html_views + mv.views) - - def test_get_views_best_match_returns_None(self): - request = DummyRequest() - request.accept = DummyAccept(None) - mv = self._makeOne() - mv.accepts = ['text/html'] - mv.views = [(99, lambda *arg: None)] - self.assertEqual(mv.get_views(request), mv.views) - - def test_match_not_found(self): - from repoze.bfg.exceptions import NotFound - mv = self._makeOne() - context = DummyContext() - request = DummyRequest() - self.assertRaises(NotFound, mv.match, context, request) - - def test_match_predicate_fails(self): - from repoze.bfg.exceptions import NotFound - mv = self._makeOne() - def view(context, request): - """ """ - view.__predicated__ = lambda *arg: False - mv.views = [(100, view, None)] - context = DummyContext() - request = DummyRequest() - self.assertRaises(NotFound, mv.match, context, request) - - def test_match_predicate_succeeds(self): - mv = self._makeOne() - def view(context, request): - """ """ - view.__predicated__ = lambda *arg: True - mv.views = [(100, view, None)] - context = DummyContext() - request = DummyRequest() - result = mv.match(context, request) - self.assertEqual(result, view) - - def test_permitted_no_views(self): - from repoze.bfg.exceptions import NotFound - mv = self._makeOne() - context = DummyContext() - request = DummyRequest() - self.assertRaises(NotFound, mv.__permitted__, context, request) - - def test_permitted_no_match_with__permitted__(self): - mv = self._makeOne() - def view(context, request): - """ """ - mv.views = [(100, view, None)] - self.assertEqual(mv.__permitted__(None, None), True) - - def test_permitted(self): - mv = self._makeOne() - def view(context, request): - """ """ - def permitted(context, request): - return False - view.__permitted__ = permitted - mv.views = [(100, view, None)] - context = DummyContext() - request = DummyRequest() - result = mv.__permitted__(context, request) - self.assertEqual(result, False) - - def test__call__not_found(self): - from repoze.bfg.exceptions import NotFound - mv = self._makeOne() - context = DummyContext() - request = DummyRequest() - self.assertRaises(NotFound, mv, context, request) - - def test___call__intermediate_not_found(self): - from repoze.bfg.exceptions import PredicateMismatch - mv = self._makeOne() - context = DummyContext() - request = DummyRequest() - request.view_name = '' - expected_response = DummyResponse() - def view1(context, request): - raise PredicateMismatch - def view2(context, request): - return expected_response - mv.views = [(100, view1, None), (99, view2, None)] - response = mv(context, request) - self.assertEqual(response, expected_response) - - def test___call__raise_not_found_isnt_interpreted_as_pred_mismatch(self): - from repoze.bfg.exceptions import NotFound - mv = self._makeOne() - context = DummyContext() - request = DummyRequest() - request.view_name = '' - def view1(context, request): - raise NotFound - def view2(context, request): - """ """ - mv.views = [(100, view1, None), (99, view2, None)] - self.assertRaises(NotFound, mv, context, request) - - def test___call__(self): - mv = self._makeOne() - context = DummyContext() - request = DummyRequest() - request.view_name = '' - expected_response = DummyResponse() - def view(context, request): - return expected_response - mv.views = [(100, view, None)] - response = mv(context, request) - self.assertEqual(response, expected_response) - - def test__call_permissive__not_found(self): - from repoze.bfg.exceptions import NotFound - mv = self._makeOne() - context = DummyContext() - request = DummyRequest() - self.assertRaises(NotFound, mv, context, request) - - def test___call_permissive_has_call_permissive(self): - mv = self._makeOne() - context = DummyContext() - request = DummyRequest() - request.view_name = '' - expected_response = DummyResponse() - def view(context, request): - """ """ - def permissive(context, request): - return expected_response - view.__call_permissive__ = permissive - mv.views = [(100, view, None)] - response = mv.__call_permissive__(context, request) - self.assertEqual(response, expected_response) - - def test___call_permissive_has_no_call_permissive(self): - mv = self._makeOne() - context = DummyContext() - request = DummyRequest() - request.view_name = '' - expected_response = DummyResponse() - def view(context, request): - return expected_response - mv.views = [(100, view, None)] - response = mv.__call_permissive__(context, request) - self.assertEqual(response, expected_response) - - def test__call__with_accept_match(self): - mv = self._makeOne() - context = DummyContext() - request = DummyRequest() - request.accept = DummyAccept('text/html', 'text/xml') - expected_response = DummyResponse() - def view(context, request): - return expected_response - mv.views = [(100, None)] - mv.media_views['text/xml'] = [(100, view, None)] - mv.accepts = ['text/xml'] - response = mv(context, request) - self.assertEqual(response, expected_response) - - def test__call__with_accept_miss(self): - mv = self._makeOne() - context = DummyContext() - request = DummyRequest() - request.accept = DummyAccept('text/plain', 'text/html') - expected_response = DummyResponse() - def view(context, request): - return expected_response - mv.views = [(100, view, None)] - mv.media_views['text/xml'] = [(100, None, None)] - mv.accepts = ['text/xml'] - response = mv(context, request) - self.assertEqual(response, expected_response) - - -class TestRequestOnly(unittest.TestCase): - def _callFUT(self, arg): - from repoze.bfg.configuration import requestonly - return requestonly(arg) - - def test_newstyle_class_no_init(self): - class foo(object): - """ """ - self.assertFalse(self._callFUT(foo)) - - def test_newstyle_class_init_toomanyargs(self): - class foo(object): - def __init__(self, context, request): - """ """ - self.assertFalse(self._callFUT(foo)) - - def test_newstyle_class_init_onearg_named_request(self): - class foo(object): - def __init__(self, request): - """ """ - self.assertTrue(self._callFUT(foo)) - - def test_newstyle_class_init_onearg_named_somethingelse(self): - class foo(object): - def __init__(self, req): - """ """ - self.assertTrue(self._callFUT(foo)) - - def test_newstyle_class_init_defaultargs_firstname_not_request(self): - class foo(object): - def __init__(self, context, request=None): - """ """ - self.assertFalse(self._callFUT(foo)) - - def test_newstyle_class_init_defaultargs_firstname_request(self): - class foo(object): - def __init__(self, request, foo=1, bar=2): - """ """ - self.assertTrue(self._callFUT(foo)) - - def test_newstyle_class_init_noargs(self): - class foo(object): - def __init__(): - """ """ - self.assertFalse(self._callFUT(foo)) - - def test_oldstyle_class_no_init(self): - class foo: - """ """ - self.assertFalse(self._callFUT(foo)) - - def test_oldstyle_class_init_toomanyargs(self): - class foo: - def __init__(self, context, request): - """ """ - self.assertFalse(self._callFUT(foo)) - - def test_oldstyle_class_init_onearg_named_request(self): - class foo: - def __init__(self, request): - """ """ - self.assertTrue(self._callFUT(foo)) - - def test_oldstyle_class_init_onearg_named_somethingelse(self): - class foo: - def __init__(self, req): - """ """ - self.assertTrue(self._callFUT(foo)) - - def test_oldstyle_class_init_defaultargs_firstname_not_request(self): - class foo: - def __init__(self, context, request=None): - """ """ - self.assertFalse(self._callFUT(foo)) - - def test_oldstyle_class_init_defaultargs_firstname_request(self): - class foo: - def __init__(self, request, foo=1, bar=2): - """ """ - self.assertTrue(self._callFUT(foo), True) - - def test_oldstyle_class_init_noargs(self): - class foo: - def __init__(): - """ """ - self.assertFalse(self._callFUT(foo)) - - def test_function_toomanyargs(self): - def foo(context, request): - """ """ - self.assertFalse(self._callFUT(foo)) - - def test_function_onearg_named_request(self): - def foo(request): - """ """ - self.assertTrue(self._callFUT(foo)) - - def test_function_onearg_named_somethingelse(self): - def foo(req): - """ """ - self.assertTrue(self._callFUT(foo)) - - def test_function_defaultargs_firstname_not_request(self): - def foo(context, request=None): - """ """ - self.assertFalse(self._callFUT(foo)) - - def test_function_defaultargs_firstname_request(self): - def foo(request, foo=1, bar=2): - """ """ - self.assertTrue(self._callFUT(foo)) - - def test_function_noargs(self): - def foo(): - """ """ - self.assertFalse(self._callFUT(foo)) - - def test_instance_toomanyargs(self): - class Foo: - def __call__(self, context, request): - """ """ - foo = Foo() - self.assertFalse(self._callFUT(foo)) - - def test_instance_defaultargs_onearg_named_request(self): - class Foo: - def __call__(self, request): - """ """ - foo = Foo() - self.assertTrue(self._callFUT(foo)) - - def test_instance_defaultargs_onearg_named_somethingelse(self): - class Foo: - def __call__(self, req): - """ """ - foo = Foo() - self.assertTrue(self._callFUT(foo)) - - def test_instance_defaultargs_firstname_not_request(self): - class Foo: - def __call__(self, context, request=None): - """ """ - foo = Foo() - self.assertFalse(self._callFUT(foo)) - - def test_instance_defaultargs_firstname_request(self): - class Foo: - def __call__(self, request, foo=1, bar=2): - """ """ - foo = Foo() - self.assertTrue(self._callFUT(foo), True) - - def test_instance_nocall(self): - class Foo: pass - foo = Foo() - self.assertFalse(self._callFUT(foo)) - -class TestMakeApp(unittest.TestCase): - def setUp(self): - testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _callFUT(self, *arg, **kw): - from repoze.bfg.configuration import make_app - return make_app(*arg, **kw) - - def test_it(self): - settings = {'a':1} - rootfactory = object() - app = self._callFUT(rootfactory, settings=settings, - Configurator=DummyConfigurator) - self.assertEqual(app.root_factory, rootfactory) - self.assertEqual(app.settings, settings) - self.assertEqual(app.zcml_file, 'configure.zcml') - self.assertEqual(app.zca_hooked, True) - - def test_it_options_means_settings(self): - settings = {'a':1} - rootfactory = object() - app = self._callFUT(rootfactory, options=settings, - Configurator=DummyConfigurator) - self.assertEqual(app.root_factory, rootfactory) - self.assertEqual(app.settings, settings) - self.assertEqual(app.zcml_file, 'configure.zcml') - - def test_it_with_package(self): - package = object() - rootfactory = object() - app = self._callFUT(rootfactory, package=package, - Configurator=DummyConfigurator) - self.assertEqual(app.package, package) - - def test_it_with_custom_configure_zcml(self): - rootfactory = object() - settings = {'configure_zcml':'2.zcml'} - app = self._callFUT(rootfactory, filename='1.zcml', settings=settings, - Configurator=DummyConfigurator) - self.assertEqual(app.zcml_file, '2.zcml') - -class TestDottedNameResolver(unittest.TestCase): - def _makeOne(self, package=None): - from repoze.bfg.configuration import DottedNameResolver - return DottedNameResolver(package) - - def config_exc(self, func, *arg, **kw): - from repoze.bfg.exceptions import ConfigurationError - try: - func(*arg, **kw) - except ConfigurationError, e: - return e - else: - raise AssertionError('Invalid not raised') # pragma: no cover - - def test_zope_dottedname_style_resolve_absolute(self): - typ = self._makeOne() - result = typ._zope_dottedname_style( - 'repoze.bfg.tests.test_configuration.TestDottedNameResolver') - self.assertEqual(result, self.__class__) - - def test_zope_dottedname_style_irrresolveable_absolute(self): - typ = self._makeOne() - self.assertRaises(ImportError, typ._zope_dottedname_style, - 'repoze.bfg.test_configuration.nonexisting_name') - - def test__zope_dottedname_style_resolve_relative(self): - import repoze.bfg.tests - typ = self._makeOne(package=repoze.bfg.tests) - result = typ._zope_dottedname_style( - '.test_configuration.TestDottedNameResolver') - self.assertEqual(result, self.__class__) - - def test__zope_dottedname_style_resolve_relative_leading_dots(self): - import repoze.bfg.tests.test_configuration - typ = self._makeOne(package=repoze.bfg.tests) - result = typ._zope_dottedname_style( - '..tests.test_configuration.TestDottedNameResolver') - self.assertEqual(result, self.__class__) - - def test__zope_dottedname_style_resolve_relative_is_dot(self): - import repoze.bfg.tests - typ = self._makeOne(package=repoze.bfg.tests) - result = typ._zope_dottedname_style('.') - self.assertEqual(result, repoze.bfg.tests) - - def test__zope_dottedname_style_irresolveable_relative_is_dot(self): - typ = self._makeOne() - e = self.config_exc(typ._zope_dottedname_style, '.') - self.assertEqual( - e.args[0], - "relative name '.' irresolveable without package") - - def test_zope_dottedname_style_resolve_relative_nocurrentpackage(self): - typ = self._makeOne() - e = self.config_exc(typ._zope_dottedname_style, '.whatever') - self.assertEqual( - e.args[0], - "relative name '.whatever' irresolveable without package") - - def test_zope_dottedname_style_irrresolveable_relative(self): - import repoze.bfg.tests - typ = self._makeOne(package=repoze.bfg.tests) - self.assertRaises(ImportError, typ._zope_dottedname_style, - '.notexisting') - - def test__zope_dottedname_style_resolveable_relative(self): - import repoze.bfg - typ = self._makeOne(package=repoze.bfg) - result = typ._zope_dottedname_style('.tests') - from repoze.bfg import tests - self.assertEqual(result, tests) - - def test__zope_dottedname_style_irresolveable_absolute(self): - typ = self._makeOne() - self.assertRaises( - ImportError, - typ._zope_dottedname_style, 'repoze.bfg.fudge.bar') - - def test__zope_dottedname_style_resolveable_absolute(self): - typ = self._makeOne() - result = typ._zope_dottedname_style( - 'repoze.bfg.tests.test_configuration.TestDottedNameResolver') - self.assertEqual(result, self.__class__) - - def test__pkg_resources_style_resolve_absolute(self): - typ = self._makeOne() - result = typ._pkg_resources_style( - 'repoze.bfg.tests.test_configuration:TestDottedNameResolver') - self.assertEqual(result, self.__class__) - - def test__pkg_resources_style_irrresolveable_absolute(self): - typ = self._makeOne() - self.assertRaises(ImportError, typ._pkg_resources_style, - 'repoze.bfg.tests:nonexisting') - - def test__pkg_resources_style_resolve_relative(self): - import repoze.bfg.tests - typ = self._makeOne(package=repoze.bfg.tests) - result = typ._pkg_resources_style( - '.test_configuration:TestDottedNameResolver') - self.assertEqual(result, self.__class__) - - def test__pkg_resources_style_resolve_relative_is_dot(self): - import repoze.bfg.tests - typ = self._makeOne(package=repoze.bfg.tests) - result = typ._pkg_resources_style('.') - self.assertEqual(result, repoze.bfg.tests) - - def test__pkg_resources_style_resolve_relative_nocurrentpackage(self): - typ = self._makeOne() - from repoze.bfg.exceptions import ConfigurationError - self.assertRaises(ConfigurationError, typ._pkg_resources_style, - '.whatever') - - def test__pkg_resources_style_irrresolveable_relative(self): - import repoze.bfg - typ = self._makeOne(package=repoze.bfg) - self.assertRaises(ImportError, typ._pkg_resources_style, - ':notexisting') - - def test_resolve_not_a_string(self): - typ = self._makeOne() - e = self.config_exc(typ.resolve, None) - self.assertEqual(e.args[0], 'None is not a string') - - def test_resolve_using_pkgresources_style(self): - typ = self._makeOne() - result = typ.resolve( - 'repoze.bfg.tests.test_configuration:TestDottedNameResolver') - self.assertEqual(result, self.__class__) - - def test_resolve_using_zope_dottedname_style(self): - typ = self._makeOne() - result = typ.resolve( - 'repoze.bfg.tests.test_configuration:TestDottedNameResolver') - self.assertEqual(result, self.__class__) - - def test_resolve_missing_raises(self): - typ = self._makeOne() - e = self.config_exc(typ.resolve, 'cant.be.found') - self.assertEqual(e.args[0], - "The dotted name 'cant.be.found' cannot be imported") - - def test_ctor_string_module_resolveable(self): - import repoze.bfg.tests - typ = self._makeOne('repoze.bfg.tests.test_configuration') - self.assertEqual(typ.package, repoze.bfg.tests) - self.assertEqual(typ.package_name, 'repoze.bfg.tests') - - def test_ctor_string_package_resolveable(self): - import repoze.bfg.tests - typ = self._makeOne('repoze.bfg.tests') - self.assertEqual(typ.package, repoze.bfg.tests) - self.assertEqual(typ.package_name, 'repoze.bfg.tests') - - def test_ctor_string_irresolveable(self): - from repoze.bfg.configuration import ConfigurationError - self.assertRaises(ConfigurationError, self._makeOne, 'cant.be.found') - - def test_ctor_module(self): - import repoze.bfg.tests - import repoze.bfg.tests.test_configuration - typ = self._makeOne(repoze.bfg.tests.test_configuration) - self.assertEqual(typ.package, repoze.bfg.tests) - self.assertEqual(typ.package_name, 'repoze.bfg.tests') - - def test_ctor_package(self): - import repoze.bfg.tests - typ = self._makeOne(repoze.bfg.tests) - self.assertEqual(typ.package, repoze.bfg.tests) - self.assertEqual(typ.package_name, 'repoze.bfg.tests') - - def test_ctor_None(self): - typ = self._makeOne(None) - self.assertEqual(typ.package, None) - self.assertEqual(typ.package_name, None) - -class Test_isexception(unittest.TestCase): - def _callFUT(self, ob): - from repoze.bfg.configuration import isexception - return isexception(ob) - - def test_is_exception_instance(self): - class E(Exception): - pass - e = E() - self.assertEqual(self._callFUT(e), True) - - def test_is_exception_class(self): - class E(Exception): - pass - self.assertEqual(self._callFUT(E), True) - - def test_is_IException(self): - from repoze.bfg.interfaces import IException - self.assertEqual(self._callFUT(IException), True) - - def test_is_IException_subinterface(self): - from repoze.bfg.interfaces import IException - class ISubException(IException): - pass - self.assertEqual(self._callFUT(ISubException), True) - -class DummyRequest: - subpath = () - def __init__(self): - self.environ = {'PATH_INFO':'/static'} - self.params = {} - self.cookies = {} - def copy(self): - return self - def get_response(self, app): - return app - -class DummyContext: - pass - -class DummyLock: - def acquire(self): - self.acquired = True - - def release(self): - self.released = True - -class DummyPackage: - def __init__(self, name): - self.__name__ = name - -class DummyOverrides: - def __init__(self, package): - self.package = package - self.inserted = [] - - def insert(self, path, package, prefix): - self.inserted.append((path, package, prefix)) - -class DummyUnderOverride: - def __call__(self, package, path, override_package, override_prefix, - _info=u''): - self.package = package - self.path = path - self.override_package = override_package - self.override_prefix = override_prefix - -from zope.interface import Interface -class IDummy(Interface): - pass - -class IOther(Interface): - pass - -class DummyResponse: - status = '200 OK' - headerlist = () - app_iter = () - body = '' - -class DummyLogger: - def __init__(self): - self.messages = [] - def info(self, msg): - self.messages.append(msg) - warn = info - debug = info - -class DummySecurityPolicy: - def __init__(self, permitted=True): - self.permitted = permitted - - def effective_principals(self, request): - return [] - - def permits(self, context, principals, permission): - return self.permitted - -class DummyConfigurator(object): - def __init__(self, registry=None, package=None, root_factory=None, - settings=None): - self.root_factory = root_factory - self.package = package - self.settings = settings - - def begin(self, request=None): - self.begun = True - self.request = request - - def end(self): - self.ended = True - - def load_zcml(self, filename): - self.zcml_file = filename - - def make_wsgi_app(self): - return self - - def hook_zca(self): - self.zca_hooked = True - -class DummyAccept(object): - def __init__(self, *matches): - self.matches = list(matches) - - def best_match(self, offered): - if self.matches: - for match in self.matches: - if match in offered: - self.matches.remove(match) - return match - def __contains__(self, val): - return val in self.matches - -from zope.interface import implements -from repoze.bfg.interfaces import IMultiView -class DummyMultiView: - implements(IMultiView) - def __init__(self): - self.views = [] - self.name = 'name' - def add(self, view, order, accept=None, phash=None): - self.views.append((view, accept, phash)) - def __call__(self, context, request): - return 'OK1' - def __permitted__(self, context, request): - """ """ - -class DummyGetSiteManager(object): - def sethook(self, hook): - self.hook = hook - def reset(self): - self.unhooked = True - -class DummyThreadLocalManager(object): - pushed = None - popped = False - def push(self, d): - self.pushed = d - def pop(self): - self.popped = True - -class IFactory(Interface): - pass - -class DummyFactory(object): - implements(IFactory) - def __call__(self): - """ """ - -class DummyEvent: - implements(IDummy) - -class DummyStaticURLInfo: - def __init__(self): - self.added = [] - - def add(self, name, spec, **kw): - self.added.append((name, spec, kw)) - -def dummy_view(request): - return 'OK' - -def dummyfactory(request): - """ """ diff --git a/repoze/bfg/tests/test_decorator.py b/repoze/bfg/tests/test_decorator.py deleted file mode 100644 index d41c62c65..000000000 --- a/repoze/bfg/tests/test_decorator.py +++ /dev/null @@ -1,29 +0,0 @@ -import unittest - -class TestReify(unittest.TestCase): - def _makeOne(self, wrapped): - from repoze.bfg.decorator import reify - return reify(wrapped) - - def test___get__withinst(self): - def wrapped(inst): - return 'a' - decorator = self._makeOne(wrapped) - inst = Dummy() - result = decorator.__get__(inst) - self.assertEqual(result, 'a') - self.assertEqual(inst.__dict__['wrapped'], 'a') - - def test___get__noinst(self): - decorator = self._makeOne(None) - result = decorator.__get__(None) - self.assertEqual(result, decorator) - - def test___doc__copied(self): - def wrapped(inst): - """My doc""" - decorator = self._makeOne(wrapped) - self.assertEqual(decorator.__doc__, "My doc") - -class Dummy(object): - pass diff --git a/repoze/bfg/tests/test_docs.py b/repoze/bfg/tests/test_docs.py deleted file mode 100644 index a00171842..000000000 --- a/repoze/bfg/tests/test_docs.py +++ /dev/null @@ -1,35 +0,0 @@ -import unittest - -if 0: - # no released version of manuel actually works with :lineno: - # settings yet - class ManuelDocsCase(unittest.TestCase): - def __new__(self, test): - return getattr(self, test)() - - @classmethod - def test_docs(cls): - import os - import pkg_resources - import manuel.testing - import manuel.codeblock - import manuel.capture - import manuel.ignore - m = manuel.ignore.Manuel() - m += manuel.codeblock.Manuel() - m += manuel.capture.Manuel() - docs = [] - - egg_path = pkg_resources.get_distribution('repoze.bfg').location - path = os.path.join(egg_path, 'docs') - for root, dirs, files in os.walk(path): - for ignore in ('.svn', '.build', '.hg', '.git', 'CVS'): - if ignore in dirs: - dirs.remove(ignore) - - for filename in files: - if filename.endswith('.rst'): - docs.append(os.path.join(root, filename)) - - print path - return manuel.testing.TestSuite(m, *docs) diff --git a/repoze/bfg/tests/test_encode.py b/repoze/bfg/tests/test_encode.py deleted file mode 100644 index 364247fb3..000000000 --- a/repoze/bfg/tests/test_encode.py +++ /dev/null @@ -1,61 +0,0 @@ -import unittest - -class UrlEncodeTests(unittest.TestCase): - def _callFUT(self, query, doseq=False): - from repoze.bfg.encode import urlencode - return urlencode(query, doseq) - - def test_ascii_only(self): - result = self._callFUT([('a',1), ('b',2)]) - self.assertEqual(result, 'a=1&b=2') - - def test_unicode_key(self): - la = unicode('LaPe\xc3\xb1a', 'utf-8') - result = self._callFUT([(la, 1), ('b',2)]) - self.assertEqual(result, 'LaPe%C3%B1a=1&b=2') - - def test_unicode_val_single(self): - la = unicode('LaPe\xc3\xb1a', 'utf-8') - result = self._callFUT([('a', la), ('b',2)]) - self.assertEqual(result, 'a=LaPe%C3%B1a&b=2') - - def test_unicode_val_multiple(self): - la = [unicode('LaPe\xc3\xb1a', 'utf-8')] * 2 - result = self._callFUT([('a', la), ('b',2)], doseq=True) - self.assertEqual(result, 'a=LaPe%C3%B1a&a=LaPe%C3%B1a&b=2') - - def test_dict(self): - result = self._callFUT({'a':1}) - self.assertEqual(result, 'a=1') - -class URLQuoteTests(unittest.TestCase): - def _callFUT(self, val, safe=''): - from repoze.bfg.encode import url_quote - return url_quote(val, safe) - - def test_it_default(self): - la = 'La/Pe\xc3\xb1a' - result = self._callFUT(la) - self.assertEqual(result, 'La%2FPe%C3%B1a') - - def test_it_with_safe(self): - la = 'La/Pe\xc3\xb1a' - result = self._callFUT(la, '/') - self.assertEqual(result, 'La/Pe%C3%B1a') - -class TestQuotePlus(unittest.TestCase): - def _callFUT(self, val, safe=''): - from repoze.bfg.encode import quote_plus - return quote_plus(val, safe) - - def test_it_default(self): - la = 'La Pe\xc3\xb1a' - result = self._callFUT(la) - self.assertEqual(result, 'La+Pe%C3%B1a') - - def test_it_with_safe(self): - la = 'La /Pe\xc3\xb1a' - result = self._callFUT(la, '/') - self.assertEqual(result, 'La+/Pe%C3%B1a') - - diff --git a/repoze/bfg/tests/test_events.py b/repoze/bfg/tests/test_events.py deleted file mode 100644 index d097ca0f4..000000000 --- a/repoze/bfg/tests/test_events.py +++ /dev/null @@ -1,181 +0,0 @@ -import unittest - -class NewRequestEventTests(unittest.TestCase): - def _getTargetClass(self): - from repoze.bfg.events import NewRequest - return NewRequest - - def _makeOne(self, request): - return self._getTargetClass()(request) - - def test_class_implements(self): - from repoze.bfg.interfaces import INewRequest - from zope.interface.verify import verifyClass - klass = self._getTargetClass() - verifyClass(INewRequest, klass) - - def test_instance_implements(self): - from repoze.bfg.interfaces import INewRequest - from zope.interface.verify import verifyObject - request = DummyRequest() - inst = self._makeOne(request) - verifyObject(INewRequest, inst) - - def test_ctor(self): - request = DummyRequest() - inst = self._makeOne(request) - self.assertEqual(inst.request, request) - -class NewResponseEventTests(unittest.TestCase): - def _getTargetClass(self): - from repoze.bfg.events import NewResponse - return NewResponse - - def _makeOne(self, request, response): - return self._getTargetClass()(request, response) - - def test_class_implements(self): - from repoze.bfg.interfaces import INewResponse - from zope.interface.verify import verifyClass - klass = self._getTargetClass() - verifyClass(INewResponse, klass) - - def test_instance_implements(self): - from repoze.bfg.interfaces import INewResponse - from zope.interface.verify import verifyObject - request = DummyRequest() - response = DummyResponse() - inst = self._makeOne(request, response) - verifyObject(INewResponse, inst) - - def test_ctor(self): - request = DummyRequest() - response = DummyResponse() - inst = self._makeOne(request, response) - self.assertEqual(inst.request, request) - self.assertEqual(inst.response, response) - -class ApplicationCreatedEventTests(unittest.TestCase): - def test_alias_object_implements(self): - from repoze.bfg.events import WSGIApplicationCreatedEvent - event = WSGIApplicationCreatedEvent(object()) - from repoze.bfg.interfaces import IWSGIApplicationCreatedEvent - from repoze.bfg.interfaces import IApplicationCreated - from zope.interface.verify import verifyObject - verifyObject(IWSGIApplicationCreatedEvent, event) - verifyObject(IApplicationCreated, event) - - def test_alias_class_implements(self): - from repoze.bfg.events import WSGIApplicationCreatedEvent - from repoze.bfg.interfaces import IWSGIApplicationCreatedEvent - from repoze.bfg.interfaces import IApplicationCreated - from zope.interface.verify import verifyClass - verifyClass(IWSGIApplicationCreatedEvent, WSGIApplicationCreatedEvent) - verifyClass(IApplicationCreated, WSGIApplicationCreatedEvent) - - def test_object_implements(self): - from repoze.bfg.events import ApplicationCreated - event = ApplicationCreated(object()) - from repoze.bfg.interfaces import IApplicationCreated - from zope.interface.verify import verifyObject - verifyObject(IApplicationCreated, event) - - def test_class_implements(self): - from repoze.bfg.events import ApplicationCreated - from repoze.bfg.interfaces import IApplicationCreated - from zope.interface.verify import verifyClass - verifyClass(IApplicationCreated, ApplicationCreated) - -class ContextFoundEventTests(unittest.TestCase): - def test_alias_class_implements(self): - from zope.interface.verify import verifyClass - from repoze.bfg.events import AfterTraversal - from repoze.bfg.interfaces import IAfterTraversal - from repoze.bfg.interfaces import IContextFound - verifyClass(IAfterTraversal, AfterTraversal) - verifyClass(IContextFound, AfterTraversal) - - def test_alias_instance_implements(self): - from zope.interface.verify import verifyObject - from repoze.bfg.events import AfterTraversal - from repoze.bfg.interfaces import IAfterTraversal - from repoze.bfg.interfaces import IContextFound - request = DummyRequest() - inst = AfterTraversal(request) - verifyObject(IAfterTraversal, inst) - verifyObject(IContextFound, inst) - - def test_class_implements(self): - from zope.interface.verify import verifyClass - from repoze.bfg.events import ContextFound - from repoze.bfg.interfaces import IContextFound - verifyClass(IContextFound, ContextFound) - - def test_instance_implements(self): - from zope.interface.verify import verifyObject - from repoze.bfg.events import ContextFound - from repoze.bfg.interfaces import IContextFound - request = DummyRequest() - inst = ContextFound(request) - verifyObject(IContextFound, inst) - -class TestSubscriber(unittest.TestCase): - def setUp(self): - registry = DummyRegistry() - from repoze.bfg.configuration import Configurator - self.config = Configurator(registry) - self.config.begin() - - def tearDown(self): - self.config.end() - - def _makeOne(self, *ifaces): - from repoze.bfg.events import subscriber - return subscriber(*ifaces) - - def test_register(self): - from zope.interface import Interface - class IFoo(Interface): pass - class IBar(Interface): pass - dec = self._makeOne(IFoo, IBar) - def foo(): pass - config = DummyConfigurator() - scanner = Dummy() - scanner.config = config - dec.register(scanner, None, foo) - self.assertEqual(config.subscribed, [(foo, (IFoo, IBar))]) - - def test___call__(self): - dec = self._makeOne() - dummy_venusian = DummyVenusian() - dec.venusian = dummy_venusian - def foo(): pass - dec(foo) - self.assertEqual(dummy_venusian.attached, [(foo, dec.register, 'bfg')]) - -class DummyConfigurator(object): - def __init__(self): - self.subscribed = [] - - def add_subscriber(self, wrapped, ifaces): - self.subscribed.append((wrapped, ifaces)) - -class DummyRegistry(object): - pass - -class DummyVenusian(object): - def __init__(self): - self.attached = [] - - def attach(self, wrapped, fn, category=None): - self.attached.append((wrapped, fn, category)) - -class Dummy: - pass - -class DummyRequest: - pass - -class DummyResponse: - pass - diff --git a/repoze/bfg/tests/test_exceptions.py b/repoze/bfg/tests/test_exceptions.py deleted file mode 100644 index 4091eb941..000000000 --- a/repoze/bfg/tests/test_exceptions.py +++ /dev/null @@ -1,45 +0,0 @@ -import unittest - -class TestExceptionResponse(unittest.TestCase): - def _makeOne(self, message): - from repoze.bfg.exceptions import ExceptionResponse - return ExceptionResponse(message) - - def test_app_iter(self): - exc = self._makeOne('') - self.failUnless('<code></code>' in exc.app_iter[0]) - - def test_headerlist(self): - exc = self._makeOne('') - headerlist = exc.headerlist - headerlist.sort() - app_iter = exc.app_iter - clen = str(len(app_iter[0])) - self.assertEqual(headerlist[0], ('Content-Length', clen)) - self.assertEqual(headerlist[1], ('Content-Type', 'text/html')) - - def test_withmessage(self): - exc = self._makeOne('abc&123') - self.failUnless('<code>abc&123</code>' in exc.app_iter[0]) - -class TestNotFound(unittest.TestCase): - def _makeOne(self, message): - from repoze.bfg.exceptions import NotFound - return NotFound(message) - - def test_it(self): - from repoze.bfg.exceptions import ExceptionResponse - e = self._makeOne('notfound') - self.failUnless(isinstance(e, ExceptionResponse)) - self.assertEqual(e.status, '404 Not Found') - -class TestForbidden(unittest.TestCase): - def _makeOne(self, message): - from repoze.bfg.exceptions import Forbidden - return Forbidden(message) - - def test_it(self): - from repoze.bfg.exceptions import ExceptionResponse - e = self._makeOne('unauthorized') - self.failUnless(isinstance(e, ExceptionResponse)) - self.assertEqual(e.status, '401 Unauthorized') diff --git a/repoze/bfg/tests/test_i18n.py b/repoze/bfg/tests/test_i18n.py deleted file mode 100644 index 95017807f..000000000 --- a/repoze/bfg/tests/test_i18n.py +++ /dev/null @@ -1,394 +0,0 @@ -# -*- coding: utf-8 -*- -# - -import unittest -from repoze.bfg.testing import cleanUp - -class TestTranslationString(unittest.TestCase): - def _makeOne(self, *arg, **kw): - from repoze.bfg.i18n import TranslationString - return TranslationString(*arg, **kw) - - def test_it(self): - # this is part of the API, we don't actually need to test much more - # than that it's importable - ts = self._makeOne('a') - self.assertEqual(ts, 'a') - -class TestTranslationStringFactory(unittest.TestCase): - def _makeOne(self, *arg, **kw): - from repoze.bfg.i18n import TranslationStringFactory - return TranslationStringFactory(*arg, **kw) - - def test_it(self): - # this is part of the API, we don't actually need to test much more - # than that it's importable - factory = self._makeOne('a') - self.assertEqual(factory('').domain, 'a') - -class TestLocalizer(unittest.TestCase): - def _makeOne(self, *arg, **kw): - from repoze.bfg.i18n import Localizer - return Localizer(*arg, **kw) - - def test_ctor(self): - localizer = self._makeOne('en_US', None) - self.assertEqual(localizer.locale_name, 'en_US') - self.assertEqual(localizer.translations, None) - - def test_translate(self): - translations = DummyTranslations() - localizer = self._makeOne(None, translations) - self.assertEqual(localizer.translate('123', domain='1', - mapping={}), '123') - self.failUnless(localizer.translator) - - def test_pluralize(self): - translations = DummyTranslations() - localizer = self._makeOne(None, translations) - self.assertEqual(localizer.pluralize('singular', 'plural', 1, - domain='1', mapping={}), - 'singular') - self.failUnless(localizer.pluralizer) - -class Test_negotiate_locale_name(unittest.TestCase): - def setUp(self): - cleanUp() - - def tearDown(self): - cleanUp() - - def _callFUT(self, request): - from repoze.bfg.i18n import negotiate_locale_name - return negotiate_locale_name(request) - - def _registerImpl(self, impl): - from repoze.bfg.threadlocal import get_current_registry - registry = get_current_registry() - from repoze.bfg.interfaces import ILocaleNegotiator - registry.registerUtility(impl, ILocaleNegotiator) - - def test_no_registry_on_request(self): - self._registerImpl(dummy_negotiator) - request = DummyRequest() - result = self._callFUT(request) - self.assertEqual(result, 'bogus') - - def test_with_registry_on_request(self): - from repoze.bfg.threadlocal import get_current_registry - registry = get_current_registry() - self._registerImpl(dummy_negotiator) - request = DummyRequest() - request.registry = registry - result = self._callFUT(request) - self.assertEqual(result, 'bogus') - - def test_default_from_settings(self): - from repoze.bfg.threadlocal import get_current_registry - registry = get_current_registry() - settings = {'default_locale_name':'settings'} - from repoze.bfg.interfaces import ISettings - registry.registerUtility(settings, ISettings) - request = DummyRequest() - request.registry = registry - result = self._callFUT(request) - self.assertEqual(result, 'settings') - - def test_use_default_locale_negotiator(self): - from repoze.bfg.threadlocal import get_current_registry - registry = get_current_registry() - request = DummyRequest() - request.registry = registry - request._LOCALE_ = 'locale' - result = self._callFUT(request) - self.assertEqual(result, 'locale') - - def test_default_default(self): - request = DummyRequest() - result = self._callFUT(request) - self.assertEqual(result, 'en') - -class Test_get_locale_name(unittest.TestCase): - def setUp(self): - cleanUp() - - def tearDown(self): - cleanUp() - - def _callFUT(self, request): - from repoze.bfg.i18n import get_locale_name - return get_locale_name(request) - - def _registerImpl(self, impl): - from repoze.bfg.threadlocal import get_current_registry - registry = get_current_registry() - from repoze.bfg.interfaces import ILocaleNegotiator - registry.registerUtility(impl, ILocaleNegotiator) - - def test_name_on_request(self): - request = DummyRequest() - request.bfg_locale_name = 'ie' - result = self._callFUT(request) - self.assertEqual(result, 'ie') - - def test_name_not_on_request(self): - self._registerImpl(dummy_negotiator) - request = DummyRequest() - result = self._callFUT(request) - self.assertEqual(result, 'bogus') - self.assertEqual(request.bfg_locale_name, 'bogus') - -class Test_get_localizer(unittest.TestCase): - def setUp(self): - cleanUp() - - def tearDown(self): - cleanUp() - - def _callFUT(self, request): - from repoze.bfg.i18n import get_localizer - return get_localizer(request) - - def test_no_registry_on_request(self): - request = DummyRequest() - request.bfg_localizer = '123' - result = self._callFUT(request) - self.assertEqual(result, '123') - - def test_with_registry_on_request(self): - from repoze.bfg.threadlocal import get_current_registry - registry = get_current_registry() - request = DummyRequest() - request.bfg_localizer = '123' - request.registry = registry - result = self._callFUT(request) - self.assertEqual(result, '123') - - def test_locale_on_request(self): - request = DummyRequest() - request.bfg_localizer = 'abc' - result = self._callFUT(request) - self.assertEqual(result, 'abc') - - def test_locale_from_registry(self): - from repoze.bfg.threadlocal import get_current_registry - from repoze.bfg.interfaces import ILocalizer - registry = get_current_registry() - locale = 'abc' - registry.registerUtility(locale, ILocalizer, name='en') - request = DummyRequest() - request.bfg_locale_name = 'en' - result = self._callFUT(request) - self.assertEqual(result, 'abc') - - def test_locale_from_mo(self): - import os - from repoze.bfg.threadlocal import get_current_registry - from repoze.bfg.interfaces import ITranslationDirectories - from repoze.bfg.i18n import Localizer - registry = get_current_registry() - here = os.path.dirname(__file__) - localedir = os.path.join(here, 'localeapp', 'locale') - localedirs = [localedir] - registry.registerUtility(localedirs, ITranslationDirectories) - request = DummyRequest() - request.bfg_locale_name = 'de' - result = self._callFUT(request) - self.assertEqual(result.__class__, Localizer) - self.assertEqual(result.translate('Approve', 'deformsite'), - 'Genehmigen') - self.assertEqual(result.translate('Approve'), 'Approve') - self.failUnless(hasattr(result, 'pluralize')) - - def test_locale_from_mo_bad_mo(self): - import os - from repoze.bfg.threadlocal import get_current_registry - from repoze.bfg.interfaces import ITranslationDirectories - from repoze.bfg.i18n import Localizer - registry = get_current_registry() - here = os.path.dirname(__file__) - localedir = os.path.join(here, 'localeapp', 'locale') - localedirs = [localedir] - registry.registerUtility(localedirs, ITranslationDirectories) - request = DummyRequest() - request.bfg_locale_name = 'be' - result = self._callFUT(request) - self.assertEqual(result.__class__, Localizer) - self.assertEqual(result.translate('Approve', 'deformsite'), - 'Approve') - -class Test_default_locale_negotiator(unittest.TestCase): - def setUp(self): - cleanUp() - - def tearDown(self): - cleanUp() - - def _callFUT(self, request): - from repoze.bfg.i18n import default_locale_negotiator - return default_locale_negotiator(request) - - def test_from_none(self): - request = DummyRequest() - result = self._callFUT(request) - self.assertEqual(result, None) - - def test_from_request_attr(self): - request = DummyRequest() - request._LOCALE_ = 'foo' - result = self._callFUT(request) - self.assertEqual(result, 'foo') - - def test_from_params(self): - request = DummyRequest() - request.params['_LOCALE_'] = 'foo' - result = self._callFUT(request) - self.assertEqual(result, 'foo') - - def test_from_cookies(self): - request = DummyRequest() - request.cookies['_LOCALE_'] = 'foo' - result = self._callFUT(request) - self.assertEqual(result, 'foo') - -class TestTranslations(unittest.TestCase): - def _getTargetClass(self): - from repoze.bfg.i18n import Translations - return Translations - - def _makeOne(self): - messages1 = [ - ('foo', 'Voh'), - (('foo1', 1), 'Voh1'), - ] - messages2 = [ - ('foo', 'VohD'), - (('foo1', 1), 'VohD1'), - ] - - klass = self._getTargetClass() - - translations1 = klass(None, domain='messages') - translations1._catalog = dict(messages1) - translations1.plural = lambda *arg: 1 - translations2 = klass(None, domain='messages1') - translations2._catalog = dict(messages2) - translations2.plural = lambda *arg: 1 - translations = translations1.add(translations2, merge=False) - return translations - - def test_load_domain_None(self): - import gettext - import os - here = os.path.dirname(__file__) - localedir = os.path.join(here, 'localeapp', 'locale') - locales = ['de', 'en'] - klass = self._getTargetClass() - result = klass.load(localedir, locales, domain=None) - self.assertEqual(result.__class__, gettext.NullTranslations) - - def test_load_found_locale_and_domain(self): - import os - here = os.path.dirname(__file__) - localedir = os.path.join(here, 'localeapp', 'locale') - locales = ['de', 'en'] - klass = self._getTargetClass() - result = klass.load(localedir, locales, domain='deformsite') - self.assertEqual(result.__class__, klass) - - def test_load_found_locale_and_domain_locale_is_string(self): - import os - here = os.path.dirname(__file__) - localedir = os.path.join(here, 'localeapp', 'locale') - locales = 'de' - klass = self._getTargetClass() - result = klass.load(localedir, locales, domain='deformsite') - self.assertEqual(result.__class__, klass) - - def test___repr__(self): - inst = self._makeOne() - result = repr(inst) - self.assertEqual(result, '<Translations: "None">') - - def test_merge_not_gnutranslations(self): - inst = self._makeOne() - self.assertEqual(inst.merge(None), inst) - - def test_merge_gnutranslations(self): - inst = self._makeOne() - inst2 = self._makeOne() - inst2._catalog['a'] = 'b' - inst.merge(inst2) - self.assertEqual(inst._catalog['a'], 'b') - - def test_add_different_domain_merge_true_notexisting(self): - inst = self._makeOne() - inst2 = self._makeOne() - inst2.domain = 'domain2' - inst.add(inst2) - self.assertEqual(inst._domains['domain2'], inst2) - - def test_add_different_domain_merge_true_existing(self): - inst = self._makeOne() - inst2 = self._makeOne() - inst3 = self._makeOne() - inst2.domain = 'domain2' - inst2._catalog['a'] = 'b' - inst3.domain = 'domain2' - inst._domains['domain2'] = inst3 - inst.add(inst2) - self.assertEqual(inst._domains['domain2'], inst3) - self.assertEqual(inst3._catalog['a'], 'b') - - def test_add_same_domain_merge_true(self): - inst = self._makeOne() - inst2 = self._makeOne() - inst2._catalog['a'] = 'b' - inst.add(inst2) - self.assertEqual(inst._catalog['a'], 'b') - - def test_dgettext(self): - t = self._makeOne() - self.assertEqual(t.dgettext('messages', 'foo'), 'Voh') - self.assertEqual(t.dgettext('messages1', 'foo'), 'VohD') - - def test_ldgettext(self): - t = self._makeOne() - self.assertEqual(t.ldgettext('messages', 'foo'), 'Voh') - self.assertEqual(t.ldgettext('messages1', 'foo'), 'VohD') - - def test_dugettext(self): - t = self._makeOne() - self.assertEqual(t.dugettext('messages', 'foo'), 'Voh') - self.assertEqual(t.dugettext('messages1', 'foo'), 'VohD') - - def test_dngettext(self): - t = self._makeOne() - self.assertEqual(t.dngettext('messages', 'foo1', 'foos1', 1), 'Voh1') - self.assertEqual(t.dngettext('messages1', 'foo1', 'foos1', 1), 'VohD1') - - def test_ldngettext(self): - t = self._makeOne() - self.assertEqual(t.ldngettext('messages', 'foo1', 'foos1', 1), 'Voh1') - self.assertEqual(t.ldngettext('messages1', 'foo1', 'foos1', 1), 'VohD1') - - def test_dungettext(self): - t = self._makeOne() - self.assertEqual(t.dungettext('messages', 'foo1', 'foos1', 1), 'Voh1') - self.assertEqual(t.dungettext('messages1', 'foo1', 'foos1', 1), 'VohD1') - - -class DummyRequest(object): - def __init__(self): - self.params = {} - self.cookies = {} - -def dummy_negotiator(request): - return 'bogus' - -class DummyTranslations(object): - def ugettext(self, text): - return text - - def ungettext(self, singular, plural, n): - return singular diff --git a/repoze/bfg/tests/test_integration.py b/repoze/bfg/tests/test_integration.py deleted file mode 100644 index b6eb860ee..000000000 --- a/repoze/bfg/tests/test_integration.py +++ /dev/null @@ -1,236 +0,0 @@ -import os -import unittest - -from repoze.bfg.wsgi import wsgiapp -from repoze.bfg.view import bfg_view -from repoze.bfg.view import static - -from zope.interface import Interface - -from repoze.bfg import testing - -class INothing(Interface): - pass - -@bfg_view(for_=INothing) -@wsgiapp -def wsgiapptest(environ, start_response): - """ """ - return '123' - -class WGSIAppPlusBFGViewTests(unittest.TestCase): - def test_it(self): - from venusian import ATTACH_ATTR - import types - self.failUnless(getattr(wsgiapptest, ATTACH_ATTR)) - self.failUnless(type(wsgiapptest) is types.FunctionType) - context = DummyContext() - request = DummyRequest() - result = wsgiapptest(context, request) - self.assertEqual(result, '123') - - def test_scanned(self): - from repoze.bfg.interfaces import IRequest - from repoze.bfg.interfaces import IView - from repoze.bfg.interfaces import IViewClassifier - from repoze.bfg.configuration import Configurator - from repoze.bfg.tests import test_integration - config = Configurator() - config.scan(test_integration) - reg = config.registry - view = reg.adapters.lookup( - (IViewClassifier, IRequest, INothing), IView, name='') - self.assertEqual(view, wsgiapptest) - -here = os.path.dirname(__file__) -staticapp = static(os.path.join(here, 'fixtures')) - -class TestStaticApp(unittest.TestCase): - def test_it(self): - from webob import Request - context = DummyContext() - from StringIO import StringIO - request = Request({'PATH_INFO':'', - 'SCRIPT_NAME':'', - 'SERVER_NAME':'localhost', - 'SERVER_PORT':'80', - 'REQUEST_METHOD':'GET', - 'wsgi.version':(1,0), - 'wsgi.url_scheme':'http', - 'wsgi.input':StringIO()}) - request.subpath = ['minimal.pt'] - result = staticapp(context, request) - self.assertEqual(result.status, '200 OK') - self.assertEqual( - result.body, - open(os.path.join(here, 'fixtures/minimal.pt'), 'r').read()) - -class TwillBase(unittest.TestCase): - root_factory = None - def setUp(self): - import sys - import twill - from repoze.bfg.configuration import Configurator - config = Configurator(root_factory=self.root_factory) - config.load_zcml(self.config) - twill.add_wsgi_intercept('localhost', 6543, config.make_wsgi_app) - if sys.platform is 'win32': # pragma: no cover - out = open('nul:', 'wb') - else: - out = open('/dev/null', 'wb') - twill.set_output(out) - testing.setUp(registry=config.registry) - - def tearDown(self): - import twill - import twill.commands - twill.commands.reset_browser() - twill.remove_wsgi_intercept('localhost', 6543) - twill.set_output(None) - testing.tearDown() - -class TestFixtureApp(TwillBase): - config = 'repoze.bfg.tests.fixtureapp:configure.zcml' - def test_it(self): - import twill.commands - browser = twill.commands.get_browser() - browser.go('http://localhost:6543/another.html') - self.assertEqual(browser.get_code(), 200) - self.assertEqual(browser.get_html(), 'fixture') - browser.go('http://localhost:6543') - self.assertEqual(browser.get_code(), 200) - self.assertEqual(browser.get_html(), 'fixture') - browser.go('http://localhost:6543/dummyskin.html') - self.assertEqual(browser.get_code(), 404) - browser.go('http://localhost:6543/error.html') - self.assertEqual(browser.get_code(), 200) - self.assertEqual(browser.get_html(), 'supressed') - browser.go('http://localhost:6543/protected.html') - self.assertEqual(browser.get_code(), 401) - -class TestCCBug(TwillBase): - # "unordered" as reported in IRC by author of - # http://labs.creativecommons.org/2010/01/13/cc-engine-and-web-non-frameworks/ - config = 'repoze.bfg.tests.ccbugapp:configure.zcml' - def test_it(self): - import twill.commands - browser = twill.commands.get_browser() - browser.go('http://localhost:6543/licenses/1/v1/rdf') - self.assertEqual(browser.get_code(), 200) - self.assertEqual(browser.get_html(), 'rdf') - browser.go('http://localhost:6543/licenses/1/v1/juri') - self.assertEqual(browser.get_code(), 200) - self.assertEqual(browser.get_html(), 'juri') - -class TestHybridApp(TwillBase): - # make sure views registered for a route "win" over views registered - # without one, even though the context of the non-route view may - # be more specific than the route view. - config = 'repoze.bfg.tests.hybridapp:configure.zcml' - def test_it(self): - import twill.commands - browser = twill.commands.get_browser() - browser.go('http://localhost:6543/') - self.assertEqual(browser.get_code(), 200) - self.assertEqual(browser.get_html(), 'global') - browser.go('http://localhost:6543/abc') - self.assertEqual(browser.get_code(), 200) - self.assertEqual(browser.get_html(), 'route') - browser.go('http://localhost:6543/def') - self.assertEqual(browser.get_code(), 200) - self.assertEqual(browser.get_html(), 'route2') - browser.go('http://localhost:6543/ghi') - self.assertEqual(browser.get_code(), 200) - self.assertEqual(browser.get_html(), 'global') - browser.go('http://localhost:6543/jkl') - self.assertEqual(browser.get_code(), 404) - browser.go('http://localhost:6543/mno/global2') - self.assertEqual(browser.get_code(), 404) - browser.go('http://localhost:6543/pqr/global2') - self.assertEqual(browser.get_code(), 200) - self.assertEqual(browser.get_html(), 'global2') - browser.go('http://localhost:6543/error') - self.assertEqual(browser.get_code(), 200) - self.assertEqual(browser.get_html(), 'supressed') - browser.go('http://localhost:6543/error2') - self.assertEqual(browser.get_code(), 200) - self.assertEqual(browser.get_html(), 'supressed2') - browser.go('http://localhost:6543/error_sub') - self.assertEqual(browser.get_code(), 200) - self.assertEqual(browser.get_html(), 'supressed2') - -class TestRestBugApp(TwillBase): - # test bug reported by delijati 2010/2/3 (http://pastebin.com/d4cc15515) - config = 'repoze.bfg.tests.restbugapp:configure.zcml' - def test_it(self): - import twill.commands - browser = twill.commands.get_browser() - browser.go('http://localhost:6543/pet') - self.assertEqual(browser.get_code(), 200) - self.assertEqual(browser.get_html(), 'gotten') - -class TestViewDecoratorApp(TwillBase): - config = 'repoze.bfg.tests.viewdecoratorapp:configure.zcml' - def test_it(self): - import twill.commands - browser = twill.commands.get_browser() - browser.go('http://localhost:6543/first') - self.assertEqual(browser.get_code(), 200) - self.failUnless('OK' in browser.get_html()) - - browser.go('http://localhost:6543/second') - self.assertEqual(browser.get_code(), 200) - self.failUnless('OK2' in browser.get_html()) - - browser.go('http://localhost:6543/third') - self.assertEqual(browser.get_code(), 200) - self.failUnless('OK3' in browser.get_html()) - -from repoze.bfg.tests.exceptionviewapp.models import AnException, NotAnException -excroot = {'anexception':AnException(), - 'notanexception':NotAnException()} - -class TestExceptionViewsApp(TwillBase): - config = 'repoze.bfg.tests.exceptionviewapp:configure.zcml' - root_factory = lambda *arg: excroot - def test_it(self): - import twill.commands - browser = twill.commands.get_browser() - browser.go('http://localhost:6543/') - self.assertEqual(browser.get_code(), 200) - self.failUnless('maybe' in browser.get_html()) - - browser.go('http://localhost:6543/notanexception') - self.assertEqual(browser.get_code(), 200) - self.failUnless('no' in browser.get_html()) - - browser.go('http://localhost:6543/anexception') - self.assertEqual(browser.get_code(), 200) - self.failUnless('yes' in browser.get_html()) - - browser.go('http://localhost:6543/route_raise_exception') - self.assertEqual(browser.get_code(), 200) - self.failUnless('yes' in browser.get_html()) - - browser.go('http://localhost:6543/route_raise_exception2') - self.assertEqual(browser.get_code(), 200) - self.failUnless('yes' in browser.get_html()) - - browser.go('http://localhost:6543/route_raise_exception3') - self.assertEqual(browser.get_code(), 200) - self.failUnless('whoa' in browser.get_html()) - - browser.go('http://localhost:6543/route_raise_exception4') - self.assertEqual(browser.get_code(), 200) - self.failUnless('whoa' in browser.get_html()) - -class DummyContext(object): - pass - -class DummyRequest: - subpath = ('__init__.py',) - traversed = None - environ = {'REQUEST_METHOD':'GET', 'wsgi.version':(1,0)} - def get_response(self, application): - return application(None, None) - diff --git a/repoze/bfg/tests/test_location.py b/repoze/bfg/tests/test_location.py deleted file mode 100644 index 9b8360f8b..000000000 --- a/repoze/bfg/tests/test_location.py +++ /dev/null @@ -1,40 +0,0 @@ -import unittest - -class TestInside(unittest.TestCase): - def _callFUT(self, one, two): - from repoze.bfg.location import inside - return inside(one, two) - - def test_inside(self): - o1 = Location() - o2 = Location(); o2.__parent__ = o1 - o3 = Location(); o3.__parent__ = o2 - o4 = Location(); o4.__parent__ = o3 - - self.assertEqual(self._callFUT(o1, o1), True) - self.assertEqual(self._callFUT(o2, o1), True) - self.assertEqual(self._callFUT(o3, o1), True) - self.assertEqual(self._callFUT(o4, o1), True) - self.assertEqual(self._callFUT(o1, o4), False) - self.assertEqual(self._callFUT(o1, None), False) - -class TestLineage(unittest.TestCase): - def _callFUT(self, context): - from repoze.bfg.location import lineage - return lineage(context) - - def test_lineage(self): - o1 = Location() - o2 = Location(); o2.__parent__ = o1 - o3 = Location(); o3.__parent__ = o2 - o4 = Location(); o4.__parent__ = o3 - result = list(self._callFUT(o3)) - self.assertEqual(result, [o3, o2, o1]) - result = list(self._callFUT(o1)) - self.assertEqual(result, [o1]) - -from repoze.bfg.interfaces import ILocation -from zope.interface import implements -class Location(object): - implements(ILocation) - __name__ = __parent__ = None diff --git a/repoze/bfg/tests/test_log.py b/repoze/bfg/tests/test_log.py deleted file mode 100644 index 4cc8d12a0..000000000 --- a/repoze/bfg/tests/test_log.py +++ /dev/null @@ -1,16 +0,0 @@ -import unittest - -class TestFunctions(unittest.TestCase): - def test_make_stream_logger(self): - from repoze.bfg.log import make_stream_logger - import logging - import sys - logger = make_stream_logger('foo', sys.stderr, levelname='DEBUG', - fmt='%(message)s') - self.assertEqual(logger.name, 'foo') - self.assertEqual(logger.handlers[0].stream, sys.stderr) - self.assertEqual(logger.handlers[0].formatter._fmt, '%(message)s') - self.assertEqual(logger.level, logging.DEBUG) - - - diff --git a/repoze/bfg/tests/test_paster.py b/repoze/bfg/tests/test_paster.py deleted file mode 100644 index 43837b5f0..000000000 --- a/repoze/bfg/tests/test_paster.py +++ /dev/null @@ -1,186 +0,0 @@ -import unittest - -class TestBFGShellCommand(unittest.TestCase): - def _getTargetClass(self): - from repoze.bfg.paster import BFGShellCommand - return BFGShellCommand - - def _makeOne(self): - return self._getTargetClass()('bfgshell') - - def test_command_ipython_disabled(self): - command = self._makeOne() - interact = DummyInteractor() - app = DummyApp() - loadapp = DummyLoadApp(app) - command.interact = (interact,) - command.loadapp = (loadapp,) - command.args = ('/foo/bar/myapp.ini', 'myapp') - class Options(object): pass - command.options = Options() - command.options.disable_ipython =True - command.command(IPShell=None) - self.assertEqual(loadapp.config_name, 'config:/foo/bar/myapp.ini') - self.assertEqual(loadapp.section_name, 'myapp') - self.failUnless(loadapp.relative_to) - self.assertEqual(len(app.threadlocal_manager.pushed), 1) - pushed = app.threadlocal_manager.pushed[0] - self.assertEqual(pushed['registry'], dummy_registry) - self.assertEqual(pushed['request'].registry, dummy_registry) - self.assertEqual(interact.local, {'root':dummy_root}) - self.failUnless(interact.banner) - self.assertEqual(len(app.threadlocal_manager.popped), 1) - - def test_command_ipython_enabled(self): - command = self._makeOne() - app = DummyApp() - loadapp = DummyLoadApp(app) - command.loadapp = (loadapp,) - dummy_shell_factory = DummyIPShellFactory() - command.args = ('/foo/bar/myapp.ini', 'myapp') - class Options(object): pass - command.options = Options() - command.options.disable_ipython = False - command.command(IPShell=dummy_shell_factory) - self.assertEqual(loadapp.config_name, 'config:/foo/bar/myapp.ini') - self.assertEqual(loadapp.section_name, 'myapp') - self.failUnless(loadapp.relative_to) - self.assertEqual(len(app.threadlocal_manager.pushed), 1) - pushed = app.threadlocal_manager.pushed[0] - self.assertEqual(pushed['registry'], dummy_registry) - self.assertEqual(pushed['request'].registry, dummy_registry) - self.assertEqual(dummy_shell_factory.shell.local_ns,{'root':dummy_root}) - self.assertEqual(dummy_shell_factory.shell.global_ns, {}) - self.failUnless('\n\n' in dummy_shell_factory.shell.IP.BANNER) - self.assertEqual(len(app.threadlocal_manager.popped), 1) - - def test_command_get_app_hookable(self): - from paste.deploy import loadapp - command = self._makeOne() - app = DummyApp() - apped = [] - def get_app(*arg, **kw): - apped.append((arg, kw)) - return app - command.get_app = get_app - interact = DummyInteractor() - app = DummyApp() - command.interact = (interact,) - command.args = ('/foo/bar/myapp.ini', 'myapp') - class Options(object): pass - command.options = Options() - command.options.disable_ipython =True - command.command(IPShell=None) - self.assertEqual(len(app.threadlocal_manager.pushed), 1) - pushed = app.threadlocal_manager.pushed[0] - self.assertEqual(pushed['registry'], dummy_registry) - self.assertEqual(pushed['request'].registry, dummy_registry) - self.assertEqual(interact.local, {'root':dummy_root}) - self.failUnless(interact.banner) - self.assertEqual(len(app.threadlocal_manager.popped), 1) - self.assertEqual(apped, [(('/foo/bar/myapp.ini', 'myapp'), - {'loadapp': loadapp})]) - - def test_command_get_root_hookable(self): - command = self._makeOne() - interact = DummyInteractor() - app = DummyApp() - loadapp = DummyLoadApp(app) - command.interact = (interact,) - command.loadapp = (loadapp,) - root = Dummy() - apps = [] - def get_root(app): - apps.append(app) - return root, lambda *arg: None - command.get_root =get_root - command.args = ('/foo/bar/myapp.ini', 'myapp') - class Options(object): pass - command.options = Options() - command.options.disable_ipython =True - command.command(IPShell=None) - self.assertEqual(loadapp.config_name, 'config:/foo/bar/myapp.ini') - self.assertEqual(loadapp.section_name, 'myapp') - self.failUnless(loadapp.relative_to) - self.assertEqual(len(app.threadlocal_manager.pushed), 0) - self.assertEqual(interact.local, {'root':root}) - self.failUnless(interact.banner) - self.assertEqual(apps, [app]) - -class TestGetApp(unittest.TestCase): - def _callFUT(self, config_file, section_name, loadapp): - from repoze.bfg.paster import get_app - return get_app(config_file, section_name, loadapp) - - def test_it(self): - import os - app = DummyApp() - loadapp = DummyLoadApp(app) - result = self._callFUT('/foo/bar/myapp.ini', 'myapp', loadapp) - self.assertEqual(loadapp.config_name, 'config:/foo/bar/myapp.ini') - self.assertEqual(loadapp.section_name, 'myapp') - self.assertEqual(loadapp.relative_to, os.getcwd()) - self.assertEqual(result, app) - -class Dummy: - pass - -class DummyIPShellFactory(object): - def __call__(self, argv, user_ns=None): - shell = DummyIPShell() - shell(user_ns, {}) - self.shell = shell - return shell - -class DummyIPShell(object): - IP = Dummy() - IP.BANNER = 'foo' - def __call__(self, local_ns, global_ns): - self.local_ns = local_ns - self.global_ns = global_ns - - def mainloop(self): - pass - -dummy_root = Dummy() - -class DummyRegistry(object): - def queryUtility(self, iface, default=None): - return default - -dummy_registry = DummyRegistry() - -class DummyInteractor: - def __call__(self, banner, local): - self.banner = banner - self.local = local - -class DummyLoadApp: - def __init__(self, app): - self.app = app - - def __call__(self, config_name, name=None, relative_to=None): - self.config_name = config_name - self.section_name = name - self.relative_to = relative_to - return self.app - -class DummyApp: - def __init__(self): - self.registry = dummy_registry - self.threadlocal_manager = DummyThreadLocalManager() - - def root_factory(self, environ): - return dummy_root - -class DummyThreadLocalManager: - def __init__(self): - self.pushed = [] - self.popped = [] - - def push(self, item): - self.pushed.append(item) - - def pop(self): - self.popped.append(True) - diff --git a/repoze/bfg/tests/test_path.py b/repoze/bfg/tests/test_path.py deleted file mode 100644 index 8ee0474f9..000000000 --- a/repoze/bfg/tests/test_path.py +++ /dev/null @@ -1,172 +0,0 @@ -import unittest - -class TestCallerPath(unittest.TestCase): - def tearDown(self): - from repoze.bfg.tests import test_path - if hasattr(test_path, '__bfg_abspath__'): - del test_path.__bfg_abspath__ - - def _callFUT(self, path, level=2): - from repoze.bfg.path import caller_path - return caller_path(path, level) - - def test_isabs(self): - result = self._callFUT('/a/b/c') - self.assertEqual(result, '/a/b/c') - - def test_pkgrelative(self): - import os - here = os.path.abspath(os.path.dirname(__file__)) - result = self._callFUT('a/b/c') - self.assertEqual(result, os.path.join(here, 'a/b/c')) - - def test_memoization_has_bfg_abspath(self): - import os - from repoze.bfg.tests import test_path - test_path.__bfg_abspath__ = '/foo/bar' - result = self._callFUT('a/b/c') - self.assertEqual(result, os.path.join('/foo/bar', 'a/b/c')) - - def test_memoization_success(self): - import os - here = os.path.abspath(os.path.dirname(__file__)) - from repoze.bfg.tests import test_path - result = self._callFUT('a/b/c') - self.assertEqual(result, os.path.join(here, 'a/b/c')) - self.assertEqual(test_path.__bfg_abspath__, here) - -class TestCallerModule(unittest.TestCase): - def _callFUT(self, level=2): - from repoze.bfg.path import caller_module - return caller_module(level) - - def test_it_level_1(self): - from repoze.bfg.tests import test_path - result = self._callFUT(1) - self.assertEqual(result, test_path) - - def test_it_level_2(self): - from repoze.bfg.tests import test_path - result = self._callFUT(2) - self.assertEqual(result, test_path) - - def test_it_level_3(self): - from repoze.bfg.tests import test_path - result = self._callFUT(3) - self.failIfEqual(result, test_path) - -class TestCallerPackage(unittest.TestCase): - def _callFUT(self, *arg, **kw): - from repoze.bfg.path import caller_package - return caller_package(*arg, **kw) - - def test_it_level_1(self): - from repoze.bfg import tests - result = self._callFUT(1) - self.assertEqual(result, tests) - - def test_it_level_2(self): - from repoze.bfg import tests - result = self._callFUT(2) - self.assertEqual(result, tests) - - def test_it_level_3(self): - import unittest - result = self._callFUT(3) - self.assertEqual(result, unittest) - - def test_it_package(self): - import repoze.bfg.tests - def dummy_caller_module(*arg): - return repoze.bfg.tests - result = self._callFUT(1, caller_module=dummy_caller_module) - self.assertEqual(result, repoze.bfg.tests) - -class TestPackagePath(unittest.TestCase): - def _callFUT(self, package): - from repoze.bfg.path import package_path - return package_path(package) - - def test_it_package(self): - from repoze.bfg import tests - package = DummyPackageOrModule(tests) - result = self._callFUT(package) - self.assertEqual(result, package.package_path) - - def test_it_module(self): - from repoze.bfg.tests import test_path - module = DummyPackageOrModule(test_path) - result = self._callFUT(module) - self.assertEqual(result, module.package_path) - - def test_memoization_success(self): - from repoze.bfg.tests import test_path - module = DummyPackageOrModule(test_path) - self._callFUT(module) - self.assertEqual(module.__bfg_abspath__, module.package_path) - - def test_memoization_fail(self): - from repoze.bfg.tests import test_path - module = DummyPackageOrModule(test_path, raise_exc=TypeError) - result = self._callFUT(module) - self.failIf(hasattr(module, '__bfg_abspath__')) - self.assertEqual(result, module.package_path) - -class TestPackageOf(unittest.TestCase): - def _callFUT(self, package): - from repoze.bfg.path import package_of - return package_of(package) - - def test_it_package(self): - from repoze.bfg import tests - package = DummyPackageOrModule(tests) - result = self._callFUT(package) - self.assertEqual(result, tests) - - def test_it_module(self): - import repoze.bfg.tests.test_configuration - from repoze.bfg import tests - package = DummyPackageOrModule(repoze.bfg.tests.test_configuration) - result = self._callFUT(package) - self.assertEqual(result, tests) - -class TestPackageName(unittest.TestCase): - def _callFUT(self, package): - from repoze.bfg.path import package_name - return package_name(package) - - def test_it_package(self): - from repoze.bfg import tests - package = DummyPackageOrModule(tests) - result = self._callFUT(package) - self.assertEqual(result, 'repoze.bfg.tests') - - def test_it_module(self): - from repoze.bfg.tests import test_path - module = DummyPackageOrModule(test_path) - result = self._callFUT(module) - self.assertEqual(result, 'repoze.bfg.tests') - - def test_it_None(self): - result = self._callFUT(None) - self.assertEqual(result, '__main__') - -class DummyPackageOrModule: - def __init__(self, real_package_or_module, raise_exc=None): - self.__dict__['raise_exc'] = raise_exc - self.__dict__['__name__'] = real_package_or_module.__name__ - import os - self.__dict__['package_path'] = os.path.dirname( - os.path.abspath(real_package_or_module.__file__)) - self.__dict__['__file__'] = real_package_or_module.__file__ - - def __setattr__(self, key, val): - if self.raise_exc is not None: - raise self.raise_exc - self.__dict__[key] = val - - - - - - diff --git a/repoze/bfg/tests/test_registry.py b/repoze/bfg/tests/test_registry.py deleted file mode 100644 index b6185964a..000000000 --- a/repoze/bfg/tests/test_registry.py +++ /dev/null @@ -1,42 +0,0 @@ -import unittest - -class TestRegistry(unittest.TestCase): - def _getTargetClass(self): - from repoze.bfg.registry import Registry - return Registry - - def _makeOne(self): - return self._getTargetClass()() - - def test_registerHandler_and_notify(self): - registry = self._makeOne() - self.assertEqual(registry.has_listeners, False) - L = [] - def f(event): - L.append(event) - registry.registerHandler(f, [IDummyEvent]) - self.assertEqual(registry.has_listeners, True) - event = DummyEvent() - registry.notify(event) - self.assertEqual(L, [event]) - - def test_registerSubscriptionAdapter(self): - registry = self._makeOne() - self.assertEqual(registry.has_listeners, False) - from zope.interface import Interface - registry.registerSubscriptionAdapter(DummyEvent, - [IDummyEvent], Interface) - self.assertEqual(registry.has_listeners, True) - -class DummyModule: - __path__ = "foo" - __name__ = "dummy" - __file__ = '' - -from zope.interface import Interface -from zope.interface import implements -class IDummyEvent(Interface): - pass - -class DummyEvent(object): - implements(IDummyEvent) diff --git a/repoze/bfg/tests/test_renderers.py b/repoze/bfg/tests/test_renderers.py deleted file mode 100644 index 264b4a547..000000000 --- a/repoze/bfg/tests/test_renderers.py +++ /dev/null @@ -1,499 +0,0 @@ -import unittest - -from repoze.bfg.testing import cleanUp -from repoze.bfg import testing - -class TestTemplateRendererFactory(unittest.TestCase): - def setUp(self): - cleanUp() - - def tearDown(self): - cleanUp() - - def _callFUT(self, path, factory): - from repoze.bfg.renderers import template_renderer_factory - return template_renderer_factory(path, factory) - - def test_abspath_notfound(self): - from repoze.bfg.interfaces import ITemplateRenderer - abspath = '/wont/exist' - testing.registerUtility({}, ITemplateRenderer, name=abspath) - self.assertRaises(ValueError, self._callFUT, abspath, None) - - def test_abspath_alreadyregistered(self): - from repoze.bfg.interfaces import ITemplateRenderer - import os - abspath = os.path.abspath(__file__) - renderer = {} - testing.registerUtility(renderer, ITemplateRenderer, name=abspath) - result = self._callFUT(abspath, None) - self.failUnless(result is renderer) - - def test_abspath_notyetregistered(self): - from repoze.bfg.interfaces import ITemplateRenderer - import os - abspath = os.path.abspath(__file__) - renderer = {} - testing.registerUtility(renderer, ITemplateRenderer, name=abspath) - result = self._callFUT(abspath, None) - self.failUnless(result is renderer) - - def test_relpath_path_registered(self): - renderer = {} - from repoze.bfg.interfaces import ITemplateRenderer - testing.registerUtility(renderer, ITemplateRenderer, name='foo/bar') - result = self._callFUT('foo/bar', None) - self.failUnless(renderer is result) - - def test_relpath_is_package_registered(self): - renderer = {} - from repoze.bfg.interfaces import ITemplateRenderer - testing.registerUtility(renderer, ITemplateRenderer, name='foo:bar/baz') - result = self._callFUT('foo:bar/baz', None) - self.failUnless(renderer is result) - - def test_spec_notfound(self): - self.assertRaises(ValueError, self._callFUT, - 'repoze.bfg.tests:wont/exist', None) - - def test_spec_alreadyregistered(self): - from repoze.bfg.interfaces import ITemplateRenderer - from repoze.bfg import tests - module_name = tests.__name__ - relpath = 'test_renderers.py' - spec = '%s:%s' % (module_name, relpath) - renderer = {} - testing.registerUtility(renderer, ITemplateRenderer, name=spec) - result = self._callFUT(spec, None) - self.failUnless(result is renderer) - - def test_spec_notyetregistered(self): - import os - from repoze.bfg import tests - module_name = tests.__name__ - relpath = 'test_renderers.py' - renderer = {} - factory = DummyFactory(renderer) - spec = '%s:%s' % (module_name, relpath) - result = self._callFUT(spec, factory) - self.failUnless(result is renderer) - path = os.path.abspath(__file__) - if path.endswith('pyc'): # pragma: no cover - path = path[:-1] - self.assertEqual(factory.path, path) - self.assertEqual(factory.kw, {}) - - def test_reload_resources_true(self): - from repoze.bfg.threadlocal import get_current_registry - from repoze.bfg.interfaces import ISettings - from repoze.bfg.interfaces import ITemplateRenderer - settings = {'reload_resources':True} - testing.registerUtility(settings, ISettings) - renderer = {} - factory = DummyFactory(renderer) - result = self._callFUT('repoze.bfg.tests:test_renderers.py', factory) - self.failUnless(result is renderer) - spec = '%s:%s' % ('repoze.bfg.tests', 'test_renderers.py') - reg = get_current_registry() - self.assertEqual(reg.queryUtility(ITemplateRenderer, name=spec), - None) - - def test_reload_resources_false(self): - from repoze.bfg.threadlocal import get_current_registry - from repoze.bfg.interfaces import ISettings - from repoze.bfg.interfaces import ITemplateRenderer - settings = {'reload_resources':False} - testing.registerUtility(settings, ISettings) - renderer = {} - factory = DummyFactory(renderer) - result = self._callFUT('repoze.bfg.tests:test_renderers.py', factory) - self.failUnless(result is renderer) - spec = '%s:%s' % ('repoze.bfg.tests', 'test_renderers.py') - reg = get_current_registry() - self.assertNotEqual(reg.queryUtility(ITemplateRenderer, name=spec), - None) - -class TestRendererFromName(unittest.TestCase): - def setUp(self): - cleanUp() - - def tearDown(self): - cleanUp() - - def _callFUT(self, path, package=None): - from repoze.bfg.renderers import renderer_from_name - return renderer_from_name(path, package) - - def test_it(self): - from repoze.bfg.interfaces import IRendererFactory - import os - here = os.path.dirname(os.path.abspath(__file__)) - fixture = os.path.join(here, 'fixtures/minimal.pt') - def factory(path, **kw): - return path - testing.registerUtility(factory, IRendererFactory, name='.pt') - result = self._callFUT(fixture) - self.assertEqual(result, fixture) - - def test_with_package(self): - from repoze.bfg.interfaces import IRendererFactory - def factory(path, **kw): - return path - testing.registerUtility(factory, IRendererFactory, name='.pt') - import repoze.bfg.tests - result = self._callFUT('fixtures/minimal.pt', repoze.bfg.tests) - self.assertEqual(result, 'repoze.bfg.tests:fixtures/minimal.pt') - - def test_it_no_renderer(self): - self.assertRaises(ValueError, self._callFUT, 'foo') - - -class Test_json_renderer_factory(unittest.TestCase): - def _callFUT(self, name): - from repoze.bfg.renderers import json_renderer_factory - return json_renderer_factory(name) - - def test_it(self): - renderer = self._callFUT(None) - result = renderer({'a':1}, {}) - self.assertEqual(result, '{"a": 1}') - - def test_with_request_content_type_notset(self): - request = testing.DummyRequest() - renderer = self._callFUT(None) - renderer({'a':1}, {'request':request}) - self.assertEqual(request.response_content_type, 'application/json') - - def test_with_request_content_type_set(self): - request = testing.DummyRequest() - request.response_content_type = 'text/mishmash' - renderer = self._callFUT(None) - renderer({'a':1}, {'request':request}) - self.assertEqual(request.response_content_type, 'text/mishmash') - -class Test_string_renderer_factory(unittest.TestCase): - def _callFUT(self, name): - from repoze.bfg.renderers import string_renderer_factory - return string_renderer_factory(name) - - def test_it_unicode(self): - renderer = self._callFUT(None) - value = unicode('La Pe\xc3\xb1a', 'utf-8') - result = renderer(value, {}) - self.assertEqual(result, value) - - def test_it_str(self): - renderer = self._callFUT(None) - value = 'La Pe\xc3\xb1a' - result = renderer(value, {}) - self.assertEqual(result, value) - - def test_it_other(self): - renderer = self._callFUT(None) - value = None - result = renderer(value, {}) - self.assertEqual(result, 'None') - - def test_with_request_content_type_notset(self): - request = testing.DummyRequest() - renderer = self._callFUT(None) - renderer(None, {'request':request}) - self.assertEqual(request.response_content_type, 'text/plain') - - def test_with_request_content_type_set(self): - request = testing.DummyRequest() - request.response_content_type = 'text/mishmash' - renderer = self._callFUT(None) - renderer(None, {'request':request}) - self.assertEqual(request.response_content_type, 'text/mishmash') - -class Test_rendered_response(unittest.TestCase): - def setUp(self): - testing.setUp() - from zope.deprecation import __show__ - __show__.off() - - def tearDown(self): - testing.tearDown() - from zope.deprecation import __show__ - __show__.on() - - def _callFUT(self, renderer, response, view=None, - context=None, request=None, renderer_name=None): - from repoze.bfg.renderers import rendered_response - if request is None: - request = testing.DummyRequest() - return rendered_response(renderer, response, view, - context, request, renderer_name) - - def _makeRenderer(self): - def renderer(*arg): - return 'Hello!' - return renderer - - def test_is_response(self): - renderer = self._makeRenderer() - response = DummyResponse() - result = self._callFUT(renderer, response) - self.assertEqual(result, response) - - def test_calls_renderer(self): - renderer = self._makeRenderer() - response = {'a':'1'} - result = self._callFUT(renderer, response) - self.assertEqual(result.body, 'Hello!') - - -class TestRendererHelper(unittest.TestCase): - def setUp(self): - self.config = cleanUp() - - def tearDown(self): - cleanUp() - - def _makeOne(self, *arg, **kw): - from repoze.bfg.renderers import RendererHelper - return RendererHelper(*arg, **kw) - - def _registerRendererFactory(self): - from repoze.bfg.interfaces import IRendererFactory - def renderer(*arg): - def respond(*arg): - return arg - return respond - self.config.registry.registerUtility(renderer, IRendererFactory, - name='.foo') - return renderer - - def test_resolve_spec_path_is_None(self): - helper = self._makeOne('loo.foo') - result = helper.resolve_spec(None) - self.assertEqual(result, None) - - def test_resolve_spec_package_is_None(self): - helper = self._makeOne('loo.foo') - result = helper.resolve_spec('/foo/bar') - self.assertEqual(result, '/foo/bar') - - def test_resolve_spec_absolute(self): - helper = self._makeOne('loo.foo') - result = helper.resolve_spec('repoze.bfg:flub') - self.assertEqual(result, 'repoze.bfg:flub') - - def test_resolve_spec_relative(self): - helper = self._makeOne('loo.foo', package='repoze.bfg') - result = helper.resolve_spec('flub') - self.assertEqual(result, 'repoze.bfg:flub') - - def test_render_to_response(self): - self._registerRendererFactory() - request = Dummy() - helper = self._makeOne('loo.foo') - response = helper.render_to_response('values', 'system_values', - request=request) - self.assertEqual(response.body, ('values', 'system_values')) - - def test_render_explicit_registry(self): - factory = self._registerRendererFactory() - class DummyRegistry(object): - def __init__(self): - self.responses = [factory, lambda *arg: {}] - def queryUtility(self, iface, name=None): - self.queried = True - return self.responses.pop(0) - reg = DummyRegistry() - helper = self._makeOne('loo.foo', registry=reg) - result = helper.render('value', {}) - self.assertEqual(result, ('value', {})) - self.failUnless(reg.queried) - - def test_render_system_values_is_None(self): - self._registerRendererFactory() - request = Dummy() - context = Dummy() - request.context = context - helper = self._makeOne('loo.foo') - result = helper.render('values', None, request=request) - system = {'request':request, 'context':context, - 'renderer_name':'loo.foo', 'view':None} - self.assertEqual(result, ('values', system)) - - def test_render_renderer_globals_factory_active(self): - self._registerRendererFactory() - from repoze.bfg.interfaces import IRendererGlobalsFactory - def rg(system): - return {'a':1} - self.config.registry.registerUtility(rg, IRendererGlobalsFactory) - helper = self._makeOne('loo.foo') - result = helper.render('values', None) - self.assertEqual(result[1]['a'], 1) - - def test__make_response_with_content_type(self): - request = testing.DummyRequest() - attrs = {'response_content_type':'text/nonsense'} - request.__dict__.update(attrs) - helper = self._makeOne('loo.foo') - response = helper._make_response('abc', request) - self.assertEqual(response.content_type, 'text/nonsense') - self.assertEqual(response.body, 'abc') - - def test__make_response_with_headerlist(self): - request = testing.DummyRequest() - attrs = {'response_headerlist':[('a', '1'), ('b', '2')]} - request.__dict__.update(attrs) - helper = self._makeOne('loo.foo') - response = helper._make_response('abc', request) - self.assertEqual(response.headerlist, - [('Content-Type', 'text/html; charset=UTF-8'), - ('Content-Length', '3'), - ('a', '1'), - ('b', '2')]) - self.assertEqual(response.body, 'abc') - - def test__make_response_with_status(self): - request = testing.DummyRequest() - attrs = {'response_status':'406 You Lose'} - request.__dict__.update(attrs) - helper = self._makeOne('loo.foo') - response = helper._make_response('abc', request) - self.assertEqual(response.status, '406 You Lose') - self.assertEqual(response.body, 'abc') - - def test__make_response_with_charset(self): - request = testing.DummyRequest() - attrs = {'response_charset':'UTF-16'} - request.__dict__.update(attrs) - helper = self._makeOne('loo.foo') - response = helper._make_response('abc', request) - self.assertEqual(response.charset, 'UTF-16') - - def test__make_response_with_cache_for(self): - request = testing.DummyRequest() - attrs = {'response_cache_for':100} - request.__dict__.update(attrs) - helper = self._makeOne('loo.foo') - response = helper._make_response('abc', request) - self.assertEqual(response.cache_control.max_age, 100) - - def test_with_alternate_response_factory(self): - from repoze.bfg.interfaces import IResponseFactory - class ResponseFactory(object): - def __init__(self, result): - self.result = result - self.config.registry.registerUtility(ResponseFactory, IResponseFactory) - request = testing.DummyRequest() - helper = self._makeOne('loo.foo') - response = helper._make_response('abc', request) - self.assertEqual(response.__class__, ResponseFactory) - self.assertEqual(response.result, 'abc') - - def test__make_response_with_real_request(self): - # functional - from repoze.bfg.request import Request - request = Request({}) - attrs = {'response_status':'406 You Lose'} - request.__dict__.update(attrs) - helper = self._makeOne('loo.foo') - response = helper._make_response('abc', request) - self.assertEqual(response.status, '406 You Lose') - self.assertEqual(response.body, 'abc') - -class Test_render(unittest.TestCase): - def setUp(self): - self.config = testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _callFUT(self, renderer_name, value, request=None, package=None): - from repoze.bfg.renderers import render - return render(renderer_name, value, request=request, package=package) - - def test_it_no_request(self): - renderer = self.config.testing_add_renderer( - 'repoze.bfg.tests:abc/def.pt') - renderer.string_response = 'abc' - result = self._callFUT('abc/def.pt', dict(a=1)) - self.assertEqual(result, 'abc') - renderer.assert_(a=1) - renderer.assert_(request=None) - - def test_it_with_request(self): - renderer = self.config.testing_add_renderer( - 'repoze.bfg.tests:abc/def.pt') - renderer.string_response = 'abc' - request = testing.DummyRequest() - result = self._callFUT('abc/def.pt', - dict(a=1), request=request) - self.assertEqual(result, 'abc') - renderer.assert_(a=1) - renderer.assert_(request=request) - -class Test_render_to_response(unittest.TestCase): - def setUp(self): - self.config = testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _callFUT(self, renderer_name, value, request=None, package=None): - from repoze.bfg.renderers import render_to_response - return render_to_response(renderer_name, value, request=request, - package=package) - - def test_it_no_request(self): - renderer = self.config.testing_add_renderer( - 'repoze.bfg.tests:abc/def.pt') - renderer.string_response = 'abc' - response = self._callFUT('abc/def.pt', dict(a=1)) - self.assertEqual(response.body, 'abc') - renderer.assert_(a=1) - renderer.assert_(request=None) - - def test_it_with_request(self): - renderer = self.config.testing_add_renderer( - 'repoze.bfg.tests:abc/def.pt') - renderer.string_response = 'abc' - request = testing.DummyRequest() - response = self._callFUT('abc/def.pt', - dict(a=1), request=request) - self.assertEqual(response.body, 'abc') - renderer.assert_(a=1) - renderer.assert_(request=request) - -class Test_get_renderer(unittest.TestCase): - def setUp(self): - self.config = testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _callFUT(self, renderer_name, **kw): - from repoze.bfg.renderers import get_renderer - return get_renderer(renderer_name) - - def test_it(self): - renderer = self.config.testing_add_renderer( - 'repoze.bfg.tests:abc/def.pt') - result = self._callFUT('abc/def.pt') - self.assertEqual(result, renderer) - -class Dummy: - pass - -class DummyResponse: - status = '200 OK' - headerlist = () - app_iter = () - body = '' - -class DummyFactory: - def __init__(self, renderer): - self.renderer = renderer - - def __call__(self, path, **kw): - self.path = path - self.kw = kw - return self.renderer - - diff --git a/repoze/bfg/tests/test_request.py b/repoze/bfg/tests/test_request.py deleted file mode 100644 index f1874d60a..000000000 --- a/repoze/bfg/tests/test_request.py +++ /dev/null @@ -1,231 +0,0 @@ -import unittest - -class TestRequest(unittest.TestCase): - def _makeOne(self, environ): - return self._getTargetClass()(environ) - - def _getTargetClass(self): - from repoze.bfg.request import Request - return Request - - def test_charset_defaults_to_utf8(self): - r = self._makeOne({'PATH_INFO':'/'}) - self.assertEqual(r.charset, 'UTF-8') - - def test_exception_defaults_to_None(self): - r = self._makeOne({'PATH_INFO':'/'}) - self.assertEqual(r.exception, None) - - def test_params_decoded_from_utf_8_by_default(self): - environ = { - 'PATH_INFO':'/', - 'QUERY_STRING':'la=La%20Pe%C3%B1a' - } - request = self._makeOne(environ) - request.charset = None - self.assertEqual(request.GET['la'], u'La Pe\xf1a') - - def test_class_implements(self): - from repoze.bfg.interfaces import IRequest - klass = self._getTargetClass() - self.assertTrue(IRequest.implementedBy(klass)) - - def test_instance_provides(self): - from repoze.bfg.interfaces import IRequest - inst = self._makeOne({}) - self.assertTrue(IRequest.providedBy(inst)) - - def test_setattr_and_getattr_dotnotation(self): - inst = self._makeOne({}) - inst.foo = 1 - self.assertEqual(inst.foo, 1) - - def test_setattr_and_getattr(self): - inst = self._makeOne({}) - setattr(inst, 'bar', 1) - self.assertEqual(getattr(inst, 'bar'), 1) - - def test___contains__(self): - environ ={'zooma':1} - inst = self._makeOne(environ) - self.failUnless('zooma' in inst) - - def test___delitem__(self): - environ = {'zooma':1} - inst = self._makeOne(environ) - del inst['zooma'] - self.failIf('zooma' in environ) - - def test___getitem__(self): - environ = {'zooma':1} - inst = self._makeOne(environ) - self.assertEqual(inst['zooma'], 1) - - def test___iter__(self): - environ = {'zooma':1} - inst = self._makeOne(environ) - iterator = iter(inst) - self.assertEqual(list(iterator), list(iter(environ))) - - def test___setitem__(self): - environ = {} - inst = self._makeOne(environ) - inst['zooma'] = 1 - self.assertEqual(environ, {'zooma':1}) - - def test_get(self): - environ = {'zooma':1} - inst = self._makeOne(environ) - self.assertEqual(inst.get('zooma'), 1) - - def test_has_key(self): - environ = {'zooma':1} - inst = self._makeOne(environ) - self.assertEqual(inst.has_key('zooma'), True) - - def test_items(self): - environ = {'zooma':1} - inst = self._makeOne(environ) - self.assertEqual(inst.items(), environ.items()) - - def test_iteritems(self): - environ = {'zooma':1} - inst = self._makeOne(environ) - self.assertEqual(list(inst.iteritems()), list(environ.iteritems())) - - def test_iterkeys(self): - environ = {'zooma':1} - inst = self._makeOne(environ) - self.assertEqual(list(inst.iterkeys()), list(environ.iterkeys())) - - def test_itervalues(self): - environ = {'zooma':1} - inst = self._makeOne(environ) - self.assertEqual(list(inst.itervalues()), list(environ.itervalues())) - - def test_keys(self): - environ = {'zooma':1} - inst = self._makeOne(environ) - self.assertEqual(inst.keys(), environ.keys()) - - def test_pop(self): - environ = {'zooma':1} - inst = self._makeOne(environ) - popped = inst.pop('zooma') - self.assertEqual(environ, {}) - self.assertEqual(popped, 1) - - def test_popitem(self): - environ = {'zooma':1} - inst = self._makeOne(environ) - popped = inst.popitem() - self.assertEqual(environ, {}) - self.assertEqual(popped, ('zooma', 1)) - - def test_setdefault(self): - environ = {} - inst = self._makeOne(environ) - marker = [] - result = inst.setdefault('a', marker) - self.assertEqual(environ, {'a':marker}) - self.assertEqual(result, marker) - - def test_update(self): - environ = {} - inst = self._makeOne(environ) - inst.update({'a':1}, b=2) - self.assertEqual(environ, {'a':1, 'b':2}) - - def test_values(self): - environ = {'zooma':1} - inst = self._makeOne(environ) - result = inst.values() - self.assertEqual(result, environ.values()) - - def test_add_response_callback(self): - inst = self._makeOne({}) - self.assertEqual(inst.response_callbacks, ()) - def callback(request, response): - """ """ - inst.add_response_callback(callback) - self.assertEqual(inst.response_callbacks, [callback]) - inst.add_response_callback(callback) - self.assertEqual(inst.response_callbacks, [callback, callback]) - - def test__process_response_callbacks(self): - inst = self._makeOne({}) - def callback1(request, response): - request.called1 = True - response.called1 = True - def callback2(request, response): - request.called2 = True - response.called2 = True - inst.response_callbacks = [callback1, callback2] - response = DummyResponse() - inst._process_response_callbacks(response) - self.assertEqual(inst.called1, True) - self.assertEqual(inst.called2, True) - self.assertEqual(response.called1, True) - self.assertEqual(response.called2, True) - self.assertEqual(inst.response_callbacks, []) - - def test_add_finished_callback(self): - inst = self._makeOne({}) - self.assertEqual(inst.finished_callbacks, ()) - def callback(request): - """ """ - inst.add_finished_callback(callback) - self.assertEqual(inst.finished_callbacks, [callback]) - inst.add_finished_callback(callback) - self.assertEqual(inst.finished_callbacks, [callback, callback]) - - def test__process_finished_callbacks(self): - inst = self._makeOne({}) - def callback1(request): - request.called1 = True - def callback2(request): - request.called2 = True - inst.finished_callbacks = [callback1, callback2] - inst._process_finished_callbacks() - self.assertEqual(inst.called1, True) - self.assertEqual(inst.called2, True) - self.assertEqual(inst.finished_callbacks, []) - -class Test_route_request_iface(unittest.TestCase): - def _callFUT(self, name): - from repoze.bfg.request import route_request_iface - return route_request_iface(name) - - def test_it(self): - iface = self._callFUT('routename') - self.assertEqual(iface.__name__, 'routename_IRequest') - self.assertTrue(hasattr(iface, 'combined')) - self.assertEqual(iface.combined.__name__, 'routename_combined_IRequest') - -class Test_add_global_response_headers(unittest.TestCase): - def _callFUT(self, request, headerlist): - from repoze.bfg.request import add_global_response_headers - return add_global_response_headers(request, headerlist) - - def test_it(self): - request = DummyRequest() - response = DummyResponse() - self._callFUT(request, [('c', 1)]) - self.assertEqual(len(request.response_callbacks), 1) - request.response_callbacks[0](None, response) - self.assertEqual(response.headerlist, [('c', 1)] ) - -class DummyRequest: - def __init__(self, environ=None): - if environ is None: - environ = {} - self.environ = environ - - def add_response_callback(self, callback): - self.response_callbacks = [callback] - -class DummyResponse: - def __init__(self): - self.headerlist = [] - - diff --git a/repoze/bfg/tests/test_resource.py b/repoze/bfg/tests/test_resource.py deleted file mode 100644 index 191d72c8b..000000000 --- a/repoze/bfg/tests/test_resource.py +++ /dev/null @@ -1,431 +0,0 @@ -import unittest -from repoze.bfg.testing import cleanUp - -class TestOverrideProvider(unittest.TestCase): - def setUp(self): - cleanUp() - - def tearDown(self): - cleanUp() - - def _getTargetClass(self): - from repoze.bfg.resource import OverrideProvider - return OverrideProvider - - def _makeOne(self, module): - klass = self._getTargetClass() - return klass(module) - - def _registerOverrides(self, overrides, name='repoze.bfg.tests'): - from repoze.bfg.interfaces import IPackageOverrides - from repoze.bfg.threadlocal import get_current_registry - reg = get_current_registry() - reg.registerUtility(overrides, IPackageOverrides, name=name) - - def test_get_resource_filename_no_overrides(self): - import os - resource_name = 'test_resource.py' - import repoze.bfg.tests - provider = self._makeOne(repoze.bfg.tests) - here = os.path.dirname(os.path.abspath(__file__)) - expected = os.path.join(here, resource_name) - result = provider.get_resource_filename(None, resource_name) - self.assertEqual(result, expected) - - def test_get_resource_stream_no_overrides(self): - import os - resource_name = 'test_resource.py' - import repoze.bfg.tests - provider = self._makeOne(repoze.bfg.tests) - here = os.path.dirname(os.path.abspath(__file__)) - expected = open(os.path.join(here, resource_name)).read() - result = provider.get_resource_stream(None, resource_name) - self.assertEqual(result.read(), expected) - - def test_get_resource_string_no_overrides(self): - import os - resource_name = 'test_resource.py' - import repoze.bfg.tests - provider = self._makeOne(repoze.bfg.tests) - here = os.path.dirname(os.path.abspath(__file__)) - expected = open(os.path.join(here, resource_name)).read() - result = provider.get_resource_string(None, resource_name) - self.assertEqual(result, expected) - - def test_has_resource_no_overrides(self): - resource_name = 'test_resource.py' - import repoze.bfg.tests - provider = self._makeOne(repoze.bfg.tests) - result = provider.has_resource(resource_name) - self.assertEqual(result, True) - - def test_resource_isdir_no_overrides(self): - file_resource_name = 'test_resource.py' - directory_resource_name = 'fixtures' - import repoze.bfg.tests - provider = self._makeOne(repoze.bfg.tests) - result = provider.resource_isdir(file_resource_name) - self.assertEqual(result, False) - result = provider.resource_isdir(directory_resource_name) - self.assertEqual(result, True) - - def test_resource_listdir_no_overrides(self): - resource_name = 'fixtures' - import repoze.bfg.tests - provider = self._makeOne(repoze.bfg.tests) - result = provider.resource_isdir(resource_name) - self.failUnless(result) - - def test_get_resource_filename_override_returns_None(self): - overrides = DummyOverrides(None) - self._registerOverrides(overrides) - import os - resource_name = 'test_resource.py' - import repoze.bfg.tests - provider = self._makeOne(repoze.bfg.tests) - here = os.path.dirname(os.path.abspath(__file__)) - expected = os.path.join(here, resource_name) - result = provider.get_resource_filename(None, resource_name) - self.assertEqual(result, expected) - - def test_get_resource_stream_override_returns_None(self): - overrides = DummyOverrides(None) - self._registerOverrides(overrides) - import os - resource_name = 'test_resource.py' - import repoze.bfg.tests - provider = self._makeOne(repoze.bfg.tests) - here = os.path.dirname(os.path.abspath(__file__)) - expected = os.path.join(here, resource_name) - result = provider.get_resource_filename(None, resource_name) - self.assertEqual(result, expected) - - def test_get_resource_string_override_returns_None(self): - overrides = DummyOverrides(None) - self._registerOverrides(overrides) - import os - resource_name = 'test_resource.py' - import repoze.bfg.tests - provider = self._makeOne(repoze.bfg.tests) - here = os.path.dirname(os.path.abspath(__file__)) - expected = os.path.join(here, resource_name) - result = provider.get_resource_filename(None, resource_name) - self.assertEqual(result, expected) - - def test_has_resource_override_returns_None(self): - overrides = DummyOverrides(None) - self._registerOverrides(overrides) - resource_name = 'test_resource.py' - import repoze.bfg.tests - provider = self._makeOne(repoze.bfg.tests) - result = provider.has_resource(resource_name) - self.assertEqual(result, True) - - def test_resource_isdir_override_returns_None(self): - overrides = DummyOverrides(None) - self._registerOverrides(overrides) - resource_name = 'fixtures' - import repoze.bfg.tests - provider = self._makeOne(repoze.bfg.tests) - result = provider.resource_isdir(resource_name) - self.assertEqual(result, True) - - def test_resource_listdir_override_returns_None(self): - overrides = DummyOverrides(None) - self._registerOverrides(overrides) - resource_name = 'fixtures' - import repoze.bfg.tests - provider = self._makeOne(repoze.bfg.tests) - result = provider.resource_listdir(resource_name) - self.failUnless(result) - - def test_get_resource_filename_override_returns_value(self): - overrides = DummyOverrides('value') - import repoze.bfg.tests - self._registerOverrides(overrides) - provider = self._makeOne(repoze.bfg.tests) - result = provider.get_resource_filename(None, 'test_resource.py') - self.assertEqual(result, 'value') - - def test_get_resource_stream_override_returns_value(self): - overrides = DummyOverrides('value') - import repoze.bfg.tests - self._registerOverrides(overrides) - provider = self._makeOne(repoze.bfg.tests) - result = provider.get_resource_stream(None, 'test_resource.py') - self.assertEqual(result, 'value') - - def test_get_resource_string_override_returns_value(self): - overrides = DummyOverrides('value') - import repoze.bfg.tests - self._registerOverrides(overrides) - provider = self._makeOne(repoze.bfg.tests) - result = provider.get_resource_string(None, 'test_resource.py') - self.assertEqual(result, 'value') - - def test_has_resource_override_returns_True(self): - overrides = DummyOverrides(True) - import repoze.bfg.tests - self._registerOverrides(overrides) - provider = self._makeOne(repoze.bfg.tests) - result = provider.has_resource('test_resource.py') - self.assertEqual(result, True) - - def test_resource_isdir_override_returns_False(self): - overrides = DummyOverrides(False) - import repoze.bfg.tests - self._registerOverrides(overrides) - provider = self._makeOne(repoze.bfg.tests) - result = provider.resource_isdir('fixtures') - self.assertEqual(result, False) - - def test_resource_listdir_override_returns_values(self): - overrides = DummyOverrides(['a']) - import repoze.bfg.tests - self._registerOverrides(overrides) - provider = self._makeOne(repoze.bfg.tests) - result = provider.resource_listdir('fixtures') - self.assertEqual(result, ['a']) - -class TestPackageOverrides(unittest.TestCase): - def _getTargetClass(self): - from repoze.bfg.resource import PackageOverrides - return PackageOverrides - - def _makeOne(self, package, pkg_resources=None): - klass = self._getTargetClass() - if pkg_resources is None: - pkg_resources = DummyPkgResources() - return klass(package, pkg_resources=pkg_resources) - - def test_ctor_package_already_has_loader_of_different_type(self): - package = DummyPackage('package') - package.__loader__ = True - self.assertRaises(TypeError, self._makeOne, package) - - def test_ctor_package_already_has_loader_of_same_type(self): - package = DummyPackage('package') - package.__loader__ = self._makeOne(package) - po = self._makeOne(package) - self.assertEqual(package.__loader__, po) - - def test_ctor_sets_loader(self): - package = DummyPackage('package') - po = self._makeOne(package) - self.assertEqual(package.__loader__, po) - - def test_ctor_registers_loader_type(self): - from repoze.bfg.resource import OverrideProvider - dummy_pkg_resources = DummyPkgResources() - package = DummyPackage('package') - po = self._makeOne(package, dummy_pkg_resources) - self.assertEqual(dummy_pkg_resources.registered, [(po.__class__, - OverrideProvider)]) - - def test_ctor_sets_local_state(self): - package = DummyPackage('package') - po = self._makeOne(package) - self.assertEqual(po.overrides, []) - self.assertEqual(po.overridden_package_name, 'package') - - def test_insert_directory(self): - from repoze.bfg.resource import DirectoryOverride - package = DummyPackage('package') - po = self._makeOne(package) - po.overrides= [None] - po.insert('foo/', 'package', 'bar/') - self.assertEqual(len(po.overrides), 2) - override = po.overrides[0] - self.assertEqual(override.__class__, DirectoryOverride) - - def test_insert_file(self): - from repoze.bfg.resource import FileOverride - package = DummyPackage('package') - po = self._makeOne(package) - po.overrides= [None] - po.insert('foo.pt', 'package', 'bar.pt') - self.assertEqual(len(po.overrides), 2) - override = po.overrides[0] - self.assertEqual(override.__class__, FileOverride) - - def test_search_path(self): - overrides = [ DummyOverride(None), DummyOverride(('package', 'name'))] - package = DummyPackage('package') - po = self._makeOne(package) - po.overrides= overrides - self.assertEqual(list(po.search_path('whatever')), - [('package', 'name')]) - - def test_get_filename(self): - import os - overrides = [ DummyOverride(None), DummyOverride( - ('repoze.bfg.tests', 'test_resource.py'))] - package = DummyPackage('package') - po = self._makeOne(package) - po.overrides= overrides - here = os.path.dirname(os.path.abspath(__file__)) - expected = os.path.join(here, 'test_resource.py') - self.assertEqual(po.get_filename('whatever'), expected) - - def test_get_stream(self): - import os - overrides = [ DummyOverride(None), DummyOverride( - ('repoze.bfg.tests', 'test_resource.py'))] - package = DummyPackage('package') - po = self._makeOne(package) - po.overrides= overrides - here = os.path.dirname(os.path.abspath(__file__)) - expected = open(os.path.join(here, 'test_resource.py')).read() - self.assertEqual(po.get_stream('whatever').read(), expected) - - def test_get_string(self): - import os - overrides = [ DummyOverride(None), DummyOverride( - ('repoze.bfg.tests', 'test_resource.py'))] - package = DummyPackage('package') - po = self._makeOne(package) - po.overrides= overrides - here = os.path.dirname(os.path.abspath(__file__)) - expected = open(os.path.join(here, 'test_resource.py')).read() - self.assertEqual(po.get_string('whatever'), expected) - - def test_has_resource(self): - overrides = [ DummyOverride(None), DummyOverride( - ('repoze.bfg.tests', 'test_resource.py'))] - package = DummyPackage('package') - po = self._makeOne(package) - po.overrides= overrides - self.assertEqual(po.has_resource('whatever'), True) - - def test_isdir_false(self): - overrides = [ DummyOverride( - ('repoze.bfg.tests', 'test_resource.py'))] - package = DummyPackage('package') - po = self._makeOne(package) - po.overrides= overrides - self.assertEqual(po.isdir('whatever'), False) - - def test_isdir_true(self): - overrides = [ DummyOverride( - ('repoze.bfg.tests', 'fixtures'))] - package = DummyPackage('package') - po = self._makeOne(package) - po.overrides= overrides - self.assertEqual(po.isdir('whatever'), True) - - def test_listdir(self): - overrides = [ DummyOverride( - ('repoze.bfg.tests', 'fixtures'))] - package = DummyPackage('package') - po = self._makeOne(package) - po.overrides= overrides - self.failUnless(po.listdir('whatever')) - -class TestDirectoryOverride(unittest.TestCase): - def _getTargetClass(self): - from repoze.bfg.resource import DirectoryOverride - return DirectoryOverride - - def _makeOne(self, path, package, prefix): - klass = self._getTargetClass() - return klass(path, package, prefix) - - def test_it_match(self): - o = self._makeOne('foo/', 'package', 'bar/') - result = o('foo/something.pt') - self.assertEqual(result, ('package', 'bar/something.pt')) - - def test_it_no_match(self): - o = self._makeOne('foo/', 'package', 'bar/') - result = o('baz/notfound.pt') - self.assertEqual(result, None) - -class Test_resolve_resource_spec(unittest.TestCase): - def _callFUT(self, spec, package_name='__main__'): - from repoze.bfg.resource import resolve_resource_spec - return resolve_resource_spec(spec, package_name) - - def test_abspath(self): - import os - here = os.path.dirname(__file__) - path = os.path.abspath(here) - package_name, filename = self._callFUT(path, 'apackage') - self.assertEqual(filename, path) - self.assertEqual(package_name, None) - - def test_rel_spec(self): - pkg = 'repoze.bfg.tests' - path = 'test_resource.py' - package_name, filename = self._callFUT(path, pkg) - self.assertEqual(package_name, 'repoze.bfg.tests') - self.assertEqual(filename, 'test_resource.py') - - def test_abs_spec(self): - pkg = 'repoze.bfg.tests' - path = 'repoze.bfg.nottests:test_resource.py' - package_name, filename = self._callFUT(path, pkg) - self.assertEqual(package_name, 'repoze.bfg.nottests') - self.assertEqual(filename, 'test_resource.py') - - def test_package_name_is_None(self): - pkg = None - path = 'test_resource.py' - package_name, filename = self._callFUT(path, pkg) - self.assertEqual(package_name, None) - self.assertEqual(filename, 'test_resource.py') - - def test_package_name_is_package_object(self): - import repoze.bfg.tests - pkg = repoze.bfg.tests - path = 'test_resource.py' - package_name, filename = self._callFUT(path, pkg) - self.assertEqual(package_name, 'repoze.bfg.tests') - self.assertEqual(filename, 'test_resource.py') - - -class TestFileOverride(unittest.TestCase): - def _getTargetClass(self): - from repoze.bfg.resource import FileOverride - return FileOverride - - def _makeOne(self, path, package, prefix): - klass = self._getTargetClass() - return klass(path, package, prefix) - - def test_it_match(self): - o = self._makeOne('foo.pt', 'package', 'bar.pt') - result = o('foo.pt') - self.assertEqual(result, ('package', 'bar.pt')) - - def test_it_no_match(self): - o = self._makeOne('foo.pt', 'package', 'bar.pt') - result = o('notfound.pt') - self.assertEqual(result, None) - -class DummyOverride: - def __init__(self, result): - self.result = result - - def __call__(self, resource_name): - return self.result - -class DummyOverrides: - def __init__(self, result): - self.result = result - - def get_filename(self, resource_name): - return self.result - - listdir = isdir = has_resource = get_stream = get_string = get_filename - -class DummyPkgResources: - def __init__(self): - self.registered = [] - - def register_loader_type(self, typ, inst): - self.registered.append((typ, inst)) - -class DummyPackage: - def __init__(self, name): - self.__name__ = name - diff --git a/repoze/bfg/tests/test_router.py b/repoze/bfg/tests/test_router.py deleted file mode 100644 index fade0679b..000000000 --- a/repoze/bfg/tests/test_router.py +++ /dev/null @@ -1,1034 +0,0 @@ -import unittest - -from repoze.bfg import testing - -class TestRouter(unittest.TestCase): - def setUp(self): - testing.setUp() - from repoze.bfg.threadlocal import get_current_registry - self.registry = get_current_registry() - - def tearDown(self): - testing.tearDown() - - def _registerRouteRequest(self, name): - from repoze.bfg.interfaces import IRouteRequest - from repoze.bfg.request import route_request_iface - iface = route_request_iface(name) - self.registry.registerUtility(iface, IRouteRequest, name=name) - return iface - - def _connectRoute(self, name, path, factory=None): - from repoze.bfg.interfaces import IRoutesMapper - from repoze.bfg.urldispatch import RoutesMapper - mapper = self.registry.queryUtility(IRoutesMapper) - if mapper is None: - mapper = RoutesMapper() - self.registry.registerUtility(mapper, IRoutesMapper) - mapper.connect(name, path, factory) - - def _registerLogger(self): - from repoze.bfg.interfaces import IDebugLogger - logger = DummyLogger() - self.registry.registerUtility(logger, IDebugLogger) - return logger - - def _registerSettings(self, **kw): - from repoze.bfg.interfaces import ISettings - settings = {'debug_authorization':False, 'debug_notfound':False} - settings.update(kw) - self.registry.registerUtility(settings, ISettings) - - def _registerTraverserFactory(self, context, view_name='', subpath=None, - traversed=None, virtual_root=None, - virtual_root_path=None, raise_error=None, - **kw): - from repoze.bfg.interfaces import ITraverser - - if virtual_root is None: - virtual_root = context - if subpath is None: - subpath = [] - if traversed is None: - traversed = [] - if virtual_root_path is None: - virtual_root_path = [] - - class DummyTraverserFactory: - def __init__(self, root): - self.root = root - - def __call__(self, request): - if raise_error: - raise raise_error - values = {'root':self.root, - 'context':context, - 'view_name':view_name, - 'subpath':subpath, - 'traversed':traversed, - 'virtual_root':virtual_root, - 'virtual_root_path':virtual_root_path} - kw.update(values) - return kw - - self.registry.registerAdapter(DummyTraverserFactory, (None,), - ITraverser, name='') - - def _registerView(self, app, name, classifier, req_iface, ctx_iface): - from repoze.bfg.interfaces import IView - self.registry.registerAdapter( - app, (classifier, req_iface, ctx_iface), IView, name) - - def _registerEventListener(self, iface): - L = [] - def listener(event): - L.append(event) - self.registry.registerHandler(listener, (iface,)) - return L - - def _registerRootFactory(self, val): - rootfactory = DummyRootFactory(val) - from repoze.bfg.interfaces import IRootFactory - self.registry.registerUtility(rootfactory, IRootFactory) - return rootfactory - - def _getTargetClass(self): - from repoze.bfg.router import Router - return Router - - def _makeOne(self): - klass = self._getTargetClass() - return klass(self.registry) - - def _makeEnviron(self, **extras): - environ = { - 'wsgi.url_scheme':'http', - 'SERVER_NAME':'localhost', - 'SERVER_PORT':'8080', - 'REQUEST_METHOD':'GET', - 'PATH_INFO':'/', - } - environ.update(extras) - return environ - - def test_root_policy(self): - context = DummyContext() - self._registerTraverserFactory(context) - rootfactory = self._registerRootFactory('abc') - router = self._makeOne() - self.assertEqual(router.root_policy, rootfactory) - - def test_request_factory(self): - from repoze.bfg.interfaces import IRequestFactory - class DummyRequestFactory(object): - pass - self.registry.registerUtility(DummyRequestFactory, IRequestFactory) - router = self._makeOne() - self.assertEqual(router.request_factory, DummyRequestFactory) - - def test_call_traverser_default(self): - from repoze.bfg.exceptions import NotFound - environ = self._makeEnviron() - logger = self._registerLogger() - router = self._makeOne() - start_response = DummyStartResponse() - why = exc_raised(NotFound, router, environ, start_response) - self.failUnless('/' in why[0], why) - self.failIf('debug_notfound' in why[0]) - self.assertEqual(len(logger.messages), 0) - - def test_traverser_raises_notfound_class(self): - from repoze.bfg.exceptions import NotFound - environ = self._makeEnviron() - context = DummyContext() - self._registerTraverserFactory(context, raise_error=NotFound) - router = self._makeOne() - start_response = DummyStartResponse() - self.assertRaises(NotFound, router, environ, start_response) - - def test_traverser_raises_notfound_instance(self): - from repoze.bfg.exceptions import NotFound - environ = self._makeEnviron() - context = DummyContext() - self._registerTraverserFactory(context, raise_error=NotFound('foo')) - router = self._makeOne() - start_response = DummyStartResponse() - why = exc_raised(NotFound, router, environ, start_response) - self.failUnless('foo' in why[0], why) - - def test_traverser_raises_forbidden_class(self): - from repoze.bfg.exceptions import Forbidden - environ = self._makeEnviron() - context = DummyContext() - self._registerTraverserFactory(context, raise_error=Forbidden) - router = self._makeOne() - start_response = DummyStartResponse() - self.assertRaises(Forbidden, router, environ, start_response) - - def test_traverser_raises_forbidden_instance(self): - from repoze.bfg.exceptions import Forbidden - environ = self._makeEnviron() - context = DummyContext() - self._registerTraverserFactory(context, raise_error=Forbidden('foo')) - router = self._makeOne() - start_response = DummyStartResponse() - why = exc_raised(Forbidden, router, environ, start_response) - self.failUnless('foo' in why[0], why) - - def test_call_no_view_registered_no_isettings(self): - from repoze.bfg.exceptions import NotFound - environ = self._makeEnviron() - context = DummyContext() - self._registerTraverserFactory(context) - logger = self._registerLogger() - router = self._makeOne() - start_response = DummyStartResponse() - why = exc_raised(NotFound, router, environ, start_response) - self.failUnless('/' in why[0], why) - self.failIf('debug_notfound' in why[0]) - self.assertEqual(len(logger.messages), 0) - - def test_call_no_view_registered_debug_notfound_false(self): - from repoze.bfg.exceptions import NotFound - environ = self._makeEnviron() - context = DummyContext() - self._registerTraverserFactory(context) - logger = self._registerLogger() - self._registerSettings(debug_notfound=False) - router = self._makeOne() - start_response = DummyStartResponse() - why = exc_raised(NotFound, router, environ, start_response) - self.failUnless('/' in why[0], why) - self.failIf('debug_notfound' in why[0]) - self.assertEqual(len(logger.messages), 0) - - def test_call_no_view_registered_debug_notfound_true(self): - from repoze.bfg.exceptions import NotFound - environ = self._makeEnviron() - context = DummyContext() - self._registerTraverserFactory(context) - self._registerSettings(debug_notfound=True) - logger = self._registerLogger() - router = self._makeOne() - start_response = DummyStartResponse() - why = exc_raised(NotFound, router, environ, start_response) - self.failUnless( - "debug_notfound of url http://localhost:8080/; path_info: '/', " - "context:" in why[0]) - self.failUnless("view_name: '', subpath: []" in why[0]) - self.failUnless('http://localhost:8080' in why[0], why) - - self.assertEqual(len(logger.messages), 1) - message = logger.messages[0] - self.failUnless('of url http://localhost:8080' in message) - self.failUnless("path_info: '/'" in message) - self.failUnless('DummyContext instance at' in message) - self.failUnless("view_name: ''" in message) - self.failUnless("subpath: []" in message) - - def test_call_view_returns_nonresponse(self): - from repoze.bfg.interfaces import IViewClassifier - context = DummyContext() - self._registerTraverserFactory(context) - environ = self._makeEnviron() - view = DummyView('abc') - self._registerView(view, '', IViewClassifier, None, None) - router = self._makeOne() - start_response = DummyStartResponse() - self.assertRaises(ValueError, router, environ, start_response) - - def test_call_view_registered_nonspecific_default_path(self): - from repoze.bfg.interfaces import IViewClassifier - context = DummyContext() - self._registerTraverserFactory(context) - response = DummyResponse() - response.app_iter = ['Hello world'] - view = DummyView(response) - environ = self._makeEnviron() - self._registerView(view, '', IViewClassifier, None, None) - self._registerRootFactory(context) - router = self._makeOne() - start_response = DummyStartResponse() - result = router(environ, start_response) - self.assertEqual(result, ['Hello world']) - self.assertEqual(start_response.headers, ()) - self.assertEqual(start_response.status, '200 OK') - request = view.request - self.assertEqual(request.view_name, '') - self.assertEqual(request.subpath, []) - self.assertEqual(request.context, context) - self.assertEqual(request.root, context) - - def test_call_view_registered_nonspecific_nondefault_path_and_subpath(self): - from repoze.bfg.interfaces import IViewClassifier - context = DummyContext() - self._registerTraverserFactory(context, view_name='foo', - subpath=['bar'], - traversed=['context']) - self._registerRootFactory(context) - response = DummyResponse() - response.app_iter = ['Hello world'] - view = DummyView(response) - environ = self._makeEnviron() - self._registerView(view, 'foo', IViewClassifier, None, None) - router = self._makeOne() - start_response = DummyStartResponse() - result = router(environ, start_response) - self.assertEqual(result, ['Hello world']) - self.assertEqual(start_response.headers, ()) - self.assertEqual(start_response.status, '200 OK') - request = view.request - self.assertEqual(request.view_name, 'foo') - self.assertEqual(request.subpath, ['bar']) - self.assertEqual(request.context, context) - self.assertEqual(request.root, context) - - def test_call_view_registered_specific_success(self): - from zope.interface import Interface - from zope.interface import directlyProvides - class IContext(Interface): - pass - from repoze.bfg.interfaces import IRequest - from repoze.bfg.interfaces import IViewClassifier - context = DummyContext() - directlyProvides(context, IContext) - self._registerTraverserFactory(context) - self._registerRootFactory(context) - response = DummyResponse() - response.app_iter = ['Hello world'] - view = DummyView(response) - environ = self._makeEnviron() - self._registerView(view, '', IViewClassifier, IRequest, IContext) - router = self._makeOne() - start_response = DummyStartResponse() - result = router(environ, start_response) - self.assertEqual(result, ['Hello world']) - self.assertEqual(start_response.headers, ()) - self.assertEqual(start_response.status, '200 OK') - request = view.request - self.assertEqual(request.view_name, '') - self.assertEqual(request.subpath, []) - self.assertEqual(request.context, context) - self.assertEqual(request.root, context) - - def test_call_view_registered_specific_fail(self): - from zope.interface import Interface - from zope.interface import directlyProvides - from repoze.bfg.exceptions import NotFound - from repoze.bfg.interfaces import IViewClassifier - class IContext(Interface): - pass - class INotContext(Interface): - pass - from repoze.bfg.interfaces import IRequest - context = DummyContext() - directlyProvides(context, INotContext) - self._registerTraverserFactory(context, subpath=['']) - response = DummyResponse() - view = DummyView(response) - environ = self._makeEnviron() - self._registerView(view, '', IViewClassifier, IRequest, IContext) - router = self._makeOne() - start_response = DummyStartResponse() - self.assertRaises(NotFound, router, environ, start_response) - - def test_call_view_raises_forbidden(self): - from zope.interface import Interface - from zope.interface import directlyProvides - from repoze.bfg.exceptions import Forbidden - class IContext(Interface): - pass - from repoze.bfg.interfaces import IRequest - from repoze.bfg.interfaces import IViewClassifier - context = DummyContext() - directlyProvides(context, IContext) - self._registerTraverserFactory(context, subpath=['']) - response = DummyResponse() - view = DummyView(response, raise_exception=Forbidden("unauthorized")) - environ = self._makeEnviron() - self._registerView(view, '', IViewClassifier, IRequest, IContext) - router = self._makeOne() - start_response = DummyStartResponse() - why = exc_raised(Forbidden, router, environ, start_response) - self.assertEqual(why[0], 'unauthorized') - - def test_call_view_raises_notfound(self): - from zope.interface import Interface - from zope.interface import directlyProvides - class IContext(Interface): - pass - from repoze.bfg.interfaces import IRequest - from repoze.bfg.interfaces import IViewClassifier - from repoze.bfg.exceptions import NotFound - context = DummyContext() - directlyProvides(context, IContext) - self._registerTraverserFactory(context, subpath=['']) - response = DummyResponse() - view = DummyView(response, raise_exception=NotFound("notfound")) - environ = self._makeEnviron() - self._registerView(view, '', IViewClassifier, IRequest, IContext) - router = self._makeOne() - start_response = DummyStartResponse() - why = exc_raised(NotFound, router, environ, start_response) - self.assertEqual(why[0], 'notfound') - - def test_call_request_has_response_callbacks(self): - from zope.interface import Interface - from zope.interface import directlyProvides - class IContext(Interface): - pass - from repoze.bfg.interfaces import IRequest - from repoze.bfg.interfaces import IViewClassifier - context = DummyContext() - directlyProvides(context, IContext) - self._registerTraverserFactory(context, subpath=['']) - response = DummyResponse('200 OK') - def view(context, request): - def callback(request, response): - response.called_back = True - request.response_callbacks = [callback] - return response - environ = self._makeEnviron() - self._registerView(view, '', IViewClassifier, IRequest, IContext) - router = self._makeOne() - start_response = DummyStartResponse() - router(environ, start_response) - self.assertEqual(response.called_back, True) - - def test_call_request_has_finished_callbacks_when_view_succeeds(self): - from zope.interface import Interface - from zope.interface import directlyProvides - class IContext(Interface): - pass - from repoze.bfg.interfaces import IRequest - from repoze.bfg.interfaces import IViewClassifier - context = DummyContext() - directlyProvides(context, IContext) - self._registerTraverserFactory(context, subpath=['']) - response = DummyResponse('200 OK') - def view(context, request): - def callback(request): - request.environ['called_back'] = True - request.finished_callbacks = [callback] - return response - environ = self._makeEnviron() - self._registerView(view, '', IViewClassifier, IRequest, IContext) - router = self._makeOne() - start_response = DummyStartResponse() - router(environ, start_response) - self.assertEqual(environ['called_back'], True) - - def test_call_request_has_finished_callbacks_when_view_raises(self): - from zope.interface import Interface - from zope.interface import directlyProvides - class IContext(Interface): - pass - from repoze.bfg.interfaces import IRequest - from repoze.bfg.interfaces import IViewClassifier - context = DummyContext() - directlyProvides(context, IContext) - self._registerTraverserFactory(context, subpath=['']) - def view(context, request): - def callback(request): - request.environ['called_back'] = True - request.finished_callbacks = [callback] - raise NotImplementedError - environ = self._makeEnviron() - self._registerView(view, '', IViewClassifier, IRequest, IContext) - router = self._makeOne() - start_response = DummyStartResponse() - exc_raised(NotImplementedError, router, environ, start_response) - self.assertEqual(environ['called_back'], True) - - def test_call_request_factory_raises(self): - # making sure finally doesnt barf when a request cannot be created - environ = self._makeEnviron() - router = self._makeOne() - def dummy_request_factory(environ): - raise NotImplementedError - router.request_factory = dummy_request_factory - start_response = DummyStartResponse() - exc_raised(NotImplementedError, router, environ, start_response) - - def test_call_eventsends(self): - from repoze.bfg.interfaces import INewRequest - from repoze.bfg.interfaces import INewResponse - from repoze.bfg.interfaces import IContextFound - from repoze.bfg.interfaces import IViewClassifier - context = DummyContext() - self._registerTraverserFactory(context) - response = DummyResponse() - response.app_iter = ['Hello world'] - view = DummyView(response) - environ = self._makeEnviron() - self._registerView(view, '', IViewClassifier, None, None) - request_events = self._registerEventListener(INewRequest) - aftertraversal_events = self._registerEventListener(IContextFound) - response_events = self._registerEventListener(INewResponse) - router = self._makeOne() - start_response = DummyStartResponse() - result = router(environ, start_response) - self.assertEqual(len(request_events), 1) - self.assertEqual(request_events[0].request.environ, environ) - self.assertEqual(len(aftertraversal_events), 1) - self.assertEqual(aftertraversal_events[0].request.environ, environ) - self.assertEqual(len(response_events), 1) - self.assertEqual(response_events[0].response, response) - self.assertEqual(result, response.app_iter) - - def test_call_pushes_and_pops_threadlocal_manager(self): - from repoze.bfg.interfaces import IViewClassifier - context = DummyContext() - self._registerTraverserFactory(context) - response = DummyResponse() - response.app_iter = ['Hello world'] - view = DummyView(response) - environ = self._makeEnviron() - self._registerView(view, '', IViewClassifier, None, None) - router = self._makeOne() - start_response = DummyStartResponse() - router.threadlocal_manager = DummyThreadLocalManager() - router(environ, start_response) - self.assertEqual(len(router.threadlocal_manager.pushed), 1) - self.assertEqual(len(router.threadlocal_manager.popped), 1) - - def test_call_route_matches_and_has_factory(self): - from repoze.bfg.interfaces import IViewClassifier - self._registerRouteRequest('foo') - root = object() - def factory(request): - return root - self._connectRoute('foo', 'archives/:action/:article', factory) - context = DummyContext() - self._registerTraverserFactory(context) - response = DummyResponse() - response.app_iter = ['Hello world'] - view = DummyView(response) - environ = self._makeEnviron(PATH_INFO='/archives/action1/article1') - self._registerView(view, '', IViewClassifier, None, None) - self._registerRootFactory(context) - router = self._makeOne() - start_response = DummyStartResponse() - result = router(environ, start_response) - self.assertEqual(result, ['Hello world']) - self.assertEqual(start_response.headers, ()) - self.assertEqual(start_response.status, '200 OK') - request = view.request - self.assertEqual(request.view_name, '') - self.assertEqual(request.subpath, []) - self.assertEqual(request.context, context) - self.assertEqual(request.root, root) - matchdict = {'action':'action1', 'article':'article1'} - self.assertEqual(environ['bfg.routes.matchdict'], matchdict) - self.assertEqual(environ['bfg.routes.route'].name, 'foo') - self.assertEqual(request.matchdict, matchdict) - self.assertEqual(request.matched_route.name, 'foo') - - def test_call_route_matches_doesnt_overwrite_subscriber_iface(self): - from repoze.bfg.interfaces import INewRequest - from repoze.bfg.interfaces import IViewClassifier - from zope.interface import alsoProvides - from zope.interface import Interface - self._registerRouteRequest('foo') - class IFoo(Interface): - pass - def listener(event): - alsoProvides(event.request, IFoo) - self.registry.registerHandler(listener, (INewRequest,)) - root = object() - def factory(request): - return root - self._connectRoute('foo', 'archives/:action/:article', factory) - context = DummyContext() - self._registerTraverserFactory(context) - response = DummyResponse() - response.app_iter = ['Hello world'] - view = DummyView(response) - environ = self._makeEnviron(PATH_INFO='/archives/action1/article1') - self._registerView(view, '', IViewClassifier, None, None) - self._registerRootFactory(context) - router = self._makeOne() - start_response = DummyStartResponse() - result = router(environ, start_response) - self.assertEqual(result, ['Hello world']) - self.assertEqual(start_response.headers, ()) - self.assertEqual(start_response.status, '200 OK') - request = view.request - self.assertEqual(request.view_name, '') - self.assertEqual(request.subpath, []) - self.assertEqual(request.context, context) - self.assertEqual(request.root, root) - matchdict = {'action':'action1', 'article':'article1'} - self.assertEqual(environ['bfg.routes.matchdict'], matchdict) - self.assertEqual(environ['bfg.routes.route'].name, 'foo') - self.assertEqual(request.matchdict, matchdict) - self.assertEqual(request.matched_route.name, 'foo') - self.failUnless(IFoo.providedBy(request)) - - def test_root_factory_raises_notfound(self): - from repoze.bfg.interfaces import IRootFactory - from repoze.bfg.exceptions import NotFound - from zope.interface import Interface - from zope.interface import directlyProvides - def rootfactory(request): - raise NotFound('from root factory') - self.registry.registerUtility(rootfactory, IRootFactory) - class IContext(Interface): - pass - context = DummyContext() - directlyProvides(context, IContext) - environ = self._makeEnviron() - router = self._makeOne() - start_response = DummyStartResponse() - why = exc_raised(NotFound, router, environ, start_response) - self.failUnless('from root factory' in why[0]) - - def test_root_factory_raises_forbidden(self): - from repoze.bfg.interfaces import IRootFactory - from repoze.bfg.exceptions import Forbidden - from zope.interface import Interface - from zope.interface import directlyProvides - def rootfactory(request): - raise Forbidden('from root factory') - self.registry.registerUtility(rootfactory, IRootFactory) - class IContext(Interface): - pass - context = DummyContext() - directlyProvides(context, IContext) - environ = self._makeEnviron() - router = self._makeOne() - start_response = DummyStartResponse() - why = exc_raised(Forbidden, router, environ, start_response) - self.failUnless('from root factory' in why[0]) - - def test_root_factory_exception_propagating(self): - from repoze.bfg.interfaces import IRootFactory - from zope.interface import Interface - from zope.interface import directlyProvides - def rootfactory(request): - raise RuntimeError() - self.registry.registerUtility(rootfactory, IRootFactory) - class IContext(Interface): - pass - context = DummyContext() - directlyProvides(context, IContext) - environ = self._makeEnviron() - router = self._makeOne() - start_response = DummyStartResponse() - self.assertRaises(RuntimeError, router, environ, start_response) - - def test_traverser_exception_propagating(self): - environ = self._makeEnviron() - context = DummyContext() - self._registerTraverserFactory(context, raise_error=RuntimeError()) - router = self._makeOne() - start_response = DummyStartResponse() - self.assertRaises(RuntimeError, router, environ, start_response) - - def test_call_view_exception_propagating(self): - from zope.interface import Interface - from zope.interface import directlyProvides - class IContext(Interface): - pass - from repoze.bfg.interfaces import IRequest - from repoze.bfg.interfaces import IViewClassifier - from repoze.bfg.interfaces import IRequestFactory - def rfactory(environ): - return request - self.registry.registerUtility(rfactory, IRequestFactory) - from repoze.bfg.request import Request - request = Request.blank('/') - context = DummyContext() - directlyProvides(context, IContext) - self._registerTraverserFactory(context, subpath=['']) - response = DummyResponse() - view = DummyView(response, raise_exception=RuntimeError) - environ = self._makeEnviron() - self._registerView(view, '', IViewClassifier, IRequest, IContext) - router = self._makeOne() - start_response = DummyStartResponse() - self.assertRaises(RuntimeError, router, environ, start_response) - # ``exception`` must be attached to request even if a suitable - # exception view cannot be found - self.assertEqual(request.exception.__class__, RuntimeError) - - def test_call_view_raises_exception_view(self): - from repoze.bfg.interfaces import IViewClassifier - from repoze.bfg.interfaces import IExceptionViewClassifier - from repoze.bfg.interfaces import IRequest - response = DummyResponse() - exception_response = DummyResponse() - exception_response.app_iter = ["Hello, world"] - view = DummyView(response, raise_exception=RuntimeError) - exception_view = DummyView(exception_response) - environ = self._makeEnviron() - self._registerView(view, '', IViewClassifier, IRequest, None) - self._registerView(exception_view, '', IExceptionViewClassifier, - IRequest, RuntimeError) - router = self._makeOne() - start_response = DummyStartResponse() - result = router(environ, start_response) - self.assertEqual(result, ["Hello, world"]) - self.assertEqual(view.request.exception.__class__, RuntimeError) - - def test_call_view_raises_super_exception_sub_exception_view(self): - from repoze.bfg.interfaces import IViewClassifier - from repoze.bfg.interfaces import IExceptionViewClassifier - from repoze.bfg.interfaces import IRequest - class SuperException(Exception): - pass - class SubException(SuperException): - pass - response = DummyResponse() - exception_response = DummyResponse() - exception_response.app_iter = ["Hello, world"] - view = DummyView(response, raise_exception=SuperException) - exception_view = DummyView(exception_response) - environ = self._makeEnviron() - self._registerView(view, '', IViewClassifier, IRequest, None) - self._registerView(exception_view, '', IExceptionViewClassifier, - IRequest, SubException) - router = self._makeOne() - start_response = DummyStartResponse() - self.assertRaises(SuperException, router, environ, start_response) - - def test_call_view_raises_sub_exception_super_exception_view(self): - from repoze.bfg.interfaces import IViewClassifier - from repoze.bfg.interfaces import IExceptionViewClassifier - from repoze.bfg.interfaces import IRequest - class SuperException(Exception): - pass - class SubException(SuperException): - pass - response = DummyResponse() - exception_response = DummyResponse() - exception_response.app_iter = ["Hello, world"] - view = DummyView(response, raise_exception=SubException) - exception_view = DummyView(exception_response) - environ = self._makeEnviron() - self._registerView(view, '', IViewClassifier, IRequest, None) - self._registerView(exception_view, '', IExceptionViewClassifier, - IRequest, SuperException) - router = self._makeOne() - start_response = DummyStartResponse() - result = router(environ, start_response) - self.assertEqual(result, ["Hello, world"]) - - def test_call_view_raises_exception_another_exception_view(self): - from repoze.bfg.interfaces import IViewClassifier - from repoze.bfg.interfaces import IExceptionViewClassifier - from repoze.bfg.interfaces import IRequest - class MyException(Exception): - pass - class AnotherException(Exception): - pass - response = DummyResponse() - exception_response = DummyResponse() - exception_response.app_iter = ["Hello, world"] - view = DummyView(response, raise_exception=MyException) - exception_view = DummyView(exception_response) - environ = self._makeEnviron() - self._registerView(view, '', IViewClassifier, IRequest, None) - self._registerView(exception_view, '', IExceptionViewClassifier, - IRequest, AnotherException) - router = self._makeOne() - start_response = DummyStartResponse() - self.assertRaises(MyException, router, environ, start_response) - - def test_root_factory_raises_exception_view(self): - from repoze.bfg.interfaces import IRootFactory - from repoze.bfg.interfaces import IRequest - from repoze.bfg.interfaces import IExceptionViewClassifier - def rootfactory(request): - raise RuntimeError() - self.registry.registerUtility(rootfactory, IRootFactory) - exception_response = DummyResponse() - exception_response.app_iter = ["Hello, world"] - exception_view = DummyView(exception_response) - self._registerView(exception_view, '', IExceptionViewClassifier, - IRequest, RuntimeError) - environ = self._makeEnviron() - router = self._makeOne() - start_response = DummyStartResponse() - app_iter = router(environ, start_response) - self.assertEqual(app_iter, ["Hello, world"]) - - def test_traverser_raises_exception_view(self): - from repoze.bfg.interfaces import IRequest - from repoze.bfg.interfaces import IExceptionViewClassifier - environ = self._makeEnviron() - context = DummyContext() - self._registerTraverserFactory(context, raise_error=RuntimeError()) - exception_response = DummyResponse() - exception_response.app_iter = ["Hello, world"] - exception_view = DummyView(exception_response) - self._registerView(exception_view, '', IExceptionViewClassifier, - IRequest, RuntimeError) - router = self._makeOne() - start_response = DummyStartResponse() - result = router(environ, start_response) - self.assertEqual(result, ["Hello, world"]) - - def test_exception_view_returns_non_response(self): - from repoze.bfg.interfaces import IRequest - from repoze.bfg.interfaces import IViewClassifier - from repoze.bfg.interfaces import IExceptionViewClassifier - environ = self._makeEnviron() - response = DummyResponse() - view = DummyView(response, raise_exception=RuntimeError) - self._registerView(view, '', IViewClassifier, IRequest, None) - exception_view = DummyView(None) - self._registerView(exception_view, '', IExceptionViewClassifier, - IRequest, RuntimeError) - router = self._makeOne() - start_response = DummyStartResponse() - self.assertRaises(ValueError, router, environ, start_response) - - def test_call_route_raises_route_exception_view(self): - from repoze.bfg.interfaces import IViewClassifier - from repoze.bfg.interfaces import IExceptionViewClassifier - req_iface = self._registerRouteRequest('foo') - self._connectRoute('foo', 'archives/:action/:article', None) - view = DummyView(DummyResponse(), raise_exception=RuntimeError) - self._registerView(view, '', IViewClassifier, req_iface, None) - response = DummyResponse() - response.app_iter = ["Hello, world"] - exception_view = DummyView(response) - self._registerView(exception_view, '', IExceptionViewClassifier, - req_iface, RuntimeError) - environ = self._makeEnviron(PATH_INFO='/archives/action1/article1') - start_response = DummyStartResponse() - router = self._makeOne() - result = router(environ, start_response) - self.assertEqual(result, ["Hello, world"]) - - def test_call_view_raises_exception_route_view(self): - from repoze.bfg.interfaces import IViewClassifier - from repoze.bfg.interfaces import IExceptionViewClassifier - from repoze.bfg.interfaces import IRequest - req_iface = self._registerRouteRequest('foo') - self._connectRoute('foo', 'archives/:action/:article', None) - view = DummyView(DummyResponse(), raise_exception=RuntimeError) - self._registerView(view, '', IViewClassifier, IRequest, None) - response = DummyResponse() - response.app_iter = ["Hello, world"] - exception_view = DummyView(response) - self._registerView(exception_view, '', IExceptionViewClassifier, - req_iface, RuntimeError) - environ = self._makeEnviron() - start_response = DummyStartResponse() - router = self._makeOne() - self.assertRaises(RuntimeError, router, environ, start_response) - - def test_call_route_raises_exception_view(self): - from repoze.bfg.interfaces import IViewClassifier - from repoze.bfg.interfaces import IExceptionViewClassifier - from repoze.bfg.interfaces import IRequest - req_iface = self._registerRouteRequest('foo') - self._connectRoute('foo', 'archives/:action/:article', None) - view = DummyView(DummyResponse(), raise_exception=RuntimeError) - self._registerView(view, '', IViewClassifier, req_iface, None) - response = DummyResponse() - response.app_iter = ["Hello, world"] - exception_view = DummyView(response) - self._registerView(exception_view, '', IExceptionViewClassifier, - IRequest, RuntimeError) - environ = self._makeEnviron(PATH_INFO='/archives/action1/article1') - start_response = DummyStartResponse() - router = self._makeOne() - result = router(environ, start_response) - self.assertEqual(result, ["Hello, world"]) - - def test_call_route_raises_super_exception_sub_exception_view(self): - from repoze.bfg.interfaces import IViewClassifier - from repoze.bfg.interfaces import IExceptionViewClassifier - from repoze.bfg.interfaces import IRequest - class SuperException(Exception): - pass - class SubException(SuperException): - pass - req_iface = self._registerRouteRequest('foo') - self._connectRoute('foo', 'archives/:action/:article', None) - view = DummyView(DummyResponse(), raise_exception=SuperException) - self._registerView(view, '', IViewClassifier, req_iface, None) - response = DummyResponse() - response.app_iter = ["Hello, world"] - exception_view = DummyView(response) - self._registerView(exception_view, '', IExceptionViewClassifier, - IRequest, SubException) - environ = self._makeEnviron(PATH_INFO='/archives/action1/article1') - start_response = DummyStartResponse() - router = self._makeOne() - self.assertRaises(SuperException, router, environ, start_response) - - def test_call_route_raises_sub_exception_super_exception_view(self): - from repoze.bfg.interfaces import IViewClassifier - from repoze.bfg.interfaces import IExceptionViewClassifier - from repoze.bfg.interfaces import IRequest - class SuperException(Exception): - pass - class SubException(SuperException): - pass - req_iface = self._registerRouteRequest('foo') - self._connectRoute('foo', 'archives/:action/:article', None) - view = DummyView(DummyResponse(), raise_exception=SubException) - self._registerView(view, '', IViewClassifier, req_iface, None) - response = DummyResponse() - response.app_iter = ["Hello, world"] - exception_view = DummyView(response) - self._registerView(exception_view, '', IExceptionViewClassifier, - IRequest, SuperException) - environ = self._makeEnviron(PATH_INFO='/archives/action1/article1') - start_response = DummyStartResponse() - router = self._makeOne() - result = router(environ, start_response) - self.assertEqual(result, ["Hello, world"]) - - def test_call_route_raises_exception_another_exception_view(self): - from repoze.bfg.interfaces import IViewClassifier - from repoze.bfg.interfaces import IExceptionViewClassifier - from repoze.bfg.interfaces import IRequest - class MyException(Exception): - pass - class AnotherException(Exception): - pass - req_iface = self._registerRouteRequest('foo') - self._connectRoute('foo', 'archives/:action/:article', None) - view = DummyView(DummyResponse(), raise_exception=MyException) - self._registerView(view, '', IViewClassifier, req_iface, None) - response = DummyResponse() - response.app_iter = ["Hello, world"] - exception_view = DummyView(response) - self._registerView(exception_view, '', IExceptionViewClassifier, - IRequest, AnotherException) - environ = self._makeEnviron(PATH_INFO='/archives/action1/article1') - start_response = DummyStartResponse() - router = self._makeOne() - self.assertRaises(MyException, router, environ, start_response) - - def test_call_route_raises_exception_view_specializing(self): - from repoze.bfg.interfaces import IViewClassifier - from repoze.bfg.interfaces import IExceptionViewClassifier - from repoze.bfg.interfaces import IRequest - req_iface = self._registerRouteRequest('foo') - self._connectRoute('foo', 'archives/:action/:article', None) - view = DummyView(DummyResponse(), raise_exception=RuntimeError) - self._registerView(view, '', IViewClassifier, req_iface, None) - response = DummyResponse() - response.app_iter = ["Hello, world"] - exception_view = DummyView(response) - self._registerView(exception_view, '', IExceptionViewClassifier, - IRequest, RuntimeError) - response_spec = DummyResponse() - response_spec.app_iter = ["Hello, special world"] - exception_view_spec = DummyView(response_spec) - self._registerView(exception_view_spec, '', IExceptionViewClassifier, - req_iface, RuntimeError) - environ = self._makeEnviron(PATH_INFO='/archives/action1/article1') - start_response = DummyStartResponse() - router = self._makeOne() - result = router(environ, start_response) - self.assertEqual(result, ["Hello, special world"]) - - def test_call_route_raises_exception_view_another_route(self): - from repoze.bfg.interfaces import IViewClassifier - from repoze.bfg.interfaces import IExceptionViewClassifier - req_iface = self._registerRouteRequest('foo') - another_req_iface = self._registerRouteRequest('bar') - self._connectRoute('foo', 'archives/:action/:article', None) - view = DummyView(DummyResponse(), raise_exception=RuntimeError) - self._registerView(view, '', IViewClassifier, req_iface, None) - response = DummyResponse() - response.app_iter = ["Hello, world"] - exception_view = DummyView(response) - self._registerView(exception_view, '', IExceptionViewClassifier, - another_req_iface, RuntimeError) - environ = self._makeEnviron(PATH_INFO='/archives/action1/article1') - start_response = DummyStartResponse() - router = self._makeOne() - self.assertRaises(RuntimeError, router, environ, start_response) - - def test_call_view_raises_exception_view_route(self): - from repoze.bfg.interfaces import IRequest - from repoze.bfg.interfaces import IViewClassifier - from repoze.bfg.interfaces import IExceptionViewClassifier - req_iface = self._registerRouteRequest('foo') - response = DummyResponse() - exception_response = DummyResponse() - exception_response.app_iter = ["Hello, world"] - view = DummyView(response, raise_exception=RuntimeError) - exception_view = DummyView(exception_response) - environ = self._makeEnviron() - self._registerView(view, '', IViewClassifier, IRequest, None) - self._registerView(exception_view, '', IExceptionViewClassifier, - req_iface, RuntimeError) - router = self._makeOne() - start_response = DummyStartResponse() - self.assertRaises(RuntimeError, router, environ, start_response) - -class DummyContext: - pass - -class DummyView: - def __init__(self, response, raise_exception=None): - self.response = response - self.raise_exception = raise_exception - - def __call__(self, context, request): - self.context = context - self.request = request - if not self.raise_exception is None: - raise self.raise_exception - return self.response - -class DummyRootFactory: - def __init__(self, root): - self.root = root - - def __call__(self, environ): - return self.root - -class DummyStartResponse: - status = () - headers = () - def __call__(self, status, headers): - self.status = status - self.headers = headers - -class DummyResponse: - headerlist = () - app_iter = () - def __init__(self, status='200 OK'): - self.status = status - -class DummyThreadLocalManager: - def __init__(self): - self.pushed = [] - self.popped = [] - - def push(self, val): - self.pushed.append(val) - - def pop(self): - self.popped.append(True) - -class DummyAuthenticationPolicy: - pass - -class DummyLogger: - def __init__(self): - self.messages = [] - def info(self, msg): - self.messages.append(msg) - warn = info - debug = info - -def exc_raised(exc, func, *arg, **kw): - try: - func(*arg, **kw) - except exc, e: - return e - else: - raise AssertionError('%s not raised' % exc) # pragma: no cover - - diff --git a/repoze/bfg/tests/test_scripting.py b/repoze/bfg/tests/test_scripting.py deleted file mode 100644 index 2663c4a0f..000000000 --- a/repoze/bfg/tests/test_scripting.py +++ /dev/null @@ -1,81 +0,0 @@ -import unittest - -class TestGetRoot(unittest.TestCase): - def _callFUT(self, app, request=None): - from repoze.bfg.paster import get_root - return get_root(app, request) - - def test_it_norequest(self): - app = DummyApp() - root, closer = self._callFUT(app) - self.assertEqual(len(app.threadlocal_manager.pushed), 1) - pushed = app.threadlocal_manager.pushed[0] - self.assertEqual(pushed['registry'], dummy_registry) - self.assertEqual(pushed['request'].registry, app.registry) - self.assertEqual(len(app.threadlocal_manager.popped), 0) - closer() - self.assertEqual(len(app.threadlocal_manager.popped), 1) - - def test_it_withrequest(self): - app = DummyApp() - request = DummyRequest({}) - root, closer = self._callFUT(app, request) - self.assertEqual(len(app.threadlocal_manager.pushed), 1) - pushed = app.threadlocal_manager.pushed[0] - self.assertEqual(pushed['registry'], dummy_registry) - self.assertEqual(pushed['request'], request) - self.assertEqual(len(app.threadlocal_manager.popped), 0) - closer() - self.assertEqual(len(app.threadlocal_manager.popped), 1) - - def test_it_requestfactory_overridden(self): - app = DummyApp() - request = Dummy() - class DummyFactory(object): - @classmethod - def blank(cls, path): - return request - registry = DummyRegistry(DummyFactory) - app.registry = registry - root, closer = self._callFUT(app) - self.assertEqual(len(app.threadlocal_manager.pushed), 1) - pushed = app.threadlocal_manager.pushed[0] - self.assertEqual(pushed['request'], request) - -class Dummy: - pass - -dummy_root = Dummy() - -class DummyRegistry(object): - def __init__(self, result=None): - self.result = result - - def queryUtility(self, iface, default=None): - return self.result or default - -dummy_registry = DummyRegistry() - -class DummyApp: - def __init__(self): - self.registry = dummy_registry - self.threadlocal_manager = DummyThreadLocalManager() - - def root_factory(self, environ): - return dummy_root - -class DummyThreadLocalManager: - def __init__(self): - self.pushed = [] - self.popped = [] - - def push(self, item): - self.pushed.append(item) - - def pop(self): - self.popped.append(True) - -class DummyRequest: - def __init__(self, environ): - self.environ = environ - diff --git a/repoze/bfg/tests/test_security.py b/repoze/bfg/tests/test_security.py deleted file mode 100644 index 13a0e2d9b..000000000 --- a/repoze/bfg/tests/test_security.py +++ /dev/null @@ -1,395 +0,0 @@ -import unittest - -from repoze.bfg.testing import cleanUp - - -class TestAllPermissionsList(unittest.TestCase): - def setUp(self): - cleanUp() - - def tearDown(self): - cleanUp() - - def _getTargetClass(self): - from repoze.bfg.security import AllPermissionsList - return AllPermissionsList - - def _makeOne(self): - return self._getTargetClass()() - - def test_it(self): - thing = self._makeOne() - self.failUnless(thing.__eq__(thing)) - self.assertEqual(thing.__iter__(), ()) - self.failUnless('anything' in thing) - - def test_singleton(self): - from repoze.bfg.security import ALL_PERMISSIONS - self.assertEqual(ALL_PERMISSIONS.__class__, self._getTargetClass()) - -class TestAllowed(unittest.TestCase): - def _getTargetClass(self): - from repoze.bfg.security import Allowed - return Allowed - - def _makeOne(self, *arg, **kw): - klass = self._getTargetClass() - return klass(*arg, **kw) - - def test_it(self): - allowed = self._makeOne('hello') - self.assertEqual(allowed.msg, 'hello') - self.assertEqual(allowed, True) - self.failUnless(allowed) - self.assertEqual(str(allowed), 'hello') - self.failUnless('<Allowed instance at ' in repr(allowed)) - self.failUnless("with msg 'hello'>" in repr(allowed)) - -class TestDenied(unittest.TestCase): - def _getTargetClass(self): - from repoze.bfg.security import Denied - return Denied - - def _makeOne(self, *arg, **kw): - klass = self._getTargetClass() - return klass(*arg, **kw) - - def test_it(self): - denied = self._makeOne('hello') - self.assertEqual(denied.msg, 'hello') - self.assertEqual(denied, False) - self.failIf(denied) - self.assertEqual(str(denied), 'hello') - self.failUnless('<Denied instance at ' in repr(denied)) - self.failUnless("with msg 'hello'>" in repr(denied)) - -class TestACLAllowed(unittest.TestCase): - def _getTargetClass(self): - from repoze.bfg.security import ACLAllowed - return ACLAllowed - - def _makeOne(self, *arg, **kw): - klass = self._getTargetClass() - return klass(*arg, **kw) - - def test_it(self): - msg = ("ACLAllowed permission 'permission' via ACE 'ace' in ACL 'acl' " - "on context 'ctx' for principals 'principals'") - allowed = self._makeOne('ace', 'acl', 'permission', 'principals', 'ctx') - self.failUnless(msg in allowed.msg) - self.assertEqual(allowed, True) - self.failUnless(allowed) - self.assertEqual(str(allowed), msg) - self.failUnless('<ACLAllowed instance at ' in repr(allowed)) - self.failUnless("with msg %r>" % msg in repr(allowed)) - -class TestACLDenied(unittest.TestCase): - def _getTargetClass(self): - from repoze.bfg.security import ACLDenied - return ACLDenied - - def _makeOne(self, *arg, **kw): - klass = self._getTargetClass() - return klass(*arg, **kw) - - def test_it(self): - msg = ("ACLDenied permission 'permission' via ACE 'ace' in ACL 'acl' " - "on context 'ctx' for principals 'principals'") - denied = self._makeOne('ace', 'acl', 'permission', 'principals', 'ctx') - self.failUnless(msg in denied.msg) - self.assertEqual(denied, False) - self.failIf(denied) - self.assertEqual(str(denied), msg) - self.failUnless('<ACLDenied instance at ' in repr(denied)) - self.failUnless("with msg %r>" % msg in repr(denied)) - -class TestViewExecutionPermitted(unittest.TestCase): - def setUp(self): - cleanUp() - - def tearDown(self): - cleanUp() - - def _callFUT(self, *arg, **kw): - from repoze.bfg.security import view_execution_permitted - return view_execution_permitted(*arg, **kw) - - def _registerSecuredView(self, view_name, allow=True): - from repoze.bfg.threadlocal import get_current_registry - from zope.interface import Interface - from repoze.bfg.interfaces import ISecuredView - from repoze.bfg.interfaces import IViewClassifier - class Checker(object): - def __permitted__(self, context, request): - self.context = context - self.request = request - return allow - checker = Checker() - reg = get_current_registry() - reg.registerAdapter(checker, (IViewClassifier, Interface, Interface), - ISecuredView, view_name) - return checker - - def test_no_permission(self): - from repoze.bfg.threadlocal import get_current_registry - from repoze.bfg.interfaces import ISettings - settings = dict(debug_authorization=True) - reg = get_current_registry() - reg.registerUtility(settings, ISettings) - context = DummyContext() - request = DummyRequest({}) - result = self._callFUT(context, request, '') - msg = result.msg - self.failUnless("Allowed: view name '' in context" in msg) - self.failUnless('(no permission defined)' in msg) - self.assertEqual(result, True) - - def test_with_permission(self): - from zope.interface import Interface - from zope.interface import directlyProvides - from repoze.bfg.interfaces import IRequest - class IContext(Interface): - pass - context = DummyContext() - directlyProvides(context, IContext) - self._registerSecuredView('', True) - request = DummyRequest({}) - directlyProvides(request, IRequest) - result = self._callFUT(context, request, '') - self.failUnless(result is True) - -class TestHasPermission(unittest.TestCase): - def setUp(self): - cleanUp() - - def tearDown(self): - cleanUp() - - def _callFUT(self, *arg): - from repoze.bfg.security import has_permission - return has_permission(*arg) - - def test_no_authentication_policy(self): - request = _makeRequest() - result = self._callFUT('view', None, request) - self.assertEqual(result, True) - self.assertEqual(result.msg, 'No authentication policy in use.') - - def test_authentication_policy_no_authorization_policy(self): - request = _makeRequest() - _registerAuthenticationPolicy(request.registry, None) - self.assertRaises(ValueError, self._callFUT, 'view', None, request) - - def test_authn_and_authz_policies_registered(self): - request = _makeRequest() - _registerAuthenticationPolicy(request.registry, None) - _registerAuthorizationPolicy(request.registry, 'yo') - self.assertEqual(self._callFUT('view', None, request), 'yo') - - def test_no_registry_on_request(self): - from repoze.bfg.threadlocal import get_current_registry - request = DummyRequest({}) - registry = get_current_registry() - _registerAuthenticationPolicy(registry, None) - _registerAuthorizationPolicy(registry, 'yo') - self.assertEqual(self._callFUT('view', None, request), 'yo') - -class TestAuthenticatedUserId(unittest.TestCase): - def setUp(self): - cleanUp() - - def tearDown(self): - cleanUp() - - def _callFUT(self, request): - from repoze.bfg.security import authenticated_userid - return authenticated_userid(request) - - def test_no_authentication_policy(self): - request = _makeRequest() - result = self._callFUT(request) - self.assertEqual(result, None) - - def test_with_authentication_policy(self): - request = _makeRequest() - _registerAuthenticationPolicy(request.registry, 'yo') - result = self._callFUT(request) - self.assertEqual(result, 'yo') - - def test_with_authentication_policy_no_reg_on_request(self): - from repoze.bfg.threadlocal import get_current_registry - request = DummyRequest({}) - registry = get_current_registry() - _registerAuthenticationPolicy(registry, 'yo') - result = self._callFUT(request) - self.assertEqual(result, 'yo') - -class TestEffectivePrincipals(unittest.TestCase): - def setUp(self): - cleanUp() - - def tearDown(self): - cleanUp() - - def _callFUT(self, request): - from repoze.bfg.security import effective_principals - return effective_principals(request) - - def test_no_authentication_policy(self): - request = _makeRequest() - result = self._callFUT(request) - self.assertEqual(result, []) - - def test_with_authentication_policy(self): - request = _makeRequest() - _registerAuthenticationPolicy(request.registry, 'yo') - result = self._callFUT(request) - self.assertEqual(result, 'yo') - - def test_with_authentication_policy_no_reg_on_request(self): - from repoze.bfg.threadlocal import get_current_registry - registry = get_current_registry() - request = DummyRequest({}) - _registerAuthenticationPolicy(registry, 'yo') - result = self._callFUT(request) - self.assertEqual(result, 'yo') - -class TestPrincipalsAllowedByPermission(unittest.TestCase): - def setUp(self): - cleanUp() - - def tearDown(self): - cleanUp() - - def _callFUT(self, *arg): - from repoze.bfg.security import principals_allowed_by_permission - return principals_allowed_by_permission(*arg) - - def test_no_authorization_policy(self): - from repoze.bfg.security import Everyone - context = DummyContext() - result = self._callFUT(context, 'view') - self.assertEqual(result, [Everyone]) - - def test_with_authorization_policy(self): - from repoze.bfg.threadlocal import get_current_registry - registry = get_current_registry() - _registerAuthorizationPolicy(registry, 'yo') - context = DummyContext() - result = self._callFUT(context, 'view') - self.assertEqual(result, 'yo') - -class TestRemember(unittest.TestCase): - def setUp(self): - cleanUp() - - def tearDown(self): - cleanUp() - - def _callFUT(self, *arg): - from repoze.bfg.security import remember - return remember(*arg) - - def test_no_authentication_policy(self): - request = _makeRequest() - result = self._callFUT(request, 'me') - self.assertEqual(result, []) - - def test_with_authentication_policy(self): - request = _makeRequest() - registry = request.registry - _registerAuthenticationPolicy(registry, 'yo') - result = self._callFUT(request, 'me') - self.assertEqual(result, 'yo') - - def test_with_authentication_policy_no_reg_on_request(self): - from repoze.bfg.threadlocal import get_current_registry - registry = get_current_registry() - request = DummyRequest({}) - _registerAuthenticationPolicy(registry, 'yo') - result = self._callFUT(request, 'me') - self.assertEqual(result, 'yo') - -class TestForget(unittest.TestCase): - def setUp(self): - cleanUp() - - def tearDown(self): - cleanUp() - - def _callFUT(self, *arg): - from repoze.bfg.security import forget - return forget(*arg) - - def test_no_authentication_policy(self): - request = _makeRequest() - result = self._callFUT(request) - self.assertEqual(result, []) - - def test_with_authentication_policy(self): - request = _makeRequest() - _registerAuthenticationPolicy(request.registry, 'yo') - result = self._callFUT(request) - self.assertEqual(result, 'yo') - - def test_with_authentication_policy_no_reg_on_request(self): - from repoze.bfg.threadlocal import get_current_registry - registry = get_current_registry() - request = DummyRequest({}) - _registerAuthenticationPolicy(registry, 'yo') - result = self._callFUT(request) - self.assertEqual(result, 'yo') - -class DummyContext: - def __init__(self, *arg, **kw): - self.__dict__.update(kw) - -class DummyRequest: - def __init__(self, environ): - self.environ = environ - -class DummyAuthenticationPolicy: - def __init__(self, result): - self.result = result - - def effective_principals(self, request): - return self.result - - def authenticated_userid(self, request): - return self.result - - def remember(self, request, principal, **kw): - return self.result - - def forget(self, request): - return self.result - -class DummyAuthorizationPolicy: - def __init__(self, result): - self.result = result - - def permits(self, context, principals, permission): - return self.result - - def principals_allowed_by_permission(self, context, permission): - return self.result - -def _registerAuthenticationPolicy(reg, result): - from repoze.bfg.interfaces import IAuthenticationPolicy - policy = DummyAuthenticationPolicy(result) - reg.registerUtility(policy, IAuthenticationPolicy) - return policy - -def _registerAuthorizationPolicy(reg, result): - from repoze.bfg.interfaces import IAuthorizationPolicy - policy = DummyAuthorizationPolicy(result) - reg.registerUtility(policy, IAuthorizationPolicy) - return policy - -def _makeRequest(): - from repoze.bfg.registry import Registry - request = DummyRequest({}) - request.registry = Registry() - return request - - diff --git a/repoze/bfg/tests/test_settings.py b/repoze/bfg/tests/test_settings.py deleted file mode 100644 index be73f9dce..000000000 --- a/repoze/bfg/tests/test_settings.py +++ /dev/null @@ -1,203 +0,0 @@ -import unittest - -class TestSettings(unittest.TestCase): - def _getTargetClass(self): - from repoze.bfg.settings import Settings - return Settings - - def _makeOne(self, d=None, environ=None): - if environ is None: - environ = {} - klass = self._getTargetClass() - return klass(d, _environ_=environ) - - def test_getattr(self): - settings = self._makeOne({'reload_templates':False}) - self.assertEqual(settings.reload_templates, False) - - def test_getattr_raises_attribute_error(self): - settings = self._makeOne() - self.assertRaises(AttributeError, settings.__getattr__, 'mykey') - - def test_noargs(self): - settings = self._makeOne() - self.assertEqual(settings['debug_authorization'], False) - self.assertEqual(settings['debug_notfound'], False) - self.assertEqual(settings['reload_templates'], False) - self.assertEqual(settings['reload_resources'], False) - self.assertEqual(settings['configure_zcml'], '') - - def test_reload_templates(self): - settings = self._makeOne({}) - self.assertEqual(settings['reload_templates'], False) - result = self._makeOne({'reload_templates':'false'}) - self.assertEqual(result['reload_templates'], False) - result = self._makeOne({'reload_templates':'t'}) - self.assertEqual(result['reload_templates'], True) - result = self._makeOne({'reload_templates':'1'}) - self.assertEqual(result['reload_templates'], True) - result = self._makeOne({}, {'BFG_RELOAD_TEMPLATES':'1'}) - self.assertEqual(result['reload_templates'], True) - result = self._makeOne({'reload_templates':'false'}, - {'BFG_RELOAD_TEMPLATES':'1'}) - self.assertEqual(result['reload_templates'], True) - - def test_reload_resources(self): - result = self._makeOne({}) - self.assertEqual(result['reload_resources'], False) - result = self._makeOne({'reload_resources':'false'}) - self.assertEqual(result['reload_resources'], False) - result = self._makeOne({'reload_resources':'t'}) - self.assertEqual(result['reload_resources'], True) - result = self._makeOne({'reload_resources':'1'}) - self.assertEqual(result['reload_resources'], True) - result = self._makeOne({}, {'BFG_RELOAD_RESOURCES':'1'}) - self.assertEqual(result['reload_resources'], True) - result = self._makeOne({'reload_resources':'false'}, - {'BFG_RELOAD_RESOURCES':'1'}) - self.assertEqual(result['reload_resources'], True) - - def test_reload_all(self): - result = self._makeOne({}) - self.assertEqual(result['reload_templates'], False) - self.assertEqual(result['reload_resources'], False) - result = self._makeOne({'reload_all':'false'}) - self.assertEqual(result['reload_templates'], False) - self.assertEqual(result['reload_resources'], False) - result = self._makeOne({'reload_all':'t'}) - self.assertEqual(result['reload_templates'], True) - self.assertEqual(result['reload_resources'], True) - result = self._makeOne({'reload_all':'1'}) - self.assertEqual(result['reload_templates'], True) - self.assertEqual(result['reload_resources'], True) - result = self._makeOne({}, {'BFG_RELOAD_ALL':'1'}) - self.assertEqual(result['reload_templates'], True) - self.assertEqual(result['reload_resources'], True) - result = self._makeOne({'reload_all':'false'}, - {'BFG_RELOAD_ALL':'1'}) - self.assertEqual(result['reload_templates'], True) - self.assertEqual(result['reload_resources'], True) - - def test_debug_authorization(self): - result = self._makeOne({}) - self.assertEqual(result['debug_authorization'], False) - result = self._makeOne({'debug_authorization':'false'}) - self.assertEqual(result['debug_authorization'], False) - result = self._makeOne({'debug_authorization':'t'}) - self.assertEqual(result['debug_authorization'], True) - result = self._makeOne({'debug_authorization':'1'}) - self.assertEqual(result['debug_authorization'], True) - result = self._makeOne({}, {'BFG_DEBUG_AUTHORIZATION':'1'}) - self.assertEqual(result['debug_authorization'], True) - result = self._makeOne({'debug_authorization':'false'}, - {'BFG_DEBUG_AUTHORIZATION':'1'}) - self.assertEqual(result['debug_authorization'], True) - - def test_debug_notfound(self): - result = self._makeOne({}) - self.assertEqual(result['debug_notfound'], False) - result = self._makeOne({'debug_notfound':'false'}) - self.assertEqual(result['debug_notfound'], False) - result = self._makeOne({'debug_notfound':'t'}) - self.assertEqual(result['debug_notfound'], True) - result = self._makeOne({'debug_notfound':'1'}) - self.assertEqual(result['debug_notfound'], True) - result = self._makeOne({}, {'BFG_DEBUG_NOTFOUND':'1'}) - self.assertEqual(result['debug_notfound'], True) - result = self._makeOne({'debug_notfound':'false'}, - {'BFG_DEBUG_NOTFOUND':'1'}) - self.assertEqual(result['debug_notfound'], True) - - def test_debug_templates(self): - result = self._makeOne({}) - self.assertEqual(result['debug_templates'], False) - result = self._makeOne({'debug_templates':'false'}) - self.assertEqual(result['debug_templates'], False) - result = self._makeOne({'debug_templates':'t'}) - self.assertEqual(result['debug_templates'], True) - result = self._makeOne({'debug_templates':'1'}) - self.assertEqual(result['debug_templates'], True) - result = self._makeOne({}, {'BFG_DEBUG_TEMPLATES':'1'}) - self.assertEqual(result['debug_templates'], True) - result = self._makeOne({'debug_templates':'false'}, - {'BFG_DEBUG_TEMPLATES':'1'}) - self.assertEqual(result['debug_templates'], True) - - def test_debug_all(self): - result = self._makeOne({}) - self.assertEqual(result['debug_notfound'], False) - self.assertEqual(result['debug_authorization'], False) - self.assertEqual(result['debug_templates'], False) - result = self._makeOne({'debug_all':'false'}) - self.assertEqual(result['debug_notfound'], False) - self.assertEqual(result['debug_authorization'], False) - self.assertEqual(result['debug_templates'], False) - result = self._makeOne({'debug_all':'t'}) - self.assertEqual(result['debug_notfound'], True) - self.assertEqual(result['debug_authorization'], True) - self.assertEqual(result['debug_templates'], True) - result = self._makeOne({'debug_all':'1'}) - self.assertEqual(result['debug_notfound'], True) - self.assertEqual(result['debug_authorization'], True) - self.assertEqual(result['debug_templates'], True) - result = self._makeOne({}, {'BFG_DEBUG_ALL':'1'}) - self.assertEqual(result['debug_notfound'], True) - self.assertEqual(result['debug_authorization'], True) - self.assertEqual(result['debug_templates'], True) - result = self._makeOne({'debug_all':'false'}, - {'BFG_DEBUG_ALL':'1'}) - self.assertEqual(result['debug_notfound'], True) - self.assertEqual(result['debug_authorization'], True) - self.assertEqual(result['debug_templates'], True) - - def test_configure_zcml(self): - result = self._makeOne({}) - self.assertEqual(result['configure_zcml'], '') - result = self._makeOne({'configure_zcml':'abc'}) - self.assertEqual(result['configure_zcml'], 'abc') - result = self._makeOne({}, {'BFG_CONFIGURE_ZCML':'abc'}) - self.assertEqual(result['configure_zcml'], 'abc') - result = self._makeOne({'configure_zcml':'def'}, - {'BFG_CONFIGURE_ZCML':'abc'}) - self.assertEqual(result['configure_zcml'], 'abc') - - def test_default_locale_name(self): - result = self._makeOne({}) - self.assertEqual(result['default_locale_name'], 'en') - result = self._makeOne({'default_locale_name':'abc'}) - self.assertEqual(result['default_locale_name'], 'abc') - result = self._makeOne({}, {'BFG_DEFAULT_LOCALE_NAME':'abc'}) - self.assertEqual(result['default_locale_name'], 'abc') - result = self._makeOne({'default_locale_name':'def'}, - {'BFG_DEFAULT_LOCALE_NAME':'abc'}) - self.assertEqual(result['default_locale_name'], 'abc') - - def test_originals_kept(self): - result = self._makeOne({'a':'i am so a'}) - self.assertEqual(result['a'], 'i am so a') - - -class TestGetSettings(unittest.TestCase): - def setUp(self): - from repoze.bfg.configuration import Configurator - from repoze.bfg.registry import Registry - registry = Registry('testing') - self.config = Configurator(registry=registry) - self.config.begin() - - def tearDown(self): - self.config.end() - - def _callFUT(self): - from repoze.bfg.settings import get_settings - return get_settings() - - def test_it_nosettings(self): - self.assertEqual(self._callFUT(), None) - - def test_it_withsettings(self): - from repoze.bfg.interfaces import ISettings - settings = {'a':1} - self.config.registry.registerUtility(settings, ISettings) - self.assertEqual(self._callFUT(), settings) - diff --git a/repoze/bfg/tests/test_static.py b/repoze/bfg/tests/test_static.py deleted file mode 100644 index 449860883..000000000 --- a/repoze/bfg/tests/test_static.py +++ /dev/null @@ -1,343 +0,0 @@ -import unittest -from repoze.bfg.testing import cleanUp - -class TestPackageURLParser(unittest.TestCase): - def _getTargetClass(self): - from repoze.bfg.static import PackageURLParser - return PackageURLParser - - def _makeOne(self, *arg, **kw): - return self._getTargetClass()(*arg, **kw) - - - def _makeEnviron(self, **kw): - environ = { - 'wsgi.url_scheme':'http', - 'wsgi.version':(1,0), - 'SERVER_NAME':'example.com', - 'SERVER_PORT':'6543', - 'PATH_INFO':'/', - 'SCRIPT_NAME':'', - 'REQUEST_METHOD':'GET', - } - environ.update(kw) - return environ - - def test_ctor_allargs(self): - inst = self._makeOne('package', 'resource/name', root_resource='root', - cache_max_age=100) - self.assertEqual(inst.package_name, 'package') - self.assertEqual(inst.resource_name, 'resource/name') - self.assertEqual(inst.root_resource, 'root') - self.assertEqual(inst.cache_max_age, 100) - - def test_ctor_defaultargs(self): - inst = self._makeOne('package', 'resource/name') - self.assertEqual(inst.package_name, 'package') - self.assertEqual(inst.resource_name, 'resource/name') - self.assertEqual(inst.root_resource, 'resource/name') - self.assertEqual(inst.cache_max_age, None) - - def test_call_adds_slash_path_info_empty(self): - environ = self._makeEnviron(PATH_INFO='') - inst = self._makeOne('repoze.bfg.tests', 'fixtures/static') - sr = DummyStartResponse() - response = inst(environ, sr) - body = response[0] - self.failUnless('301 Moved Permanently' in body) - self.failUnless('http://example.com:6543/' in body) - - def test_path_info_slash_means_index_html(self): - environ = self._makeEnviron() - inst = self._makeOne('repoze.bfg.tests', 'fixtures/static') - sr = DummyStartResponse() - response = inst(environ, sr) - body = response[0] - self.failUnless('<html>static</html>' in body) - - def test_resource_out_of_bounds(self): - environ = self._makeEnviron() - inst = self._makeOne('repoze.bfg.tests', 'fixtures/static') - inst.root_resource = 'abcdef' - sr = DummyStartResponse() - response = inst(environ, sr) - body = response[0] - self.failUnless('404 Not Found' in body) - self.failUnless('http://example.com:6543/' in body) - - def test_resource_doesnt_exist(self): - environ = self._makeEnviron(PATH_INFO='/notthere') - inst = self._makeOne('repoze.bfg.tests', 'fixtures/static') - sr = DummyStartResponse() - response = inst(environ, sr) - body = response[0] - self.failUnless('404 Not Found' in body) - self.failUnless('http://example.com:6543/' in body) - - def test_resource_isdir(self): - environ = self._makeEnviron(PATH_INFO='/subdir/') - inst = self._makeOne('repoze.bfg.tests', 'fixtures/static') - sr = DummyStartResponse() - response = inst(environ, sr) - body = response[0] - self.failUnless('<html>subdir</html>' in body) - - def test_resource_is_file(self): - environ = self._makeEnviron(PATH_INFO='/index.html') - inst = self._makeOne('repoze.bfg.tests', 'fixtures/static') - sr = DummyStartResponse() - response = inst(environ, sr) - body = response[0] - self.failUnless('<html>static</html>' in body) - - def test_resource_is_file_with_cache_max_age(self): - environ = self._makeEnviron(PATH_INFO='/index.html') - inst = self._makeOne('repoze.bfg.tests', 'fixtures/static', - cache_max_age=600) - sr = DummyStartResponse() - response = inst(environ, sr) - body = response[0] - self.failUnless('<html>static</html>' in body) - self.assertEqual(len(sr.headerlist), 8) - header_names = [ x[0] for x in sr.headerlist ] - header_names.sort() - self.assertEqual(header_names, - ['Accept-Ranges', 'Cache-Control', - 'Content-Length', 'Content-Range', - 'Content-Type', 'ETag', 'Expires', 'Last-Modified']) - - def test_resource_is_file_with_no_cache_max_age(self): - environ = self._makeEnviron(PATH_INFO='/index.html') - inst = self._makeOne('repoze.bfg.tests', 'fixtures/static') - sr = DummyStartResponse() - response = inst(environ, sr) - body = response[0] - self.failUnless('<html>static</html>' in body) - self.assertEqual(len(sr.headerlist), 6) - header_names = [ x[0] for x in sr.headerlist ] - header_names.sort() - self.assertEqual(header_names, - ['Accept-Ranges', 'Content-Length', 'Content-Range', - 'Content-Type', 'ETag', 'Last-Modified']) - - def test_if_none_match(self): - class DummyEq(object): - def __eq__(self, other): - return True - dummy_eq = DummyEq() - environ = self._makeEnviron(HTTP_IF_NONE_MATCH=dummy_eq) - inst = self._makeOne('repoze.bfg.tests', 'fixtures/static') - sr = DummyStartResponse() - response = inst(environ, sr) - self.assertEqual(len(sr.headerlist), 1) - self.assertEqual(sr.status, '304 Not Modified') - self.assertEqual(sr.headerlist[0][0], 'ETag') - self.assertEqual(response[0], '') - - def test_repr(self): - inst = self._makeOne('repoze.bfg.tests', 'fixtures/static') - self.failUnless( - repr(inst).startswith( - '<PackageURLParser repoze.bfg.tests:fixtures/static at')) - - def test_not_found(self): - inst = self._makeOne('repoze.bfg.tests', 'fixtures/static') - environ = self._makeEnviron() - sr = DummyStartResponse() - response = inst.not_found(environ, sr, 'debug_message') - body = response[0] - self.failUnless('404 Not Found' in body) - self.assertEqual(sr.status, '404 Not Found') - -class TestStaticView(unittest.TestCase): - def setUp(self): - cleanUp() - - def tearDown(self): - cleanUp() - - def _getTargetClass(self): - from repoze.bfg.view import static - return static - - def _makeOne(self, path, package_name=None): - return self._getTargetClass()(path, package_name=package_name) - - def _makeEnviron(self, **extras): - environ = { - 'wsgi.url_scheme':'http', - 'wsgi.version':(1,0), - 'SERVER_NAME':'localhost', - 'SERVER_PORT':'8080', - 'REQUEST_METHOD':'GET', - } - environ.update(extras) - return environ - - def test_abspath(self): - import os - path = os.path.dirname(__file__) - view = self._makeOne(path) - context = DummyContext() - request = DummyRequest() - request.subpath = ['__init__.py'] - request.environ = self._makeEnviron() - response = view(context, request) - self.assertEqual(request.copied, True) - self.assertEqual(response.directory, path) - - def test_relpath(self): - path = 'fixtures' - view = self._makeOne(path) - context = DummyContext() - request = DummyRequest() - request.subpath = ['__init__.py'] - request.environ = self._makeEnviron() - response = view(context, request) - self.assertEqual(request.copied, True) - self.assertEqual(response.root_resource, 'fixtures') - self.assertEqual(response.resource_name, 'fixtures') - self.assertEqual(response.package_name, 'repoze.bfg.tests') - self.assertEqual(response.cache_max_age, 3600) - - def test_relpath_withpackage(self): - view = self._makeOne('another:fixtures') - context = DummyContext() - request = DummyRequest() - request.subpath = ['__init__.py'] - request.environ = self._makeEnviron() - response = view(context, request) - self.assertEqual(request.copied, True) - self.assertEqual(response.root_resource, 'fixtures') - self.assertEqual(response.resource_name, 'fixtures') - self.assertEqual(response.package_name, 'another') - self.assertEqual(response.cache_max_age, 3600) - - def test_relpath_withpackage_name(self): - view = self._makeOne('fixtures', package_name='another') - context = DummyContext() - request = DummyRequest() - request.subpath = ['__init__.py'] - request.environ = self._makeEnviron() - response = view(context, request) - self.assertEqual(request.copied, True) - self.assertEqual(response.root_resource, 'fixtures') - self.assertEqual(response.resource_name, 'fixtures') - self.assertEqual(response.package_name, 'another') - self.assertEqual(response.cache_max_age, 3600) - -class TestStaticURLInfo(unittest.TestCase): - def _getTargetClass(self): - from repoze.bfg.static import StaticURLInfo - return StaticURLInfo - - def _makeOne(self, config): - return self._getTargetClass()(config) - - def test_verifyClass(self): - from repoze.bfg.interfaces import IStaticURLInfo - from zope.interface.verify import verifyClass - verifyClass(IStaticURLInfo, self._getTargetClass()) - - def test_verifyObject(self): - from repoze.bfg.interfaces import IStaticURLInfo - from zope.interface.verify import verifyObject - verifyObject(IStaticURLInfo, self._makeOne(None)) - - def test_ctor(self): - info = self._makeOne(None) - self.assertEqual(info.registrations, []) - self.assertEqual(info.config, None) - - def test_generate_missing(self): - inst = self._makeOne(None) - request = DummyRequest() - self.assertRaises(ValueError, inst.generate, 'path', request) - - def test_generate_slash_in_name1(self): - inst = self._makeOne(None) - inst.registrations = [('http://example.com/foo/', 'package:path/',True)] - request = DummyRequest() - result = inst.generate('package:path/abc', request) - self.assertEqual(result, 'http://example.com/foo/abc') - - def test_generate_slash_in_name2(self): - inst = self._makeOne(None) - inst.registrations = [('http://example.com/foo/', 'package:path/',True)] - request = DummyRequest() - result = inst.generate('package:path/', request) - self.assertEqual(result, 'http://example.com/foo/') - - def test_generate_route_url(self): - inst = self._makeOne(None) - inst.registrations = [('viewname/', 'package:path/', False)] - def route_url(n, r, **kw): - self.assertEqual(n, 'viewname/') - self.assertEqual(r, request) - self.assertEqual(kw, {'subpath':'abc', 'a':1}) - return 'url' - request = DummyRequest() - inst.route_url = route_url - result = inst.generate('package:path/abc', request, a=1) - self.assertEqual(result, 'url') - - def test_add_already_exists(self): - inst = self._makeOne(None) - inst.registrations = [('http://example.com/', 'package:path/', True)] - inst.add('http://example.com', 'anotherpackage:path') - expected = [('http://example.com/', 'anotherpackage:path/', True)] - self.assertEqual(inst.registrations, expected) - - def test_add_url_withendslash(self): - inst = self._makeOne(None) - inst.add('http://example.com/', 'anotherpackage:path') - expected = [('http://example.com/', 'anotherpackage:path/', True)] - self.assertEqual(inst.registrations, expected) - - def test_add_url_noendslash(self): - inst = self._makeOne(None) - inst.add('http://example.com', 'anotherpackage:path') - expected = [('http://example.com/', 'anotherpackage:path/', True)] - self.assertEqual(inst.registrations, expected) - - def test_add_viewname(self): - from repoze.bfg.static import static_view - class Config: - def add_route(self, *arg, **kw): - self.arg = arg - self.kw = kw - config = Config() - inst = self._makeOne(config) - inst.add('view', 'anotherpackage:path', cache_max_age=1) - expected = [('view/', 'anotherpackage:path/', False)] - self.assertEqual(inst.registrations, expected) - self.assertEqual(config.arg, ('view/', 'view/*subpath')) - self.assertEqual(config.kw['_info'], None) - self.assertEqual(config.kw['view_for'], self._getTargetClass()) - self.assertEqual(config.kw['factory'](), inst) - self.assertEqual(config.kw['view'].__class__, static_view) - self.assertEqual(config.kw['view'].app.cache_max_age, 1) - self.assertEqual(inst.registrations, expected) - -class DummyStartResponse: - def __call__(self, status, headerlist, exc_info=None): - self.status = status - self.headerlist = headerlist - self.exc_info = exc_info - -class DummyContext: - pass - -class DummyRequest: - def __init__(self, environ=None): - if environ is None: - environ = {} - self.environ = environ - - def get_response(self, application): - return application - - def copy(self): - self.copied = True - return self - diff --git a/repoze/bfg/tests/test_testing.py b/repoze/bfg/tests/test_testing.py deleted file mode 100644 index b900a44a4..000000000 --- a/repoze/bfg/tests/test_testing.py +++ /dev/null @@ -1,749 +0,0 @@ - -import unittest - -class TestBase(unittest.TestCase): - def setUp(self): - from repoze.bfg.threadlocal import manager - from repoze.bfg.registry import Registry - manager.clear() - registry = Registry('testing') - self.registry = registry - manager.push({'registry':registry, 'request':None}) - from zope.deprecation import __show__ - __show__.off() - - def tearDown(self): - from repoze.bfg.threadlocal import manager - manager.clear() - from zope.deprecation import __show__ - __show__.on() - -class Test_registerDummySecurityPolicy(TestBase): - def test_registerDummySecurityPolicy(self): - from repoze.bfg import testing - testing.registerDummySecurityPolicy('user', ('group1', 'group2'), - permissive=False) - from repoze.bfg.interfaces import IAuthenticationPolicy - from repoze.bfg.interfaces import IAuthorizationPolicy - ut = self.registry.getUtility(IAuthenticationPolicy) - from repoze.bfg.testing import DummySecurityPolicy - self.failUnless(isinstance(ut, DummySecurityPolicy)) - ut = self.registry.getUtility(IAuthorizationPolicy) - self.assertEqual(ut.userid, 'user') - self.assertEqual(ut.groupids, ('group1', 'group2')) - self.assertEqual(ut.permissive, False) - -class Test_registerModels(TestBase): - def test_registerModels(self): - ob1 = object() - ob2 = object() - models = {'/ob1':ob1, '/ob2':ob2} - from repoze.bfg import testing - testing.registerModels(models) - from repoze.bfg.interfaces import ITraverser - adapter = self.registry.getAdapter(None, ITraverser) - result = adapter({'PATH_INFO':'/ob1'}) - self.assertEqual(result['context'], ob1) - self.assertEqual(result['view_name'], '') - self.assertEqual(result['subpath'], ()) - self.assertEqual(result['traversed'], (u'ob1',)) - self.assertEqual(result['virtual_root'], ob1) - self.assertEqual(result['virtual_root_path'], ()) - result = adapter({'PATH_INFO':'/ob2'}) - self.assertEqual(result['context'], ob2) - self.assertEqual(result['view_name'], '') - self.assertEqual(result['subpath'], ()) - self.assertEqual(result['traversed'], (u'ob2',)) - self.assertEqual(result['virtual_root'], ob2) - self.assertEqual(result['virtual_root_path'], ()) - self.assertRaises(KeyError, adapter, {'PATH_INFO':'/ob3'}) - from repoze.bfg.traversal import find_model - self.assertEqual(find_model(None, '/ob1'), ob1) - -class Test_registerTemplateRenderer(TestBase): - def test_registerTemplateRenderer(self): - from repoze.bfg import testing - renderer = testing.registerTemplateRenderer('templates/foo') - from repoze.bfg.testing import DummyTemplateRenderer - self.failUnless(isinstance(renderer, DummyTemplateRenderer)) - from repoze.bfg.renderers import render_to_response - render_to_response('templates/foo', dict(foo=1, bar=2)) - renderer.assert_(foo=1) - renderer.assert_(bar=2) - - def test_registerTemplateRenderer_explicitrenderer(self): - from repoze.bfg import testing - def renderer(kw, system): - self.assertEqual(kw, {'foo':1, 'bar':2}) - renderer = testing.registerTemplateRenderer('templates/foo', renderer) - from repoze.bfg.renderers import render_to_response - render_to_response('templates/foo', dict(foo=1, bar=2)) - -class Test_registerEventListener(TestBase): - def test_registerEventListener_single(self): - from repoze.bfg import testing - L = testing.registerEventListener(IDummy) - event = DummyEvent() - self.registry.notify(event) - self.assertEqual(len(L), 1) - self.assertEqual(L[0], event) - self.registry.notify(object()) - self.assertEqual(len(L), 1) - - def test_registerEventListener_multiple(self): - from repoze.bfg import testing - L = testing.registerEventListener((Interface, IDummy)) - event = DummyEvent() - event.object = 'foo' - # the below is the equivalent of z.c.event.objectEventNotify(event) - self.registry.subscribers((event.object, event), None) - self.assertEqual(len(L), 2) - self.assertEqual(L[0], 'foo') - self.assertEqual(L[1], event) - - def test_registerEventListener_defaults(self): - from repoze.bfg import testing - L = testing.registerEventListener() - event = object() - self.registry.notify(event) - self.assertEqual(L[-1], event) - event2 = object() - self.registry.notify(event2) - self.assertEqual(L[-1], event2) - -class Test_registerView(TestBase): - def test_registerView_defaults(self): - from repoze.bfg import testing - view = testing.registerView('moo.html') - import types - self.failUnless(isinstance(view, types.FunctionType)) - from repoze.bfg.view import render_view_to_response - request = DummyRequest() - request.registry = self.registry - response = render_view_to_response(None, request, 'moo.html') - self.assertEqual(view(None, None).body, response.body) - - def test_registerView_withresult(self): - from repoze.bfg import testing - view = testing.registerView('moo.html', 'yo') - import types - self.failUnless(isinstance(view, types.FunctionType)) - from repoze.bfg.view import render_view_to_response - request = DummyRequest() - request.registry = self.registry - response = render_view_to_response(None, request, 'moo.html') - self.assertEqual(response.body, 'yo') - - def test_registerView_custom(self): - from repoze.bfg import testing - def view(context, request): - from webob import Response - return Response('123') - view = testing.registerView('moo.html', view=view) - import types - self.failUnless(isinstance(view, types.FunctionType)) - from repoze.bfg.view import render_view_to_response - request = DummyRequest() - request.registry = self.registry - response = render_view_to_response(None, request, 'moo.html') - self.assertEqual(response.body, '123') - - def test_registerView_with_permission_denying(self): - from repoze.bfg import testing - from repoze.bfg.exceptions import Forbidden - def view(context, request): - """ """ - view = testing.registerView('moo.html', view=view, permission='bar') - testing.registerDummySecurityPolicy(permissive=False) - import types - self.failUnless(isinstance(view, types.FunctionType)) - from repoze.bfg.view import render_view_to_response - request = DummyRequest() - request.registry = self.registry - self.assertRaises(Forbidden, render_view_to_response, - None, request, 'moo.html') - - def test_registerView_with_permission_denying2(self): - from repoze.bfg import testing - from repoze.bfg.security import view_execution_permitted - def view(context, request): - """ """ - view = testing.registerView('moo.html', view=view, permission='bar') - testing.registerDummySecurityPolicy(permissive=False) - import types - self.failUnless(isinstance(view, types.FunctionType)) - result = view_execution_permitted(None, None, 'moo.html') - self.assertEqual(result, False) - - def test_registerView_with_permission_allowing(self): - from repoze.bfg import testing - def view(context, request): - from webob import Response - return Response('123') - view = testing.registerView('moo.html', view=view, permission='bar') - testing.registerDummySecurityPolicy(permissive=True) - import types - self.failUnless(isinstance(view, types.FunctionType)) - from repoze.bfg.view import render_view_to_response - request = DummyRequest() - request.registry = self.registry - result = render_view_to_response(None, request, 'moo.html') - self.assertEqual(result.app_iter, ['123']) - - def test_registerViewPermission_defaults(self): - from zope.interface import Interface - from repoze.bfg.interfaces import IViewPermission - from repoze.bfg import testing - testing.registerViewPermission('moo.html') - result = self.registry.getMultiAdapter( - (Interface, Interface), IViewPermission, 'moo.html') - self.assertEqual(result, True) - - def test_registerViewPermission_denying(self): - from zope.interface import Interface - from repoze.bfg.interfaces import IViewPermission - from repoze.bfg import testing - testing.registerViewPermission('moo.html', result=False) - result = self.registry.getMultiAdapter( - (Interface, Interface), IViewPermission, 'moo.html') - self.assertEqual(result, False) - - def test_registerViewPermission_custom(self): - from zope.interface import Interface - from repoze.bfg.interfaces import IViewPermission - def viewperm(context, request): - return True - from repoze.bfg import testing - testing.registerViewPermission('moo.html', viewpermission=viewperm) - result = self.registry.getMultiAdapter( - (Interface, Interface), IViewPermission, 'moo.html') - self.assertEqual(result, True) - -class Test_registerAdapter(TestBase): - def test_registerAdapter(self): - from zope.interface import Interface - class provides(Interface): - pass - class Provider: - pass - class for_(Interface): - pass - from repoze.bfg import testing - testing.registerAdapter(Provider, (for_, for_), provides, name='foo') - adapter = self.registry.adapters.lookup( - (for_, for_), provides, name='foo') - self.assertEqual(adapter, Provider) - - def test_registerAdapter_notlist(self): - from zope.interface import Interface - class provides(Interface): - pass - class Provider: - pass - class for_(Interface): - pass - from repoze.bfg import testing - testing.registerAdapter(Provider, for_, provides, name='foo') - adapter = self.registry.adapters.lookup( - (for_,), provides, name='foo') - self.assertEqual(adapter, Provider) - -class Test_registerUtility(TestBase): - def test_registerUtility(self): - from zope.interface import implements - from zope.interface import Interface - class iface(Interface): - pass - class impl: - implements(iface) - def __call__(self): - return 'foo' - utility = impl() - from repoze.bfg import testing - testing.registerUtility(utility, iface, name='mudge') - self.assertEqual(self.registry.getUtility(iface, name='mudge')(), 'foo') - -class Test_registerSubscriber(TestBase): - def test_it(self): - from repoze.bfg import testing - L = [] - def subscriber(event): - L.append(event) - testing.registerSubscriber(subscriber, iface=IDummy) - event = DummyEvent() - self.registry.notify(event) - self.assertEqual(len(L), 1) - self.assertEqual(L[0], event) - self.registry.notify(object()) - self.assertEqual(len(L), 1) - -class Test_registerRoute(TestBase): - def test_registerRoute(self): - from repoze.bfg.url import route_url - from repoze.bfg.interfaces import IRoutesMapper - from repoze.bfg.testing import registerRoute - registerRoute(':pagename', 'home', DummyFactory) - mapper = self.registry.getUtility(IRoutesMapper) - self.assertEqual(len(mapper.routelist), 1) - request = DummyRequest() - self.assertEqual(route_url('home', request, pagename='abc'), - 'http://example.com/abc') - -class Test_registerRoutesMapper(TestBase): - def test_registerRoutesMapper(self): - from repoze.bfg.interfaces import IRoutesMapper - from repoze.bfg.testing import registerRoutesMapper - result = registerRoutesMapper() - mapper = self.registry.getUtility(IRoutesMapper) - self.assertEqual(result, mapper) - -class Test_registerSettings(TestBase): - def test_registerSettings(self): - from repoze.bfg.interfaces import ISettings - from repoze.bfg.testing import registerSettings - registerSettings({'a':1, 'b':2}) - settings = self.registry.getUtility(ISettings) - self.assertEqual(settings['a'], 1) - self.assertEqual(settings['b'], 2) - registerSettings(b=3, c=4) - settings = self.registry.getUtility(ISettings) - self.assertEqual(settings['a'], 1) - self.assertEqual(settings['b'], 3) - self.assertEqual(settings['c'], 4) - -class TestDummyRootFactory(unittest.TestCase): - def _makeOne(self, environ): - from repoze.bfg.testing import DummyRootFactory - return DummyRootFactory(environ) - - def test_it(self): - environ = {'bfg.routes.matchdict':{'a':1}} - factory = self._makeOne(environ) - self.assertEqual(factory.a, 1) - -class TestDummySecurityPolicy(unittest.TestCase): - def _getTargetClass(self): - from repoze.bfg.testing import DummySecurityPolicy - return DummySecurityPolicy - - def _makeOne(self, userid=None, groupids=(), permissive=True): - klass = self._getTargetClass() - return klass(userid, groupids, permissive) - - def test_authenticated_userid(self): - policy = self._makeOne('user') - self.assertEqual(policy.authenticated_userid(None), 'user') - - def test_effective_principals_userid(self): - policy = self._makeOne('user', ('group1',)) - from repoze.bfg.security import Everyone - from repoze.bfg.security import Authenticated - self.assertEqual(policy.effective_principals(None), - [Everyone, Authenticated, 'user', 'group1']) - - def test_effective_principals_nouserid(self): - policy = self._makeOne() - from repoze.bfg.security import Everyone - self.assertEqual(policy.effective_principals(None), [Everyone]) - - def test_permits(self): - policy = self._makeOne() - self.assertEqual(policy.permits(None, None, None), True) - - def test_principals_allowed_by_permission(self): - policy = self._makeOne('user', ('group1',)) - from repoze.bfg.security import Everyone - from repoze.bfg.security import Authenticated - result = policy.principals_allowed_by_permission(None, None) - self.assertEqual(result, [Everyone, Authenticated, 'user', 'group1']) - - def test_forget(self): - policy = self._makeOne() - self.assertEqual(policy.forget(None), []) - - def test_remember(self): - policy = self._makeOne() - self.assertEqual(policy.remember(None, None), []) - - - -class TestDummyModel(unittest.TestCase): - def _getTargetClass(self): - from repoze.bfg.testing import DummyModel - return DummyModel - - def _makeOne(self, name=None, parent=None, **kw): - klass = self._getTargetClass() - return klass(name, parent, **kw) - - def test__setitem__and__getitem__and__delitem__and__contains__and_get(self): - class Dummy: - pass - dummy = Dummy() - model = self._makeOne() - model['abc'] = dummy - self.assertEqual(dummy.__name__, 'abc') - self.assertEqual(dummy.__parent__, model) - self.assertEqual(model['abc'], dummy) - self.assertEqual(model.get('abc'), dummy) - self.assertRaises(KeyError, model.__getitem__, 'none') - self.failUnless('abc' in model) - del model['abc'] - self.failIf('abc' in model) - self.assertEqual(model.get('abc', 'foo'), 'foo') - self.assertEqual(model.get('abc'), None) - - def test_extra_params(self): - model = self._makeOne(foo=1) - self.assertEqual(model.foo, 1) - - def test_clone(self): - model = self._makeOne('name', 'parent', foo=1, bar=2) - clone = model.clone('name2', 'parent2', bar=1) - self.assertEqual(clone.bar, 1) - self.assertEqual(clone.__name__, 'name2') - self.assertEqual(clone.__parent__, 'parent2') - self.assertEqual(clone.foo, 1) - - def test_keys_items_values_len(self): - class Dummy: - pass - model = self._makeOne() - model['abc'] = Dummy() - model['def'] = Dummy() - self.assertEqual(model.values(), model.subs.values()) - self.assertEqual(model.items(), model.subs.items()) - self.assertEqual(model.keys(), model.subs.keys()) - self.assertEqual(len(model), 2) - - def test_nonzero(self): - model = self._makeOne() - self.assertEqual(model.__nonzero__(), True) - - def test_ctor_with__provides__(self): - model = self._makeOne(__provides__=IDummy) - self.failUnless(IDummy.providedBy(model)) - -class TestDummyRequest(unittest.TestCase): - def _getTargetClass(self): - from repoze.bfg.testing import DummyRequest - return DummyRequest - - def _makeOne(self, *arg, **kw): - return self._getTargetClass()(*arg, **kw) - - def test_params(self): - request = self._makeOne(params = {'say':'Hello'}, - environ = {'PATH_INFO':'/foo'}, - headers = {'X-Foo':'YUP'}, - ) - self.assertEqual(request.params['say'], 'Hello') - self.assertEqual(request.GET['say'], 'Hello') - self.assertEqual(request.POST['say'], 'Hello') - self.assertEqual(request.headers['X-Foo'], 'YUP') - self.assertEqual(request.environ['PATH_INFO'], '/foo') - - def test_defaults(self): - from repoze.bfg.threadlocal import get_current_registry - request = self._makeOne() - self.assertEqual(request.method, 'GET') - self.assertEqual(request.application_url, 'http://example.com') - self.assertEqual(request.host_url, 'http://example.com') - self.assertEqual(request.path_url, 'http://example.com') - self.assertEqual(request.url, 'http://example.com') - self.assertEqual(request.host, 'example.com:80') - self.assertEqual(request.content_length, 0) - self.assertEqual(request.environ.get('PATH_INFO'), None) - self.assertEqual(request.headers.get('X-Foo'), None) - self.assertEqual(request.params.get('foo'), None) - self.assertEqual(request.GET.get('foo'), None) - self.assertEqual(request.POST.get('foo'), None) - self.assertEqual(request.cookies.get('type'), None) - self.assertEqual(request.path, '/') - self.assertEqual(request.path_info, '/') - self.assertEqual(request.script_name, '') - self.assertEqual(request.path_qs, '') - self.assertEqual(request.view_name, '') - self.assertEqual(request.subpath, ()) - self.assertEqual(request.context, None) - self.assertEqual(request.root, None) - self.assertEqual(request.virtual_root, None) - self.assertEqual(request.virtual_root_path, ()) - self.assertEqual(request.registry, get_current_registry()) - - def test_params_explicit(self): - request = self._makeOne(params = {'foo':'bar'}) - self.assertEqual(request.params['foo'], 'bar') - self.assertEqual(request.GET['foo'], 'bar') - self.assertEqual(request.POST['foo'], 'bar') - - def test_environ_explicit(self): - request = self._makeOne(environ = {'PATH_INFO':'/foo'}) - self.assertEqual(request.environ['PATH_INFO'], '/foo') - - def test_headers_explicit(self): - request = self._makeOne(headers = {'X-Foo':'YUP'}) - self.assertEqual(request.headers['X-Foo'], 'YUP') - - def test_path_explicit(self): - request = self._makeOne(path = '/abc') - self.assertEqual(request.path, '/abc') - - def test_cookies_explicit(self): - request = self._makeOne(cookies = {'type': 'gingersnap'}) - self.assertEqual(request.cookies['type'], 'gingersnap') - - def test_post_explicit(self): - POST = {'foo': 'bar', 'baz': 'qux'} - request = self._makeOne(post=POST) - self.assertEqual(request.method, 'POST') - self.assertEqual(request.POST, POST) - # N.B.: Unlike a normal request, passing 'post' should *not* put - # explict POST data into params: doing so masks a possible - # XSS bug in the app. Tests for apps which don't care about - # the distinction should just use 'params'. - self.assertEqual(request.params, {}) - - def test_post_empty_shadows_params(self): - request = self._makeOne(params={'foo': 'bar'}, post={}) - self.assertEqual(request.method, 'POST') - self.assertEqual(request.params.get('foo'), 'bar') - self.assertEqual(request.POST.get('foo'), None) - - def test_kwargs(self): - request = self._makeOne(water = 1) - self.assertEqual(request.water, 1) - - def test_add_response_callback(self): - request = self._makeOne() - request.add_response_callback(1) - self.assertEqual(request.response_callbacks, [1]) - - -class TestDummyTemplateRenderer(unittest.TestCase): - def _getTargetClass(self, ): - from repoze.bfg.testing import DummyTemplateRenderer - return DummyTemplateRenderer - - def _makeOne(self, string_response=''): - return self._getTargetClass()(string_response=string_response) - - def test_implementation(self): - renderer = self._makeOne() - impl = renderer.implementation() - impl(a=1, b=2) - self.assertEqual(renderer._implementation._received['a'], 1) - self.assertEqual(renderer._implementation._received['b'], 2) - - def test_getattr(self): - renderer = self._makeOne() - renderer({'a':1}) - self.assertEqual(renderer.a, 1) - self.assertRaises(AttributeError, renderer.__getattr__, 'b') - - def test_assert_(self): - renderer = self._makeOne() - renderer({'a':1, 'b':2}) - self.assertRaises(AssertionError, renderer.assert_, c=1) - self.assertRaises(AssertionError, renderer.assert_, b=3) - self.failUnless(renderer.assert_(a=1, b=2)) - - def test_nondefault_string_response(self): - renderer = self._makeOne('abc') - result = renderer({'a':1, 'b':2}) - self.assertEqual(result, 'abc') - -class Test_setUp(unittest.TestCase): - def _callFUT(self, **kw): - from repoze.bfg.testing import setUp - return setUp(**kw) - - def test_it_defaults(self): - from repoze.bfg.threadlocal import manager - from repoze.bfg.threadlocal import get_current_registry - from repoze.bfg.registry import Registry - from zope.component import getSiteManager - old = True - manager.push(old) - try: - 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: - result = getSiteManager.sethook(None) - self.assertEqual(result, get_current_registry) - getSiteManager.reset() - manager.clear() - - def test_it_with_registry(self): - from zope.component import getSiteManager - from repoze.bfg.threadlocal import manager - registry = object() - try: - self._callFUT(registry=registry) - current = manager.get() - self.assertEqual(current['registry'], registry) - finally: - getSiteManager.reset() - manager.clear() - - def test_it_with_request(self): - from zope.component import getSiteManager - from repoze.bfg.threadlocal import manager - request = object() - try: - self._callFUT(request=request) - current = manager.get() - self.assertEqual(current['request'], request) - finally: - getSiteManager.reset() - manager.clear() - - def test_it_with_hook_zca_false(self): - from zope.component import getSiteManager - from repoze.bfg.threadlocal import manager - registry = object() - try: - self._callFUT(registry=registry, hook_zca=False) - sm = getSiteManager() - self.failIf(sm is registry) - finally: - getSiteManager.reset() - manager.clear() - -class Test_cleanUp(Test_setUp): - def _callFUT(self, *arg, **kw): - from repoze.bfg.testing import cleanUp - return cleanUp(*arg, **kw) - -class Test_tearDown(unittest.TestCase): - def _callFUT(self, **kw): - from repoze.bfg.testing import tearDown - return tearDown(**kw) - - def test_defaults(self): - from repoze.bfg.threadlocal import manager - from zope.component import getSiteManager - registry = DummyRegistry() - old = {'registry':registry} - hook = lambda *arg: None - try: - getSiteManager.sethook(hook) - manager.push(old) - self._callFUT() - current = manager.get() - self.assertNotEqual(current, old) - self.assertEqual(registry.inited, 2) - finally: - result = getSiteManager.sethook(None) - self.assertNotEqual(result, hook) - getSiteManager.reset() - manager.clear() - - def test_registry_cannot_be_inited(self): - from repoze.bfg.threadlocal import manager - registry = DummyRegistry() - def raiseit(name): - raise TypeError - registry.__init__ = raiseit - old = {'registry':registry} - try: - manager.push(old) - self._callFUT() # doesn't blow up - current = manager.get() - self.assertNotEqual(current, old) - self.assertEqual(registry.inited, 1) - finally: - manager.clear() - - def test_unhook_zc_false(self): - from repoze.bfg.threadlocal import manager - from zope.component import getSiteManager - hook = lambda *arg: None - try: - getSiteManager.sethook(hook) - self._callFUT(unhook_zca=False) - finally: - result = getSiteManager.sethook(None) - self.assertEqual(result, hook) - getSiteManager.reset() - manager.clear() - -class TestDummyRendererFactory(unittest.TestCase): - def _makeOne(self, name, factory): - from repoze.bfg.testing import DummyRendererFactory - return DummyRendererFactory(name, factory) - - def test_add_no_colon(self): - f = self._makeOne('name', None) - f.add('spec', 'renderer') - self.assertEqual(f.renderers['spec'], 'renderer') - - def test_add_with_colon(self): - f = self._makeOne('name', None) - f.add('spec:spec2', 'renderer') - self.assertEqual(f.renderers['spec:spec2'], 'renderer') - self.assertEqual(f.renderers['spec2'], 'renderer') - - def test_call(self): - f = self._makeOne('name', None) - f.renderers['spec'] = 'renderer' - self.assertEqual(f('spec'), 'renderer') - - def test_call2(self): - f = self._makeOne('name', None) - f.renderers['spec'] = 'renderer' - self.assertEqual(f('spec:spec'), 'renderer') - - def test_call3(self): - def factory(spec): - return 'renderer' - f = self._makeOne('name', factory) - self.assertEqual(f('spec'), 'renderer') - - def test_call_miss(self): - f = self._makeOne('name', None) - self.assertRaises(KeyError, f, 'spec') - -class TestMockTemplate(unittest.TestCase): - def _makeOne(self, response): - from repoze.bfg.testing import MockTemplate - return MockTemplate(response) - - def test_getattr(self): - template = self._makeOne(None) - self.assertEqual(template.foo, template) - - def test_getitem(self): - template = self._makeOne(None) - self.assertEqual(template['foo'], template) - - def test_call(self): - template = self._makeOne('123') - self.assertEqual(template(), '123') - -from zope.interface import Interface -from zope.interface import implements - -class IDummy(Interface): - pass - -class DummyEvent: - implements(IDummy) - -class DummyRequest: - application_url = 'http://example.com' - -class DummyFactory: - def __init__(self, environ): - """ """ - -class DummyRegistry(object): - inited = 0 - __name__ = 'name' - def __init__(self, name=''): - self.inited = self.inited + 1 - diff --git a/repoze/bfg/tests/test_threadlocal.py b/repoze/bfg/tests/test_threadlocal.py deleted file mode 100644 index 6bb18c4ff..000000000 --- a/repoze/bfg/tests/test_threadlocal.py +++ /dev/null @@ -1,95 +0,0 @@ -from repoze.bfg import testing -import unittest - -class TestThreadLocalManager(unittest.TestCase): - def setUp(self): - testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _getTargetClass(self): - from repoze.bfg.threadlocal import ThreadLocalManager - return ThreadLocalManager - - def _makeOne(self, default=lambda *x: 1): - return self._getTargetClass()(default) - - def test_init(self): - local = self._makeOne() - self.assertEqual(local.stack, []) - self.assertEqual(local.get(), 1) - - def test_default(self): - def thedefault(): - return '123' - local = self._makeOne(thedefault) - self.assertEqual(local.stack, []) - self.assertEqual(local.get(), '123') - - def test_push_and_pop(self): - local = self._makeOne() - local.push(True) - self.assertEqual(local.get(), True) - self.assertEqual(local.pop(), True) - self.assertEqual(local.pop(), None) - self.assertEqual(local.get(), 1) - - def test_set_get_and_clear(self): - local = self._makeOne() - local.set(None) - self.assertEqual(local.stack, [None]) - self.assertEqual(local.get(), None) - local.clear() - self.assertEqual(local.get(), 1) - local.clear() - self.assertEqual(local.get(), 1) - - -class TestGetCurrentRequest(unittest.TestCase): - def _callFUT(self): - from repoze.bfg.threadlocal import get_current_request - return get_current_request() - - def test_it_None(self): - request = self._callFUT() - self.assertEqual(request, None) - - def test_it(self): - from repoze.bfg.threadlocal import manager - request = object() - try: - manager.push({'request':request}) - self.assertEqual(self._callFUT(), request) - finally: - manager.pop() - self.assertEqual(self._callFUT(), None) - -class GetCurrentRegistryTests(unittest.TestCase): - def setUp(self): - testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _callFUT(self): - from repoze.bfg.threadlocal import get_current_registry - return get_current_registry() - - def test_it(self): - from repoze.bfg.threadlocal import manager - try: - manager.push({'registry':123}) - self.assertEqual(self._callFUT(), 123) - finally: - manager.pop() - -class GetCurrentRegistryWithoutTestingRegistry(unittest.TestCase): - def _callFUT(self): - from repoze.bfg.threadlocal import get_current_registry - return get_current_registry() - - def test_it(self): - from repoze.bfg.registry import global_registry - self.assertEqual(self._callFUT(), global_registry) - diff --git a/repoze/bfg/tests/test_traversal.py b/repoze/bfg/tests/test_traversal.py deleted file mode 100644 index 1cae0a05f..000000000 --- a/repoze/bfg/tests/test_traversal.py +++ /dev/null @@ -1,1033 +0,0 @@ -import unittest - -from repoze.bfg.testing import cleanUp - -class TraversalPathTests(unittest.TestCase): - def _callFUT(self, path): - from repoze.bfg.traversal import traversal_path - return traversal_path(path) - - def test_path_startswith_endswith(self): - self.assertEqual(self._callFUT('/foo/'), (u'foo',)) - - def test_empty_elements(self): - self.assertEqual(self._callFUT('foo///'), (u'foo',)) - - def test_onedot(self): - self.assertEqual(self._callFUT('foo/./bar'), (u'foo', u'bar')) - - def test_twodots(self): - self.assertEqual(self._callFUT('foo/../bar'), (u'bar',)) - - def test_element_urllquoted(self): - self.assertEqual(self._callFUT('/foo/space%20thing/bar'), - (u'foo', u'space thing', u'bar')) - - def test_segments_are_unicode(self): - result = self._callFUT('/foo/bar') - self.assertEqual(type(result[0]), unicode) - self.assertEqual(type(result[1]), unicode) - - def test_same_value_returned_if_cached(self): - result1 = self._callFUT('/foo/bar') - result2 = self._callFUT('/foo/bar') - self.assertEqual(result1, (u'foo', u'bar')) - self.assertEqual(result2, (u'foo', u'bar')) - - def test_utf8(self): - import urllib - la = 'La Pe\xc3\xb1a' - encoded = urllib.quote(la) - decoded = unicode(la, 'utf-8') - path = '/'.join([encoded, encoded]) - self.assertEqual(self._callFUT(path), (decoded, decoded)) - - def test_utf16(self): - from repoze.bfg.exceptions import URLDecodeError - import urllib - la = unicode('La Pe\xc3\xb1a', 'utf-8').encode('utf-16') - encoded = urllib.quote(la) - path = '/'.join([encoded, encoded]) - self.assertRaises(URLDecodeError, self._callFUT, path) - - def test_unicode_highorder_chars(self): - path = u'/%E6%B5%81%E8%A1%8C%E8%B6%8B%E5%8A%BF' - self.assertEqual(self._callFUT(path), (u'\u6d41\u884c\u8d8b\u52bf',)) - - def test_unicode_simple(self): - path = u'/abc' - self.assertEqual(self._callFUT(path), (u'abc',)) - - def test_unicode_undecodeable_to_ascii(self): - path = unicode('/La Pe\xc3\xb1a', 'utf-8') - self.assertRaises(UnicodeEncodeError, self._callFUT, path) - -class ModelGraphTraverserTests(unittest.TestCase): - def setUp(self): - cleanUp() - - def tearDown(self): - cleanUp() - - def _getTargetClass(self): - from repoze.bfg.traversal import ModelGraphTraverser - return ModelGraphTraverser - - def _makeOne(self, *arg, **kw): - klass = self._getTargetClass() - return klass(*arg, **kw) - - def _getEnviron(self, **kw): - environ = {} - environ.update(kw) - return environ - - def test_class_conforms_to_ITraverser(self): - from zope.interface.verify import verifyClass - from repoze.bfg.interfaces import ITraverser - verifyClass(ITraverser, self._getTargetClass()) - - def test_instance_conforms_to_ITraverser(self): - from zope.interface.verify import verifyObject - from repoze.bfg.interfaces import ITraverser - context = DummyContext() - verifyObject(ITraverser, self._makeOne(context)) - - def test_call_with_no_pathinfo(self): - policy = self._makeOne(None) - environ = self._getEnviron() - result = policy(environ) - self.assertEqual(result['context'], None) - self.assertEqual(result['view_name'], '') - self.assertEqual(result['subpath'], ()) - self.assertEqual(result['traversed'], ()) - self.assertEqual(result['root'], policy.root) - self.assertEqual(result['virtual_root'], policy.root) - self.assertEqual(result['virtual_root_path'], ()) - - def test_call_pathel_with_no_getitem(self): - policy = self._makeOne(None) - environ = self._getEnviron(PATH_INFO='/foo/bar') - result = policy(environ) - self.assertEqual(result['context'], None) - self.assertEqual(result['view_name'], 'foo') - self.assertEqual(result['subpath'], ('bar',)) - self.assertEqual(result['traversed'], ()) - self.assertEqual(result['root'], policy.root) - self.assertEqual(result['virtual_root'], policy.root) - self.assertEqual(result['virtual_root_path'], ()) - - def test_call_withconn_getitem_emptypath_nosubpath(self): - root = DummyContext() - policy = self._makeOne(root) - environ = self._getEnviron(PATH_INFO='') - result = policy(environ) - self.assertEqual(result['context'], root) - self.assertEqual(result['view_name'], '') - self.assertEqual(result['subpath'], ()) - self.assertEqual(result['traversed'], ()) - self.assertEqual(result['root'], root) - self.assertEqual(result['virtual_root'], root) - self.assertEqual(result['virtual_root_path'], ()) - - def test_call_withconn_getitem_withpath_nosubpath(self): - foo = DummyContext() - root = DummyContext(foo) - policy = self._makeOne(root) - environ = self._getEnviron(PATH_INFO='/foo/bar') - result = policy(environ) - self.assertEqual(result['context'], foo) - self.assertEqual(result['view_name'], 'bar') - self.assertEqual(result['subpath'], ()) - self.assertEqual(result['traversed'], (u'foo',)) - self.assertEqual(result['root'], root) - self.assertEqual(result['virtual_root'], root) - self.assertEqual(result['virtual_root_path'], ()) - - def test_call_withconn_getitem_withpath_withsubpath(self): - foo = DummyContext() - root = DummyContext(foo) - policy = self._makeOne(root) - environ = self._getEnviron(PATH_INFO='/foo/bar/baz/buz') - result = policy(environ) - self.assertEqual(result['context'], foo) - self.assertEqual(result['view_name'], 'bar') - self.assertEqual(result['subpath'], ('baz', 'buz')) - self.assertEqual(result['traversed'], (u'foo',)) - self.assertEqual(result['root'], root) - self.assertEqual(result['virtual_root'], root) - self.assertEqual(result['virtual_root_path'], ()) - - def test_call_with_explicit_viewname(self): - foo = DummyContext() - root = DummyContext(foo) - policy = self._makeOne(root) - environ = self._getEnviron(PATH_INFO='/@@foo') - result = policy(environ) - self.assertEqual(result['context'], root) - self.assertEqual(result['view_name'], 'foo') - self.assertEqual(result['subpath'], ()) - self.assertEqual(result['traversed'], ()) - self.assertEqual(result['root'], root) - self.assertEqual(result['virtual_root'], root) - self.assertEqual(result['virtual_root_path'], ()) - - def test_call_with_vh_root(self): - environ = self._getEnviron(PATH_INFO='/baz', - HTTP_X_VHM_ROOT='/foo/bar') - baz = DummyContext(None, 'baz') - bar = DummyContext(baz, 'bar') - foo = DummyContext(bar, 'foo') - root = DummyContext(foo, 'root') - policy = self._makeOne(root) - result = policy(environ) - self.assertEqual(result['context'], baz) - self.assertEqual(result['view_name'], '') - self.assertEqual(result['subpath'], ()) - self.assertEqual(result['traversed'], (u'foo', u'bar', u'baz')) - self.assertEqual(result['root'], root) - self.assertEqual(result['virtual_root'], bar) - self.assertEqual(result['virtual_root_path'], (u'foo', u'bar')) - - def test_call_with_vh_root2(self): - environ = self._getEnviron(PATH_INFO='/bar/baz', - HTTP_X_VHM_ROOT='/foo') - baz = DummyContext(None, 'baz') - bar = DummyContext(baz, 'bar') - foo = DummyContext(bar, 'foo') - root = DummyContext(foo, 'root') - policy = self._makeOne(root) - result = policy(environ) - self.assertEqual(result['context'], baz) - self.assertEqual(result['view_name'], '') - self.assertEqual(result['subpath'], ()) - self.assertEqual(result['traversed'], (u'foo', u'bar', u'baz')) - self.assertEqual(result['root'], root) - self.assertEqual(result['virtual_root'], foo) - self.assertEqual(result['virtual_root_path'], (u'foo',)) - - def test_call_with_vh_root3(self): - environ = self._getEnviron(PATH_INFO='/foo/bar/baz', - HTTP_X_VHM_ROOT='/') - baz = DummyContext() - bar = DummyContext(baz) - foo = DummyContext(bar) - root = DummyContext(foo) - policy = self._makeOne(root) - result = policy(environ) - self.assertEqual(result['context'], baz) - self.assertEqual(result['view_name'], '') - self.assertEqual(result['subpath'], ()) - self.assertEqual(result['traversed'], (u'foo', u'bar', u'baz')) - self.assertEqual(result['root'], root) - self.assertEqual(result['virtual_root'], root) - self.assertEqual(result['virtual_root_path'], ()) - - def test_call_with_vh_root4(self): - environ = self._getEnviron(PATH_INFO='/', - HTTP_X_VHM_ROOT='/foo/bar/baz') - baz = DummyContext(None, 'baz') - bar = DummyContext(baz, 'bar') - foo = DummyContext(bar, 'foo') - root = DummyContext(foo, 'root') - policy = self._makeOne(root) - result = policy(environ) - self.assertEqual(result['context'], baz) - self.assertEqual(result['view_name'], '') - self.assertEqual(result['subpath'], ()) - self.assertEqual(result['traversed'], (u'foo', u'bar', u'baz')) - self.assertEqual(result['root'], root) - self.assertEqual(result['virtual_root'], baz) - self.assertEqual(result['virtual_root_path'], (u'foo', u'bar', u'baz')) - - def test_call_with_vh_root_path_root(self): - policy = self._makeOne(None) - environ = self._getEnviron(HTTP_X_VHM_ROOT='/', - PATH_INFO='/') - result = policy(environ) - self.assertEqual(result['context'], None) - self.assertEqual(result['view_name'], '') - self.assertEqual(result['subpath'], ()) - self.assertEqual(result['traversed'], ()) - self.assertEqual(result['root'], policy.root) - self.assertEqual(result['virtual_root'], policy.root) - self.assertEqual(result['virtual_root_path'], ()) - - def test_non_utf8_path_segment_unicode_path_segments_fails(self): - foo = DummyContext() - root = DummyContext(foo) - policy = self._makeOne(root) - segment = unicode('LaPe\xc3\xb1a', 'utf-8').encode('utf-16') - environ = self._getEnviron(PATH_INFO='/%s' % segment) - from repoze.bfg.exceptions import URLDecodeError - self.assertRaises(URLDecodeError, policy, environ) - - def test_non_utf8_path_segment_settings_unicode_path_segments_fails(self): - foo = DummyContext() - root = DummyContext(foo) - policy = self._makeOne(root) - segment = unicode('LaPe\xc3\xb1a', 'utf-8').encode('utf-16') - environ = self._getEnviron(PATH_INFO='/%s' % segment) - from repoze.bfg.exceptions import URLDecodeError - self.assertRaises(URLDecodeError, policy, environ) - - def test_withroute_nothingfancy(self): - model = DummyContext() - traverser = self._makeOne(model) - environ = {'bfg.routes.matchdict': {}} - result = traverser(environ) - self.assertEqual(result['context'], model) - self.assertEqual(result['view_name'], '') - self.assertEqual(result['subpath'], ()) - self.assertEqual(result['traversed'], ()) - self.assertEqual(result['root'], model) - self.assertEqual(result['virtual_root'], model) - self.assertEqual(result['virtual_root_path'], ()) - - def test_withroute_with_subpath_string(self): - model = DummyContext() - traverser = self._makeOne(model) - environ = {'bfg.routes.matchdict': {'subpath':'/a/b/c'}} - result = traverser(environ) - self.assertEqual(result['context'], model) - self.assertEqual(result['view_name'], '') - self.assertEqual(result['subpath'], ('a', 'b','c')) - self.assertEqual(result['traversed'], ()) - self.assertEqual(result['root'], model) - self.assertEqual(result['virtual_root'], model) - self.assertEqual(result['virtual_root_path'], ()) - - def test_withroute_with_subpath_tuple(self): - model = DummyContext() - traverser = self._makeOne(model) - environ = {'bfg.routes.matchdict': {'subpath':('a', 'b', 'c')}} - result = traverser(environ) - self.assertEqual(result['context'], model) - self.assertEqual(result['view_name'], '') - self.assertEqual(result['subpath'], ('a', 'b','c')) - self.assertEqual(result['traversed'], ()) - self.assertEqual(result['root'], model) - self.assertEqual(result['virtual_root'], model) - self.assertEqual(result['virtual_root_path'], ()) - - def test_withroute_and_traverse_string(self): - model = DummyContext() - traverser = self._makeOne(model) - environ = {'bfg.routes.matchdict': {'traverse':'foo/bar'}} - result = traverser(environ) - self.assertEqual(result['context'], model) - self.assertEqual(result['view_name'], 'foo') - self.assertEqual(result['subpath'], ('bar',)) - self.assertEqual(result['traversed'], ()) - self.assertEqual(result['root'], model) - self.assertEqual(result['virtual_root'], model) - self.assertEqual(result['virtual_root_path'], ()) - - def test_withroute_and_traverse_tuple(self): - model = DummyContext() - traverser = self._makeOne(model) - environ = {'bfg.routes.matchdict': {'traverse':('foo', 'bar')}} - result = traverser(environ) - self.assertEqual(result['context'], model) - self.assertEqual(result['view_name'], 'foo') - self.assertEqual(result['subpath'], ('bar',)) - self.assertEqual(result['traversed'], ()) - self.assertEqual(result['root'], model) - self.assertEqual(result['virtual_root'], model) - self.assertEqual(result['virtual_root_path'], ()) - -class FindInterfaceTests(unittest.TestCase): - def _callFUT(self, context, iface): - from repoze.bfg.traversal import find_interface - return find_interface(context, iface) - - def test_it_interface(self): - baz = DummyContext() - bar = DummyContext(baz) - foo = DummyContext(bar) - root = DummyContext(foo) - root.__parent__ = None - root.__name__ = 'root' - foo.__parent__ = root - foo.__name__ = 'foo' - bar.__parent__ = foo - bar.__name__ = 'bar' - baz.__parent__ = bar - baz.__name__ = 'baz' - from zope.interface import directlyProvides - from zope.interface import Interface - class IFoo(Interface): - pass - directlyProvides(root, IFoo) - result = self._callFUT(baz, IFoo) - self.assertEqual(result.__name__, 'root') - - def test_it_class(self): - class DummyRoot(object): - def __init__(self, child): - self.child = child - baz = DummyContext() - bar = DummyContext(baz) - foo = DummyContext(bar) - root = DummyRoot(foo) - root.__parent__ = None - root.__name__ = 'root' - foo.__parent__ = root - foo.__name__ = 'foo' - bar.__parent__ = foo - bar.__name__ = 'bar' - baz.__parent__ = bar - baz.__name__ = 'baz' - result = self._callFUT(baz, DummyRoot) - self.assertEqual(result.__name__, 'root') - -class FindRootTests(unittest.TestCase): - def _callFUT(self, context): - from repoze.bfg.traversal import find_root - return find_root(context) - - def test_it(self): - dummy = DummyContext() - baz = DummyContext() - baz.__parent__ = dummy - baz.__name__ = 'baz' - dummy.__parent__ = None - dummy.__name__ = None - result = self._callFUT(baz) - self.assertEqual(result, dummy) - -class FindModelTests(unittest.TestCase): - def _callFUT(self, context, name): - from repoze.bfg.traversal import find_model - return find_model(context, name) - - def _registerTraverser(self, traverser): - from repoze.bfg.threadlocal import get_current_registry - reg = get_current_registry() - from repoze.bfg.interfaces import ITraverser - from zope.interface import Interface - reg.registerAdapter(traverser, (Interface,), ITraverser) - - def test_list(self): - model = DummyContext() - traverser = make_traverser({'context':model, 'view_name':''}) - self._registerTraverser(traverser) - result = self._callFUT(model, ['']) - self.assertEqual(result, model) - self.assertEqual(model.request.environ['PATH_INFO'], '/') - - def test_generator(self): - model = DummyContext() - traverser = make_traverser({'context':model, 'view_name':''}) - self._registerTraverser(traverser) - def foo(): - yield '' - result = self._callFUT(model, foo()) - self.assertEqual(result, model) - self.assertEqual(model.request.environ['PATH_INFO'], '/') - - def test_self_string_found(self): - model = DummyContext() - traverser = make_traverser({'context':model, 'view_name':''}) - self._registerTraverser(traverser) - result = self._callFUT(model, '') - self.assertEqual(result, model) - self.assertEqual(model.request.environ['PATH_INFO'], '') - - def test_self_tuple_found(self): - model = DummyContext() - traverser = make_traverser({'context':model, 'view_name':''}) - self._registerTraverser(traverser) - result = self._callFUT(model, ()) - self.assertEqual(result, model) - self.assertEqual(model.request.environ['PATH_INFO'], '') - - def test_relative_string_found(self): - model = DummyContext() - baz = DummyContext() - traverser = make_traverser({'context':baz, 'view_name':''}) - self._registerTraverser(traverser) - result = self._callFUT(model, 'baz') - self.assertEqual(result, baz) - self.assertEqual(model.request.environ['PATH_INFO'], 'baz') - - def test_relative_tuple_found(self): - model = DummyContext() - baz = DummyContext() - traverser = make_traverser({'context':baz, 'view_name':''}) - self._registerTraverser(traverser) - result = self._callFUT(model, ('baz',)) - self.assertEqual(result, baz) - self.assertEqual(model.request.environ['PATH_INFO'], 'baz') - - def test_relative_string_notfound(self): - model = DummyContext() - baz = DummyContext() - traverser = make_traverser({'context':baz, 'view_name':'bar'}) - self._registerTraverser(traverser) - self.assertRaises(KeyError, self._callFUT, model, 'baz') - self.assertEqual(model.request.environ['PATH_INFO'], 'baz') - - def test_relative_tuple_notfound(self): - model = DummyContext() - baz = DummyContext() - traverser = make_traverser({'context':baz, 'view_name':'bar'}) - self._registerTraverser(traverser) - self.assertRaises(KeyError, self._callFUT, model, ('baz',)) - self.assertEqual(model.request.environ['PATH_INFO'], 'baz') - - def test_absolute_string_found(self): - root = DummyContext() - model = DummyContext() - model.__parent__ = root - model.__name__ = 'baz' - traverser = make_traverser({'context':root, 'view_name':''}) - self._registerTraverser(traverser) - result = self._callFUT(model, '/') - self.assertEqual(result, root) - self.assertEqual(root.wascontext, True) - self.assertEqual(root.request.environ['PATH_INFO'], '/') - - def test_absolute_tuple_found(self): - root = DummyContext() - model = DummyContext() - model.__parent__ = root - model.__name__ = 'baz' - traverser = make_traverser({'context':root, 'view_name':''}) - self._registerTraverser(traverser) - result = self._callFUT(model, ('',)) - self.assertEqual(result, root) - self.assertEqual(root.wascontext, True) - self.assertEqual(root.request.environ['PATH_INFO'], '/') - - def test_absolute_string_notfound(self): - root = DummyContext() - model = DummyContext() - model.__parent__ = root - model.__name__ = 'baz' - traverser = make_traverser({'context':root, 'view_name':'fuz'}) - self._registerTraverser(traverser) - self.assertRaises(KeyError, self._callFUT, model, '/') - self.assertEqual(root.wascontext, True) - self.assertEqual(root.request.environ['PATH_INFO'], '/') - - def test_absolute_tuple_notfound(self): - root = DummyContext() - model = DummyContext() - model.__parent__ = root - model.__name__ = 'baz' - traverser = make_traverser({'context':root, 'view_name':'fuz'}) - self._registerTraverser(traverser) - self.assertRaises(KeyError, self._callFUT, model, ('',)) - self.assertEqual(root.wascontext, True) - self.assertEqual(root.request.environ['PATH_INFO'], '/') - - -class ModelPathTests(unittest.TestCase): - def _callFUT(self, model, *elements): - from repoze.bfg.traversal import model_path - return model_path(model, *elements) - - def test_it(self): - baz = DummyContext() - bar = DummyContext(baz) - foo = DummyContext(bar) - root = DummyContext(foo) - root.__parent__ = None - root.__name__ = None - foo.__parent__ = root - foo.__name__ = 'foo ' - bar.__parent__ = foo - bar.__name__ = 'bar' - baz.__parent__ = bar - baz.__name__ = 'baz' - result = self._callFUT(baz, 'this/theotherthing', 'that') - self.assertEqual(result, '/foo%20/bar/baz/this%2Ftheotherthing/that') - - def test_root_default(self): - root = DummyContext() - root.__parent__ = None - root.__name__ = None - result = self._callFUT(root) - self.assertEqual(result, '/') - - def test_root_default_emptystring(self): - root = DummyContext() - root.__parent__ = None - root.__name__ = '' - result = self._callFUT(root) - self.assertEqual(result, '/') - - def test_root_object_nonnull_name_direct(self): - root = DummyContext() - root.__parent__ = None - root.__name__ = 'flubadub' - result = self._callFUT(root) - self.assertEqual(result, 'flubadub') # insane case - - def test_root_object_nonnull_name_indirect(self): - root = DummyContext() - root.__parent__ = None - root.__name__ = 'flubadub' - other = DummyContext() - other.__parent__ = root - other.__name__ = 'barker' - result = self._callFUT(other) - self.assertEqual(result, 'flubadub/barker') # insane case - - def test_nonroot_default(self): - root = DummyContext() - root.__parent__ = None - root.__name__ = None - other = DummyContext() - other.__parent__ = root - other.__name__ = 'other' - result = self._callFUT(other) - self.assertEqual(result, '/other') - - def test_path_with_None_itermediate_names(self): - root = DummyContext() - root.__parent__ = None - root.__name__ = None - other = DummyContext() - other.__parent__ = root - other.__name__ = None - other2 = DummyContext() - other2.__parent__ = other - other2.__name__ = 'other2' - result = self._callFUT(other2) - self.assertEqual(result, '//other2') - -class ModelPathTupleTests(unittest.TestCase): - def _callFUT(self, model, *elements): - from repoze.bfg.traversal import model_path_tuple - return model_path_tuple(model, *elements) - - def test_it(self): - baz = DummyContext() - bar = DummyContext(baz) - foo = DummyContext(bar) - root = DummyContext(foo) - root.__parent__ = None - root.__name__ = None - foo.__parent__ = root - foo.__name__ = 'foo ' - bar.__parent__ = foo - bar.__name__ = 'bar' - baz.__parent__ = bar - baz.__name__ = 'baz' - result = self._callFUT(baz, 'this/theotherthing', 'that') - self.assertEqual(result, ('','foo ', 'bar', 'baz', 'this/theotherthing', - 'that')) - - def test_root_default(self): - root = DummyContext() - root.__parent__ = None - root.__name__ = None - result = self._callFUT(root) - self.assertEqual(result, ('',)) - - def test_nonroot_default(self): - root = DummyContext() - root.__parent__ = None - root.__name__ = None - other = DummyContext() - other.__parent__ = root - other.__name__ = 'other' - result = self._callFUT(other) - self.assertEqual(result, ('', 'other')) - - def test_path_with_None_itermediate_names(self): - root = DummyContext() - root.__parent__ = None - root.__name__ = None - other = DummyContext() - other.__parent__ = root - other.__name__ = None - other2 = DummyContext() - other2.__parent__ = other - other2.__name__ = 'other2' - result = self._callFUT(other2) - self.assertEqual(result, ('', '', 'other2')) - -class QuotePathSegmentTests(unittest.TestCase): - def _callFUT(self, s): - from repoze.bfg.traversal import quote_path_segment - return quote_path_segment(s) - - def test_unicode(self): - la = unicode('/La Pe\xc3\xb1a', 'utf-8') - result = self._callFUT(la) - self.assertEqual(result, '%2FLa%20Pe%C3%B1a') - - def test_string(self): - s = '/ hello!' - result = self._callFUT(s) - self.assertEqual(result, '%2F%20hello%21') - -class TraversalContextURLTests(unittest.TestCase): - def _makeOne(self, context, url): - return self._getTargetClass()(context, url) - - def _getTargetClass(self): - from repoze.bfg.traversal import TraversalContextURL - return TraversalContextURL - - def _registerTraverser(self, traverser): - from repoze.bfg.threadlocal import get_current_registry - reg = get_current_registry() - from repoze.bfg.interfaces import ITraverser - from zope.interface import Interface - reg.registerAdapter(traverser, (Interface,), ITraverser) - - def test_class_conforms_to_IContextURL(self): - from zope.interface.verify import verifyClass - from repoze.bfg.interfaces import IContextURL - verifyClass(IContextURL, self._getTargetClass()) - - def test_instance_conforms_to_IContextURL(self): - from zope.interface.verify import verifyObject - from repoze.bfg.interfaces import IContextURL - context = DummyContext() - request = DummyRequest() - verifyObject(IContextURL, self._makeOne(context, request)) - - def test_call_withlineage(self): - baz = DummyContext() - bar = DummyContext(baz) - foo = DummyContext(bar) - root = DummyContext(foo) - root.__parent__ = None - root.__name__ = None - foo.__parent__ = root - foo.__name__ = 'foo ' - bar.__parent__ = foo - bar.__name__ = 'bar' - baz.__parent__ = bar - baz.__name__ = 'baz' - request = DummyRequest() - context_url = self._makeOne(baz, request) - result = context_url() - self.assertEqual(result, 'http://example.com:5432/foo%20/bar/baz/') - - def test_call_nolineage(self): - context = DummyContext() - context.__name__ = '' - context.__parent__ = None - request = DummyRequest() - context_url = self._makeOne(context, request) - result = context_url() - self.assertEqual(result, 'http://example.com:5432/') - - def test_call_unicode_mixed_with_bytes_in_model_names(self): - root = DummyContext() - root.__parent__ = None - root.__name__ = None - one = DummyContext() - one.__parent__ = root - one.__name__ = unicode('La Pe\xc3\xb1a', 'utf-8') - two = DummyContext() - two.__parent__ = one - two.__name__ = 'La Pe\xc3\xb1a' - request = DummyRequest() - context_url = self._makeOne(two, request) - result = context_url() - self.assertEqual(result, - 'http://example.com:5432/La%20Pe%C3%B1a/La%20Pe%C3%B1a/') - - def test_call_with_virtual_root_path(self): - from repoze.bfg.interfaces import VH_ROOT_KEY - root = DummyContext() - root.__parent__ = None - root.__name__ = None - one = DummyContext() - one.__parent__ = root - one.__name__ = 'one' - two = DummyContext() - two.__parent__ = one - two.__name__ = 'two' - request = DummyRequest({VH_ROOT_KEY:'/one'}) - context_url = self._makeOne(two, request) - result = context_url() - self.assertEqual(result, 'http://example.com:5432/two/') - - request = DummyRequest({VH_ROOT_KEY:'/one/two'}) - context_url = self._makeOne(two, request) - result = context_url() - self.assertEqual(result, 'http://example.com:5432/') - - def test_virtual_root_no_virtual_root_path(self): - root = DummyContext() - root.__name__ = None - root.__parent__ = None - one = DummyContext() - one.__name__ = 'one' - one.__parent__ = root - request = DummyRequest() - context_url = self._makeOne(one, request) - self.assertEqual(context_url.virtual_root(), root) - - def test_virtual_root_no_virtual_root_path_with_root_on_request(self): - context = DummyContext() - context.__parent__ = None - request = DummyRequest() - request.root = DummyContext() - context_url = self._makeOne(context, request) - self.assertEqual(context_url.virtual_root(), request.root) - - def test_virtual_root_with_virtual_root_path(self): - from repoze.bfg.interfaces import VH_ROOT_KEY - context = DummyContext() - context.__parent__ = None - traversed_to = DummyContext() - environ = {VH_ROOT_KEY:'/one'} - request = DummyRequest(environ) - traverser = make_traverser({'context':traversed_to, 'view_name':''}) - self._registerTraverser(traverser) - context_url = self._makeOne(context, request) - self.assertEqual(context_url.virtual_root(), traversed_to) - self.assertEqual(context.request.environ['PATH_INFO'], '/one') - - def test_empty_names_not_ignored(self): - bar = DummyContext() - empty = DummyContext(bar) - root = DummyContext(empty) - root.__parent__ = None - root.__name__ = None - empty.__parent__ = root - empty.__name__ = '' - bar.__parent__ = empty - bar.__name__ = 'bar' - request = DummyRequest() - context_url = self._makeOne(bar, request) - result = context_url() - self.assertEqual(result, 'http://example.com:5432//bar/') - -class TestVirtualRoot(unittest.TestCase): - def setUp(self): - cleanUp() - - def tearDown(self): - cleanUp() - - def _callFUT(self, model, request): - from repoze.bfg.traversal import virtual_root - return virtual_root(model, request) - - def test_registered(self): - from repoze.bfg.interfaces import IContextURL - from zope.interface import Interface - request = _makeRequest() - request.registry.registerAdapter(DummyContextURL, (Interface,Interface), - IContextURL) - context = DummyContext() - result = self._callFUT(context, request) - self.assertEqual(result, '123') - - def test_default(self): - context = DummyContext() - request = _makeRequest() - request.environ['PATH_INFO'] = '/' - result = self._callFUT(context, request) - self.assertEqual(result, context) - - def test_default_no_registry_on_request(self): - context = DummyContext() - request = _makeRequest() - del request.registry - request.environ['PATH_INFO'] = '/' - result = self._callFUT(context, request) - self.assertEqual(result, context) - -class TraverseTests(unittest.TestCase): - def setUp(self): - cleanUp() - - def tearDown(self): - cleanUp() - - def _callFUT(self, context, name): - from repoze.bfg.traversal import traverse - return traverse(context, name) - - def _registerTraverser(self, traverser): - from repoze.bfg.threadlocal import get_current_registry - reg = get_current_registry() - from repoze.bfg.interfaces import ITraverser - from zope.interface import Interface - reg.registerAdapter(traverser, (Interface,), ITraverser) - - def test_request_has_registry(self): - from repoze.bfg.threadlocal import get_current_registry - model = DummyContext() - traverser = make_traverser({'context':model, 'view_name':''}) - self._registerTraverser(traverser) - self._callFUT(model, ['']) - self.assertEqual(model.request.registry, get_current_registry()) - - def test_list(self): - model = DummyContext() - traverser = make_traverser({'context':model, 'view_name':''}) - self._registerTraverser(traverser) - self._callFUT(model, ['']) - self.assertEqual(model.request.environ['PATH_INFO'], '/') - - def test_generator(self): - model = DummyContext() - traverser = make_traverser({'context':model, 'view_name':''}) - self._registerTraverser(traverser) - def foo(): - yield '' - self._callFUT(model, foo()) - self.assertEqual(model.request.environ['PATH_INFO'], '/') - - def test_self_string_found(self): - model = DummyContext() - traverser = make_traverser({'context':model, 'view_name':''}) - self._registerTraverser(traverser) - self._callFUT(model, '') - self.assertEqual(model.request.environ['PATH_INFO'], '') - - def test_self_tuple_found(self): - model = DummyContext() - traverser = make_traverser({'context':model, 'view_name':''}) - self._registerTraverser(traverser) - self._callFUT(model, ()) - self.assertEqual(model.request.environ['PATH_INFO'], '') - - def test_relative_string_found(self): - model = DummyContext() - baz = DummyContext() - traverser = make_traverser({'context':baz, 'view_name':''}) - self._registerTraverser(traverser) - self._callFUT(model, 'baz') - self.assertEqual(model.request.environ['PATH_INFO'], 'baz') - - def test_relative_tuple_found(self): - model = DummyContext() - baz = DummyContext() - traverser = make_traverser({'context':baz, 'view_name':''}) - self._registerTraverser(traverser) - self._callFUT(model, ('baz',)) - self.assertEqual(model.request.environ['PATH_INFO'], 'baz') - - def test_absolute_string_found(self): - root = DummyContext() - model = DummyContext() - model.__parent__ = root - model.__name__ = 'baz' - traverser = make_traverser({'context':root, 'view_name':''}) - self._registerTraverser(traverser) - self._callFUT(model, '/') - self.assertEqual(root.wascontext, True) - self.assertEqual(root.request.environ['PATH_INFO'], '/') - - def test_absolute_tuple_found(self): - root = DummyContext() - model = DummyContext() - model.__parent__ = root - model.__name__ = 'baz' - traverser = make_traverser({'context':root, 'view_name':''}) - self._registerTraverser(traverser) - self._callFUT(model, ('',)) - self.assertEqual(root.wascontext, True) - self.assertEqual(root.request.environ['PATH_INFO'], '/') - - def test_empty_sequence(self): - root = DummyContext() - model = DummyContext() - model.__parent__ = root - model.__name__ = 'baz' - traverser = make_traverser({'context':root, 'view_name':''}) - self._registerTraverser(traverser) - self._callFUT(model, []) - self.assertEqual(model.wascontext, True) - self.assertEqual(model.request.environ['PATH_INFO'], '') - - def test_default_traverser(self): - model = DummyContext() - result = self._callFUT(model, '') - self.assertEqual(result['view_name'], '') - self.assertEqual(result['context'], model) - - def test_requestfactory_overridden(self): - from repoze.bfg.interfaces import IRequestFactory - from repoze.bfg.request import Request - from repoze.bfg.threadlocal import get_current_registry - reg = get_current_registry() - class MyRequest(Request): - pass - reg.registerUtility(MyRequest, IRequestFactory) - model = DummyContext() - traverser = make_traverser({'context':model, 'view_name':''}) - self._registerTraverser(traverser) - self._callFUT(model, ['']) - self.assertEqual(model.request.__class__, MyRequest) - -class TestDefaultRootFactory(unittest.TestCase): - def _getTargetClass(self): - from repoze.bfg.traversal import DefaultRootFactory - return DefaultRootFactory - - def _makeOne(self, environ): - return self._getTargetClass()(environ) - - def test_no_matchdict(self): - environ = {} - root = self._makeOne(environ) - self.assertEqual(root.__parent__, None) - self.assertEqual(root.__name__, None) - - def test_matchdict(self): - class DummyRequest: - pass - request = DummyRequest() - request.matchdict = {'a':1, 'b':2} - root = self._makeOne(request) - self.assertEqual(root.a, 1) - self.assertEqual(root.b, 2) - - -def make_traverser(result): - class DummyTraverser(object): - def __init__(self, context): - self.context = context - context.wascontext = True - def __call__(self, request): - self.context.request = request - return result - return DummyTraverser - -class DummyContext(object): - __parent__ = None - def __init__(self, next=None, name=None): - self.next = next - self.__name__ = name - - def __getitem__(self, name): - if self.next is None: - raise KeyError, name - return self.next - - def __repr__(self): - return '<DummyContext with name %s at id %s>'%(self.__name__, id(self)) - -class DummyRequest: - application_url = 'http://example.com:5432' # app_url never ends with slash - def __init__(self, environ=None): - if environ is None: - environ = {} - self.environ = environ - -class DummyContextURL: - def __init__(self, context, request): - pass - - def virtual_root(self): - return '123' - -def _makeRequest(environ=None): - from repoze.bfg.registry import Registry - request = DummyRequest() - request.registry = Registry() - return request diff --git a/repoze/bfg/tests/test_url.py b/repoze/bfg/tests/test_url.py deleted file mode 100644 index 1b6f7814c..000000000 --- a/repoze/bfg/tests/test_url.py +++ /dev/null @@ -1,304 +0,0 @@ -import unittest - -from repoze.bfg.testing import cleanUp - -class ModelURLTests(unittest.TestCase): - def setUp(self): - cleanUp() - - def tearDown(self): - cleanUp() - - def _callFUT(self, model, request, *elements, **kw): - from repoze.bfg.url import model_url - return model_url(model, request, *elements, **kw) - - def _registerContextURL(self, reg): - from repoze.bfg.interfaces import IContextURL - from zope.interface import Interface - class DummyContextURL(object): - def __init__(self, context, request): - pass - def __call__(self): - return 'http://example.com/context/' - reg.registerAdapter(DummyContextURL, (Interface, Interface), - IContextURL) - - def test_root_default(self): - request = _makeRequest() - self._registerContextURL(request.registry) - root = DummyContext() - result = self._callFUT(root, request) - self.assertEqual(result, 'http://example.com/context/') - - def test_extra_args(self): - request = _makeRequest() - self._registerContextURL(request.registry) - context = DummyContext() - result = self._callFUT(context, request, 'this/theotherthing', 'that') - self.assertEqual( - result, - 'http://example.com/context/this%2Ftheotherthing/that') - - def test_unicode_in_element_names(self): - request = _makeRequest() - self._registerContextURL(request.registry) - uc = unicode('La Pe\xc3\xb1a', 'utf-8') - context = DummyContext() - result = self._callFUT(context, request, uc) - self.assertEqual(result, - 'http://example.com/context/La%20Pe%C3%B1a') - - def test_element_names_url_quoted(self): - request = _makeRequest() - self._registerContextURL(request.registry) - context = DummyContext() - result = self._callFUT(context, request, 'a b c') - self.assertEqual(result, 'http://example.com/context/a%20b%20c') - - def test_with_query_dict(self): - request = _makeRequest() - self._registerContextURL(request.registry) - context = DummyContext() - uc = unicode('La Pe\xc3\xb1a', 'utf-8') - result = self._callFUT(context, request, 'a', query={'a':uc}) - self.assertEqual(result, - 'http://example.com/context/a?a=La+Pe%C3%B1a') - - def test_with_query_seq(self): - request = _makeRequest() - self._registerContextURL(request.registry) - context = DummyContext() - uc = unicode('La Pe\xc3\xb1a', 'utf-8') - result = self._callFUT(context, request, 'a', query=[('a', 'hi there'), - ('b', uc)]) - self.assertEqual(result, - 'http://example.com/context/a?a=hi+there&b=La+Pe%C3%B1a') - - def test_anchor_is_after_root_when_no_elements(self): - request = _makeRequest() - self._registerContextURL(request.registry) - context = DummyContext() - result = self._callFUT(context, request, anchor='a') - self.assertEqual(result, - 'http://example.com/context/#a') - - def test_anchor_is_after_elements_when_no_qs(self): - request = _makeRequest() - self._registerContextURL(request.registry) - context = DummyContext() - result = self._callFUT(context, request, 'a', anchor='b') - self.assertEqual(result, - 'http://example.com/context/a#b') - - def test_anchor_is_after_qs_when_qs_is_present(self): - request = _makeRequest() - self._registerContextURL(request.registry) - context = DummyContext() - result = self._callFUT(context, request, 'a', - query={'b':'c'}, anchor='d') - self.assertEqual(result, - 'http://example.com/context/a?b=c#d') - - def test_anchor_is_encoded_utf8_if_unicode(self): - request = _makeRequest() - self._registerContextURL(request.registry) - context = DummyContext() - uc = unicode('La Pe\xc3\xb1a', 'utf-8') - result = self._callFUT(context, request, anchor=uc) - self.assertEqual(result, - 'http://example.com/context/#La Pe\xc3\xb1a') - - def test_anchor_is_not_urlencoded(self): - request = _makeRequest() - self._registerContextURL(request.registry) - context = DummyContext() - result = self._callFUT(context, request, anchor=' /#') - self.assertEqual(result, - 'http://example.com/context/# /#') - - def test_no_IContextURL_registered(self): - # falls back to TraversalContextURL - root = DummyContext() - root.__name__ = '' - root.__parent__ = None - request = _makeRequest() - request.environ = {} - result = self._callFUT(root, request) - self.assertEqual(result, 'http://example.com:5432/') - - def test_no_registry_on_request(self): - from repoze.bfg.threadlocal import get_current_registry - reg = get_current_registry() - request = DummyRequest() - self._registerContextURL(reg) - root = DummyContext() - result = self._callFUT(root, request) - self.assertEqual(result, 'http://example.com/context/') - -class TestRouteUrl(unittest.TestCase): - def setUp(self): - cleanUp() - - def tearDown(self): - cleanUp() - - def _callFUT(self, *arg, **kw): - from repoze.bfg.url import route_url - return route_url(*arg, **kw) - - def test_with_elements(self): - from repoze.bfg.interfaces import IRoutesMapper - request = _makeRequest() - mapper = DummyRoutesMapper(route=DummyRoute('/1/2/3')) - request.registry.registerUtility(mapper, IRoutesMapper) - result = self._callFUT('flub', request, 'extra1', 'extra2', - a=1, b=2, c=3, _query={'a':1}, - _anchor=u"foo") - self.assertEqual(result, - 'http://example.com:5432/1/2/3/extra1/extra2?a=1#foo') - - def test_no_elements(self): - from repoze.bfg.interfaces import IRoutesMapper - request = _makeRequest() - mapper = DummyRoutesMapper(route=DummyRoute('/1/2/3')) - request.registry.registerUtility(mapper, IRoutesMapper) - result = self._callFUT('flub', request, a=1, b=2, c=3, _query={'a':1}, - _anchor=u"foo") - self.assertEqual(result, - 'http://example.com:5432/1/2/3?a=1#foo') - - def test_it_generation_error(self): - from repoze.bfg.interfaces import IRoutesMapper - request = _makeRequest() - mapper = DummyRoutesMapper(raise_exc=KeyError) - request.registry.registerUtility(mapper, IRoutesMapper) - mapper.raise_exc = KeyError - self.assertRaises(KeyError, self._callFUT, 'flub', request, a=1) - - def test_generate_doesnt_receive_query_or_anchor(self): - from repoze.bfg.interfaces import IRoutesMapper - route = DummyRoute(result='') - mapper = DummyRoutesMapper(route=route) - from zope.component import getSiteManager - sm = getSiteManager() - sm.registerUtility(mapper, IRoutesMapper) - request = DummyRequest() - result = self._callFUT('flub', request, _query=dict(name='some_name')) - self.assertEqual(route.kw, {}) # shouldnt have anchor/query - self.assertEqual(result, 'http://example.com:5432?name=some_name') - - def test_with_app_url(self): - from repoze.bfg.interfaces import IRoutesMapper - request = _makeRequest() - mapper = DummyRoutesMapper(route=DummyRoute(result='/1/2/3')) - request.registry.registerUtility(mapper, IRoutesMapper) - result = self._callFUT('flub', request, _app_url='http://example2.com') - self.assertEqual(result, 'http://example2.com/1/2/3') - - def test_with_pregenerator(self): - from repoze.bfg.interfaces import IRoutesMapper - request = _makeRequest() - route = DummyRoute(result='/1/2/3') - def pregenerator(request, elements, kw): - return ('a',), {'_app_url':'http://example2.com'} - route.pregenerator = pregenerator - mapper = DummyRoutesMapper(route=route) - request.registry.registerUtility(mapper, IRoutesMapper) - result = self._callFUT('flub', request) - self.assertEqual(result, 'http://example2.com/1/2/3/a') - self.assertEqual(route.kw, {}) # shouldnt have anchor/query - -class TestStaticUrl(unittest.TestCase): - def setUp(self): - cleanUp() - - def tearDown(self): - cleanUp() - - def _callFUT(self, *arg, **kw): - from repoze.bfg.url import static_url - return static_url(*arg, **kw) - - def test_staticurlinfo_notfound(self): - request = _makeRequest() - self.assertRaises(ValueError, self._callFUT, 'static/foo.css', request) - - def test_abspath(self): - request = _makeRequest() - self.assertRaises(ValueError, self._callFUT, '/static/foo.css', request) - - def test_found_rel(self): - from repoze.bfg.interfaces import IStaticURLInfo - request = _makeRequest() - info = DummyStaticURLInfo('abc') - request.registry.registerUtility(info, IStaticURLInfo) - result = self._callFUT('static/foo.css', request) - self.assertEqual(result, 'abc') - self.assertEqual(info.args, - ('repoze.bfg.tests:static/foo.css', request, {}) ) - - def test_found_abs(self): - from repoze.bfg.interfaces import IStaticURLInfo - request = _makeRequest() - info = DummyStaticURLInfo('abc') - request.registry.registerUtility(info, IStaticURLInfo) - result = self._callFUT('repoze.bfg.tests:static/foo.css', request) - self.assertEqual(result, 'abc') - self.assertEqual(info.args, - ('repoze.bfg.tests:static/foo.css', request, {}) ) - - def test_found_abs_no_registry_on_request(self): - from repoze.bfg.threadlocal import get_current_registry - from repoze.bfg.interfaces import IStaticURLInfo - request = DummyRequest() - registry = get_current_registry() - info = DummyStaticURLInfo('abc') - registry.registerUtility(info, IStaticURLInfo) - result = self._callFUT('repoze.bfg.tests:static/foo.css', request) - self.assertEqual(result, 'abc') - self.assertEqual(info.args, - ('repoze.bfg.tests:static/foo.css', request, {}) ) - -class DummyContext(object): - def __init__(self, next=None): - self.next = next - -class DummyRequest: - application_url = 'http://example.com:5432' # app_url never ends with slash - def __init__(self, environ=None): - if environ is None: - environ = {} - self.environ = environ - -class DummyRoutesMapper: - raise_exc = None - def __init__(self, route=None, raise_exc=False): - self.route = route - - def get_route(self, route_name): - return self.route - -class DummyRoute: - pregenerator = None - def __init__(self, result='/1/2/3'): - self.result = result - - def generate(self, kw): - self.kw = kw - return self.result - -def _makeRequest(environ=None): - from repoze.bfg.registry import Registry - request = DummyRequest(environ) - request.registry = Registry() - return request - -class DummyStaticURLInfo: - def __init__(self, result): - self.result = result - - def generate(self, path, request, **kw): - self.args = path, request, kw - return self.result - diff --git a/repoze/bfg/tests/test_urldispatch.py b/repoze/bfg/tests/test_urldispatch.py deleted file mode 100644 index bf43750ea..000000000 --- a/repoze/bfg/tests/test_urldispatch.py +++ /dev/null @@ -1,318 +0,0 @@ -import unittest -from repoze.bfg import testing - -class TestRoute(unittest.TestCase): - def _getTargetClass(self): - from repoze.bfg.urldispatch import Route - return Route - - def _makeOne(self, *arg): - return self._getTargetClass()(*arg) - - def test_provides_IRoute(self): - from repoze.bfg.interfaces import IRoute - from zope.interface.verify import verifyObject - verifyObject(IRoute, self._makeOne('name', 'pattern')) - - def test_ctor(self): - import types - route = self._makeOne('name', ':path', 'factory') - self.assertEqual(route.pattern, ':path') - self.assertEqual(route.path, ':path') - self.assertEqual(route.name, 'name') - self.assertEqual(route.factory, 'factory') - self.failUnless(route.generate.__class__ is types.FunctionType) - self.failUnless(route.match.__class__ is types.FunctionType) - - def test_ctor_defaults(self): - import types - route = self._makeOne('name', ':path') - self.assertEqual(route.pattern, ':path') - self.assertEqual(route.path, ':path') - self.assertEqual(route.name, 'name') - self.assertEqual(route.factory, None) - self.failUnless(route.generate.__class__ is types.FunctionType) - self.failUnless(route.match.__class__ is types.FunctionType) - - def test_match(self): - route = self._makeOne('name', ':path') - self.assertEqual(route.match('/whatever'), {'path':'whatever'}) - - def test_generate(self): - route = self._makeOne('name', ':path') - self.assertEqual(route.generate({'path':'abc'}), '/abc') - -class RoutesMapperTests(unittest.TestCase): - def setUp(self): - testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _getRequest(self, **kw): - from repoze.bfg.threadlocal import get_current_registry - environ = {'SERVER_NAME':'localhost', - 'wsgi.url_scheme':'http'} - environ.update(kw) - request = DummyRequest(environ) - reg = get_current_registry() - request.registry = reg - return request - - def _getTargetClass(self): - from repoze.bfg.urldispatch import RoutesMapper - return RoutesMapper - - def _makeOne(self): - klass = self._getTargetClass() - return klass() - - def test_provides_IRoutesMapper(self): - from repoze.bfg.interfaces import IRoutesMapper - from zope.interface.verify import verifyObject - verifyObject(IRoutesMapper, self._makeOne()) - - def test_no_route_matches(self): - mapper = self._makeOne() - request = self._getRequest(PATH_INFO='/') - result = mapper(request) - self.assertEqual(result['match'], None) - self.assertEqual(result['route'], None) - - def test_connect_name_exists_removes_old(self): - mapper = self._makeOne() - mapper.connect('foo', 'archives/:action/:article') - mapper.connect('foo', 'archives/:action/:article2') - self.assertEqual(len(mapper.routelist), 1) - self.assertEqual(len(mapper.routes), 1) - self.assertEqual(mapper.routes['foo'].pattern, - 'archives/:action/:article2') - self.assertEqual(mapper.routelist[0].pattern, - 'archives/:action/:article2') - - def test___call__route_matches(self): - mapper = self._makeOne() - mapper.connect('foo', 'archives/:action/:article') - request = self._getRequest(PATH_INFO='/archives/action1/article1') - result = mapper(request) - self.assertEqual(result['route'], mapper.routes['foo']) - self.assertEqual(result['match']['action'], 'action1') - self.assertEqual(result['match']['article'], 'article1') - - def test___call__route_matches_with_predicates(self): - mapper = self._makeOne() - mapper.connect('foo', 'archives/:action/:article', - predicates=[lambda *arg: True]) - request = self._getRequest(PATH_INFO='/archives/action1/article1') - result = mapper(request) - self.assertEqual(result['route'], mapper.routes['foo']) - self.assertEqual(result['match']['action'], 'action1') - self.assertEqual(result['match']['article'], 'article1') - - def test___call__route_fails_to_match_with_predicates(self): - mapper = self._makeOne() - mapper.connect('foo', 'archives/:action/article1', - predicates=[lambda *arg: True, lambda *arg: False]) - mapper.connect('bar', 'archives/:action/:article') - request = self._getRequest(PATH_INFO='/archives/action1/article1') - result = mapper(request) - self.assertEqual(result['route'], mapper.routes['bar']) - self.assertEqual(result['match']['action'], 'action1') - self.assertEqual(result['match']['article'], 'article1') - - def test___call__custom_predicate_gets_info(self): - mapper = self._makeOne() - def pred(info, request): - self.assertEqual(info['match'], {'action':u'action1'}) - self.assertEqual(info['route'], mapper.routes['foo']) - return True - mapper.connect('foo', 'archives/:action/article1', predicates=[pred]) - request = self._getRequest(PATH_INFO='/archives/action1/article1') - mapper(request) - - def test_cc_bug(self): - # "unordered" as reported in IRC by author of - # http://labs.creativecommons.org/2010/01/13/cc-engine-and-web-non-frameworks/ - mapper = self._makeOne() - mapper.connect('rdf', 'licenses/:license_code/:license_version/rdf') - mapper.connect('juri', - 'licenses/:license_code/:license_version/:jurisdiction') - - request = self._getRequest(PATH_INFO='/licenses/1/v2/rdf') - result = mapper(request) - self.assertEqual(result['route'], mapper.routes['rdf']) - self.assertEqual(result['match']['license_code'], '1') - self.assertEqual(result['match']['license_version'], 'v2') - - request = self._getRequest(PATH_INFO='/licenses/1/v2/usa') - result = mapper(request) - self.assertEqual(result['route'], mapper.routes['juri']) - self.assertEqual(result['match']['license_code'], '1') - self.assertEqual(result['match']['license_version'], 'v2') - self.assertEqual(result['match']['jurisdiction'], 'usa') - - def test___call__root_route_matches(self): - mapper = self._makeOne() - mapper.connect('root', '') - request = self._getRequest(PATH_INFO='/') - result = mapper(request) - self.assertEqual(result['route'], mapper.routes['root']) - self.assertEqual(result['match'], {}) - - def test___call__root_route_matches2(self): - mapper = self._makeOne() - mapper.connect('root', '/') - request = self._getRequest(PATH_INFO='/') - result = mapper(request) - self.assertEqual(result['route'], mapper.routes['root']) - self.assertEqual(result['match'], {}) - - def test___call__root_route_when_path_info_empty(self): - mapper = self._makeOne() - mapper.connect('root', '/') - request = self._getRequest(PATH_INFO='') - result = mapper(request) - self.assertEqual(result['route'], mapper.routes['root']) - self.assertEqual(result['match'], {}) - - def test___call__no_path_info(self): - mapper = self._makeOne() - mapper.connect('root', '/') - request = self._getRequest() - result = mapper(request) - self.assertEqual(result['route'], mapper.routes['root']) - self.assertEqual(result['match'], {}) - - def test_has_routes(self): - mapper = self._makeOne() - self.assertEqual(mapper.has_routes(), False) - mapper.connect('whatever', 'archives/:action/:article') - self.assertEqual(mapper.has_routes(), True) - - def test_get_routes(self): - from repoze.bfg.urldispatch import Route - mapper = self._makeOne() - self.assertEqual(mapper.get_routes(), []) - mapper.connect('whatever', 'archives/:action/:article') - routes = mapper.get_routes() - self.assertEqual(len(routes), 1) - self.assertEqual(routes[0].__class__, Route) - - def test_get_route_matches(self): - mapper = self._makeOne() - mapper.connect('whatever', 'archives/:action/:article') - result = mapper.get_route('whatever') - self.assertEqual(result.pattern, 'archives/:action/:article') - - def test_get_route_misses(self): - mapper = self._makeOne() - result = mapper.get_route('whatever') - self.assertEqual(result, None) - - def test_generate(self): - mapper = self._makeOne() - def generator(kw): - return 123 - route = DummyRoute(generator) - mapper.routes['abc'] = route - self.assertEqual(mapper.generate('abc', {}), 123) - -class TestCompileRoute(unittest.TestCase): - def _callFUT(self, pattern): - from repoze.bfg.urldispatch import _compile_route - return _compile_route(pattern) - - def test_no_star(self): - matcher, generator = self._callFUT('/foo/:baz/biz/:buz/bar') - self.assertEqual(matcher('/foo/baz/biz/buz/bar'), - {'baz':'baz', 'buz':'buz'}) - self.assertEqual(matcher('foo/baz/biz/buz/bar'), None) - self.assertEqual(generator({'baz':1, 'buz':2}), '/foo/1/biz/2/bar') - - def test_with_star(self): - matcher, generator = self._callFUT('/foo/:baz/biz/:buz/bar*traverse') - self.assertEqual(matcher('/foo/baz/biz/buz/bar'), - {'baz':'baz', 'buz':'buz', 'traverse':()}) - self.assertEqual(matcher('/foo/baz/biz/buz/bar/everything/else/here'), - {'baz':'baz', 'buz':'buz', - 'traverse':('everything', 'else', 'here')}) - self.assertEqual(matcher('foo/baz/biz/buz/bar'), None) - self.assertEqual(generator( - {'baz':1, 'buz':2, 'traverse':u'/a/b'}), '/foo/1/biz/2/bar/a/b') - - def test_no_beginning_slash(self): - matcher, generator = self._callFUT('foo/:baz/biz/:buz/bar') - self.assertEqual(matcher('/foo/baz/biz/buz/bar'), - {'baz':'baz', 'buz':'buz'}) - self.assertEqual(matcher('foo/baz/biz/buz/bar'), None) - self.assertEqual(generator({'baz':1, 'buz':2}), '/foo/1/biz/2/bar') - - def test_url_decode_error(self): - from repoze.bfg.exceptions import URLDecodeError - matcher, generator = self._callFUT('/:foo') - self.assertRaises(URLDecodeError, matcher, '/%FF%FE%8B%00') - -class TestCompileRouteMatchFunctional(unittest.TestCase): - def matches(self, pattern, path, expected): - from repoze.bfg.urldispatch import _compile_route - matcher = _compile_route(pattern)[0] - result = matcher(path) - self.assertEqual(result, expected) - - def generates(self, pattern, dict, result): - from repoze.bfg.urldispatch import _compile_route - self.assertEqual(_compile_route(pattern)[1](dict), result) - - def test_matcher_functional(self): - self.matches('/', '', None) - self.matches('', '', None) - self.matches('/', '/foo', None) - self.matches('/foo/', '/foo', None) - self.matches('/:x', '', None) - self.matches('/:x', '/', None) - self.matches('/abc/:def', '/abc/', None) - self.matches('/abc/:def:baz', '/abc/bleep', None) # bad pattern - self.matches('', '/', {}) - self.matches('/', '/', {}) - self.matches('/:x', '/a', {'x':'a'}) - self.matches('zzz/:x', '/zzz/abc', {'x':'abc'}) - self.matches('zzz/:x*traverse', '/zzz/abc', {'x':'abc', 'traverse':()}) - self.matches('zzz/:x*traverse', '/zzz/abc/def/g', - {'x':'abc', 'traverse':('def', 'g')}) - self.matches('*traverse', '/zzz/abc', {'traverse':('zzz', 'abc')}) - self.matches('*traverse', '/zzz/%20abc', {'traverse':('zzz', ' abc')}) - self.matches(':x', '/La%20Pe%C3%B1a', {'x':u'La Pe\xf1a'}) - self.matches('*traverse', '/La%20Pe%C3%B1a/x', - {'traverse':(u'La Pe\xf1a', 'x')}) - self.matches('/foo/:id.html', '/foo/bar.html', {'id':'bar'}) - - def test_generator_functional(self): - self.generates('', {}, '/') - self.generates('/', {}, '/') - self.generates('/:x', {'x':''}, '/') - self.generates('/:x', {'x':'a'}, '/a') - self.generates('zzz/:x', {'x':'abc'}, '/zzz/abc') - self.generates('zzz/:x*traverse', {'x':'abc', 'traverse':''}, - '/zzz/abc') - self.generates('zzz/:x*traverse', {'x':'abc', 'traverse':'/def/g'}, - '/zzz/abc/def/g') - self.generates('/:x', {'x':unicode('/La Pe\xc3\xb1a', 'utf-8')}, - '/%2FLa%20Pe%C3%B1a') - self.generates('/:x*y', {'x':unicode('/La Pe\xc3\xb1a', 'utf-8'), - 'y':'/rest/of/path'}, - '/%2FLa%20Pe%C3%B1a/rest/of/path') - self.generates('*traverse', {'traverse':('a', u'La Pe\xf1a')}, - '/a/La%20Pe%C3%B1a') - self.generates('/foo/:id.html', {'id':'bar'}, '/foo/bar.html') - -class DummyContext(object): - """ """ - -class DummyRequest(object): - def __init__(self, environ): - self.environ = environ - -class DummyRoute(object): - def __init__(self, generator): - self.generate = generator - diff --git a/repoze/bfg/tests/test_view.py b/repoze/bfg/tests/test_view.py deleted file mode 100644 index e5adc8de1..000000000 --- a/repoze/bfg/tests/test_view.py +++ /dev/null @@ -1,499 +0,0 @@ -import unittest -import sys - -from repoze.bfg.testing import cleanUp - -class BaseTest(object): - def setUp(self): - cleanUp() - - def tearDown(self): - cleanUp() - - def _registerView(self, reg, app, name): - from repoze.bfg.interfaces import IRequest - from repoze.bfg.interfaces import IViewClassifier - for_ = (IViewClassifier, IRequest, IContext) - from repoze.bfg.interfaces import IView - reg.registerAdapter(app, for_, IView, name) - - def _makeEnviron(self, **extras): - environ = { - 'wsgi.url_scheme':'http', - 'wsgi.version':(1,0), - 'SERVER_NAME':'localhost', - 'SERVER_PORT':'8080', - 'REQUEST_METHOD':'GET', - } - environ.update(extras) - return environ - - def _makeRequest(self, **environ): - from repoze.bfg.interfaces import IRequest - from zope.interface import directlyProvides - from webob import Request - from repoze.bfg.registry import Registry - environ = self._makeEnviron(**environ) - request = Request(environ) - request.registry = Registry() - directlyProvides(request, IRequest) - return request - - def _makeContext(self): - from zope.interface import directlyProvides - context = DummyContext() - directlyProvides(context, IContext) - return context - - -class RenderViewToResponseTests(BaseTest, unittest.TestCase): - def _callFUT(self, *arg, **kw): - from repoze.bfg.view import render_view_to_response - return render_view_to_response(*arg, **kw) - - def test_call_no_view_registered(self): - request = self._makeRequest() - context = self._makeContext() - result = self._callFUT(context, request, name='notregistered') - self.assertEqual(result, None) - - def test_call_no_registry_on_request(self): - request = self._makeRequest() - del request.registry - context = self._makeContext() - result = self._callFUT(context, request, name='notregistered') - self.assertEqual(result, None) - - def test_call_view_registered_secure(self): - request = self._makeRequest() - context = self._makeContext() - response = DummyResponse() - view = make_view(response) - self._registerView(request.registry, view, 'registered') - response = self._callFUT(context, request, name='registered', - secure=True) - self.assertEqual(response.status, '200 OK') - - def test_call_view_registered_insecure_no_call_permissive(self): - context = self._makeContext() - request = self._makeRequest() - response = DummyResponse() - view = make_view(response) - self._registerView(request.registry, view, 'registered') - response = self._callFUT(context, request, name='registered', - secure=False) - self.assertEqual(response.status, '200 OK') - - def test_call_view_registered_insecure_with_call_permissive(self): - context = self._makeContext() - request = self._makeRequest() - response = DummyResponse() - view = make_view(response) - def anotherview(context, request): - return DummyResponse('anotherview') - view.__call_permissive__ = anotherview - self._registerView(request.registry, view, 'registered') - response = self._callFUT(context, request, name='registered', - secure=False) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.app_iter, ['anotherview']) - -class RenderViewToIterableTests(BaseTest, unittest.TestCase): - def _callFUT(self, *arg, **kw): - from repoze.bfg.view import render_view_to_iterable - return render_view_to_iterable(*arg, **kw) - - def test_call_no_view_registered(self): - request = self._makeRequest() - context = self._makeContext() - result = self._callFUT(context, request, name='notregistered') - self.assertEqual(result, None) - - def test_call_view_registered_secure(self): - request = self._makeRequest() - context = self._makeContext() - response = DummyResponse() - view = make_view(response) - self._registerView(request.registry, view, 'registered') - iterable = self._callFUT(context, request, name='registered', - secure=True) - self.assertEqual(iterable, ()) - - def test_call_view_registered_insecure_no_call_permissive(self): - context = self._makeContext() - request = self._makeRequest() - response = DummyResponse() - view = make_view(response) - self._registerView(request.registry, view, 'registered') - iterable = self._callFUT(context, request, name='registered', - secure=False) - self.assertEqual(iterable, ()) - - def test_call_view_registered_insecure_with_call_permissive(self): - context = self._makeContext() - request = self._makeRequest() - response = DummyResponse() - view = make_view(response) - def anotherview(context, request): - return DummyResponse('anotherview') - view.__call_permissive__ = anotherview - self._registerView(request.registry, view, 'registered') - iterable = self._callFUT(context, request, name='registered', - secure=False) - self.assertEqual(iterable, ['anotherview']) - -class RenderViewTests(BaseTest, unittest.TestCase): - def _callFUT(self, *arg, **kw): - from repoze.bfg.view import render_view - return render_view(*arg, **kw) - - def test_call_no_view_registered(self): - request = self._makeRequest() - context = self._makeContext() - result = self._callFUT(context, request, name='notregistered') - self.assertEqual(result, None) - - def test_call_view_registered_secure(self): - request = self._makeRequest() - context = self._makeContext() - response = DummyResponse() - view = make_view(response) - self._registerView(request.registry, view, 'registered') - s = self._callFUT(context, request, name='registered', secure=True) - self.assertEqual(s, '') - - def test_call_view_registered_insecure_no_call_permissive(self): - context = self._makeContext() - request = self._makeRequest() - response = DummyResponse() - view = make_view(response) - self._registerView(request.registry, view, 'registered') - s = self._callFUT(context, request, name='registered', secure=False) - self.assertEqual(s, '') - - def test_call_view_registered_insecure_with_call_permissive(self): - context = self._makeContext() - request = self._makeRequest() - response = DummyResponse() - view = make_view(response) - def anotherview(context, request): - return DummyResponse('anotherview') - view.__call_permissive__ = anotherview - self._registerView(request.registry, view, 'registered') - s = self._callFUT(context, request, name='registered', secure=False) - self.assertEqual(s, 'anotherview') - -class TestIsResponse(unittest.TestCase): - def _callFUT(self, *arg, **kw): - from repoze.bfg.view import is_response - return is_response(*arg, **kw) - - def test_is(self): - response = DummyResponse() - self.assertEqual(self._callFUT(response), True) - - def test_isnt(self): - response = None - self.assertEqual(self._callFUT(response), False) - - def test_partial_inst(self): - response = DummyResponse() - response.app_iter = None - self.assertEqual(self._callFUT(response), False) - - def test_status_not_string(self): - response = DummyResponse() - response.status = None - self.assertEqual(self._callFUT(response), False) - -class TestBFGViewDecorator(unittest.TestCase): - def setUp(self): - cleanUp() - - def tearDown(self): - cleanUp() - - def _getTargetClass(self): - from repoze.bfg.view import bfg_view - return bfg_view - - def _makeOne(self, *arg, **kw): - return self._getTargetClass()(*arg, **kw) - - def test_create_defaults(self): - decorator = self._makeOne() - self.assertEqual(decorator.name, '') - self.assertEqual(decorator.request_type, None) - self.assertEqual(decorator.context, None) - self.assertEqual(decorator.permission, None) - - def test_create_nondefaults(self): - decorator = self._makeOne(name=None, request_type=None, for_=None, - permission='foo') - self.assertEqual(decorator.name, None) - self.assertEqual(decorator.request_type, None) - self.assertEqual(decorator.context, None) - self.assertEqual(decorator.permission, 'foo') - - def test_call_function(self): - decorator = self._makeOne() - venusian = DummyVenusian() - decorator.venusian = venusian - def foo(): pass - wrapped = decorator(foo) - self.failUnless(wrapped is foo) - settings = call_venusian(venusian) - self.assertEqual(len(settings), 1) - self.assertEqual(settings[0]['permission'], None) - self.assertEqual(settings[0]['context'], None) - self.assertEqual(settings[0]['request_type'], None) - - def test_call_class(self): - decorator = self._makeOne() - venusian = DummyVenusian() - decorator.venusian = venusian - decorator.venusian.info.scope = 'class' - class foo(object): pass - wrapped = decorator(foo) - self.failUnless(wrapped is foo) - settings = call_venusian(venusian) - self.assertEqual(len(settings), 1) - self.assertEqual(settings[0]['permission'], None) - self.assertEqual(settings[0]['context'], None) - self.assertEqual(settings[0]['request_type'], None) - - def test_stacking(self): - decorator1 = self._makeOne(name='1') - venusian1 = DummyVenusian() - decorator1.venusian = venusian1 - venusian2 = DummyVenusian() - decorator2 = self._makeOne(name='2') - decorator2.venusian = venusian2 - def foo(): pass - wrapped1 = decorator1(foo) - wrapped2 = decorator2(wrapped1) - self.failUnless(wrapped1 is foo) - self.failUnless(wrapped2 is foo) - settings1 = call_venusian(venusian1) - self.assertEqual(len(settings1), 1) - self.assertEqual(settings1[0]['name'], '1') - settings2 = call_venusian(venusian2) - self.assertEqual(len(settings2), 1) - self.assertEqual(settings2[0]['name'], '2') - - def test_call_as_method(self): - decorator = self._makeOne() - venusian = DummyVenusian() - decorator.venusian = venusian - decorator.venusian.info.scope = 'class' - def foo(self): pass - def bar(self): pass - class foo(object): - foomethod = decorator(foo) - barmethod = decorator(bar) - settings = call_venusian(venusian) - self.assertEqual(len(settings), 2) - self.assertEqual(settings[0]['attr'], 'foo') - self.assertEqual(settings[1]['attr'], 'bar') - - def test_with_custom_predicates(self): - decorator = self._makeOne(custom_predicates=(1,)) - venusian = DummyVenusian() - decorator.venusian = venusian - def foo(context, request): pass - decorated = decorator(foo) - self.failUnless(decorated is foo) - settings = call_venusian(venusian) - self.assertEqual(settings[0]['custom_predicates'], (1,)) - - def test_call_with_renderer_nodot(self): - decorator = self._makeOne(renderer='json') - venusian = DummyVenusian() - decorator.venusian = venusian - def foo(): pass - wrapped = decorator(foo) - self.failUnless(wrapped is foo) - settings = call_venusian(venusian) - self.assertEqual(len(settings), 1) - self.assertEqual(settings[0]['renderer'], 'json') - - def test_call_with_renderer_relpath(self): - decorator = self._makeOne(renderer='fixtures/minimal.pt') - venusian = DummyVenusian() - decorator.venusian = venusian - def foo(): pass - wrapped = decorator(foo) - self.failUnless(wrapped is foo) - settings = call_venusian(venusian) - self.assertEqual(len(settings), 1) - self.assertEqual(settings[0]['renderer'], - 'repoze.bfg.tests:fixtures/minimal.pt') - - def test_call_with_renderer_pkgpath(self): - decorator = self._makeOne( - renderer='repoze.bfg.tests:fixtures/minimal.pt') - venusian = DummyVenusian() - decorator.venusian = venusian - def foo(): pass - wrapped = decorator(foo) - self.failUnless(wrapped is foo) - settings = call_venusian(venusian) - self.assertEqual(len(settings), 1) - self.assertEqual(settings[0]['renderer'], - 'repoze.bfg.tests:fixtures/minimal.pt') - -class Test_append_slash_notfound_view(BaseTest, unittest.TestCase): - def _callFUT(self, context, request): - from repoze.bfg.view import append_slash_notfound_view - return append_slash_notfound_view(context, request) - - def _registerMapper(self, reg, match=True): - from repoze.bfg.interfaces import IRoutesMapper - class DummyRoute(object): - def __init__(self, val): - self.val = val - def match(self, path): - return self.val - class DummyMapper(object): - def __init__(self): - self.routelist = [ DummyRoute(match) ] - def get_routes(self): - return self.routelist - mapper = DummyMapper() - reg.registerUtility(mapper, IRoutesMapper) - return mapper - - def test_context_is_not_exception(self): - request = self._makeRequest(PATH_INFO='/abc') - request.exception = ExceptionResponse() - context = DummyContext() - response = self._callFUT(context, request) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.app_iter, ['Not Found']) - - def test_no_mapper(self): - request = self._makeRequest(PATH_INFO='/abc') - context = ExceptionResponse() - response = self._callFUT(context, request) - self.assertEqual(response.status, '404 Not Found') - - def test_no_path(self): - request = self._makeRequest() - context = ExceptionResponse() - self._registerMapper(request.registry, True) - response = self._callFUT(context, request) - self.assertEqual(response.status, '404 Not Found') - - def test_mapper_path_already_slash_ending(self): - request = self._makeRequest(PATH_INFO='/abc/') - context = ExceptionResponse() - self._registerMapper(request.registry, True) - response = self._callFUT(context, request) - self.assertEqual(response.status, '404 Not Found') - - def test_matches(self): - request = self._makeRequest(PATH_INFO='/abc') - context = ExceptionResponse() - self._registerMapper(request.registry, True) - response = self._callFUT(context, request) - self.assertEqual(response.status, '302 Found') - self.assertEqual(response.location, '/abc/') - -class TestAppendSlashNotFoundViewFactory(BaseTest, unittest.TestCase): - def _makeOne(self, notfound_view): - from repoze.bfg.view import AppendSlashNotFoundViewFactory - return AppendSlashNotFoundViewFactory(notfound_view) - - def test_custom_notfound_view(self): - request = self._makeRequest(PATH_INFO='/abc') - context = ExceptionResponse() - def custom_notfound(context, request): - return 'OK' - view = self._makeOne(custom_notfound) - response = view(context, request) - self.assertEqual(response, 'OK') - -class Test_default_exceptionresponse_view(unittest.TestCase): - def _callFUT(self, context, request): - from repoze.bfg.view import default_exceptionresponse_view - return default_exceptionresponse_view(context, request) - - def test_is_exception(self): - context = Exception() - result = self._callFUT(context, None) - self.failUnless(result is context) - - def test_is_not_exception_no_request_exception(self): - context = object() - request = DummyRequest() - result = self._callFUT(context, request) - self.failUnless(result is context) - - def test_is_not_exception_request_exception(self): - context = object() - request = DummyRequest() - request.exception = 'abc' - result = self._callFUT(context, request) - self.assertEqual(result, 'abc') - -class ExceptionResponse(Exception): - status = '404 Not Found' - app_iter = ['Not Found'] - headerlist = [] - -class DummyContext: - pass - -def make_view(response): - def view(context, request): - return response - return view - -class DummyRequest: - exception = None - -class DummyResponse: - status = '200 OK' - headerlist = () - def __init__(self, body=None): - if body is None: - self.app_iter = () - else: - self.app_iter = [body] - -from zope.interface import Interface -class IContext(Interface): - pass - -class DummyVenusianInfo(object): - scope = 'notaclass' - module = sys.modules['repoze.bfg.tests'] - -class DummyVenusian(object): - def __init__(self, info=None): - if info is None: - info = DummyVenusianInfo() - self.info = info - self.attachments = [] - - def attach(self, wrapped, callback, category=None): - self.attachments.append((wrapped, callback, category)) - return self.info - -class DummyConfig(object): - def __init__(self): - self.settings = [] - - def add_view(self, **kw): - self.settings.append(kw) - -class DummyVenusianContext(object): - def __init__(self): - self.config = DummyConfig() - -def call_venusian(venusian): - context = DummyVenusianContext() - for wrapped, callback, category in venusian.attachments: - callback(context, None, None) - return context.config.settings - diff --git a/repoze/bfg/tests/test_wsgi.py b/repoze/bfg/tests/test_wsgi.py deleted file mode 100644 index 5d3ec1faa..000000000 --- a/repoze/bfg/tests/test_wsgi.py +++ /dev/null @@ -1,112 +0,0 @@ -import unittest - -class WSGIAppTests(unittest.TestCase): - def _callFUT(self, app): - from repoze.bfg.wsgi import wsgiapp - return wsgiapp(app) - - def test_decorator(self): - context = DummyContext() - request = DummyRequest() - decorator = self._callFUT(dummyapp) - response = decorator(context, request) - self.assertEqual(response, dummyapp) - -class WSGIApp2Tests(unittest.TestCase): - def _callFUT(self, app): - from repoze.bfg.wsgi import wsgiapp2 - return wsgiapp2(app) - - def test_decorator_with_subpath_and_view_name(self): - context = DummyContext() - request = DummyRequest() - request.traversed = ['a', 'b'] - request.virtual_root_path = ['a'] - request.subpath = ['subpath'] - request.view_name = 'view_name' - request.environ = {'SCRIPT_NAME':'/foo'} - decorator = self._callFUT(dummyapp) - response = decorator(context, request) - self.assertEqual(response, dummyapp) - self.assertEqual(request.environ['PATH_INFO'], '/subpath') - self.assertEqual(request.environ['SCRIPT_NAME'], '/foo/b/view_name') - - def test_decorator_with_subpath_no_view_name(self): - context = DummyContext() - request = DummyRequest() - request.traversed = ['a', 'b'] - request.virtual_root_path = ['a'] - request.subpath = ['subpath'] - request.view_name = '' - request.environ = {'SCRIPT_NAME':'/foo'} - decorator = self._callFUT(dummyapp) - response = decorator(context, request) - self.assertEqual(response, dummyapp) - self.assertEqual(request.environ['PATH_INFO'], '/subpath') - self.assertEqual(request.environ['SCRIPT_NAME'], '/foo/b') - - def test_decorator_no_subpath_with_view_name(self): - context = DummyContext() - request = DummyRequest() - request.traversed = ['a', 'b'] - request.virtual_root_path = ['a'] - request.subpath = [] - request.view_name = 'view_name' - request.environ = {'SCRIPT_NAME':'/foo'} - decorator = self._callFUT(dummyapp) - response = decorator(context, request) - self.assertEqual(response, dummyapp) - self.assertEqual(request.environ['PATH_INFO'], '/') - self.assertEqual(request.environ['SCRIPT_NAME'], '/foo/b/view_name') - - def test_decorator_traversed_empty_with_view_name(self): - context = DummyContext() - request = DummyRequest() - request.traversed = [] - request.virtual_root_path = [] - request.subpath = [] - request.view_name = 'view_name' - request.environ = {'SCRIPT_NAME':'/foo'} - decorator = self._callFUT(dummyapp) - response = decorator(context, request) - self.assertEqual(response, dummyapp) - self.assertEqual(request.environ['PATH_INFO'], '/') - self.assertEqual(request.environ['SCRIPT_NAME'], '/foo/view_name') - - def test_decorator_traversed_empty_no_view_name(self): - context = DummyContext() - request = DummyRequest() - request.traversed = [] - request.virtual_root_path = [] - request.subpath = [] - request.view_name = '' - request.environ = {'SCRIPT_NAME':'/foo'} - decorator = self._callFUT(dummyapp) - response = decorator(context, request) - self.assertEqual(response, dummyapp) - self.assertEqual(request.environ['PATH_INFO'], '/') - self.assertEqual(request.environ['SCRIPT_NAME'], '/foo') - - def test_decorator_traversed_empty_no_view_name_no_script_name(self): - context = DummyContext() - request = DummyRequest() - request.traversed = [] - request.virtual_root_path = [] - request.subpath = [] - request.view_name = '' - request.environ = {'SCRIPT_NAME':''} - decorator = self._callFUT(dummyapp) - response = decorator(context, request) - self.assertEqual(response, dummyapp) - self.assertEqual(request.environ['PATH_INFO'], '/') - self.assertEqual(request.environ['SCRIPT_NAME'], '') - -def dummyapp(environ, start_response): - """ """ - -class DummyContext: - pass - -class DummyRequest: - def get_response(self, application): - return application diff --git a/repoze/bfg/tests/test_zcml.py b/repoze/bfg/tests/test_zcml.py deleted file mode 100644 index 131122d7b..000000000 --- a/repoze/bfg/tests/test_zcml.py +++ /dev/null @@ -1,1283 +0,0 @@ -import logging - -logging.basicConfig() - -import unittest - -from repoze.bfg import testing - -from zope.interface import Interface -from zope.interface import implements - -class TestViewDirective(unittest.TestCase): - def setUp(self): - testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _callFUT(self, *arg, **kw): - from repoze.bfg.zcml import view - return view(*arg, **kw) - - def test_request_type_ashttpmethod(self): - from repoze.bfg.threadlocal import get_current_registry - from repoze.bfg.interfaces import IView - from repoze.bfg.interfaces import IViewClassifier - from repoze.bfg.interfaces import IRequest - context = DummyContext() - view = lambda *arg: None - self._callFUT(context, 'repoze.view', IDummy, view=view, - request_type='GET') - actions = context.actions - self.assertEqual(len(actions), 1) - action = actions[0] - discrim = ('view', IDummy, '', None, IView, None, None, 'GET', None, - None, False, None, None, None) - self.assertEqual(action['discriminator'], discrim) - register = action['callable'] - register() - reg = get_current_registry() - wrapper = reg.adapters.lookup( - (IViewClassifier, IRequest, IDummy), IView, name='') - request = DummyRequest() - request.method = 'GET' - self.assertEqual(wrapper.__predicated__(None, request), True) - request.method = 'POST' - self.assertEqual(wrapper.__predicated__(None, request), False) - - def test_request_type_asinterfacestring(self): - from zope.interface import directlyProvides - from repoze.bfg.threadlocal import get_current_registry - from repoze.bfg.interfaces import IView - from repoze.bfg.interfaces import IViewClassifier - from repoze.bfg.interfaces import IRequest - context = DummyContext(IDummy) - view = lambda *arg: 'OK' - self._callFUT(context, 'repoze.view', IDummy, view=view, - request_type='whatever') - actions = context.actions - self.assertEqual(len(actions), 1) - discrim = ('view', IDummy, '', IDummy, IView, None, None, None, None, - None, False, None, None, None) - self.assertEqual(actions[0]['discriminator'], discrim) - register = actions[0]['callable'] - register() - reg = get_current_registry() - regview = reg.adapters.lookup( - (IViewClassifier, IRequest, IDummy), IView, name='') - self.assertNotEqual(view, regview) - request = DummyRequest() - directlyProvides(request, IDummy) - result = regview(None, request) - self.assertEqual(result, 'OK') - self.failIf(hasattr(view, '__call_permissive__')) - - def test_request_type_asnoninterfacestring(self): - from repoze.bfg.exceptions import ConfigurationError - context = DummyContext('notaninterface') - view = lambda *arg: 'OK' - self.assertRaises(ConfigurationError, - self._callFUT, - context, 'repoze.view', IDummy, view=view, - request_type='whatever') - - def test_with_dotted_renderer(self): - from repoze.bfg.threadlocal import get_current_registry - from repoze.bfg.interfaces import IView - from repoze.bfg.interfaces import IViewClassifier - from repoze.bfg.interfaces import IRendererFactory - from repoze.bfg.interfaces import IRequest - context = DummyContext() - reg = get_current_registry() - def factory(path): - def foo(*arg): - return 'OK' - return foo - reg.registerUtility(factory, IRendererFactory, name='.pt') - view = lambda *arg: None - self._callFUT(context, 'repoze.view', IDummy, view=view, - renderer='foo/template.pt') - actions = context.actions - self.assertEqual(len(actions), 1) - discrim = ('view', IDummy, '', None, IView, None, None, None, None, - None, False, None, None, None) - self.assertEqual(actions[0]['discriminator'], discrim) - register = actions[0]['callable'] - register() - regview = reg.adapters.lookup( - (IViewClassifier, IRequest, IDummy), IView, name='') - self.assertEqual(regview(None, None).body, 'OK') - - def test_with_custom_predicates(self): - from repoze.bfg.threadlocal import get_current_registry - from repoze.bfg.interfaces import IView - from repoze.bfg.interfaces import IViewClassifier - from repoze.bfg.interfaces import IRequest - context = DummyContext() - reg = get_current_registry() - view = lambda *arg: 'OK' - def pred1(context, request): - return True - def pred2(context, request): - return True - preds = (pred1, pred2) - self._callFUT(context, 'repoze.view', IDummy, view=view, - custom_predicates=preds) - actions = context.actions - self.assertEqual(len(actions), 1) - discrim = ('view', IDummy, '', None, IView, None, None, None, None, - None, False, None, None, None) - discrim = discrim + tuple(sorted(preds)) - self.assertEqual(actions[0]['discriminator'], discrim) - register = actions[0]['callable'] - register() - regview = reg.adapters.lookup( - (IViewClassifier, IRequest, IDummy), IView, name='') - self.assertEqual(regview(None, None), 'OK') - - def test_context_trumps_for(self): - from repoze.bfg.threadlocal import get_current_registry - from repoze.bfg.interfaces import IView - from repoze.bfg.interfaces import IViewClassifier - from repoze.bfg.interfaces import IRequest - context = DummyContext() - reg = get_current_registry() - view = lambda *arg: 'OK' - class Foo: - pass - self._callFUT(context, 'repoze.view', for_=Foo, view=view, - context=IDummy) - actions = context.actions - self.assertEqual(len(actions), 1) - discrim = ('view', IDummy, '', None, IView, None, None, None, None, - None, False, None, None, None) - self.assertEqual(actions[0]['discriminator'], discrim) - register = actions[0]['callable'] - register() - regview = reg.adapters.lookup( - (IViewClassifier, IRequest, IDummy), IView, name='') - self.assertEqual(regview(None, None), 'OK') - - def test_with_for(self): - from repoze.bfg.threadlocal import get_current_registry - from repoze.bfg.interfaces import IView - from repoze.bfg.interfaces import IViewClassifier - from repoze.bfg.interfaces import IRequest - context = DummyContext() - reg = get_current_registry() - view = lambda *arg: 'OK' - class Foo: - pass - self._callFUT(context, 'repoze.view', for_=IDummy, view=view) - actions = context.actions - self.assertEqual(len(actions), 1) - discrim = ('view', IDummy, '', None, IView, None, None, None, None, - None, False, None, None, None) - self.assertEqual(actions[0]['discriminator'], discrim) - register = actions[0]['callable'] - register() - regview = reg.adapters.lookup( - (IViewClassifier, IRequest, IDummy), IView, name='') - self.assertEqual(regview(None, None), 'OK') - -class TestNotFoundDirective(unittest.TestCase): - def setUp(self): - testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _callFUT(self, context, view, **kw): - from repoze.bfg.zcml import notfound - return notfound(context, view, **kw) - - def test_it(self): - from zope.interface import implementedBy - from repoze.bfg.threadlocal import get_current_registry - from repoze.bfg.interfaces import IRequest - from repoze.bfg.interfaces import IView - from repoze.bfg.interfaces import IViewClassifier - from repoze.bfg.exceptions import NotFound - - context = DummyContext() - def view(request): - return 'OK' - self._callFUT(context, view) - actions = context.actions - self.assertEqual(len(actions), 1) - - discrim = ('view', NotFound, '', None, IView, None, None, None, None, - None, False, None, None, None) - regadapt = actions[0] - self.assertEqual(regadapt['discriminator'], discrim) - register = regadapt['callable'] - register() - reg = get_current_registry() - derived_view = reg.adapters.lookup( - (IViewClassifier, IRequest, implementedBy(NotFound)), - IView, default=None) - - self.assertNotEqual(derived_view, None) - self.assertEqual(derived_view(None, None), 'OK') - self.assertEqual(derived_view.__name__, 'bwcompat_view') - - def test_it_with_dotted_renderer(self): - from zope.interface import implementedBy - from repoze.bfg.threadlocal import get_current_registry - from repoze.bfg.interfaces import IRequest - from repoze.bfg.interfaces import IView - from repoze.bfg.interfaces import IViewClassifier - from repoze.bfg.exceptions import NotFound - from repoze.bfg.configuration import Configurator - context = DummyContext() - reg = get_current_registry() - config = Configurator(reg) - def dummy_renderer_factory(*arg, **kw): - return lambda *arg, **kw: 'OK' - config.add_renderer('.pt', dummy_renderer_factory) - def view(request): - return {} - self._callFUT(context, view, renderer='fake.pt') - actions = context.actions - regadapt = actions[0] - register = regadapt['callable'] - register() - derived_view = reg.adapters.lookup( - (IViewClassifier, IRequest, implementedBy(NotFound)), - IView, default=None) - self.assertNotEqual(derived_view, None) - self.assertEqual(derived_view(None, None).body, 'OK') - self.assertEqual(derived_view.__name__, 'bwcompat_view') - -class TestForbiddenDirective(unittest.TestCase): - def setUp(self): - testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _callFUT(self, context, view, **kw): - from repoze.bfg.zcml import forbidden - return forbidden(context, view, **kw) - - def test_it(self): - from zope.interface import implementedBy - from repoze.bfg.threadlocal import get_current_registry - from repoze.bfg.interfaces import IRequest - from repoze.bfg.interfaces import IView - from repoze.bfg.interfaces import IViewClassifier - from repoze.bfg.exceptions import Forbidden - context = DummyContext() - def view(request): - return 'OK' - self._callFUT(context, view) - actions = context.actions - - self.assertEqual(len(actions), 1) - - discrim = ('view', Forbidden, '', None, IView, None, None, None, None, - None, False, None, None, None) - regadapt = actions[0] - self.assertEqual(regadapt['discriminator'], discrim) - register = regadapt['callable'] - register() - reg = get_current_registry() - derived_view = reg.adapters.lookup( - (IViewClassifier, IRequest, implementedBy(Forbidden)), - IView, default=None) - - self.assertNotEqual(derived_view, None) - self.assertEqual(derived_view(None, None), 'OK') - self.assertEqual(derived_view.__name__, 'bwcompat_view') - - def test_it_with_dotted_renderer(self): - from zope.interface import implementedBy - from repoze.bfg.threadlocal import get_current_registry - from repoze.bfg.interfaces import IRequest - from repoze.bfg.interfaces import IView - from repoze.bfg.interfaces import IViewClassifier - from repoze.bfg.exceptions import Forbidden - from repoze.bfg.configuration import Configurator - context = DummyContext() - reg = get_current_registry() - config = Configurator(reg) - def dummy_renderer_factory(*arg, **kw): - return lambda *arg, **kw: 'OK' - config.add_renderer('.pt', dummy_renderer_factory) - def view(request): - return {} - self._callFUT(context, view, renderer='fake.pt') - actions = context.actions - regadapt = actions[0] - register = regadapt['callable'] - register() - derived_view = reg.adapters.lookup( - (IViewClassifier, IRequest, implementedBy(Forbidden)), - IView, default=None) - self.assertNotEqual(derived_view, None) - self.assertEqual(derived_view(None, None).body, 'OK') - self.assertEqual(derived_view.__name__, 'bwcompat_view') - -class TestRepozeWho1AuthenticationPolicyDirective(unittest.TestCase): - def setUp(self): - testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _callFUT(self, context, **kw): - from repoze.bfg.zcml import repozewho1authenticationpolicy - return repozewho1authenticationpolicy(context, **kw) - - def test_it_defaults(self): - from repoze.bfg.threadlocal import get_current_registry - reg = get_current_registry() - from repoze.bfg.interfaces import IAuthenticationPolicy - context = DummyContext() - self._callFUT(context) - actions = context.actions - self.assertEqual(len(actions), 1) - regadapt = actions[0] - self.assertEqual(regadapt['discriminator'], IAuthenticationPolicy) - self.assertEqual(regadapt['callable'], None) - self.assertEqual(regadapt['args'], ()) - policy = reg.getUtility(IAuthenticationPolicy) - self.assertEqual(policy.callback, None) - self.assertEqual(policy.identifier_name, 'auth_tkt') - - def test_it(self): - from repoze.bfg.threadlocal import get_current_registry - reg = get_current_registry() - from repoze.bfg.interfaces import IAuthenticationPolicy - context = DummyContext() - def callback(identity, request): - """ """ - self._callFUT(context, identifier_name='something', callback=callback) - actions = context.actions - self.assertEqual(len(actions), 1) - regadapt = actions[0] - self.assertEqual(regadapt['discriminator'], IAuthenticationPolicy) - self.assertEqual(regadapt['callable'], None) - self.assertEqual(regadapt['args'], ()) - policy = reg.getUtility(IAuthenticationPolicy) - self.assertEqual(policy.callback, callback) - self.assertEqual(policy.identifier_name, 'something') - -class TestRemoteUserAuthenticationPolicyDirective(unittest.TestCase): - def setUp(self): - testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _callFUT(self, context, **kw): - from repoze.bfg.zcml import remoteuserauthenticationpolicy - return remoteuserauthenticationpolicy(context, **kw) - - def test_defaults(self): - from repoze.bfg.interfaces import IAuthenticationPolicy - from repoze.bfg.threadlocal import get_current_registry - reg = get_current_registry() - context = DummyContext() - def callback(identity, request): - """ """ - self._callFUT(context) - actions = context.actions - self.assertEqual(len(actions), 1) - regadapt = actions[0] - self.assertEqual(regadapt['discriminator'], IAuthenticationPolicy) - self.assertEqual(regadapt['callable'], None) - self.assertEqual(regadapt['args'], ()) - policy = reg.getUtility(IAuthenticationPolicy) - self.assertEqual(policy.environ_key, 'REMOTE_USER') - self.assertEqual(policy.callback, None) - - def test_it(self): - from repoze.bfg.interfaces import IAuthenticationPolicy - from repoze.bfg.threadlocal import get_current_registry - context = DummyContext() - def callback(identity, request): - """ """ - self._callFUT(context, environ_key='BLAH', callback=callback) - actions = context.actions - self.assertEqual(len(actions), 1) - regadapt = actions[0] - self.assertEqual(regadapt['discriminator'], IAuthenticationPolicy) - self.assertEqual(regadapt['callable'], None) - self.assertEqual(regadapt['args'], ()) - reg = get_current_registry() - policy = reg.getUtility(IAuthenticationPolicy) - self.assertEqual(policy.environ_key, 'BLAH') - self.assertEqual(policy.callback, callback) - -class TestAuthTktAuthenticationPolicyDirective(unittest.TestCase): - def setUp(self): - testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _callFUT(self, context, secret, **kw): - from repoze.bfg.zcml import authtktauthenticationpolicy - return authtktauthenticationpolicy(context, secret, **kw) - - def test_it_defaults(self): - from repoze.bfg.interfaces import IAuthenticationPolicy - from repoze.bfg.threadlocal import get_current_registry - reg = get_current_registry() - context = DummyContext() - self._callFUT(context, 'sosecret') - actions = context.actions - self.assertEqual(len(actions), 1) - regadapt = actions[0] - self.assertEqual(regadapt['discriminator'], IAuthenticationPolicy) - self.assertEqual(regadapt['callable'], None) - self.assertEqual(regadapt['args'], ()) - policy = reg.getUtility(IAuthenticationPolicy) - self.assertEqual(policy.cookie.secret, 'sosecret') - self.assertEqual(policy.callback, None) - - def test_it_noconfigerror(self): - from repoze.bfg.interfaces import IAuthenticationPolicy - from repoze.bfg.threadlocal import get_current_registry - reg = get_current_registry() - context = DummyContext() - def callback(identity, request): - """ """ - self._callFUT(context, 'sosecret', callback=callback, - cookie_name='repoze.bfg.auth_tkt', - secure=True, include_ip=True, timeout=100, - reissue_time=60, http_only=True, path="/sub/") - actions = context.actions - self.assertEqual(len(actions), 1) - regadapt = actions[0] - self.assertEqual(regadapt['discriminator'], IAuthenticationPolicy) - self.assertEqual(regadapt['callable'], None) - self.assertEqual(regadapt['args'], ()) - policy = reg.getUtility(IAuthenticationPolicy) - self.assertEqual(policy.cookie.path, '/sub/') - self.assertEqual(policy.cookie.http_only, True) - self.assertEqual(policy.cookie.secret, 'sosecret') - self.assertEqual(policy.callback, callback) - - def test_it_configerror(self): - from repoze.bfg.exceptions import ConfigurationError - context = DummyContext() - def callback(identity, request): - """ """ - self.assertRaises(ConfigurationError, - self._callFUT, - context, 'sosecret', callback=callback, - cookie_name='repoze.bfg.auth_tkt', - secure=True, include_ip=True, timeout=100, - reissue_time=500, http_only=True, - path="/cgi-bin/bfg.cgi/") - -class TestACLAuthorizationPolicyDirective(unittest.TestCase): - def setUp(self): - testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _callFUT(self, context, **kw): - from repoze.bfg.zcml import aclauthorizationpolicy - return aclauthorizationpolicy(context, **kw) - - def test_it(self): - from repoze.bfg.threadlocal import get_current_registry - from repoze.bfg.authorization import ACLAuthorizationPolicy - from repoze.bfg.interfaces import IAuthorizationPolicy - reg = get_current_registry() - context = DummyContext() - def callback(identity, request): - """ """ - self._callFUT(context) - actions = context.actions - self.assertEqual(len(actions), 1) - regadapt = actions[0] - self.assertEqual(regadapt['discriminator'], IAuthorizationPolicy) - self.assertEqual(regadapt['callable'], None) - self.assertEqual(regadapt['args'], ()) - policy = reg.getUtility(IAuthorizationPolicy) - self.assertEqual(policy.__class__, ACLAuthorizationPolicy) - -class TestRouteDirective(unittest.TestCase): - def setUp(self): - testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _callFUT(self, *arg, **kw): - from repoze.bfg.zcml import route - return route(*arg, **kw) - - def _assertRoute(self, name, pattern, num_predicates=0): - from repoze.bfg.threadlocal import get_current_registry - from repoze.bfg.interfaces import IRoutesMapper - reg = get_current_registry() - mapper = reg.getUtility(IRoutesMapper) - routes = mapper.get_routes() - route = routes[0] - self.assertEqual(len(routes), 1) - self.assertEqual(route.name, name) - self.assertEqual(route.pattern, pattern) - self.assertEqual(len(routes[0].predicates), num_predicates) - return route - - def test_with_view(self): - from repoze.bfg.threadlocal import get_current_registry - from zope.interface import Interface - from repoze.bfg.interfaces import IView - from repoze.bfg.interfaces import IViewClassifier - from repoze.bfg.interfaces import IRouteRequest - context = DummyContext() - view = lambda *arg: 'OK' - self._callFUT(context, 'name', 'pattern', view=view) - actions = context.actions - self.assertEqual(len(actions), 2) - - route_action = actions[0] - route_action['callable']() - route_discriminator = route_action['discriminator'] - self.assertEqual(route_discriminator, - ('route', 'name', False, None, None, None, None,None)) - self._assertRoute('name', 'pattern') - - view_action = actions[1] - reg = get_current_registry() - request_type = reg.getUtility(IRouteRequest, 'name') - view_discriminator = view_action['discriminator'] - discrim = ('view', None, '', None, IView, 'name', None) - self.assertEqual(view_discriminator, discrim) - wrapped = reg.adapters.lookup( - (IViewClassifier, request_type, Interface), IView, name='') - self.failUnless(wrapped) - - def test_with_view_and_view_context(self): - from repoze.bfg.threadlocal import get_current_registry - from repoze.bfg.interfaces import IView - from repoze.bfg.interfaces import IViewClassifier - from repoze.bfg.interfaces import IRouteRequest - context = DummyContext() - view = lambda *arg: 'OK' - self._callFUT(context, 'name', 'pattern', view=view, - view_context=IDummy) - actions = context.actions - self.assertEqual(len(actions), 2) - - route_action = actions[0] - route_action['callable']() - route_discriminator = route_action['discriminator'] - self.assertEqual(route_discriminator, - ('route', 'name', False, None, None, None, None,None)) - self._assertRoute('name', 'pattern') - - view_action = actions[1] - reg = get_current_registry() - request_type = reg.getUtility(IRouteRequest, 'name') - view_discriminator = view_action['discriminator'] - discrim = ('view', IDummy, '', None, IView, 'name', None) - self.assertEqual(view_discriminator, discrim) - wrapped = reg.adapters.lookup( - (IViewClassifier, request_type, IDummy), IView, name='') - self.failUnless(wrapped) - - def test_with_view_context_trumps_view_for(self): - from repoze.bfg.threadlocal import get_current_registry - from repoze.bfg.interfaces import IView - from repoze.bfg.interfaces import IViewClassifier - from repoze.bfg.interfaces import IRouteRequest - context = DummyContext() - view = lambda *arg: 'OK' - class Foo: - pass - self._callFUT(context, 'name', 'pattern', view=view, - view_context=IDummy, view_for=Foo) - actions = context.actions - self.assertEqual(len(actions), 2) - - route_action = actions[0] - route_action['callable']() - route_discriminator = route_action['discriminator'] - self.assertEqual(route_discriminator, - ('route', 'name', False, None, None, None, None,None)) - self._assertRoute('name', 'pattern') - - view_action = actions[1] - reg = get_current_registry() - request_type = reg.getUtility(IRouteRequest, 'name') - view_discriminator = view_action['discriminator'] - discrim = ('view', IDummy, '', None, IView, 'name', None) - self.assertEqual(view_discriminator, discrim) - wrapped = reg.adapters.lookup( - (IViewClassifier, request_type, IDummy), IView, name='') - self.failUnless(wrapped) - - def test_with_dotted_renderer(self): - - from repoze.bfg.threadlocal import get_current_registry - from zope.interface import Interface - from repoze.bfg.interfaces import IView - from repoze.bfg.interfaces import IViewClassifier - from repoze.bfg.interfaces import IRouteRequest - from repoze.bfg.interfaces import IRendererFactory - reg = get_current_registry() - def renderer(path): - return lambda *arg: 'OK' - reg.registerUtility(renderer, IRendererFactory, name='.pt') - - context = DummyContext() - view = lambda *arg: 'OK' - self._callFUT(context, 'name', 'pattern', view=view, - renderer='fixtureapp/templates/foo.pt') - actions = context.actions - self.assertEqual(len(actions), 2) - - route_action = actions[0] - route_action['callable']() - route_discriminator = route_action['discriminator'] - self.assertEqual(route_discriminator, - ('route', 'name', False, None, None, None, None,None)) - self._assertRoute('name', 'pattern') - - view_action = actions[1] - request_type = reg.getUtility(IRouteRequest, 'name') - view_discriminator = view_action['discriminator'] - discrim = ('view', None, '', None, IView, 'name', None) - self.assertEqual(view_discriminator, discrim) - wrapped = reg.adapters.lookup( - (IViewClassifier, request_type, Interface), IView, name='') - self.failUnless(wrapped) - request = DummyRequest() - result = wrapped(None, request) - self.assertEqual(result.body, 'OK') - - def test_with_custom_predicates(self): - def pred1(context, request): pass - def pred2(context, request): pass - preds = tuple(sorted([pred1, pred2])) - - context = DummyContext() - self._callFUT(context, 'name', 'pattern', - custom_predicates=(pred1, pred2)) - actions = context.actions - self.assertEqual(len(actions), 1) - - route_action = actions[0] - route_action['callable']() - route_discriminator = route_action['discriminator'] - self.assertEqual( - route_discriminator, - ('route', 'name', False, None, None, None, None,None) + preds) - self._assertRoute('name', 'pattern', 2) - - def test_with_path_argument_no_pattern(self): - context = DummyContext() - self._callFUT(context, 'name', path='pattern') - actions = context.actions - self.assertEqual(len(actions), 1) - - route_action = actions[0] - route_action['callable']() - route_discriminator = route_action['discriminator'] - self.assertEqual(route_discriminator, - ('route', 'name', False, None, None, None, None,None)) - self._assertRoute('name', 'pattern') - - def test_with_path_argument_and_pattern(self): - context = DummyContext() - self._callFUT(context, 'name', pattern='pattern', path='path') - actions = context.actions - self.assertEqual(len(actions), 1) - - route_action = actions[0] - route_action['callable']() - route_discriminator = route_action['discriminator'] - self.assertEqual(route_discriminator, - ('route', 'name', False, None, None, None, None,None)) - self._assertRoute('name', 'pattern') - - - def test_with_neither_path_nor_pattern(self): - from repoze.bfg.exceptions import ConfigurationError - context = DummyContext() - self.assertRaises(ConfigurationError, self._callFUT, context, 'name') - -class TestStaticDirective(unittest.TestCase): - def setUp(self): - testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _callFUT(self, *arg, **kw): - from repoze.bfg.zcml import static - return static(*arg, **kw) - - def test_it_with_slash(self): - from repoze.bfg.static import PackageURLParser - from repoze.bfg.threadlocal import get_current_registry - from zope.interface import implementedBy - from repoze.bfg.static import StaticURLInfo - from repoze.bfg.interfaces import IView - from repoze.bfg.interfaces import IViewClassifier - from repoze.bfg.interfaces import IRouteRequest - from repoze.bfg.interfaces import IRoutesMapper - context = DummyContext() - self._callFUT(context, 'name', 'fixtures/static') - actions = context.actions - self.assertEqual(len(actions), 2) - - reg = get_current_registry() - - route_action = actions[0] - discriminator = route_action['discriminator'] - self.assertEqual(discriminator, ('static', 'name')) - route_action['callable'](*route_action['args'], **route_action['kw']) - mapper = reg.getUtility(IRoutesMapper) - routes = mapper.get_routes() - self.assertEqual(len(routes), 1) - self.assertEqual(routes[0].pattern, 'name/*subpath') - self.assertEqual(routes[0].name, 'name/') - - view_action = actions[1] - discriminator = view_action['discriminator'] - self.assertEqual(discriminator[:3], ('view', StaticURLInfo, '')) - self.assertEqual(discriminator[4], IView) - iface = implementedBy(StaticURLInfo) - request_type = reg.getUtility(IRouteRequest, 'name/') - view = reg.adapters.lookup( - (IViewClassifier, request_type, iface), IView, name='') - request = DummyRequest() - self.assertEqual(view(None, request).__class__, PackageURLParser) - -class TestResourceDirective(unittest.TestCase): - def setUp(self): - testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _callFUT(self, *arg, **kw): - from repoze.bfg.zcml import resource - return resource(*arg, **kw) - - def test_it(self): - from repoze.bfg.configuration import Configurator - context = DummyContext() - self._callFUT(context, 'a', 'b') - actions = context.actions - self.assertEqual(len(actions), 1) - action = actions[0] - self.assertEqual(action['callable'].im_func, - Configurator.override_resource.im_func) - self.assertEqual(action['discriminator'], None) - self.assertEqual(action['args'], ('a', 'b', None)) - - -class TestRendererDirective(unittest.TestCase): - def setUp(self): - testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _callFUT(self, *arg, **kw): - from repoze.bfg.zcml import renderer - return renderer(*arg, **kw) - - def test_it(self): - from repoze.bfg.threadlocal import get_current_registry - from repoze.bfg.interfaces import IRendererFactory - context = DummyContext() - renderer = lambda *arg, **kw: None - self._callFUT(context, renderer, 'r') - actions = context.actions - self.assertEqual(len(actions), 1) - action = actions[0] - self.assertEqual(action['discriminator'], (IRendererFactory, 'r')) - reg = get_current_registry() - self.failUnless(reg.getUtility(IRendererFactory, 'r'), renderer) - -class TestZCMLConfigure(unittest.TestCase): - i = 0 - def _callFUT(self, path, package): - from repoze.bfg.zcml import zcml_configure - return zcml_configure(path, package) - - def setUp(self): - testing.setUp() - self.tempdir = None - import sys - import os - import tempfile - from repoze.bfg.path import package_path - from repoze.bfg.tests import fixtureapp as package - import shutil - tempdir = tempfile.mkdtemp() - modname = 'myfixture%s' % self.i - self.i += 1 - self.packagepath = os.path.join(tempdir, modname) - fixturedir = package_path(package) - shutil.copytree(fixturedir, self.packagepath) - sys.path.insert(0, tempdir) - self.module = __import__(modname) - self.tempdir = tempdir - - def tearDown(self): - testing.tearDown() - import sys - import shutil - if self.module is not None: - del sys.modules[self.module.__name__] - if self.tempdir is not None: - sys.path.pop(0) - shutil.rmtree(self.tempdir) - - def test_zcml_configure(self): - actions = self._callFUT('configure.zcml', self.module) - self.failUnless(actions) - self.failUnless(isinstance(actions, list)) - - def test_zcml_configure_nonexistent_configure_dot_zcml(self): - import os - os.remove(os.path.join(self.packagepath, 'configure.zcml')) - self.assertRaises(IOError, self._callFUT, 'configure.zcml', - self.module) - -class TestZCMLScanDirective(unittest.TestCase): - def setUp(self): - testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _callFUT(self, context, package): - from repoze.bfg.zcml import scan - return scan(context, package) - - def test_it(self): - from repoze.bfg.configuration import Configurator - dummy_module = DummyModule() - context = DummyContext() - self._callFUT(context, dummy_module) - actions = context.actions - self.assertEqual(len(actions), 1) - action = actions[0] - self.assertEqual(action['callable'].im_func, Configurator.scan.im_func) - self.assertEqual(action['discriminator'], None) - self.assertEqual(action['args'], (dummy_module, None, None)) - -class TestAdapterDirective(unittest.TestCase): - def setUp(self): - testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _callFUT(self, *arg, **kw): - from repoze.bfg.zcml import adapter - return adapter(*arg, **kw) - - def test_for_is_None_no_adaptedBy(self): - context = DummyContext() - factory = DummyFactory() - self.assertRaises(TypeError, self._callFUT, context, [factory], - provides=None, for_=None) - - def test_for_is_None_adaptedBy_still_None(self): - context = DummyContext() - factory = DummyFactory() - factory.__component_adapts__ = None - self.assertRaises(TypeError, self._callFUT, context, [factory], - provides=None, for_=None) - - def test_for_is_None_adaptedBy_set(self): - from repoze.bfg.registry import Registry - context = DummyContext() - factory = DummyFactory() - factory.__component_adapts__ = (IDummy,) - self._callFUT(context, [factory], provides=IFactory, for_=None) - self.assertEqual(len(context.actions), 1) - regadapt = context.actions[0] - self.assertEqual(regadapt['discriminator'], - ('adapter', (IDummy,), IFactory, '')) - self.assertEqual(regadapt['callable'].im_func, - Registry.registerAdapter.im_func) - self.assertEqual(regadapt['args'], - (factory, (IDummy,), IFactory, '', None)) - - def test_provides_missing(self): - context = DummyContext() - factory = DummyFactory() - self.assertRaises(TypeError, self._callFUT, context, [factory], - provides=None, for_=(IDummy,)) - - def test_provides_obtained_via_implementedBy(self): - from repoze.bfg.registry import Registry - context = DummyContext() - self._callFUT(context, [DummyFactory], for_=(IDummy,)) - regadapt = context.actions[0] - self.assertEqual(regadapt['discriminator'], - ('adapter', (IDummy,), IFactory, '')) - self.assertEqual(regadapt['callable'].im_func, - Registry.registerAdapter.im_func) - self.assertEqual(regadapt['args'], - (DummyFactory, (IDummy,), IFactory, '', None)) - - def test_multiple_factories_multiple_for(self): - context = DummyContext() - factory = DummyFactory() - self.assertRaises(ValueError, self._callFUT, context, - [factory, factory], - provides=IFactory, - for_=(IDummy, IDummy)) - - def test_no_factories_multiple_for(self): - context = DummyContext() - self.assertRaises(ValueError, self._callFUT, context, - factory=[], - provides=IFactory, - for_=(IDummy, IDummy)) - - def test_rolled_up_factories(self): - from repoze.bfg.registry import Registry - context = DummyContext() - factory = DummyFactory() - self._callFUT(context, - [factory, factory], - provides=IFactory, - for_=(IDummy,)) - regadapt = context.actions[0] - self.assertEqual(regadapt['discriminator'], - ('adapter', (IDummy,), IFactory, '')) - self.assertEqual(regadapt['callable'].im_func, - Registry.registerAdapter.im_func) - self.assertEqual(regadapt['args'][0].__module__, 'repoze.bfg.zcml') - -class TestSubscriberDirective(unittest.TestCase): - def setUp(self): - testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _callFUT(self, *arg, **kw): - from repoze.bfg.zcml import subscriber - return subscriber(*arg, **kw) - - def test_no_factory_no_handler(self): - context = DummyContext() - self.assertRaises(TypeError, - self._callFUT, context, for_=None, factory=None, - handler=None, - provides=None) - - def test_handler_with_provides(self): - context = DummyContext() - self.assertRaises(TypeError, - self._callFUT, context, for_=None, factory=None, - handler=1, provides=1) - - def test_handler_and_factory(self): - context = DummyContext() - self.assertRaises(TypeError, - self._callFUT, context, for_=None, factory=1, - handler=1, provides=None) - - def test_no_provides_with_factory(self): - context = DummyContext() - self.assertRaises(TypeError, - self._callFUT, context, for_=None, factory=1, - handler=None, provides=None) - - def test_adapted_by_as_for_is_None(self): - context = DummyContext() - factory = DummyFactory() - factory.__component_adapts__ = None - self.assertRaises(TypeError, self._callFUT, context, for_=None, - factory=factory, handler=None, provides=IFactory) - - def test_register_with_factory(self): - from repoze.bfg.registry import Registry - context = DummyContext() - factory = DummyFactory() - self._callFUT(context, for_=(IDummy,), - factory=factory, handler=None, provides=IFactory) - self.assertEqual(len(context.actions), 1) - subadapt = context.actions[0] - self.assertEqual(subadapt['discriminator'], None) - self.assertEqual(subadapt['callable'].im_func, - Registry.registerSubscriptionAdapter.im_func) - self.assertEqual(subadapt['args'], - (factory, (IDummy,), IFactory, None, None) ) - - def test_register_with_handler(self): - from repoze.bfg.configuration import Configurator - context = DummyContext() - factory = DummyFactory() - self._callFUT(context, for_=(IDummy,), - factory=None, handler=factory) - self.assertEqual(len(context.actions), 1) - subadapt = context.actions[0] - self.assertEqual(subadapt['discriminator'], None) - self.assertEqual(subadapt['callable'].im_func, - Configurator.add_subscriber.im_func) - self.assertEqual(subadapt['args'], (factory, (IDummy,), None) ) - -class TestUtilityDirective(unittest.TestCase): - def setUp(self): - testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _callFUT(self, *arg, **kw): - from repoze.bfg.zcml import utility - return utility(*arg, **kw) - - def test_factory_and_component(self): - context = DummyContext() - self.assertRaises(TypeError, self._callFUT, - context, factory=1, component=1) - - def test_missing_provides(self): - context = DummyContext() - self.assertRaises(TypeError, self._callFUT, context, provides=None) - - def test_provides_from_factory_implements(self): - from repoze.bfg.registry import Registry - context = DummyContext() - self._callFUT(context, factory=DummyFactory) - self.assertEqual(len(context.actions), 1) - utility = context.actions[0] - self.assertEqual(utility['discriminator'], ('utility', IFactory, '')) - self.assertEqual(utility['callable'].im_func, - Registry.registerUtility.im_func) - self.assertEqual(utility['args'], (None, IFactory, '', None)) - self.assertEqual(utility['kw'], {'factory':DummyFactory}) - - def test_provides_from_component_provides(self): - from repoze.bfg.registry import Registry - context = DummyContext() - component = DummyFactory() - self._callFUT(context, component=component) - self.assertEqual(len(context.actions), 1) - utility = context.actions[0] - self.assertEqual(utility['discriminator'], ('utility', IFactory, '')) - self.assertEqual(utility['callable'].im_func, - Registry.registerUtility.im_func) - self.assertEqual(utility['args'], (component, IFactory, '', None)) - self.assertEqual(utility['kw'], {}) - -class TestTranslationDirDirective(unittest.TestCase): - def setUp(self): - testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _callFUT(self, *arg, **kw): - from repoze.bfg.zcml import translationdir - return translationdir(*arg, **kw) - - def test_it(self): - from repoze.bfg.configuration import Configurator - context = DummyContext() - tdir = 'repoze.bfg.tests.localeapp:locale' - self._callFUT(context, tdir) - actions = context.actions - self.assertEqual(len(actions), 1) - action = context.actions[0] - self.assertEqual(action['discriminator'], ('tdir', tdir)) - self.assertEqual(action['callable'].im_func, - Configurator.add_translation_dirs.im_func) - self.assertEqual(action['args'], (tdir,)) - action['callable'](*action['args']) # doesn't blow up - -class TestLocaleNegotiatorDirective(unittest.TestCase): - def setUp(self): - testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _callFUT(self, *arg, **kw): - from repoze.bfg.zcml import localenegotiator - return localenegotiator(*arg, **kw) - - def test_it(self): - from repoze.bfg.configuration import Configurator - context = DummyContext() - dummy_negotiator = object() - self._callFUT(context, dummy_negotiator) - actions = context.actions - self.assertEqual(len(actions), 1) - action = context.actions[0] - self.assertEqual(action['discriminator'], 'lnegotiator') - self.assertEqual(action['callable'].im_func, - Configurator.set_locale_negotiator.im_func) - self.assertEqual(action['args'], (dummy_negotiator,)) - action['callable'](*action['args']) # doesn't blow up - -class TestDefaultPermissionDirective(unittest.TestCase): - def setUp(self): - testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _callFUT(self, context, name): - from repoze.bfg.zcml import default_permission - return default_permission(context, name) - - def test_it(self): - from repoze.bfg.threadlocal import get_current_registry - from repoze.bfg.interfaces import IDefaultPermission - reg = get_current_registry() - context = DummyContext() - self._callFUT(context, 'view') - actions = context.actions - self.assertEqual(len(actions), 1) - regadapt = actions[0] - self.assertEqual(regadapt['discriminator'], IDefaultPermission) - perm = reg.getUtility(IDefaultPermission) - self.assertEqual(perm, 'view') - -class TestLoadZCML(unittest.TestCase): - def setUp(self): - testing.setUp() - - def tearDown(self): - testing.tearDown() - - def test_it(self): - from zope.configuration import xmlconfig - import repoze.bfg.includes - xmlconfig.file('configure.zcml', package=repoze.bfg.includes) - -class TestRolledUpFactory(unittest.TestCase): - def _callFUT(self, *factories): - from repoze.bfg.zcml import _rolledUpFactory - return _rolledUpFactory(factories) - - def test_it(self): - def foo(ob): - return ob - factory = self._callFUT(foo, foo) - result = factory(True) - self.assertEqual(result, True) - -class Test_path_spec(unittest.TestCase): - def _callFUT(self, context, path): - from repoze.bfg.zcml import path_spec - return path_spec(context, path) - - def test_no_package_attr(self): - context = DummyContext() - path = '/thepath' - result = self._callFUT(context, path) - self.assertEqual(result, path) - - def test_package_attr_None(self): - context = DummyContext() - context.package = None - path = '/thepath' - result = self._callFUT(context, path) - self.assertEqual(result, path) - - def test_package_path_doesnt_start_with_abspath(self): - context = DummyContext() - context.package = DummyPackage('repoze.bfg.tests') - path = '/thepath' - result = self._callFUT(context, path) - self.assertEqual(result, path) - - def test_package_path_starts_with_abspath(self): - import pkg_resources - import os - context = DummyContext() - package = DummyPackage('repoze.bfg.tests') - package_path = pkg_resources.resource_filename('repoze.bfg.tests', '') - template_path = os.path.join(package_path, 'templates/foo.pt') - context.package = package - result = self._callFUT(context, template_path) - self.assertEqual(result, 'repoze.bfg.tests:templates/foo.pt') - - def test_package_name_is___main__(self): - context = DummyContext() - package = DummyPackage('__main__') - context.package = package - result = self._callFUT(context, '/foo.pt') - self.assertEqual(result, '/foo.pt') - - def test_path_is_already_resource_spec(self): - context = DummyContext() - result = self._callFUT(context, 'repoze.bfg.tests:foo.pt') - self.assertEqual(result, 'repoze.bfg.tests:foo.pt') - -class IDummy(Interface): - pass - -class IFactory(Interface): - pass - -class DummyFactory(object): - implements(IFactory) - def __call__(self): - """ """ - -class DummyModule: - __path__ = "foo" - __name__ = "dummy" - __file__ = '' - -class DummyContext: - def __init__(self, resolved=DummyModule): - self.actions = [] - self.info = None - self.resolved = resolved - self.package = None - - def action(self, discriminator, callable=None, args=(), kw={}, order=0): - self.actions.append( - {'discriminator':discriminator, - 'callable':callable, - 'args':args, - 'kw':kw} - ) - - def path(self, path): - return path - - def resolve(self, dottedname): - return self.resolved - -class Dummy: - pass - -class DummyRoute: - pass - -class DummyRequest: - subpath = () - def __init__(self, environ=None): - if environ is None: - environ = {} - self.environ = environ - self.path_info = environ.get('PATH_INFO', None) - - def get_response(self, app): - return app - - def copy(self): - return self - -class DummyPackage(object): - def __init__(self, name): - self.__name__ = name - self.__file__ = '/__init__.py' - diff --git a/repoze/bfg/tests/viewdecoratorapp/__init__.py b/repoze/bfg/tests/viewdecoratorapp/__init__.py deleted file mode 100644 index 5bb534f79..000000000 --- a/repoze/bfg/tests/viewdecoratorapp/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# package diff --git a/repoze/bfg/tests/viewdecoratorapp/configure.zcml b/repoze/bfg/tests/viewdecoratorapp/configure.zcml deleted file mode 100644 index 6867046df..000000000 --- a/repoze/bfg/tests/viewdecoratorapp/configure.zcml +++ /dev/null @@ -1,6 +0,0 @@ -<configure xmlns="http://namespaces.repoze.org/bfg"> - - <include package="repoze.bfg.includes" /> - <scan package="."/> - -</configure> diff --git a/repoze/bfg/tests/viewdecoratorapp/views/__init__.py b/repoze/bfg/tests/viewdecoratorapp/views/__init__.py deleted file mode 100644 index 5bb534f79..000000000 --- a/repoze/bfg/tests/viewdecoratorapp/views/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# package diff --git a/repoze/bfg/tests/viewdecoratorapp/views/templates/foo.pt b/repoze/bfg/tests/viewdecoratorapp/views/templates/foo.pt deleted file mode 100644 index 6a2f701b6..000000000 --- a/repoze/bfg/tests/viewdecoratorapp/views/templates/foo.pt +++ /dev/null @@ -1,3 +0,0 @@ -<html> -${result} -</html> diff --git a/repoze/bfg/tests/viewdecoratorapp/views/views.py b/repoze/bfg/tests/viewdecoratorapp/views/views.py deleted file mode 100644 index 29f8c7fd4..000000000 --- a/repoze/bfg/tests/viewdecoratorapp/views/views.py +++ /dev/null @@ -1,17 +0,0 @@ -import os -from repoze.bfg.view import bfg_view - -@bfg_view(renderer='templates/foo.pt', name='first') -def first(request): - return {'result':'OK1'} - -@bfg_view(renderer='repoze.bfg.tests.viewdecoratorapp.views:templates/foo.pt', - name='second') -def second(request): - return {'result':'OK2'} - -here = os.path.normpath(os.path.dirname(os.path.abspath(__file__))) -foo = os.path.join(here, 'templates', 'foo.pt') -@bfg_view(renderer=foo, name='third') -def third(request): - return {'result':'OK3'} diff --git a/repoze/bfg/threadlocal.py b/repoze/bfg/threadlocal.py deleted file mode 100644 index 631cca62a..000000000 --- a/repoze/bfg/threadlocal.py +++ /dev/null @@ -1,61 +0,0 @@ -import threading - -from repoze.bfg.registry import global_registry - -class ThreadLocalManager(threading.local): - def __init__(self, default=None): - # http://code.google.com/p/google-app-engine-django/issues/detail?id=119 - # we *must* use a keword argument for ``default`` here instead - # of a positional argument to work around a bug in the - # implementation of _threading_local.local in Python, which is - # used by GAE instead of _thread.local - self.stack = [] - self.default = default - - def push(self, info): - self.stack.append(info) - - set = push # b/c - - def pop(self): - if self.stack: - return self.stack.pop() - - def get(self): - try: - return self.stack[-1] - except IndexError: - return self.default() - - def clear(self): - self.stack[:] = [] - -def defaults(): - return {'request':None, 'registry':global_registry} - -manager = ThreadLocalManager(default=defaults) - -def get_current_request(): - """Return the currently active request or ``None`` if no request - is currently active. - - This function should be used *extremely sparingly*, usually only - in unit testing code. it's almost always usually a mistake to use - ``get_current_request`` outside a testing context because its - usage makes it possible to write code that can be neither easily - tested nor scripted. - """ - return manager.get()['request'] - -def get_current_registry(context=None): # context required by getSiteManager API - """Return the currently active :term:`application registry` or the - global application registry if no request is currently active. - - This function should be used *extremely sparingly*, usually only - in unit testing code. it's almost always usually a mistake to use - ``get_current_registry`` outside a testing context because its - usage makes it possible to write code that can be neither easily - tested nor scripted. - """ - return manager.get()['registry'] - diff --git a/repoze/bfg/traversal.py b/repoze/bfg/traversal.py deleted file mode 100644 index 84365e2ff..000000000 --- a/repoze/bfg/traversal.py +++ /dev/null @@ -1,674 +0,0 @@ -import urllib - -from zope.interface import implements -from zope.interface.interfaces import IInterface - -from repoze.lru import lru_cache - -from repoze.bfg.interfaces import IContextURL -from repoze.bfg.interfaces import IRequestFactory -from repoze.bfg.interfaces import ITraverser -from repoze.bfg.interfaces import VH_ROOT_KEY - -from repoze.bfg.encode import url_quote -from repoze.bfg.exceptions import URLDecodeError -from repoze.bfg.location import lineage -from repoze.bfg.request import Request -from repoze.bfg.threadlocal import get_current_registry - -def find_root(model): - """ Find the root node in the graph to which ``model`` - belongs. Note that ``model`` should be :term:`location`-aware. - Note that the root node is available in the request object by - accessing the ``request.root`` attribute. - """ - for location in lineage(model): - if location.__parent__ is None: - model = location - break - return model - -def find_model(model, path): - """ Given a model object and a string or tuple representing a path - (such as the return value of - :func:`repoze.bfg.traversal.model_path` or - :func:`repoze.bfg.traversal.model_path_tuple`), return a context - in this application's model graph at the specified path. The - model passed in *must* be :term:`location`-aware. If the path - cannot be resolved (if the respective node in the graph does not - exist), a :exc:`KeyError` will be raised. - - This function is the logical inverse of - :func:`repoze.bfg.traversal.model_path` and - :func:`repoze.bfg.traversal.model_path_tuple`; it can resolve any - path string or tuple generated by either of those functions. - - Rules for passing a *string* as the ``path`` argument: if the - first character in the path string is the with the ``/`` - character, the path will considered absolute and the graph - traversal will start at the root object. If the first character - of the path string is *not* the ``/`` character, the path is - considered relative and graph traversal will begin at the model - object supplied to the function as the ``model`` argument. If an - empty string is passed as ``path``, the ``model`` passed in will - be returned. Model path strings must be escaped in the following - manner: each Unicode path segment must be encoded as UTF-8 and as - each path segment must escaped via Python's :mod:`urllib.quote`. - For example, ``/path/to%20the/La%20Pe%C3%B1a`` (absolute) or - ``to%20the/La%20Pe%C3%B1a`` (relative). The - :func:`repoze.bfg.traversal.model_path` function generates strings - which follow these rules (albeit only absolute ones). - - Rules for passing a *tuple* as the ``path`` argument: if the first - element in the path tuple is the empty string (for example ``('', - 'a', 'b', 'c')``, the path is considered absolute and the graph - traversal will start at the graph root object. If the first - element in the path tuple is not the empty string (for example - ``('a', 'b', 'c')``), the path is considered relative and graph - traversal will begin at the model object supplied to the function - as the ``model`` argument. If an empty sequence is passed as - ``path``, the ``model`` passed in itself will be returned. No - URL-quoting or UTF-8-encoding of individual path segments within - the tuple is required (each segment may be any string or unicode - object representing a model name). Model path tuples generated by - :func:`repoze.bfg.traversal.model_path_tuple` can always be - resolved by ``find_model``. - """ - D = traverse(model, path) - view_name = D['view_name'] - context = D['context'] - if view_name: - raise KeyError('%r has no subelement %s' % (context, view_name)) - return context - -def find_interface(model, class_or_interface): - """ - Return the first object found in the parent chain of ``model`` - which, a) if ``class_or_interface`` is a Python class object, is - an instance of the class or any subclass of that class or b) if - ``class_or_interface`` is a :term:`interface`, provides the - specified interface. Return ``None`` if no object providing - ``interface_or_class`` can be found in the parent chain. The - ``model`` passed in *must* be :term:`location`-aware. - """ - if IInterface.providedBy(class_or_interface): - test = class_or_interface.providedBy - else: - test = lambda arg: isinstance(arg, class_or_interface) - for location in lineage(model): - if test(location): - return location - -def model_path(model, *elements): - """ Return a string object representing the absolute physical path - of the model object based on its position in the model graph, e.g - ``/foo/bar``. Any positional arguments passed in as ``elements`` - will be appended as path segments to the end of the model path. - For instance, if the model's path is ``/foo/bar`` and ``elements`` - equals ``('a', 'b')``, the returned string will be - ``/foo/bar/a/b``. The first character in the string will always - be the ``/`` character (a leading ``/`` character in a path string - represents that the path is absolute). - - Model path strings returned will be escaped in the following - manner: each unicode path segment will be encoded as UTF-8 and - each path segment will be escaped via Python's :mod:`urllib.quote`. - For example, ``/path/to%20the/La%20Pe%C3%B1a``. - - This function is a logical inverse of - :mod:`repoze.bfg.traversal.find_model`: it can be used to generate - path references that can later be resolved via that function. - - The ``model`` passed in *must* be :term:`location`-aware. - - .. note:: Each segment in the path string returned will use the - ``__name__`` attribute of the model it represents within - the graph. Each of these segments *should* be a unicode - or string object (as per the contract of - :term:`location`-awareness). However, no conversion or - safety checking of model names is performed. For - instance, if one of the models in your graph has a - ``__name__`` which (by error) is a dictionary, the - :func:`repoze.bfg.traversal.model_path` function will - attempt to append it to a string and it will cause a - :exc:`repoze.bfg.exceptions.URLDecodeError`. - - .. note:: The :term:`root` model *must* have a ``__name__`` - attribute with a value of either ``None`` or the empty - string for paths to be generated properly. If the root - model has a non-null ``__name__`` attribute, its name - will be prepended to the generated path rather than a - single leading '/' character. - """ - # joining strings is a bit expensive so we delegate to a function - # which caches the joined result for us - return _join_path_tuple(model_path_tuple(model, *elements)) - -def traverse(model, path): - """Given a model object as ``model`` and a string or tuple - representing a path as ``path`` (such as the return value of - :func:`repoze.bfg.traversal.model_path` or - :func:`repoze.bfg.traversal.model_path_tuple` or the value of - ``request.environ['PATH_INFO']``), return a dictionary with the - keys ``context``, ``root``, ``view_name``, ``subpath``, - ``traversed``, ``virtual_root``, and ``virtual_root_path``. - - A definition of each value in the returned dictionary: - - - ``context``: The :term:`context` (a :term:`model` object) found - via traversal or url dispatch. If the ``path`` passed in is the - empty string, the value of the ``model`` argument passed to this - function is returned. - - - ``root``: The model object at which :term:`traversal` begins. - If the ``model`` passed in was found via url dispatch or if the - ``path`` passed in was relative (non-absolute), the value of the - ``model`` argument passed to this function is returned. - - - ``view_name``: The :term:`view name` found during - :term:`traversal` or :term:`url dispatch`; if the ``model`` was - found via traversal, this is usually a representation of the - path segment which directly follows the path to the ``context`` - in the ``path``. The ``view_name`` will be a Unicode object or - the empty string. The ``view_name`` will be the empty string if - there is no element which follows the ``context`` path. An - example: if the path passed is ``/foo/bar``, and a context - object is found at ``/foo`` (but not at ``/foo/bar``), the 'view - name' will be ``u'bar'``. If the ``model`` was found via - urldispatch, the view_name will be the name the route found was - registered with. - - - ``subpath``: For a ``model`` found via :term:`traversal`, this - is a sequence of path segments found in the ``path`` that follow - the ``view_name`` (if any). Each of these items is a Unicode - object. If no path segments follow the ``view_name``, the - subpath will be the empty sequence. An example: if the path - passed is ``/foo/bar/baz/buz``, and a context object is found at - ``/foo`` (but not ``/foo/bar``), the 'view name' will be - ``u'bar'`` and the :term:`subpath` will be ``[u'baz', u'buz']``. - For a ``model`` found via url dispatch, the subpath will be a - sequence of values discerned from ``*subpath`` in the route - pattern matched or the empty sequence. - - - ``traversed``: The sequence of path elements traversed from the - root to find the ``context`` object during :term:`traversal`. - Each of these items is a Unicode object. If no path segments - were traversed to find the ``context`` object (e.g. if the - ``path`` provided is the empty string), the ``traversed`` value - will be the empty sequence. If the ``model`` is a model found - via :term:`url dispatch`, traversed will be None. - - - ``virtual_root``: A model object representing the 'virtual' root - of the object graph being traversed during :term:`traversal`. - See :ref:`vhosting_chapter` for a definition of the virtual root - object. If no virtual hosting is in effect, and the ``path`` - passed in was absolute, the ``virtual_root`` will be the - *physical* root object (the object at which :term:`traversal` - begins). If the ``model`` passed in was found via :term:`URL - dispatch` or if the ``path`` passed in was relative, the - ``virtual_root`` will always equal the ``root`` object (the - model passed in). - - - ``virtual_root_path`` -- If :term:`traversal` was used to find - the ``model``, this will be the sequence of path elements - traversed to find the ``virtual_root`` object. Each of these - items is a Unicode object. If no path segments were traversed - to find the ``virtual_root`` object (e.g. if virtual hosting is - not in effect), the ``traversed`` value will be the empty list. - If url dispatch was used to find the ``model``, this will be - ``None``. - - If the path cannot be resolved, a :exc:`KeyError` will be raised. - - Rules for passing a *string* as the ``path`` argument: if the - first character in the path string is the with the ``/`` - character, the path will considered absolute and the graph - traversal will start at the root object. If the first character - of the path string is *not* the ``/`` character, the path is - considered relative and graph traversal will begin at the model - object supplied to the function as the ``model`` argument. If an - empty string is passed as ``path``, the ``model`` passed in will - be returned. Model path strings must be escaped in the following - manner: each Unicode path segment must be encoded as UTF-8 and as - each path segment must escaped via Python's :mod:`urllib.quote`. - For example, ``/path/to%20the/La%20Pe%C3%B1a`` (absolute) or - ``to%20the/La%20Pe%C3%B1a`` (relative). The - :func:`repoze.bfg.traversal.model_path` function generates strings - which follow these rules (albeit only absolute ones). - - Rules for passing a *tuple* as the ``path`` argument: if the first - element in the path tuple is the empty string (for example ``('', - 'a', 'b', 'c')``, the path is considered absolute and the graph - traversal will start at the graph root object. If the first - element in the path tuple is not the empty string (for example - ``('a', 'b', 'c')``), the path is considered relative and graph - traversal will begin at the model object supplied to the function - as the ``model`` argument. If an empty sequence is passed as - ``path``, the ``model`` passed in itself will be returned. No - URL-quoting or UTF-8-encoding of individual path segments within - the tuple is required (each segment may be any string or unicode - object representing a model name). - - Explanation of the conversion of ``path`` segment values to - Unicode during traversal: Each segment is URL-unquoted, and - decoded into Unicode. Each segment is assumed to be encoded using - the UTF-8 encoding (or a subset, such as ASCII); a - :exc:`repoze.bfg.exceptions.URLDecodeError` is raised if a segment - cannot be decoded. If a segment name is empty or if it is ``.``, - it is ignored. If a segment name is ``..``, the previous segment - is deleted, and the ``..`` is ignored. As a result of this - process, the return values ``view_name``, each element in the - ``subpath``, each element in ``traversed``, and each element in - the ``virtual_root_path`` will be Unicode as opposed to a string, - and will be URL-decoded. - """ - - if hasattr(path, '__iter__'): - # the traverser factory expects PATH_INFO to be a string, not - # unicode and it expects path segments to be utf-8 and - # urlencoded (it's the same traverser which accepts PATH_INFO - # from user agents; user agents always send strings). - if path: - path = _join_path_tuple(tuple(path)) - else: - path = '' - - if path and path[0] == '/': - model = find_root(model) - - reg = get_current_registry() - request_factory = reg.queryUtility(IRequestFactory, default=Request) - request = request_factory.blank(path) - request.registry = reg - traverser = reg.queryAdapter(model, ITraverser) - if traverser is None: - traverser = ModelGraphTraverser(model) - - return traverser(request) - -def model_path_tuple(model, *elements): - """ - Return a tuple representing the absolute physical path of the - ``model`` object based on its position in an object graph, e.g - ``('', 'foo', 'bar')``. Any positional arguments passed in as - ``elements`` will be appended as elements in the tuple - representing the model path. For instance, if the model's - path is ``('', 'foo', 'bar')`` and elements equals ``('a', 'b')``, - the returned tuple will be ``('', 'foo', 'bar', 'a', b')``. The - first element of this tuple will always be the empty string (a - leading empty string element in a path tuple represents that the - path is absolute). - - This function is a logical inverse of - :func:`repoze.bfg.traversal.find_model`: it can be used to - generate path references that can later be resolved that function. - - The ``model`` passed in *must* be :term:`location`-aware. - - .. note:: Each segment in the path tuple returned will equal the - ``__name__`` attribute of the model it represents within - the graph. Each of these segments *should* be a unicode - or string object (as per the contract of - :term:`location`-awareness). However, no conversion or - safety checking of model names is performed. For - instance, if one of the models in your graph has a - ``__name__`` which (by error) is a dictionary, that - dictionary will be placed in the path tuple; no warning - or error will be given. - - .. note:: The :term:`root` model *must* have a ``__name__`` - attribute with a value of either ``None`` or the empty - string for path tuples to be generated properly. If - the root model has a non-null ``__name__`` attribute, - its name will be the first element in the generated - path tuple rather than the empty string. - """ - return tuple(_model_path_list(model, *elements)) - -def _model_path_list(model, *elements): - """ Implementation detail shared by model_path and model_path_tuple """ - path = [loc.__name__ or '' for loc in lineage(model)] - path.reverse() - path.extend(elements) - return path - -def virtual_root(model, request): - """ - Provided any :term:`model` and a :term:`request` object, return - the model object representing the :term:`virtual root` of the - current :term:`request`. Using a virtual root in a - :term:`traversal` -based :mod:`repoze.bfg` application permits - rooting, for example, the object at the traversal path ``/cms`` at - ``http://example.com/`` instead of rooting it at - ``http://example.com/cms/``. - - If the ``model`` passed in is a context obtained via - :term:`traversal`, and if the ``HTTP_X_VHM_ROOT`` key is in the - WSGI environment, the value of this key will be treated as a - 'virtual root path': the :func:`repoze.bfg.traversal.find_model` - API will be used to find the virtual root object using this path; - if the object is found, it will be returned. If the - ``HTTP_X_VHM_ROOT`` key is is not present in the WSGI environment, - the physical :term:`root` of the graph will be returned instead. - - Virtual roots are not useful at all in applications that use - :term:`URL dispatch`. Contexts obtained via URL dispatch don't - really support being virtually rooted (each URL dispatch context - is both its own physical and virtual root). However if this API - is called with a ``model`` argument which is a context obtained - via URL dispatch, the model passed in will be returned - unconditionally.""" - try: - reg = request.registry - except AttributeError: - reg = get_current_registry() # b/c - urlgenerator = reg.queryMultiAdapter((model, request), IContextURL) - if urlgenerator is None: - urlgenerator = TraversalContextURL(model, request) - return urlgenerator.virtual_root() - -@lru_cache(1000) -def traversal_path(path): - """ Given a ``PATH_INFO`` string (slash-separated path segments), - return a tuple representing that path which can be used to - traverse a graph. - - The ``PATH_INFO`` is split on slashes, creating a list of - segments. Each segment is URL-unquoted, and subsequently decoded - into Unicode. Each segment is assumed to be encoded using the - UTF-8 encoding (or a subset, such as ASCII); a - :exc:`repoze.bfg.exceptions.URLDecodeError` is raised if a segment - cannot be decoded. If a segment name is empty or if it is ``.``, - it is ignored. If a segment name is ``..``, the previous segment - is deleted, and the ``..`` is ignored. - - If this function is passed a Unicode object instead of a string, - that Unicode object *must* directly encodeable to ASCII. For - example, u'/foo' will work but u'/<unprintable unicode>' (a - Unicode object with characters that cannot be encoded to ascii) - will not. - - .. note: New in version 1.3, this API eagerly attempts to encode a - Unicode ``path`` into ASCII before attempting to split it and - decode its segments. This is for convenience. In version 1.2 - and prior, if the path was Unicode, an inappropriate call to - the ``decode()`` method of a Unicode path segment could cause a - ``UnicodeDecodeError`` to occur even if the Unicode - representation of the path contained no 'high order' - characters. - - Examples: - - ``/`` - - () - - ``/foo/bar/baz`` - - (u'foo', u'bar', u'baz') - - ``foo/bar/baz`` - - (u'foo', u'bar', u'baz') - - ``/foo/bar/baz/`` - - (u'foo', u'bar', u'baz') - - ``/foo//bar//baz/`` - - (u'foo', u'bar', u'baz') - - ``/foo/bar/baz/..`` - - (u'foo', u'bar') - - ``/my%20archives/hello`` - - (u'my archives', u'hello') - - ``/archives/La%20Pe%C3%B1a`` - - (u'archives', u'<unprintable unicode>') - - .. note:: This function does not generate the same type of tuples - that :func:`repoze.bfg.traversal.model_path_tuple` does. - In particular, the leading empty string is not present - in the tuple it returns, unlike tuples returned by - :func:`repoze.bfg.traversal.model_path_tuple`. As a - result, tuples generated by ``traversal_path`` are not - resolveable by the - :func:`repoze.bfg.traversal.find_model` API. - ``traversal_path`` is a function mostly used by the - internals of :mod:`repoze.bfg` and by people writing - their own traversal machinery, as opposed to users - writing applications in :mod:`repoze.bfg`. - """ - if isinstance(path, unicode): - path = path.encode('ascii') - path = path.strip('/') - clean = [] - for segment in path.split('/'): - segment = urllib.unquote(segment) # deal with spaces in path segment - if not segment or segment=='.': - continue - elif segment == '..': - del clean[-1] - else: - try: - segment = segment.decode('utf-8') - except UnicodeDecodeError, e: - raise URLDecodeError( - e.encoding, e.object, e.start, e.end, e.reason - ) - clean.append(segment) - return tuple(clean) - -_segment_cache = {} - -def quote_path_segment(segment): - """ Return a quoted representation of a 'path segment' (such as - the string ``__name__`` attribute of a model) as a string. If the - ``segment`` passed in is a unicode object, it is converted to a - UTF-8 string, then it is URL-quoted using Python's - ``urllib.quote``. If the ``segment`` passed in is a string, it is - URL-quoted using Python's :mod:`urllib.quote`. If the segment - passed in is not a string or unicode object, an error will be - raised. The return value of ``quote_path_segment`` is always a - string, never Unicode. - - .. note:: The return value for each segment passed to this - function is cached in a module-scope dictionary for - speed: the cached version is returned when possible - rather than recomputing the quoted version. No cache - emptying is ever done for the lifetime of an - application, however. If you pass arbitrary - user-supplied strings to this function (as opposed to - some bounded set of values from a 'working set' known to - your application), it may become a memory leak. - """ - # The bit of this code that deals with ``_segment_cache`` is an - # optimization: we cache all the computation of URL path segments - # in this module-scope dictionary with the original string (or - # unicode value) as the key, so we can look it up later without - # needing to reencode or re-url-quote it - try: - return _segment_cache[segment] - except KeyError: - if segment.__class__ is unicode: # isinstance slighly slower (~15%) - result = url_quote(segment.encode('utf-8')) - else: - result = url_quote(segment) - # we don't need a lock to mutate _segment_cache, as the below - # will generate exactly one Python bytecode (STORE_SUBSCR) - _segment_cache[segment] = result - return result - -class ModelGraphTraverser(object): - """ A model graph traverser that should be used (for speed) when - every object in the graph supplies a ``__name__`` and - ``__parent__`` attribute (ie. every object in the graph is - :term:`location` aware) .""" - - implements(ITraverser) - - VIEW_SELECTOR = '@@' - - def __init__(self, root): - self.root = root - - def __call__(self, request): - try: - environ = request.environ - except AttributeError: - # In BFG 1.0 and before, this API expected an environ - # rather than a request; some bit of code may still be - # passing us an environ. If so, deal. - environ = request - - if 'bfg.routes.matchdict' in environ: - matchdict = environ['bfg.routes.matchdict'] - - path = matchdict.get('traverse', '/') - if hasattr(path, '__iter__'): - # this is a *traverse stararg (not a :traverse) - path = '/'.join([quote_path_segment(x) for x in path]) or '/' - - subpath = matchdict.get('subpath', ()) - if not hasattr(subpath, '__iter__'): - # this is not a *subpath stararg (just a :subpath) - subpath = traversal_path(subpath) - - else: - # this request did not match a route - subpath = () - try: - path = environ['PATH_INFO'] or '/' - except KeyError: - path = '/' - - if VH_ROOT_KEY in environ: - vroot_path = environ[VH_ROOT_KEY] - vroot_tuple = traversal_path(vroot_path) - vpath = vroot_path + path - vroot_idx = len(vroot_tuple) -1 - else: - vroot_tuple = () - vpath = path - vroot_idx = -1 - - root = self.root - ob = vroot = root - - if vpath == '/' or (not vpath): - # prevent a call to traversal_path if we know it's going - # to return the empty tuple - vpath_tuple = () - else: - # we do dead reckoning here via tuple slicing instead of - # pushing and popping temporary lists for speed purposes - # and this hurts readability; apologies - i = 0 - view_selector = self.VIEW_SELECTOR - vpath_tuple = traversal_path(vpath) - for segment in vpath_tuple: - if segment[:2] == view_selector: - return {'context':ob, - 'view_name':segment[2:], - 'subpath':vpath_tuple[i+1:], - 'traversed':vpath_tuple[:vroot_idx+i+1], - 'virtual_root':vroot, - 'virtual_root_path':vroot_tuple, - 'root':root} - try: - getitem = ob.__getitem__ - except AttributeError: - return {'context':ob, - 'view_name':segment, - 'subpath':vpath_tuple[i+1:], - 'traversed':vpath_tuple[:vroot_idx+i+1], - 'virtual_root':vroot, - 'virtual_root_path':vroot_tuple, - 'root':root} - - try: - next = getitem(segment) - except KeyError: - return {'context':ob, - 'view_name':segment, - 'subpath':vpath_tuple[i+1:], - 'traversed':vpath_tuple[:vroot_idx+i+1], - 'virtual_root':vroot, - 'virtual_root_path':vroot_tuple, - 'root':root} - if i == vroot_idx: - vroot = next - ob = next - i += 1 - - return {'context':ob, 'view_name':u'', 'subpath':subpath, - 'traversed':vpath_tuple, 'virtual_root':vroot, - 'virtual_root_path':vroot_tuple, 'root':root} - -class TraversalContextURL(object): - """ The IContextURL adapter used to generate URLs for a context - object obtained via graph traversal""" - implements(IContextURL) - - vroot_varname = VH_ROOT_KEY - - def __init__(self, context, request): - self.context = context - self.request = request - - def virtual_root(self): - environ = self.request.environ - vroot_varname = self.vroot_varname - if vroot_varname in environ: - return find_model(self.context, environ[vroot_varname]) - # shortcut instead of using find_root; we probably already - # have it on the request - try: - return self.request.root - except AttributeError: - return find_root(self.context) - - def __call__(self): - """ Generate a URL based on the :term:`lineage` of a - :term:`model` object obtained via :term:`traversal`. If any - model in the context lineage has a Unicode name, it will be - converted to a UTF-8 string before being attached to the URL. - If a ``HTTP_X_VHM_ROOT`` key is present in the WSGI - environment, its value will be treated as a 'virtual root - path': the path of the URL generated by this will be - left-stripped of this virtual root path value. - """ - path = model_path(self.context) - if path != '/': - path = path + '/' - request = self.request - environ = request.environ - vroot_varname = self.vroot_varname - - # if the path starts with the virtual root path, trim it out - if vroot_varname in environ: - vroot_path = environ[vroot_varname] - if path.startswith(vroot_path): - path = path[len(vroot_path):] - - app_url = request.application_url # never ends in a slash - return app_url + path - -@lru_cache(1000) -def _join_path_tuple(tuple): - return tuple and '/'.join([quote_path_segment(x) for x in tuple]) or '/' - -class DefaultRootFactory: - __parent__ = None - __name__ = None - def __init__(self, request): - matchdict = getattr(request, 'matchdict', {}) - # 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(matchdict) diff --git a/repoze/bfg/url.py b/repoze/bfg/url.py deleted file mode 100644 index d1532f7ef..000000000 --- a/repoze/bfg/url.py +++ /dev/null @@ -1,327 +0,0 @@ -""" Utility functions for dealing with URLs in repoze.bfg """ - -import os - -from repoze.lru import lru_cache - -from repoze.bfg.interfaces import IContextURL -from repoze.bfg.interfaces import IRoutesMapper -from repoze.bfg.interfaces import IStaticURLInfo - -from repoze.bfg.encode import urlencode -from repoze.bfg.path import caller_package -from repoze.bfg.threadlocal import get_current_registry -from repoze.bfg.traversal import TraversalContextURL -from repoze.bfg.traversal import quote_path_segment - -def route_url(route_name, request, *elements, **kw): - """Generates a fully qualified URL for a named :mod:`repoze.bfg` - :term:`route configuration`. - - Use the route's ``name`` as the first positional argument. Use a - request object as the second positional argument. Additional - positional arguments are appended to the URL as path segments - after it is generated. - - Use keyword arguments to supply values which match any dynamic - path elements in the route definition. Raises a :exc:`KeyError` - exception if the URL cannot be generated for any reason (not - enough arguments, for example). - - For example, if you've defined a route named "foobar" with the path - ``:foo/:bar/*traverse``:: - - route_url('foobar', request, foo='1') => <KeyError exception> - route_url('foobar', request, foo='1', bar='2') => <KeyError exception> - route_url('foobar', request, foo='1', bar='2', - 'traverse=('a','b')) => http://e.com/1/2/a/b - route_url('foobar', request, foo='1', bar='2', - 'traverse=('/a/b')) => http://e.com/1/2/a/b - - Values replacing ``:segment`` arguments can be passed as strings - or Unicode objects. They will be encoded to UTF-8 and URL-quoted - before being placed into the generated URL. - - Values replacing ``*remainder`` arguments can be passed as strings - *or* tuples of Unicode/string values. If a tuple is passed as a - ``*remainder`` replacement value, its values are URL-quoted and - encoded to UTF-8. The resulting strings are joined with slashes - and rendered into the URL. If a string is passed as a - ``*remainder`` replacement value, it is tacked on to the URL - untouched. - - If a keyword argument ``_query`` is present, it will used to - compose a query string that will be tacked on to the end of the - URL. The value of ``_query`` must be a sequence of two-tuples - *or* a data structure with an ``.items()`` method that returns a - sequence of two-tuples (presumably a dictionary). This data - structure will be turned into a query string per the documentation - of :func:`repoze.bfg.encode.urlencode` function. After the query - data is turned into a query string, a leading ``?`` is prepended, - and the resulting string is appended to the generated URL. - - .. note:: Python data structures that are passed as ``_query`` - which are sequences or dictionaries are turned into a - string under the same rules as when run through - :func:`urllib.urlencode` with the ``doseq`` argument - equal to ``True``. This means that sequences can be - passed as values, and a k=v pair will be placed into the - query string for each value. - - If a keyword argument ``_anchor`` is present, its string - representation will be used as a named anchor in the generated URL - (e.g. if ``_anchor`` is passed as ``foo`` and the model URL is - ``http://example.com/model/url``, the resulting generated URL will - be ``http://example.com/model/url#foo``). - - .. note:: If ``_anchor`` is passed as a string, it should be UTF-8 - encoded. If ``_anchor`` is passed as a Unicode object, it - will be converted to UTF-8 before being appended to the - URL. The anchor value is not quoted in any way before - being appended to the generated URL. - - If both ``_anchor`` and ``_query`` are specified, the anchor - element will always follow the query element, - e.g. ``http://example.com?foo=1#bar``. - - If a keyword ``_app_url`` is present, it will be used as the - protocol/hostname/port/leading path prefix of the generated URL. - For example, using an ``_app_url`` of - ``http://example.com:8080/foo`` would cause the URL - ``http://example.com:8080/foo/fleeb/flub`` to be returned from - this function if the expansion of the route pattern associated - with the ``route_name`` expanded to ``/fleeb/flub``. If - ``_app_url`` is not specified, the result of - ``request.application_url`` will be used as the prefix (the - default). - - .. note:: Special treatment of ``_app_url`` was added in - :mod:`repoze.bfg` 1.3. - - This function raises a :exc:`KeyError` if the URL cannot be - generated due to missing replacement names. Extra replacement - names are ignored. - - If the route object which matches the ``route_name`` argument has - a :term:`pregenerator`, the ``*elements`` and ``**kw`` arguments - arguments passed to this function might be augmented or changed. - """ - try: - reg = request.registry - except AttributeError: - reg = get_current_registry() # b/c - mapper = reg.getUtility(IRoutesMapper) - route = mapper.get_route(route_name) - - if route is None: - raise KeyError('No such route named %s' % route_name) - - if route.pregenerator is not None: - elements, kw = route.pregenerator(request, elements, kw) - - anchor = '' - qs = '' - app_url = None - - if '_query' in kw: - qs = '?' + urlencode(kw.pop('_query'), doseq=True) - - if '_anchor' in kw: - anchor = kw.pop('_anchor') - if isinstance(anchor, unicode): - anchor = anchor.encode('utf-8') - anchor = '#' + anchor - - if '_app_url' in kw: - app_url = kw.pop('_app_url') - - path = route.generate(kw) # raises KeyError if generate fails - - if elements: - suffix = _join_elements(elements) - if not path.endswith('/'): - suffix = '/' + suffix - else: - suffix = '' - - if app_url is None: - # we only defer lookup of application_url until here because - # it's somewhat expensive; we won't need to do it if we've - # been passed _app_url - app_url = request.application_url - - return app_url + path + suffix + qs + anchor - -def model_url(model, request, *elements, **kw): - """ - Generate a string representing the absolute URL of the ``model`` - object based on the ``wsgi.url_scheme``, ``HTTP_HOST`` or - ``SERVER_NAME`` in the ``request``, plus any ``SCRIPT_NAME``. The - overall result of this function is always a UTF-8 encoded string - (never Unicode). - - Examples:: - - model_url(context, request) => - - http://example.com/ - - model_url(context, request, 'a.html') => - - http://example.com/a.html - - model_url(context, request, 'a.html', query={'q':'1'}) => - - http://example.com/a.html?q=1 - - model_url(context, request, 'a.html', anchor='abc') => - - http://example.com/a.html#abc - - Any positional arguments passed in as ``elements`` must be strings - or Unicode objects. These will be joined by slashes and appended - to the generated model URL. Each of the elements passed in is - URL-quoted before being appended; if any element is Unicode, it - will converted to a UTF-8 bytestring before being URL-quoted. - - .. warning:: if no ``elements`` arguments are specified, the model - URL will end with a trailing slash. If any - ``elements`` are used, the generated URL will *not* - end in trailing a slash. - - If a keyword argument ``query`` is present, it will used to - compose a query string that will be tacked on to the end of the - URL. The value of ``query`` must be a sequence of two-tuples *or* - a data structure with an ``.items()`` method that returns a - sequence of two-tuples (presumably a dictionary). This data - structure will be turned into a query string per the documentation - of ``repoze.url.urlencode`` function. After the query data is - turned into a query string, a leading ``?`` is prepended, and the - resulting string is appended to the generated URL. - - .. note:: Python data structures that are passed as ``query`` - which are sequences or dictionaries are turned into a - string under the same rules as when run through - :func:`urllib.urlencode` with the ``doseq`` argument - equal to ``True``. This means that sequences can be - passed as values, and a k=v pair will be placed into the - query string for each value. - - If a keyword argument ``anchor`` is present, its string - representation will be used as a named anchor in the generated URL - (e.g. if ``anchor`` is passed as ``foo`` and the model URL is - ``http://example.com/model/url``, the resulting generated URL will - be ``http://example.com/model/url#foo``). - - .. note:: If ``anchor`` is passed as a string, it should be UTF-8 - encoded. If ``anchor`` is passed as a Unicode object, it - will be converted to UTF-8 before being appended to the - URL. The anchor value is not quoted in any way before - being appended to the generated URL. - - If both ``anchor`` and ``query`` are specified, the anchor element - will always follow the query element, - e.g. ``http://example.com?foo=1#bar``. - - .. note:: If the ``model`` used is the result of a - :term:`traversal`, it must be :term:`location`-aware. - The ``model`` can also be the context of a :term:`URL - dispatch`; contexts found this way do not need to be - location-aware. - - .. note:: If a 'virtual root path' is present in the request - environment (the value of the WSGI environ key - ``HTTP_X_VHM_ROOT``), and the ``model`` was obtained via - :term:`traversal`, the URL path will not include the - virtual root prefix (it will be stripped off the - left hand side of the generated URL). - """ - try: - reg = request.registry - except AttributeError: - reg = get_current_registry() # b/c - - context_url = reg.queryMultiAdapter((model, request), IContextURL) - if context_url is None: - context_url = TraversalContextURL(model, request) - model_url = context_url() - - qs = '' - anchor = '' - - if 'query' in kw: - qs = '?' + urlencode(kw['query'], doseq=True) - - if 'anchor' in kw: - anchor = kw['anchor'] - if isinstance(anchor, unicode): - anchor = anchor.encode('utf-8') - anchor = '#' + anchor - - if elements: - suffix = _join_elements(elements) - else: - suffix = '' - - return model_url + suffix + qs + anchor - -def static_url(path, request, **kw): - """ - Generates a fully qualified URL for a static :term:`resource`. - The resource must live within a location defined via the - :meth:`repoze.bfg.configuration.Configurator.add_static_view` - :term:`configuration declaration` or the ``<static>`` ZCML - directive (see :ref:`static_resources_section`). - - Example:: - - static_url('mypackage:static/foo.css', request) => - - http://example.com/static/foo.css - - - The ``path`` argument points at a file or directory on disk which - a URL should be generated for. The ``path`` may be either a - relative path (e.g. ``static/foo.css``) or a :term:`resource - specification` (e.g. ``mypackage:static/foo.css``). A ``path`` - may not be an absolute filesystem path (a :exc:`ValueError` will - be raised if this function is supplied with an absolute path). - - The ``request`` argument should be a :term:`request` object. - - The purpose of the ``**kw`` argument is the same as the purpose of - the :func:`repoze.bfg.url.route_url` ``**kw`` argument. See the - documentation for that function to understand the arguments which - you can provide to it. However, typically, you don't need to pass - anything as ``*kw`` when generating a static resource URL. - - This function raises a :exc:`ValueError` if a static view - definition cannot be found which matches the path specification. - - .. note:: This feature is new in :mod:`repoze.bfg` 1.1. - """ - if os.path.isabs(path): - raise ValueError('Absolute paths cannot be used to generate static ' - 'urls (use a package-relative path or a resource ' - 'specification).') - if not ':' in path: - # if it's not a package:relative/name and it's not an - # /absolute/path it's a relative/path; this means its relative - # to the package in which the caller's module is defined. - package = caller_package() - path = '%s:%s' % (package.__name__, path) - - try: - reg = request.registry - except AttributeError: - reg = get_current_registry() # b/c - - info = reg.queryUtility(IStaticURLInfo) - if info is None: - raise ValueError('No static URL definition matching %s' % path) - - return info.generate(path, request, **kw) - -@lru_cache(1000) -def _join_elements(elements): - return '/'.join([quote_path_segment(s) for s in elements]) diff --git a/repoze/bfg/urldispatch.py b/repoze/bfg/urldispatch.py deleted file mode 100644 index 8aca2c421..000000000 --- a/repoze/bfg/urldispatch.py +++ /dev/null @@ -1,148 +0,0 @@ -import re -from urllib import unquote -from zope.interface import implements - -from repoze.bfg.interfaces import IRoutesMapper -from repoze.bfg.interfaces import IRoute - -from repoze.bfg.compat import all -from repoze.bfg.encode import url_quote -from repoze.bfg.exceptions import URLDecodeError -from repoze.bfg.traversal import traversal_path -from repoze.bfg.traversal import quote_path_segment - - -_marker = object() - -class Route(object): - implements(IRoute) - def __init__(self, name, pattern, factory=None, predicates=(), - pregenerator=None): - self.pattern = pattern - self.path = pattern # indefinite b/w compat, not in interface - self.match, self.generate = _compile_route(pattern) - self.name = name - self.factory = factory - self.predicates = predicates - self.pregenerator = pregenerator - -class RoutesMapper(object): - implements(IRoutesMapper) - def __init__(self): - self.routelist = [] - self.routes = {} - - def has_routes(self): - return bool(self.routelist) - - def get_routes(self): - return self.routelist - - def get_route(self, name): - return self.routes.get(name) - - def connect(self, name, pattern, factory=None, predicates=(), - pregenerator=None): - if name in self.routes: - oldroute = self.routes[name] - self.routelist.remove(oldroute) - route = Route(name, pattern, factory, predicates, pregenerator) - self.routelist.append(route) - self.routes[name] = route - return route - - def generate(self, name, kw): - return self.routes[name].generate(kw) - - def __call__(self, request): - environ = request.environ - try: - # empty if mounted under a path in mod_wsgi, for example - path = environ['PATH_INFO'] or '/' - except KeyError: - path = '/' - - for route in self.routelist: - match = route.match(path) - if match is not None: - preds = route.predicates - info = {'match':match, 'route':route} - if preds and not all((p(info, request) for p in preds)): - continue - return info - - return {'route':None, 'match':None} - -# stolen from bobo and modified -route_re = re.compile(r'(/:[a-zA-Z]\w*)') -def _compile_route(route): - if not route.startswith('/'): - route = '/' + route - star = None - if '*' in route: - route, star = route.rsplit('*', 1) - pat = route_re.split(route) - pat.reverse() - rpat = [] - gen = [] - prefix = pat.pop() - if prefix: - rpat.append(re.escape(prefix)) - gen.append(prefix) - while pat: - name = pat.pop() - name = name[2:] - gen.append('/%%(%s)s' % name) - name = '/(?P<%s>[^/]+)' % name - rpat.append(name) - s = pat.pop() - if s: - rpat.append(re.escape(s)) - gen.append(s) - - if star: - rpat.append('(?P<%s>.*?)' % star) - gen.append('%%(%s)s' % star) - - pattern = ''.join(rpat) + '$' - - match = re.compile(pattern).match - def matcher(path): - m = match(path) - if m is None: - return m - d = {} - for k,v in m.groupdict().iteritems(): - if k is not None: - if k == star: - d[k] = traversal_path(v) - else: - encoded = unquote(v) - try: - d[k] = encoded.decode('utf-8') - except UnicodeDecodeError, e: - raise URLDecodeError( - e.encoding, e.object, e.start, e.end, e.reason - ) - - - return d - - - gen = ''.join(gen) - def generator(dict): - newdict = {} - for k, v in dict.items(): - if isinstance(v, unicode): - v = v.encode('utf-8') - if k == star and hasattr(v, '__iter__'): - v = '/'.join([quote_path_segment(x) for x in v]) - elif k != star: - try: - v = url_quote(v) - except TypeError: - pass - newdict[k] = v - return gen % newdict - - return matcher, generator diff --git a/repoze/bfg/view.py b/repoze/bfg/view.py deleted file mode 100644 index c5fd60623..000000000 --- a/repoze/bfg/view.py +++ /dev/null @@ -1,551 +0,0 @@ -import mimetypes -import os - -# See http://bugs.python.org/issue5853 which is a recursion bug -# that seems to effect Python 2.6, Python 2.6.1, and 2.6.2 (a fix -# has been applied on the Python 2 trunk). This workaround should -# really be in Paste if anywhere, but it's easiest to just do it -# here and get it over with to avoid needing to deal with any -# fallout. - -if hasattr(mimetypes, 'init'): - mimetypes.init() - -from webob.exc import HTTPFound - -import venusian - -from zope.deprecation import deprecated -from zope.interface import providedBy - -from repoze.bfg.interfaces import IRoutesMapper -from repoze.bfg.interfaces import IView -from repoze.bfg.interfaces import IViewClassifier - -from repoze.bfg.path import package_path -from repoze.bfg.resource import resource_spec_from_abspath -from repoze.bfg.static import static_view as static # B/C -from repoze.bfg.threadlocal import get_current_registry - -# b/c imports -from repoze.bfg.security import view_execution_permitted - -view_execution_permitted # prevent PyFlakes from complaining - -deprecated('view_execution_permitted', - "('from repoze.bfg.view import view_execution_permitted' was " - "deprecated as of repoze.bfg 1.0; instead use 'from " - "repoze.bfg.security import view_execution_permitted')", - ) - -deprecated('NotFound', - "('from repoze.bfg.view import NotFound' was " - "deprecated as of repoze.bfg 1.1; instead use 'from " - "repoze.bfg.exceptions import NotFound')", - ) - -static = static # dont yet deprecate this (ever?) - -_marker = object() - -def render_view_to_response(context, request, name='', secure=True): - """ Call the :term:`view callable` configured with a :term:`view - configuration` that matches the :term:`view name` ``name`` - registered against the specified ``context`` and ``request`` and - return a :term:`response` object. This function will return - ``None`` if a corresponding :term:`view callable` cannot be found - (when no :term:`view configuration` matches the combination of - ``name`` / ``context`` / and ``request``). - - If `secure`` is ``True``, and the :term:`view callable` found is - protected by a permission, the permission will be checked before - calling the view function. If the permission check disallows view - execution (based on the current :term:`authorization policy`), a - :exc:`repoze.bfg.exceptions.Forbidden` exception will be raised. - The exception's ``args`` attribute explains why the view access - was disallowed. - - If ``secure`` is ``False``, no permission checking is done.""" - provides = [IViewClassifier] + map(providedBy, (request, context)) - try: - reg = request.registry - except AttributeError: - reg = get_current_registry() - view = reg.adapters.lookup(provides, IView, name=name) - if view is None: - return None - - if not secure: - # the view will have a __call_permissive__ attribute if it's - # secured; otherwise it won't. - view = getattr(view, '__call_permissive__', view) - - # if this view is secured, it will raise a Forbidden - # appropriately if the executing user does not have the proper - # permission - return view(context, request) - -def render_view_to_iterable(context, request, name='', secure=True): - """ Call the :term:`view callable` configured with a :term:`view - configuration` that matches the :term:`view name` ``name`` - registered against the specified ``context`` and ``request`` and - return an iterable object which represents the body of a response. - This function will return ``None`` if a corresponding :term:`view - callable` cannot be found (when no :term:`view configuration` - matches the combination of ``name`` / ``context`` / and - ``request``). Additionally, this function will raise a - :exc:`ValueError` if a view function is found and called but the - view function's result does not have an ``app_iter`` attribute. - - You can usually get the string representation of the return value - of this function by calling ``''.join(iterable)``, or just use - :func:`repoze.bfg.view.render_view` instead. - - If ``secure`` is ``True``, and the view is protected by a - permission, the permission will be checked before the view - function is invoked. If the permission check disallows view - execution (based on the current :term:`authentication policy`), a - :exc:`repoze.bfg.exceptions.Forbidden` exception will be raised; - its ``args`` attribute explains why the view access was - disallowed. - - If ``secure`` is ``False``, no permission checking is - done.""" - response = render_view_to_response(context, request, name, secure) - if response is None: - return None - return response.app_iter - -def render_view(context, request, name='', secure=True): - """ Call the :term:`view callable` configured with a :term:`view - configuration` that matches the :term:`view name` ``name`` - registered against the specified ``context`` and ``request`` - and unwind the view response's ``app_iter`` (see - :ref:`the_response`) into a single string. This function will - return ``None`` if a corresponding :term:`view callable` cannot be - found (when no :term:`view configuration` matches the combination - of ``name`` / ``context`` / and ``request``). Additionally, this - function will raise a :exc:`ValueError` if a view function is - found and called but the view function's result does not have an - ``app_iter`` attribute. This function will return ``None`` if a - corresponding view cannot be found. - - If ``secure`` is ``True``, and the view is protected by a - permission, the permission will be checked before the view is - invoked. If the permission check disallows view execution (based - on the current :term:`authorization policy`), a - :exc:`repoze.bfg.exceptions.Forbidden` exception will be raised; - its ``args`` attribute explains why the view access was - disallowed. - - If ``secure`` is ``False``, no permission checking is done.""" - iterable = render_view_to_iterable(context, request, name, secure) - if iterable is None: - return None - return ''.join(iterable) - -def is_response(ob): - """ Return ``True`` if ``ob`` implements the interface implied by - :ref:`the_response`. ``False`` if not. - - .. note:: this isn't a true interface check (in Zope terms), it's a - duck-typing check, as response objects are not obligated to - actually implement a Zope interface.""" - # response objects aren't obligated to implement a Zope interface, - # so we do it the hard way - if ( hasattr(ob, 'app_iter') and hasattr(ob, 'headerlist') and - hasattr(ob, 'status') ): - if ( hasattr(ob.app_iter, '__iter__') and - hasattr(ob.headerlist, '__iter__') and - isinstance(ob.status, basestring) ) : - return True - return False - -class bfg_view(object): - """ A function, class or method :term:`decorator` which allows a - developer to create view registrations nearer to a :term:`view - callable` definition than use of :term:`ZCML` or :term:`imperative - configuration` to do the same. - - For example, this code in a module ``views.py``:: - - from models import MyModel - - @bfg_view(name='my_view', context=MyModel, permission='read', - route_name='site1') - def my_view(context, request): - return 'OK' - - Might replace the following call to the - :meth:`repoze.bfg.configuration.Configurator.add_view` method:: - - import views - import models - config.add_view(views.my_view, context=models.MyModel, name='my_view', - permission='read', 'route_name='site1') - - Or might replace the following ZCML ``view`` declaration:: - - <view - for='.models.MyModel' - view='.views.my_view' - name='my_view' - permission='read' - route_name='site1' - /> - - The following arguments are supported as arguments to - ``bfg_view``: ``context``, ``permission``, ``name``, - ``request_type``, ``route_name``, ``request_method``, - ``request_param``, ``containment``, ``xhr``, ``accept``, - ``header`` and ``path_info``. - - ``context`` should be a Python object or :term:`dotted Python - name` representing the context type that must be found for this - view to be called. If ``context`` is not supplied, the interface - ``zope.interface.Interface`` (matching any context) is used. An - alias for ``context`` is ``for_``. - - If ``permission`` is not supplied, no permission is registered for - this view (it's accessible by any caller). - - If ``name`` is not supplied, the empty string is used (implying - the default view name). - - If ``attr`` is not supplied, ``None`` is used (implying the - function itself if the view is a function, or the ``__call__`` - callable attribute if the view is a class). - - If ``renderer`` is not supplied, ``None`` is used (meaning that no - renderer is associated with this view). - - If ``wrapper`` is not supplied, ``None`` is used (meaning that no - view wrapper is associated with this view). - - If ``request_type`` is not supplied, the interface - :class:`repoze.bfg.interfaces.IRequest` is used, implying the - standard request interface type. - - If ``route_name`` is not supplied, the view configuration is - considered to be made against a URL that doesn't match any defined - :term:`route`. The use of a ``route_name`` is an advanced - feature, useful only if you're also using :term:`url dispatch`. - - If ``request_method`` is not supplied, this view will match a - request with any HTTP ``REQUEST_METHOD`` - (GET/POST/PUT/HEAD/DELETE). If this parameter *is* supplied, it - must be a string naming an HTTP ``REQUEST_METHOD``, indicating - that this view will only match when the current request has a - ``REQUEST_METHOD`` that matches this value. - - If ``request_param`` is not supplied, this view will be called - when a request with any (or no) request GET or POST parameters is - encountered. If the value is present, it must be a string. If - the value supplied to the parameter has no ``=`` sign in it, it - implies that the key must exist in the ``request.params`` - dictionary for this view to 'match' the current request. If the value - supplied to the parameter has a ``=`` sign in it, e.g. - ``request_params="foo=123"``, then the key (``foo``) must both exist - in the ``request.params`` dictionary, and the value must match the - right hand side of the expression (``123``) for the view to "match" the - current request. - - ``containment`` should be a Python object or :term:`dotted Python - name` representing a class or interface type which must be found - as one of the context's location parents for this view to be - called. If ``containment`` is not supplied, this view will be - called when the context of the request has any (or no) - :term:`lineage`. If ``containment`` *is* supplied, it must be a - class or :term:`interface`, denoting that the view'matches' the - current request only if any graph :term:`lineage` node possesses - this class or interface. - - If ``xhr`` is specified, it must be a boolean value. If the value - is ``True``, the view will only be invoked if the request's - ``X-Requested-With`` header has the value ``XMLHttpRequest``. - - If ``accept`` is specified, it must be a mimetype value. If - ``accept`` is specified, the view will only be invoked if the - ``Accept`` HTTP header matches the value requested. See the - description of ``accept`` in :ref:`view_directive` for information - about the allowable composition and matching behavior of this - value. - - If ``header`` is specified, it must be a header name or a - ``headername:headervalue`` pair. If ``header`` is specified, and - possesses a value the view will only be invoked if an HTTP header - matches the value requested. If ``header`` is specified without a - value (a bare header name only), the view will only be invoked if - the HTTP header exists with any value in the request. See the - description of ``header`` in :ref:`view_directive` for information - about the allowable composition and matching behavior of this - value. - - If ``path_info`` is specified, it must be a regular - expression. The view will only be invoked if the ``PATH_INFO`` - WSGI environment variable matches the expression. - - If ``custom_predicates`` is specified, it must be a sequence of - :term:`predicate` callables (a predicate callable accepts two - arguments: ``context`` and ``request`` and returns ``True`` or - ``False``). The view will only be invoked if all custom - predicates return ``True``. - - Any individual or all parameters can be omitted. The simplest - ``bfg_view`` declaration is:: - - @bfg_view() - def my_view(...): - ... - - Such a registration implies that the view name will be - ``my_view``, registered for any :term:`context` object, using no - permission, registered against all non-URL-dispatch-based - requests, with any ``REQUEST_METHOD``, any set of request.params - values, without respect to any object in the :term:`lineage`. - - The ``bfg_view`` decorator can also be used as a class decorator - in Python 2.6 and better (Python 2.5 and below do not support - class decorators):: - - from webob import Response - from repoze.bfg.view import bfg_view - - @bfg_view() - class MyView(object): - def __init__(self, context, request): - self.context = context - self.request = request - def __call__(self): - return Response('hello from %s!' % self.context) - - In Python 2.5 and below, the ``bfg_view`` decorator can still be - used against a class, although not in decorator form:: - - from webob import Response - from repoze.bfg.view import bfg_view - - class MyView(object): - def __init__(self, context, request): - self.context = context - self.request = request - def __call__(self): - return Response('hello from %s!' % self.context) - - MyView = bfg_view()(MyView) - - .. note:: When a view is a class, the calling semantics are - different than when it is a function or another - non-class callable. See :ref:`class_as_view` for more - information. - - .. warning:: Using a class as a view is a new feature in 0.8.1+. - - The bfg_view decorator can also be used against a class method:: - - from webob import Response - from repoze.bfg.view import bfg_view - - class MyView(object): - def __init__(self, context, request): - self.context = context - self.request = request - - @bfg_view(name='hello') - def amethod(self): - return Response('hello from %s!' % self.context) - - When the ``bfg_view`` decorator is used against a class method, a - view is registered for the *class* (as described above), so the - class constructor must accept either ``request`` or ``context, - request``. The method which is decorated must return a response - (or rely on a :term:`renderer` to generate one). Using the - decorator against a particular method of a class is equivalent to - using the ``attr`` parameter in a decorator attached to the class - itself. For example, the above registration implied by the - decorator being used against the ``amethod`` method could be - spelled equivalently as:: - - from webob import Response - from repoze.bfg.view import bfg_view - - @bfg_view(attr='amethod', name='hello') - class MyView(object): - def __init__(self, context, request): - self.context = context - self.request = request - - def amethod(self): - return Response('hello from %s!' % self.context) - - .. warning:: The ability to use the ``bfg_view`` decorator as a - method decorator is new in :mod:`repoze.bfg` version - 1.1. - - To make use of any ``bfg_view`` declaration, you must perform a - :term:`scan`. To do so, either insert the following boilerplate - into your application registry's ZCML:: - - <scan package="."/> - - See :ref:`scan_directive` for more information about the ZCML - ``scan`` directive. - - Or, if you don't use ZCML, use the - :meth:`repoze.bfg.configuration.Configurator.scan` method:: - - config.scan() - """ - venusian = venusian # for testing injection - def __init__(self, name='', request_type=None, for_=None, permission=None, - route_name=None, request_method=None, request_param=None, - containment=None, attr=None, renderer=None, wrapper=None, - xhr=False, accept=None, header=None, path_info=None, - custom_predicates=(), context=None): - self.name = name - self.request_type = request_type - self.context = context or for_ - self.permission = permission - self.route_name = route_name - self.request_method = request_method - self.request_param = request_param - self.containment = containment - self.attr = attr - self.renderer = renderer - self.wrapper = wrapper - self.xhr = xhr - self.accept = accept - self.header = header - self.path_info = path_info - self.custom_predicates = custom_predicates - - def __call__(self, wrapped): - settings = self.__dict__.copy() - - def callback(context, name, ob): - context.config.add_view(view=ob, **settings) - - info = self.venusian.attach(wrapped, callback, category='bfg') - - if info.scope == 'class': - # if the decorator was attached to a method in a class, or - # otherwise executed at class scope, we need to set an - # 'attr' into the settings if one isn't already in there - if settings['attr'] is None: - settings['attr'] = wrapped.__name__ - - # try to convert the renderer provided into a fully qualified - # resource specification - abspath = settings.get('renderer') - if abspath is not None and '.' in abspath: - isabs = os.path.isabs(abspath) - if not (':' in abspath and not isabs): - # not already a resource spec - if not isabs: - pp = package_path(info.module) - abspath = os.path.join(pp, abspath) - resource = resource_spec_from_abspath(abspath, info.module) - settings['renderer'] = resource - - return wrapped - -def default_exceptionresponse_view(context, request): - if not isinstance(context, Exception): - # backwards compat for an exception response view registered via - # config.set_notfound_view or config.set_forbidden_view - # instead of as a proper exception view - context = request.exception or context - return context - -class AppendSlashNotFoundViewFactory(object): - """ There can only be one :term:`Not Found view` in any - :mod:`repoze.bfg` application. Even if you use - :func:`repoze.bfg.view.append_slash_notfound_view` as the Not - Found view, :mod:`repoze.bfg` still must generate a ``404 Not - Found`` response when it cannot redirect to a slash-appended URL; - this not found response will be visible to site users. - - If you don't care what this 404 response looks like, and you only - need redirections to slash-appended route URLs, you may use the - :func:`repoze.bfg.view.append_slash_notfound_view` object as the - Not Found view. However, if you wish to use a *custom* notfound - view callable when a URL cannot be redirected to a slash-appended - URL, you may wish to use an instance of this class as the Not - Found view, supplying a :term:`view callable` to be used as the - custom notfound view as the first argument to its constructor. - For instance: - - .. code-block:: python - - from repoze.bfg.exceptions import NotFound - from repoze.bfg.view import AppendSlashNotFoundViewFactory - - def notfound_view(context, request): - return HTTPNotFound('It aint there, stop trying!') - - custom_append_slash = AppendSlashNotFoundViewFactory(notfound_view) - config.add_view(custom_append_slash, context=NotFound) - - The ``notfound_view`` supplied must adhere to the two-argument - view callable calling convention of ``(context, request)`` - (``context`` will be the exception object). - - .. note:: This class is new as of :mod:`repoze.bfg` version 1.3. - - """ - def __init__(self, notfound_view=None): - if notfound_view is None: - notfound_view = default_exceptionresponse_view - self.notfound_view = notfound_view - - def __call__(self, context, request): - if not isinstance(context, Exception): - # backwards compat for an append_notslash_view registered via - # config.set_notfound_view instead of as a proper exception view - context = request.exception - path = request.environ.get('PATH_INFO', '/') - registry = request.registry - mapper = registry.queryUtility(IRoutesMapper) - if mapper is not None and not path.endswith('/'): - slashpath = path + '/' - for route in mapper.get_routes(): - if route.match(slashpath) is not None: - return HTTPFound(location=slashpath) - return self.notfound_view(context, request) - -append_slash_notfound_view = AppendSlashNotFoundViewFactory() -append_slash_notfound_view.__doc__ = """\ -For behavior like Django's ``APPEND_SLASH=True``, use this view as the -:term:`Not Found view` in your application. - -When this view is the Not Found view (indicating that no view was -found), and any routes have been defined in the configuration of your -application, if the value of the ``PATH_INFO`` WSGI environment -variable does not already end in a slash, and if the value of -``PATH_INFO`` *plus* a slash matches any route's path, do an HTTP -redirect to the slash-appended PATH_INFO. Note that this will *lose* -``POST`` data information (turning it into a GET), so you shouldn't -rely on this to redirect POST requests. - -If you use :term:`ZCML`, add the following to your application's -``configure.zcml`` to use this view as the Not Found view:: - - <view - context="repoze.bfg.exceptions.NotFound" - view="repoze.bfg.view.append_slash_notfound_view"/> - -Or use the -:meth:`repoze.bfg.configuration.Configurator.add_view` -method if you don't use ZCML:: - - from repoze.bfg.exceptions import NotFound - from repoze.bfg.view import append_slash_notfound_view - config.add_view(append_slash_notfound_view, context=NotFound) - -See also :ref:`changing_the_notfound_view`. - -.. note:: This function is new as of :mod:`repoze.bfg` version 1.1. -""" - - - diff --git a/repoze/bfg/wsgi.py b/repoze/bfg/wsgi.py deleted file mode 100644 index c576253b3..000000000 --- a/repoze/bfg/wsgi.py +++ /dev/null @@ -1,97 +0,0 @@ -from repoze.bfg.compat import wraps -from repoze.bfg.traversal import quote_path_segment - -def wsgiapp(wrapped): - """ Decorator to turn a WSGI application into a :mod:`repoze.bfg` - :term:`view callable`. This decorator differs from the - :func:`repoze.bfg.wsgi.wsgiapp2` decorator inasmuch as fixups of - ``PATH_INFO`` and ``SCRIPT_NAME`` within the WSGI environment *are - not* performed before the application is invoked. - - E.g., the following in a ``views.py`` module:: - - @wsgiapp - def hello_world(environ, start_response): - body = 'Hello world' - start_response('200 OK', [ ('Content-Type', 'text/plain'), - ('Content-Length', len(body)) ] ) - return [body] - - Allows the following ZCML view declaration to be made:: - - <view - view=".views.hello_world" - name="hello_world.txt" - /> - - Or the following call to - :meth:`repoze.bfg.configuration.Configurator.add_view`:: - - from views import hello_world - config.add_view(hello_world, name='hello_world.txt') - - The ``wsgiapp`` decorator will convert the result of the WSGI - application to a :term:`Response` and return it to - :mod:`repoze.bfg` as if the WSGI app were a :mod:`repoze.bfg` - view. - - """ - def decorator(context, request): - return request.get_response(wrapped) - return wraps(wrapped)(decorator) # grokkability - -def wsgiapp2(wrapped): - """ Decorator to turn a WSGI application into a :mod:`repoze.bfg` - view callable. This decorator differs from the - :func:`repoze.bfg.wsgi.wsgiapp` decorator inasmuch as fixups of - ``PATH_INFO`` and ``SCRIPT_NAME`` within the WSGI environment - *are* performed before the application is invoked. - - E.g. the following in a ``views.py`` module:: - - @wsgiapp2 - def hello_world(environ, start_response): - body = 'Hello world' - start_response('200 OK', [ ('Content-Type', 'text/plain'), - ('Content-Length', len(body)) ] ) - return [body] - - Allows the following ZCML view declaration to be made:: - - <view - view=".views.hello_world" - name="hello_world.txt" - /> - - Or the following call to - :meth:`repoze.bfg.configuration.Configurator.add_view`:: - - from views import hello_world - config.add_view(hello_world, name='hello_world.txt') - - The ``wsgiapp2`` decorator will convert the result of the WSGI - application to a Response and return it to :mod:`repoze.bfg` as if - the WSGI app were a :mod:`repoze.bfg` view. The ``SCRIPT_NAME`` - and ``PATH_INFO`` values present in the WSGI environment are fixed - up before the application is invoked. """ - - def decorator(context, request): - traversed = request.traversed - vroot_path = request.virtual_root_path or () - view_name = request.view_name - subpath = request.subpath or () - script_tuple = traversed[len(vroot_path):] - script_list = [ quote_path_segment(name) for name in script_tuple ] - if view_name: - script_list.append(quote_path_segment(view_name)) - script_name = '/' + '/'.join(script_list) - path_list = [ quote_path_segment(name) for name in subpath ] - path_info = '/' + '/'.join(path_list) - request.environ['PATH_INFO'] = path_info - script_name = request.environ['SCRIPT_NAME'] + script_name - if script_name.endswith('/'): - script_name = script_name[:-1] - request.environ['SCRIPT_NAME'] = script_name - return request.get_response(wrapped) - return wraps(wrapped)(decorator) # grokkability - diff --git a/repoze/bfg/zcml.py b/repoze/bfg/zcml.py deleted file mode 100644 index 2bf394eb8..000000000 --- a/repoze/bfg/zcml.py +++ /dev/null @@ -1,903 +0,0 @@ -import os - -from zope.configuration import xmlconfig -from zope.configuration.config import ConfigurationMachine -from zope.configuration.fields import GlobalInterface -from zope.configuration.fields import GlobalObject -from zope.configuration.fields import Tokens - -from zope.interface.interfaces import IInterface -from zope.interface import Interface -from zope.interface import implementedBy -from zope.interface import providedBy - -from zope.schema import ASCIILine -from zope.schema import Bool -from zope.schema import Int -from zope.schema import TextLine - -from repoze.bfg.interfaces import IAuthenticationPolicy -from repoze.bfg.interfaces import IAuthorizationPolicy -from repoze.bfg.interfaces import IDefaultPermission -from repoze.bfg.interfaces import IRendererFactory -from repoze.bfg.interfaces import IRouteRequest -from repoze.bfg.interfaces import IView - -from repoze.bfg.authentication import AuthTktAuthenticationPolicy -from repoze.bfg.authentication import RemoteUserAuthenticationPolicy -from repoze.bfg.authentication import RepozeWho1AuthenticationPolicy -from repoze.bfg.authorization import ACLAuthorizationPolicy -from repoze.bfg.configuration import Configurator -from repoze.bfg.exceptions import ConfigurationError -from repoze.bfg.exceptions import NotFound -from repoze.bfg.exceptions import Forbidden -from repoze.bfg.request import route_request_iface -from repoze.bfg.resource import resource_spec_from_abspath -from repoze.bfg.static import StaticURLInfo -from repoze.bfg.threadlocal import get_current_registry - -###################### directives ########################## - -class IViewDirective(Interface): - context = GlobalObject( - title=u"The interface or class this view is for.", - required=False - ) - - for_ = GlobalObject( - title=(u"The interface or class this view is for (alternate spelling " - "of ``context``)."), - required=False - ) - - permission = TextLine( - title=u"Permission", - description=u"The permission needed to use the view.", - required=False - ) - - view = GlobalObject( - title=u"", - description=u"The view function", - required=False, - ) - - name = TextLine( - title=u"The name of the view", - description=u""" - The name shows up in URLs/paths. For example 'foo' or 'foo.html'.""", - required=False, - ) - - attr = TextLine( - title=u'The callable attribute of the view object(default is __call__)', - description=u'', - required=False) - - renderer = TextLine( - title=u'The renderer asssociated with the view', - description=u'', - required=False) - - wrapper = TextLine( - title = u'The *name* of the view that acts as a wrapper for this view.', - description = u'', - required=False) - - request_type = TextLine( - title=u"The request type string or dotted name interface for the view", - description=(u"The view will be called if the interface represented by " - u"'request_type' is implemented by the request. The " - u"default request type is repoze.bfg.interfaces.IRequest"), - required=False - ) - - route_name = TextLine( - title = u'The route that must match for this view to be used', - required = False) - - containment = GlobalObject( - title = u'Dotted name of a containment class or interface', - required=False) - - request_method = TextLine( - title = u'Request method name that must be matched (e.g. GET/POST)', - description = (u'The view will be called if and only if the request ' - 'method (``request.method``) matches this string. This' - 'functionality replaces the older ``request_type`` ' - 'functionality.'), - required=False) - - request_param = TextLine( - title = (u'Request parameter name that must exist in ' - '``request.params`` for this view to match'), - description = (u'The view will be called if and only if the request ' - 'parameter exists which matches this string.'), - required=False) - - xhr = Bool( - title = (u'True if request has an X-Requested-With header with the ' - 'value "XMLHttpRequest"'), - description=(u'Useful for detecting AJAX requests issued from ' - 'jQuery, Protoype and other JavaScript libraries'), - required=False) - - accept = TextLine( - title = (u'Mimetype(s) that must be present in "Accept" HTTP header ' - 'for the view to match a request'), - description=(u'Accepts a mimetype match token in the form ' - '"text/plain", a wildcard mimetype match token in the ' - 'form "text/*" or a match-all wildcard mimetype match ' - 'token in the form "*/*".'), - required = False) - - header = TextLine( - title=u'Header name/value pair in the form "name=<regex>"', - description=u'Regular expression matching for header values', - required = False) - - path_info = TextLine( - title = (u'Regular expression which must match the ``PATH_INFO`` ' - 'header for the view to match a request'), - description=(u'Accepts a regular expression.'), - required = False) - - custom_predicates = Tokens( - title=u"One or more custom dotted names to custom predicate callables", - description=(u"A list of dotted name references to callables that " - "will be used as predicates for this view configuration"), - required=False, - value_type=GlobalObject() - ) - - -def view( - _context, - permission=None, - for_=None, - view=None, - name="", - request_type=None, - route_name=None, - request_method=None, - request_param=None, - containment=None, - attr=None, - renderer=None, - wrapper=None, - xhr=False, - accept=None, - header=None, - path_info=None, - traverse=None, - custom_predicates=(), - context=None, - cacheable=True, # not used, here for b/w compat < 0.8 - ): - - reg = get_current_registry() - - if request_type in ('GET', 'HEAD', 'PUT', 'POST', 'DELETE'): - # b/w compat for 1.0 - request_method = request_type - request_type = None - - if request_type is not None: - request_type = _context.resolve(request_type) - if not IInterface.providedBy(request_type): - raise ConfigurationError( - 'request_type must be an interface, not %s' % request_type) - - if renderer and '.' in renderer: - renderer = path_spec(_context, renderer) - - context = context or for_ - - def register(): - config = Configurator(reg, package=_context.package) - config.add_view( - permission=permission, context=context, view=view, name=name, - request_type=request_type, route_name=route_name, - request_method=request_method, request_param=request_param, - containment=containment, attr=attr, renderer=renderer, - wrapper=wrapper, xhr=xhr, accept=accept, header=header, - path_info=path_info, custom_predicates=custom_predicates, - _info=_context.info) - - discriminator = ['view', context, name, request_type, IView, containment, - request_param, request_method, route_name, attr, - xhr, accept, header, path_info] - - discriminator.extend(sorted(custom_predicates)) - discriminator = tuple(discriminator) - - _context.action( - discriminator = discriminator, - callable = register, - ) - -_view = view # for directives that take a view arg - -class IRouteDirective(Interface): - """ The interface for the ``route`` ZCML directive - """ - name = TextLine(title=u'name', required=True) - pattern = TextLine(title=u'pattern', required=False) - # alias for pattern - path = TextLine(title=u'path', required=False) - factory = GlobalObject(title=u'context factory', required=False) - view = GlobalObject(title=u'view', required=False) - - view_context = GlobalObject(title=u'view_context', required=False) - # aliases for view_context - for_ = GlobalObject(title=u'for', required=False) - view_for = GlobalObject(title=u'view_for', required=False) - - view_permission = TextLine(title=u'view_permission', required=False) - # alias for view_permission - permission = TextLine(title=u'permission', required=False) - - view_renderer = TextLine(title=u'view_renderer', required=False) - # alias for view_renderer - renderer = TextLine(title=u'renderer', required=False) - - view_attr = TextLine(title=u'view_attr', required=False) - - request_method = TextLine(title=u'request_method', required=False) - request_param = TextLine(title=u'request_param', required=False) - header = TextLine(title=u'header', required=False) - accept = TextLine(title=u'accept', required=False) - xhr = Bool(title=u'xhr', required=False) - path_info = TextLine(title=u'path_info', required=False) - - traverse = TextLine( - title=u'Traverse pattern"', - description=u'A pattern which will compose a traversal path', - required = False) - - custom_predicates = Tokens( - title=u"One or more custom dotted names to custom predicate callables", - description=(u"A list of dotted name references to callables that " - "will be used as predicates for this view configuration"), - required=False, - value_type=GlobalObject() - ) - use_global_views = Bool(title=u'use_global_views', required=False) - -def route(_context, - name, - pattern=None, - view=None, - view_for=None, - permission=None, - factory=None, - for_=None, - header=None, - xhr=False, - accept=None, - path_info=None, - request_method=None, - request_param=None, - custom_predicates=(), - view_permission=None, - view_attr=None, - renderer=None, - view_renderer=None, - view_context=None, - traverse=None, - use_global_views=False, - path=None): - """ Handle ``route`` ZCML directives - """ - # the strange ordering of the request kw args above is for b/w - # compatibility purposes. - - # these are route predicates; if they do not match, the next route - # in the routelist will be tried - reg = get_current_registry() - - if view_context is None: - view_context = view_for or for_ - - view_permission = view_permission or permission - view_renderer = view_renderer or renderer - if view_renderer and '.' in view_renderer: - view_renderer = path_spec(_context, view_renderer) - - if pattern is None: - pattern = path - - if pattern is None: - raise ConfigurationError('route directive must include a "pattern"') - - def register(): - config = Configurator(reg, package=_context.package) - config.add_route( - name, - pattern, - factory=factory, - header=header, - xhr=xhr, - accept=accept, - path_info=path_info, - request_method=request_method, - request_param=request_param, - custom_predicates=custom_predicates, - view=view, - view_context=view_context, - view_permission=view_permission, - view_renderer=view_renderer, - view_attr=view_attr, - use_global_views=use_global_views, - traverse=traverse, - _info=_context.info - ) - - discriminator = ['route', name, xhr, request_method, path_info, - request_param, header, accept] - discriminator.extend(sorted(custom_predicates)) - discriminator = tuple(discriminator) - - _context.action( - discriminator=discriminator, - callable = register, - ) - - if view: - request_iface = reg.queryUtility(IRouteRequest, name=name) - if request_iface is None: - request_iface = route_request_iface(name) - reg.registerUtility(request_iface, IRouteRequest, name=name) - _context.action( - discriminator = ( - 'view', view_context, '', None, IView, name, view_attr), - ) - -class ISystemViewDirective(Interface): - view = GlobalObject( - title=u"", - description=u"The view function", - required=False, - ) - - attr = TextLine( - title=u'The callable attribute of the view object(default is __call__)', - description=u'', - required=False) - - renderer = TextLine( - title=u'The renderer asssociated with the view', - description=u'', - required=False) - - wrapper = TextLine( - title = u'The *name* of the view that acts as a wrapper for this view.', - description = u'', - required=False) - -def notfound(_context, - view=None, - attr=None, - renderer=None, - wrapper=None): - - if renderer and '.' in renderer: - renderer = path_spec(_context, renderer) - - def register(): - reg = get_current_registry() - config = Configurator(reg, package=_context.package) - config.set_notfound_view(view=view, attr=attr, renderer=renderer, - wrapper=wrapper, _info=_context.info) - - discriminator = ('view', NotFound, '', None, IView, None, None, None, - None, attr, False, None, None, None) - - _context.action( - discriminator = discriminator, - callable = register, - ) - -def forbidden(_context, - view=None, - attr=None, - renderer=None, - wrapper=None): - - if renderer and '.' in renderer: - renderer = path_spec(_context, renderer) - - def register(): - reg = get_current_registry() - config = Configurator(reg, package=_context.package) - config.set_forbidden_view(view=view, attr=attr, renderer=renderer, - wrapper=wrapper, _info=_context.info) - - discriminator = ('view', Forbidden, '', None, IView, None, None, None, - None, attr, False, None, None, None) - - _context.action( - discriminator = discriminator, - callable = register, - ) - -class IResourceDirective(Interface): - """ - Directive for specifying that one package may override resources from - another package. - """ - to_override = TextLine( - title=u"Override spec", - description=u'The spec of the resource to override.', - required=True) - override_with = TextLine( - title=u"With spec", - description=u"The spec of the resource providing the override.", - required=True) - -def resource(_context, to_override, override_with): - reg = get_current_registry() - config = Configurator(reg, package=_context.package) - - _context.action( - discriminator = None, - callable = config.override_resource, - args = (to_override, override_with, _context.info), - ) - -class IRepozeWho1AuthenticationPolicyDirective(Interface): - identifier_name = TextLine(title=u'identitfier_name', required=False, - default=u'auth_tkt') - callback = GlobalObject(title=u'callback', required=False) - -def repozewho1authenticationpolicy(_context, identifier_name='auth_tkt', - callback=None): - policy = RepozeWho1AuthenticationPolicy(identifier_name=identifier_name, - callback=callback) - # authentication policies must be registered eagerly so they can - # be found by the view registration machinery - reg = get_current_registry() - config = Configurator(reg, package=_context.package) - config._set_authentication_policy(policy, _info=_context.info) - _context.action(discriminator=IAuthenticationPolicy) - -class IRemoteUserAuthenticationPolicyDirective(Interface): - environ_key = TextLine(title=u'environ_key', required=False, - default=u'REMOTE_USER') - callback = GlobalObject(title=u'callback', required=False) - -def remoteuserauthenticationpolicy(_context, environ_key='REMOTE_USER', - callback=None): - policy = RemoteUserAuthenticationPolicy(environ_key=environ_key, - callback=callback) - # authentication policies must be registered eagerly so they can - # be found by the view registration machinery - reg = get_current_registry() - config = Configurator(reg, package=_context.package) - config._set_authentication_policy(policy, _info=_context.info) - _context.action(discriminator=IAuthenticationPolicy) - -class IAuthTktAuthenticationPolicyDirective(Interface): - secret = TextLine(title=u'secret', required=True) - callback = GlobalObject(title=u'callback', required=False) - cookie_name = ASCIILine(title=u'cookie_name', required=False, - default='repoze.bfg.auth_tkt') - secure = Bool(title=u"secure", required=False, default=False) - include_ip = Bool(title=u"include_ip", required=False, default=False) - timeout = Int(title=u"timeout", required=False, default=None) - reissue_time = Int(title=u"reissue_time", required=False, default=None) - max_age = Int(title=u"max_age", required=False, default=None) - path = ASCIILine(title=u"path", required=False, default='/') - http_only = Bool(title=u"http_only", required=False, default=False) - -def authtktauthenticationpolicy(_context, - secret, - callback=None, - cookie_name='repoze.bfg.auth_tkt', - secure=False, - include_ip=False, - timeout=None, - reissue_time=None, - max_age=None, - http_only=False, - path='/'): - try: - policy = AuthTktAuthenticationPolicy(secret, - callback=callback, - cookie_name=cookie_name, - secure=secure, - include_ip = include_ip, - timeout = timeout, - reissue_time = reissue_time, - max_age=max_age, - http_only=http_only, - path=path) - except ValueError, why: - raise ConfigurationError(str(why)) - # authentication policies must be registered eagerly so they can - # be found by the view registration machinery - reg = get_current_registry() - config = Configurator(reg, package=_context.package) - config._set_authentication_policy(policy, _info=_context.info) - _context.action(discriminator=IAuthenticationPolicy) - -class IACLAuthorizationPolicyDirective(Interface): - pass - -def aclauthorizationpolicy(_context): - policy = ACLAuthorizationPolicy() - # authorization policies must be registered eagerly so they can be - # found by the view registration machinery - reg = get_current_registry() - config = Configurator(reg, package=_context.package) - config._set_authorization_policy(policy, _info=_context.info) - _context.action(discriminator=IAuthorizationPolicy) - -class IRendererDirective(Interface): - factory = GlobalObject( - title=u'IRendererFactory implementation', - required=True) - - name = TextLine( - title=u'Token (e.g. ``json``) or filename extension (e.g. ".pt")', - required=False) - -def renderer(_context, factory, name=''): - # renderer factories must be registered eagerly so they can be - # found by the view machinery - reg = get_current_registry() - config = Configurator(reg, package=_context.package) - config.add_renderer(name, factory, _info=_context.info) - _context.action(discriminator=(IRendererFactory, name)) - -class IStaticDirective(Interface): - name = TextLine( - title=u"The URL prefix of the static view", - description=u""" - The directory will be served up for the route that starts with - this prefix.""", - required=True) - - path = TextLine( - title=u'Path to the directory which contains resources', - description=u'May be package-relative by using a colon to ' - 'seperate package name and path relative to the package directory.', - required=True) - - cache_max_age = Int( - title=u"Cache maximum age in seconds", - required=False, - default=None) - -def static(_context, name, path, cache_max_age=3600): - """ Handle ``static`` ZCML directives - """ - path = path_spec(_context, path) - reg = get_current_registry() - config = Configurator(reg, package=_context.package) - - _context.action( - discriminator=('static', name), - callable=config.add_static_view, - args = (name, path), - kw = {'cache_max_age':cache_max_age, '_info':_context.info}, - ) - - if not '/' in name: - _context.action( - discriminator = ( - 'view', StaticURLInfo, '', None, IView, None, None, None, - name, None, None, None, None, None, - ) - ) - -class IScanDirective(Interface): - package = GlobalObject( - title=u"The package we'd like to scan.", - required=True, - ) - -def scan(_context, package): - reg = get_current_registry() - config = Configurator(reg, package=_context.package) - _context.action( - discriminator=None, - callable=config.scan, - args=(package, None, _context.info) - ) - -class ITranslationDirDirective(Interface): - dir = TextLine( - title=u"Add a translation directory", - description=(u"Add a translation directory"), - required=True, - ) - -def translationdir(_context, dir): - path = path_spec(_context, dir) - reg = get_current_registry() - config = Configurator(reg, package=_context.package) - - _context.action( - discriminator = ('tdir', path), - callable=config.add_translation_dirs, - args = (dir,), - ) - -class ILocaleNegotiatorDirective(Interface): - negotiator = GlobalObject( - title=u"Configure a locale negotiator", - description=(u'Configure a locale negotiator'), - required=True, - ) - -def localenegotiator(_context, negotiator): - reg = get_current_registry() - config = Configurator(reg, package=_context.package) - - _context.action( - discriminator = 'lnegotiator', - callable=config.set_locale_negotiator, - args = (negotiator,) - ) - -class IAdapterDirective(Interface): - """ - Register an adapter - """ - - factory = Tokens( - title=u"Adapter factory/factories", - description=(u"A list of factories (usually just one) that create" - " the adapter instance."), - required=True, - value_type=GlobalObject() - ) - - provides = GlobalInterface( - title=u"Interface the component provides", - description=(u"This attribute specifies the interface the adapter" - " instance must provide."), - required=False, - ) - - for_ = Tokens( - title=u"Specifications to be adapted", - description=u"This should be a list of interfaces or classes", - required=False, - value_type=GlobalObject( - missing_value=object(), - ), - ) - - name = TextLine( - title=u"Name", - description=(u"Adapters can have names.\n\n" - "This attribute allows you to specify the name for" - " this adapter."), - required=False, - ) - -def adapter(_context, factory, provides=None, for_=None, name=''): - if for_ is None: - if len(factory) == 1: - for_ = getattr(factory[0], '__component_adapts__', None) - - if for_ is None: - raise TypeError("No for argument was provided and can't " - "determine what the factory adapts.") - - for_ = tuple(for_) - - if provides is None: - if len(factory) == 1: - p = list(implementedBy(factory[0])) - if len(p) == 1: - provides = p[0] - - if provides is None: - raise TypeError("Missing 'provided' argument") - - # Generate a single factory from multiple factories: - factories = factory - if len(factories) == 1: - factory = factories[0] - elif len(factories) < 1: - raise ValueError("No factory specified") - elif len(factories) > 1 and len(for_) != 1: - raise ValueError("Can't use multiple factories and multiple " - "for") - else: - factory = _rolledUpFactory(factories) - - registry = get_current_registry() - _context.action( - discriminator = ('adapter', for_, provides, name), - callable = registry.registerAdapter, - args = (factory, for_, provides, name, _context.info), - ) - -class ISubscriberDirective(Interface): - """ - Register a subscriber - """ - - factory = GlobalObject( - title=u"Subscriber factory", - description=u"A factory used to create the subscriber instance.", - required=False, - ) - - handler = GlobalObject( - title=u"Handler", - description=u"A callable object that handles events.", - required=False, - ) - - provides = GlobalInterface( - title=u"Interface the component provides", - description=(u"This attribute specifies the interface the adapter" - " instance must provide."), - required=False, - ) - - for_ = Tokens( - title=u"Interfaces or classes that this subscriber depends on", - description=u"This should be a list of interfaces or classes", - required=False, - value_type=GlobalObject( - missing_value = object(), - ), - ) - -def subscriber(_context, for_=None, factory=None, handler=None, provides=None): - if factory is None: - if handler is None: - raise TypeError("No factory or handler provided") - if provides is not None: - raise TypeError("Cannot use handler with provides") - factory = handler - else: - if handler is not None: - raise TypeError("Cannot use handler with factory") - if provides is None: - raise TypeError( - "You must specify a provided interface when registering " - "a factory") - - if for_ is None: - for_ = getattr(factory, '__component_adapts__', None) - if for_ is None: - raise TypeError("No for attribute was provided and can't " - "determine what the factory (or handler) adapts.") - - for_ = tuple(for_) - - registry = get_current_registry() - config = Configurator(registry=registry, package=_context.package) - - if handler is not None: - _context.action( - discriminator = None, - callable = config.add_subscriber, - args = (handler, for_, _context.info), - ) - else: - _context.action( - discriminator = None, - callable = registry.registerSubscriptionAdapter, - args = (factory, for_, provides, None, _context.info), - ) - -class IUtilityDirective(Interface): - """Register a utility.""" - - component = GlobalObject( - title=u"Component to use", - description=(u"Python name of the implementation object. This" - " must identify an object in a module using the" - " full dotted name. If specified, the" - " ``factory`` field must be left blank."), - required=False, - ) - - factory = GlobalObject( - title=u"Factory", - description=(u"Python name of a factory which can create the" - " implementation object. This must identify an" - " object in a module using the full dotted name." - " If specified, the ``component`` field must" - " be left blank."), - required=False, - ) - - provides = GlobalInterface( - title=u"Provided interface", - description=u"Interface provided by the utility.", - required=False, - ) - - name = TextLine( - title=u"Name", - description=(u"Name of the registration. This is used by" - " application code when locating a utility."), - required=False, - ) - -def utility(_context, provides=None, component=None, factory=None, name=''): - if factory and component: - raise TypeError("Can't specify factory and component.") - - if provides is None: - if factory: - provides = list(implementedBy(factory)) - else: - provides = list(providedBy(component)) - if len(provides) == 1: - provides = provides[0] - else: - raise TypeError("Missing 'provides' attribute") - - if factory: - kw = dict(factory=factory) - else: - # older component registries don't accept factory as a kwarg, - # so if we don't need it, we don't pass it - kw = {} - - registry = get_current_registry() - _context.action( - discriminator = ('utility', provides, name), - callable = registry.registerUtility, - args = (component, provides, name, _context.info), - kw = kw, - ) - -class IDefaultPermissionDirective(Interface): - name = TextLine(title=u'name', required=True) - -def default_permission(_context, name): - """ Register a default permission name """ - # the default permission must be registered eagerly so it can - # be found by the view registration machinery - reg = get_current_registry() - config = Configurator(reg, package=_context.package) - config.set_default_permission(name) - _context.action(discriminator=IDefaultPermission) - -def path_spec(context, path): - # we prefer registering resource specifications over absolute - # paths because these can be overridden by the resource directive. - if ':' in path and not os.path.isabs(path): - # it's already a resource specification - return path - abspath = context.path(path) - if hasattr(context, 'package') and context.package: - return resource_spec_from_abspath(abspath, context.package) - return abspath - -def zcml_configure(name, package): - """ Given a ZCML filename as ``name`` and a Python package as - ``package`` which the filename should be relative to, load the - ZCML into the current ZCML registry. - - .. note:: This feature is new as of :mod:`repoze.bfg` 1.1. - """ - context = ConfigurationMachine() - xmlconfig.registerCommonDirectives(context) - context.package = package - xmlconfig.include(context, name, package) - context.execute_actions(clear=False) # the raison d'etre - return context.actions - -file_configure = zcml_configure # backwards compat (>0.8.1) - -def _rolledUpFactory(factories): - def factory(ob): - for f in factories: - ob = f(ob) - return ob - # Store the original factory for documentation - factory.factory = factories[0] - return factory - |
