From 4df5751de28947538da491dc8ebe0dfb27f742d5 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 19 Jul 2008 01:17:21 +0000 Subject: - The concept of "view factories" was removed in favor of always calling a view, which is a callable that returns a response directly (as opposed to returning a view). As a result, the ``factory`` attribute in the bfg:view ZCML statement has been renamed to ``view``. Various interface names were changed also. - ``render_template`` and ``render_transform`` no longer return a Response object. Instead, these return strings. The old behavior can be obtained by using ``render_template_to_response`` and ``render_transform_to_response``. --- CHANGES.txt | 11 +++ TODO.txt | 6 +- repoze/bfg/configure.zcml | 10 +-- repoze/bfg/interfaces.py | 35 +++------ repoze/bfg/push.py | 4 +- repoze/bfg/router.py | 39 +++++++--- repoze/bfg/sampleapp/configure.zcml | 8 +- repoze/bfg/sampleapp/models.py | 7 +- repoze/bfg/sampleapp/views.py | 20 ++--- repoze/bfg/template.py | 79 +++++++++++--------- repoze/bfg/tests/fixtureapp/configure.zcml | 2 +- repoze/bfg/tests/fixtureapp/views.py | 9 +-- repoze/bfg/tests/test_router.py | 96 ++++++++++-------------- repoze/bfg/tests/test_template.py | 80 +++++++++++++------- repoze/bfg/tests/test_traversal.py | 12 +-- repoze/bfg/tests/test_view.py | 34 --------- repoze/bfg/tests/test_wsgiadapter.py | 113 ----------------------------- repoze/bfg/tests/test_xslt.py | 95 ++++++++++++++++-------- repoze/bfg/tests/test_zcml.py | 63 ++++++---------- repoze/bfg/traversal.py | 10 +-- repoze/bfg/view.py | 20 ----- repoze/bfg/wsgiadapter.py | 48 ------------ repoze/bfg/zcml.py | 66 ++++++----------- 23 files changed, 336 insertions(+), 531 deletions(-) delete mode 100644 repoze/bfg/tests/test_view.py delete mode 100644 repoze/bfg/tests/test_wsgiadapter.py delete mode 100644 repoze/bfg/view.py delete mode 100644 repoze/bfg/wsgiadapter.py diff --git a/CHANGES.txt b/CHANGES.txt index b6df0c339..43eeb0689 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,5 +1,16 @@ After 0.1 + - The concept of "view factories" was removed in favor of always + calling a view, which is a callable that returns a response + directly (as opposed to returning a view). As a result, the + ``factory`` attribute in the bfg:view ZCML statement has been + renamed to ``view``. Various interface names were changed also. + + - ``render_template`` and ``render_transform`` no longer return a + Response object. Instead, these return strings. The old behavior + can be obtained by using ``render_template_to_response`` and + ``render_transform_to_response``. + - Added 'repoze.bfg.push:pushpage' decorator, which creates BFG views from callables which take (context, request) and return a mapping of top-level names. diff --git a/TODO.txt b/TODO.txt index bca04bd19..2fafa37ab 100644 --- a/TODO.txt +++ b/TODO.txt @@ -1,9 +1,7 @@ -- Provide sugar to make it easier to use other templating languages in - views. +- mapply decorator. -- Implement authorization against model objects. +- URL-based dispatch should get first crack at a request. -- Decide what else gets mapped in by mapply. diff --git a/repoze/bfg/configure.zcml b/repoze/bfg/configure.zcml index c518adc85..cb330a31f 100644 --- a/repoze/bfg/configure.zcml +++ b/repoze/bfg/configure.zcml @@ -4,17 +4,11 @@ - - diff --git a/repoze/bfg/interfaces.py b/repoze/bfg/interfaces.py index 4bb385438..710b91074 100644 --- a/repoze/bfg/interfaces.py +++ b/repoze/bfg/interfaces.py @@ -10,44 +10,33 @@ class IResponse(Interface): app_iter = Attribute('Iterable representing the response body') class IView(Interface): - def __call__(*arg, **kw): - """ Must return an object that implements IResponse; args are - mapped into an IView's __call__ by mapply-like code """ - -class INodeView(IView): - def __call__(node, **kw): - """ Must return an object that implements IResponse; node is an - lxml.etree Element and **kw provides parameters to an XSLT - processor """ - -class IViewFactory(Interface): def __call__(context, request): - """ Return an object that implements IView """ + """ Must return an object that implements IResponse """ class IRootPolicy(Interface): def __call__(environ): """ Return a root object """ -class IPublishTraverser(Interface): +class ITraverser(Interface): def __call__(path): """ Return a tuple in the form (context, name, subpath), typically the result of an object graph traversal """ -class IPublishTraverserFactory(Interface): +class ITraverserFactory(Interface): def __call__(context, request): """ Return an object that implements IPublishTraverser """ -class IWSGIApplication(Interface): - def __call__(environ, start_response): - """ A PEP 333 application """ +class ITemplateFactory(Interface): + def __call__(path): + """ Return an an ITemplate given a filesystem path """ -class IWSGIApplicationFactory(Interface): - def __call__(context, request, view): - """ Return an object that implements IWSGIApplication """ +class ITemplate(Interface): + def __call__(**kw): + """ Return a string result given a template path """ -class ITemplateFactory(Interface): - def __call__(template_path): - """ Return an IView given a template path """ +class INodeTemplate(Interface): + def __call__(node, **kw): + """ Return a string result given a template path """ class ISecurityPolicy(Interface): """ A utility that provides a mechanism to check authorization diff --git a/repoze/bfg/push.py b/repoze/bfg/push.py index 49b9cda27..b48f70056 100644 --- a/repoze/bfg/push.py +++ b/repoze/bfg/push.py @@ -1,5 +1,5 @@ import os.path -from repoze.bfg.template import render_template +from repoze.bfg.template import render_template_to_response class pushpage(object): """ Decorator for functions which return ZPT template namespaces. @@ -25,7 +25,7 @@ class pushpage(object): def _curried(context, request): kw = wrapped(context, request) - return render_template(path, **kw) + return render_template_to_response(path, **kw) _curried.__name__ = wrapped.__name__ return _curried diff --git a/repoze/bfg/router.py b/repoze/bfg/router.py index 791d6772e..231a3560b 100644 --- a/repoze/bfg/router.py +++ b/repoze/bfg/router.py @@ -7,15 +7,16 @@ from webob import Request from webob.exc import HTTPNotFound from webob.exc import HTTPUnauthorized -from repoze.bfg.interfaces import IPublishTraverserFactory -from repoze.bfg.interfaces import IViewFactory +from repoze.bfg.interfaces import ITraverserFactory +from repoze.bfg.interfaces import IView from repoze.bfg.interfaces import IViewPermission from repoze.bfg.interfaces import ISecurityPolicy -from repoze.bfg.interfaces import IWSGIApplicationFactory from repoze.bfg.interfaces import IRequest from repoze.bfg.registry import registry_manager +_marker = () + class Router: """ WSGI application which routes requests to 'view' code based on a view registry""" @@ -29,10 +30,12 @@ class Router: directlyProvides(request, IRequest) root = self.root_policy(environ) path = environ.get('PATH_INFO', '/') - traverser = getMultiAdapter((root, request), IPublishTraverserFactory) + traverser = getMultiAdapter((root, request), ITraverserFactory) context, name, subpath = traverser(path) - request.subpath = subpath + + request.context = context request.view_name = name + request.subpath = subpath security_policy = queryUtility(ISecurityPolicy) if security_policy: @@ -44,13 +47,27 @@ class Router: app.explanation = repr(permission) return app(environ, start_response) - app = queryMultiAdapter((context, request), IViewFactory, name=name) - if app is None: + response = queryMultiAdapter((context, request), IView, name=name, + default=_marker) + if response is _marker: app = HTTPNotFound(request.url) - else: - app = getMultiAdapter((context, request, app), - IWSGIApplicationFactory) - return app(environ, start_response) + return app(environ, start_response) + + if not isResponse(response): + raise ValueError('response was not IResponse: %s' % response) + + start_response(response.status, response.headerlist) + return response.app_iter + +def isResponse(ob): + # 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 def make_app(root_policy, package=None, filename='configure.zcml'): """ Create a view registry based on the application's ZCML. and diff --git a/repoze/bfg/sampleapp/configure.zcml b/repoze/bfg/sampleapp/configure.zcml index bd1b46d6a..121566520 100644 --- a/repoze/bfg/sampleapp/configure.zcml +++ b/repoze/bfg/sampleapp/configure.zcml @@ -12,21 +12,21 @@ @@ -34,7 +34,7 @@ diff --git a/repoze/bfg/sampleapp/models.py b/repoze/bfg/sampleapp/models.py index d07110e83..7da6f1033 100644 --- a/repoze/bfg/sampleapp/models.py +++ b/repoze/bfg/sampleapp/models.py @@ -15,8 +15,11 @@ class IBlog(Interface): pass class Blog(dict, Location): - __acl__ = [ (Allow, Everyone, 'view'), (Allow, 'group:editors', 'add'), - (Allow, 'group:managers', 'manage') ] + __acl__ = [ + (Allow, Everyone, 'view'), + (Allow, 'group:editors', 'add'), + (Allow, 'group:editors', 'edit'), + ] implements(IBlog, IMapping, ILocation) class IBlogEntry(Interface): diff --git a/repoze/bfg/sampleapp/views.py b/repoze/bfg/sampleapp/views.py index 5b72c8a28..0f536f09f 100644 --- a/repoze/bfg/sampleapp/views.py +++ b/repoze/bfg/sampleapp/views.py @@ -3,7 +3,7 @@ import time from webob.exc import HTTPFound -from repoze.bfg.template import render_template +from repoze.bfg.template import render_template_to_response from repoze.bfg.sampleapp.models import BlogEntry from repoze.bfg.security import has_permission @@ -27,8 +27,10 @@ def blog_default_view(context, request): } ) - return render_template('templates/blog.pt', name=context.__name__, - entries=entrydata, can_add=can_add) + return render_template_to_response('templates/blog.pt', + name=context.__name__, + entries=entrydata, + can_add=can_add) def blog_entry_default_view(context, request): info = { @@ -38,7 +40,7 @@ def blog_entry_default_view(context, request): 'author':context.author, 'created':datestring(context.created), } - return render_template('templates/blog_entry.pt', **info) + return render_template_to_response('templates/blog_entry.pt', **info) class BlogAddSchema(formencode.Schema): allow_extra_fields = True @@ -50,7 +52,7 @@ def blog_entry_add_view(context, request): params = request.params message = None - + author = params.get('author', '') body = params.get('body', '') title = params.get('title', '') @@ -65,15 +67,13 @@ def blog_entry_add_view(context, request): message = str(why) info['message'] = message else: - author = form['author'] - body = form['body'] - title = form['title'] + author, body, title = form['author'], form['body'], form['title'] new_entry = BlogEntry(title, body, author) name = str(time.time()) context[name] = new_entry return HTTPFound(location='/') - return render_template('templates/blog_entry_add.pt', **info) + return render_template_to_response('templates/blog_entry_add.pt', **info) def contents_view(context, request): - return render_template('templates/contents.pt', context=context) + return render_template_to_response('templates/contents.pt', context=context) diff --git a/repoze/bfg/template.py b/repoze/bfg/template.py index 8ade2fb74..0d390fecf 100644 --- a/repoze/bfg/template.py +++ b/repoze/bfg/template.py @@ -1,6 +1,8 @@ import os import sys +from webob import Response + from zope.component import queryUtility from zope.component.interfaces import ComponentLookupError from zope.component import getSiteManager @@ -8,28 +10,25 @@ from zope.component import getSiteManager from zope.interface import classProvides from zope.interface import implements -from webob import Response - -from repoze.bfg.interfaces import IView -from repoze.bfg.interfaces import INodeView from repoze.bfg.interfaces import ITemplateFactory +from repoze.bfg.interfaces import ITemplate +from repoze.bfg.interfaces import INodeTemplate class Z3CPTTemplateFactory(object): classProvides(ITemplateFactory) - implements(IView) + implements(ITemplate) def __init__(self, path): from z3c.pt import PageTemplateFile self.template = PageTemplateFile(path) - def __call__(self, *arg, **kw): + def __call__(self, **kw): result = self.template.render(**kw) - response = Response(result) - return response + return result class XSLTemplateFactory(object): classProvides(ITemplateFactory) - implements(INodeView) + implements(INodeTemplate) def __init__(self, path): self.path = path @@ -37,8 +36,7 @@ class XSLTemplateFactory(object): def __call__(self, node, **kw): processor = get_processor(self.path) result = str(processor(node, **kw)) - response = Response(result) - return response + return result # Manage XSLT processors on a per-thread basis import threading @@ -61,55 +59,70 @@ def get_processor(xslt_fn): def package_path(package): return os.path.abspath(os.path.dirname(package.__file__)) -def registerTemplate(template, path): +def registerTemplate(type, template, path): try: sm = getSiteManager() except ComponentLookupError: pass else: - sm.registerUtility(template, IView, name=path) + sm.registerUtility(template, type, name=path) def render_template(path, **kw): """ Render a z3c.pt (ZPT) template at the package-relative path (may also be absolute) using the kwargs in ``*kw`` as top-level - names and return a Response object. """ + names and return a string. """ # XXX use pkg_resources + path = caller_path(path) - if not os.path.isabs(path): - package_globals = sys._getframe(1).f_globals - package_name = package_globals['__name__'] - package = sys.modules[package_name] - prefix = package_path(package) - path = os.path.join(prefix, path) - - template = queryUtility(IView, path) + template = queryUtility(ITemplate, path) if template is None: if not os.path.exists(path): raise ValueError('Missing template file: %s' % path) template = Z3CPTTemplateFactory(path) - registerTemplate(template, path) + registerTemplate(ITemplate, template, path) return template(**kw) +def render_template_to_response(path, **kw): + """ Render a z3c.pt (ZPT) template at the package-relative path + (may also be absolute) using the kwargs in ``*kw`` as top-level + names and return a Response object. """ + path = caller_path(path) + result = render_template(path, **kw) + return Response(result) + def render_transform(path, node, **kw): """ Render a XSL template at the package-relative path (may also be absolute) using the kwargs in ``*kw`` as top-level names and - return a Response object.""" + return a string.""" # Render using XSLT + path = caller_path(path) - if not os.path.isabs(path): - package_globals = sys._getframe(1).f_globals - package_name = package_globals['__name__'] - package = sys.modules[package_name] - prefix = package_path(package) - path = os.path.join(prefix, path) - - template = queryUtility(IView, path) + template = queryUtility(INodeTemplate, path) if template is None: if not os.path.exists(path): raise ValueError('Missing template file: %s' % path) template = XSLTemplateFactory(path) - registerTemplate(template, path) + registerTemplate(INodeTemplate, template, path) return template(node, **kw) + +def render_transform_to_response(path, node, **kw): + """ Render a XSL template at the package-relative path (may also + be absolute) using the kwargs in ``*kw`` as top-level names and + return a Response object.""" + path = caller_path(path) + result = render_transform(path, node, **kw) + return Response(result) + +def caller_path(path): + if not os.path.isabs(path): + package_globals = sys._getframe(2).f_globals + package_name = package_globals['__name__'] + package = sys.modules[package_name] + prefix = package_path(package) + path = os.path.join(prefix, path) + return path + + diff --git a/repoze/bfg/tests/fixtureapp/configure.zcml b/repoze/bfg/tests/fixtureapp/configure.zcml index f08cd58ad..265d69511 100644 --- a/repoze/bfg/tests/fixtureapp/configure.zcml +++ b/repoze/bfg/tests/fixtureapp/configure.zcml @@ -6,7 +6,7 @@ diff --git a/repoze/bfg/tests/fixtureapp/views.py b/repoze/bfg/tests/fixtureapp/views.py index b9b9fc7d9..2babbc59c 100644 --- a/repoze/bfg/tests/fixtureapp/views.py +++ b/repoze/bfg/tests/fixtureapp/views.py @@ -1,8 +1,3 @@ -class FixtureView(object): - def __init__(self, context, request): - self.context = context - self.request = request +def fixture_view(context, request): + return None - def __call__(self): - pass - diff --git a/repoze/bfg/tests/test_router.py b/repoze/bfg/tests/test_router.py index 148b72427..4b1e914b7 100644 --- a/repoze/bfg/tests/test_router.py +++ b/repoze/bfg/tests/test_router.py @@ -12,14 +12,14 @@ class RouterTests(unittest.TestCase, PlacelessSetup): def _registerTraverserFactory(self, app, name, *for_): import zope.component gsm = zope.component.getGlobalSiteManager() - from repoze.bfg.interfaces import IPublishTraverserFactory - gsm.registerAdapter(app, for_, IPublishTraverserFactory, name) + from repoze.bfg.interfaces import ITraverserFactory + gsm.registerAdapter(app, for_, ITraverserFactory, name) - def _registerViewFactory(self, app, name, *for_): + def _registerView(self, app, name, *for_): import zope.component gsm = zope.component.getGlobalSiteManager() - from repoze.bfg.interfaces import IViewFactory - gsm.registerAdapter(app, for_, IViewFactory, name) + from repoze.bfg.interfaces import IView + gsm.registerAdapter(app, for_, IView, name) def _registerPermission(self, permission, name, *for_): import zope.component @@ -27,12 +27,6 @@ class RouterTests(unittest.TestCase, PlacelessSetup): from repoze.bfg.interfaces import IViewPermission gsm.registerAdapter(permission, for_, IViewPermission, name) - def _registerWSGIFactory(self, app, name, *for_): - import zope.component - gsm = zope.component.getGlobalSiteManager() - from repoze.bfg.interfaces import IWSGIApplicationFactory - gsm.registerAdapter(app, for_, IWSGIApplicationFactory, name) - def _registerSecurityPolicy(self, secpol): import zope.component gsm = zope.component.getGlobalSiteManager() @@ -77,42 +71,40 @@ class RouterTests(unittest.TestCase, PlacelessSetup): context = DummyContext() traversalfactory = make_traversal_factory(context, '', []) response = DummyResponse() - viewfactory = make_view_factory(response) - wsgifactory = make_wsgi_factory('200 OK', (), ['Hello world']) + response.app_iter = ['Hello world'] + view = make_view(response) environ = self._makeEnviron() self._registerTraverserFactory(traversalfactory, '', None, None) - self._registerViewFactory(viewfactory, '', None, None) - self._registerWSGIFactory(wsgifactory, '', None, None, None) + self._registerView(view, '', None, None) router = self._makeOne(rootpolicy, None) 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 = environ['request'] - self.assertEqual(environ['request'].subpath, []) - self.assertEqual(environ['view'].context, context) + self.assertEqual(environ['webob.adhoc_attrs']['view_name'], '') + self.assertEqual(environ['webob.adhoc_attrs']['subpath'], []) + self.assertEqual(environ['webob.adhoc_attrs']['context'], context) def test_call_view_registered_nonspecific_nondefault_path_and_subpath(self): rootpolicy = make_rootpolicy(None) context = DummyContext() traversalfactory = make_traversal_factory(context, 'foo', ['bar']) response = DummyResponse() - viewfactory = make_view_factory(response) - wsgifactory = make_wsgi_factory('200 OK', (), ['Hello world']) + response.app_iter = ['Hello world'] + view = make_view(response) environ = self._makeEnviron() self._registerTraverserFactory(traversalfactory, '', None, None) - self._registerViewFactory(viewfactory, 'foo', None, None) - self._registerWSGIFactory(wsgifactory, '', None, None, None) + self._registerView(view, 'foo', None, None) router = self._makeOne(rootpolicy, None) 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 = environ['request'] - self.assertEqual(environ['request'].subpath, ['bar']) - self.assertEqual(environ['view'].context, context) + self.assertEqual(environ['webob.adhoc_attrs']['view_name'], 'foo') + self.assertEqual(environ['webob.adhoc_attrs']['subpath'], ['bar']) + self.assertEqual(environ['webob.adhoc_attrs']['context'], context) def test_call_view_registered_specific_success(self): rootpolicy = make_rootpolicy(None) @@ -125,21 +117,20 @@ class RouterTests(unittest.TestCase, PlacelessSetup): directlyProvides(context, IContext) traversalfactory = make_traversal_factory(context, '', []) response = DummyResponse() - viewfactory = make_view_factory(response) - wsgifactory = make_wsgi_factory('200 OK', (), ['Hello world']) + response.app_iter = ['Hello world'] + view = make_view(response) environ = self._makeEnviron() self._registerTraverserFactory(traversalfactory, '', None, None) - self._registerViewFactory(viewfactory, '', IContext, IRequest) - self._registerWSGIFactory(wsgifactory, '', None, None, None) + self._registerView(view, '', IContext, IRequest) router = self._makeOne(rootpolicy, None) 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 = environ['request'] - self.assertEqual(environ['request'].subpath, []) - self.assertEqual(environ['view'].context, context) + self.assertEqual(environ['webob.adhoc_attrs']['view_name'], '') + self.assertEqual(environ['webob.adhoc_attrs']['subpath'], []) + self.assertEqual(environ['webob.adhoc_attrs']['context'], context) def test_call_view_registered_specific_fail(self): rootpolicy = make_rootpolicy(None) @@ -154,18 +145,16 @@ class RouterTests(unittest.TestCase, PlacelessSetup): directlyProvides(context, INotContext) traversalfactory = make_traversal_factory(context, '', ['']) response = DummyResponse() - viewfactory = make_view_factory(response) - wsgifactory = make_wsgi_factory('200 OK', (), ['Hello world']) + view = make_view(response) environ = self._makeEnviron() self._registerTraverserFactory(traversalfactory, '', None, None) - self._registerViewFactory(viewfactory, '', IContext, IRequest) - self._registerWSGIFactory(wsgifactory, '', None, None, None) + self._registerView(view, '', IContext, IRequest) app_context = make_appcontext() router = self._makeOne(rootpolicy, None) start_response = DummyStartResponse() result = router(environ, start_response) - self.failUnless('404' in result[0]) self.assertEqual(start_response.status, '404 Not Found') + self.failUnless('404' in result[0]) def test_call_view_registered_security_policy_permission_none(self): rootpolicy = make_rootpolicy(None) @@ -178,12 +167,10 @@ class RouterTests(unittest.TestCase, PlacelessSetup): directlyProvides(context, IContext) traversalfactory = make_traversal_factory(context, '', ['']) response = DummyResponse() - viewfactory = make_view_factory(response) - wsgifactory = make_wsgi_factory('200 OK', (), ['Hello world']) + view = make_view(response) environ = self._makeEnviron() self._registerTraverserFactory(traversalfactory, '', None, None) - self._registerViewFactory(viewfactory, '', IContext, IRequest) - self._registerWSGIFactory(wsgifactory, '', None, None, None) + self._registerView(view, '', IContext, IRequest) secpol = DummySecurityPolicy() self._registerSecurityPolicy(secpol) app_context = make_appcontext() @@ -203,14 +190,12 @@ class RouterTests(unittest.TestCase, PlacelessSetup): directlyProvides(context, IContext) traversalfactory = make_traversal_factory(context, '', ['']) response = DummyResponse() - viewfactory = make_view_factory(response) - wsgifactory = make_wsgi_factory('200 OK', (), ['Hello world']) + view = make_view(response) secpol = DummySecurityPolicy() permissionfactory = make_permission_factory(True) environ = self._makeEnviron() self._registerTraverserFactory(traversalfactory, '', None, None) - self._registerViewFactory(viewfactory, '', IContext, IRequest) - self._registerWSGIFactory(wsgifactory, '', None, None, None) + self._registerView(view, '', IContext, IRequest) self._registerSecurityPolicy(secpol) self._registerPermission(permissionfactory, '', IContext, IRequest) app_context = make_appcontext() @@ -220,7 +205,7 @@ class RouterTests(unittest.TestCase, PlacelessSetup): self.assertEqual(start_response.status, '200 OK') self.assertEqual(permissionfactory.checked_with, secpol) - def test_call_view_registered_security_policy_permission_failss(self): + def test_call_view_registered_security_policy_permission_fails(self): rootpolicy = make_rootpolicy(None) from zope.interface import Interface from zope.interface import directlyProvides @@ -231,14 +216,12 @@ class RouterTests(unittest.TestCase, PlacelessSetup): directlyProvides(context, IContext) traversalfactory = make_traversal_factory(context, '', ['']) response = DummyResponse() - viewfactory = make_view_factory(response) - wsgifactory = make_wsgi_factory('200 OK', (), ['Hello world']) + view = make_view(response) secpol = DummySecurityPolicy() permissionfactory = make_permission_factory(False) environ = self._makeEnviron() self._registerTraverserFactory(traversalfactory, '', None, None) - self._registerViewFactory(viewfactory, '', IContext, IRequest) - self._registerWSGIFactory(wsgifactory, '', None, None, None) + self._registerView(view, '', IContext, IRequest) self._registerSecurityPolicy(secpol) self._registerPermission(permissionfactory, '', IContext, IRequest) app_context = make_appcontext() @@ -287,15 +270,10 @@ def make_wsgi_factory(status, headers, app_iter): return DummyWSGIApplicationFactory -def make_view_factory(response): - class DummyViewFactory: - def __init__(self, context, request): - self.context = context - self.request = request - - def __call__(self): - return response - return DummyViewFactory +def make_view(response): + def view(context, request): + return response + return view def make_traversal_factory(context, name, subpath): class DummyTraversalFactory: diff --git a/repoze/bfg/tests/test_template.py b/repoze/bfg/tests/test_template.py index 96129504d..1a5fcf1f4 100644 --- a/repoze/bfg/tests/test_template.py +++ b/repoze/bfg/tests/test_template.py @@ -34,32 +34,24 @@ class Z3CPTTemplateFactoryTests(unittest.TestCase, Base): klass = self._getTargetClass() return klass(*arg, **kw) - def test_instance_conforms_to_IView(self): + def test_instance_implements_ITemplate(self): from zope.interface.verify import verifyObject - from repoze.bfg.interfaces import IView + from repoze.bfg.interfaces import ITemplate path = self._getTemplatePath('minimal.pt') - verifyObject(IView, self._makeOne(path)) + verifyObject(ITemplate, self._makeOne(path)) - def test_class_conforms_to_IView(self): + def test_class_implements_ITemplate(self): from zope.interface.verify import verifyClass - from repoze.bfg.interfaces import IView - verifyClass(IView, self._getTargetClass()) - - def test_class_conforms_to_ITemplateFactory(self): - from zope.interface.verify import verifyObject - from repoze.bfg.interfaces import ITemplateFactory - verifyObject(ITemplateFactory, self._getTargetClass()) + from repoze.bfg.interfaces import ITemplate + verifyClass(ITemplate, self._getTargetClass()) def test_call(self): self._zcmlConfigure() minimal = self._getTemplatePath('minimal.pt') instance = self._makeOne(minimal) result = instance() - from webob import Response - self.failUnless(isinstance(result, Response)) - self.assertEqual(result.app_iter, ['
\n
']) - self.assertEqual(result.status, '200 OK') - self.assertEqual(len(result.headerlist), 2) + self.failUnless(isinstance(result, str)) + self.assertEqual(result, '
\n
') class RenderTemplateTests(unittest.TestCase, Base): def setUp(self): @@ -75,9 +67,50 @@ class RenderTemplateTests(unittest.TestCase, Base): def test_nonabs_unregistered(self): self._zcmlConfigure() from zope.component import queryUtility - from repoze.bfg.interfaces import IView + from repoze.bfg.interfaces import ITemplate + minimal = self._getTemplatePath('minimal.pt') + self.assertEqual(queryUtility(ITemplate, minimal), None) + render = self._getFUT() + result = render(minimal) + self.failUnless(isinstance(result, str)) + self.assertEqual(result, '
\n
') + from repoze.bfg.template import Z3CPTTemplateFactory + self.failUnless(isinstance(queryUtility(ITemplate, minimal), + Z3CPTTemplateFactory)) + + def test_nonabs_registered(self): + self._zcmlConfigure() + from zope.component import getGlobalSiteManager + from zope.component import queryUtility + from repoze.bfg.template import Z3CPTTemplateFactory + from repoze.bfg.interfaces import ITemplate + minimal = self._getTemplatePath('minimal.pt') + utility = Z3CPTTemplateFactory(minimal) + gsm = getGlobalSiteManager() + gsm.registerUtility(utility, ITemplate, name=minimal) + render = self._getFUT() + result = render(minimal) + self.failUnless(isinstance(result, str)) + self.assertEqual(result, '
\n
') + self.assertEqual(queryUtility(ITemplate, minimal), utility) + +class RenderTemplateToResponseTests(unittest.TestCase, Base): + def setUp(self): + Base.setUp(self) + + def tearDown(self): + Base.tearDown(self) + + def _getFUT(self): + from repoze.bfg.template import render_template_to_response + return render_template_to_response + + def test_nonabs_unregistered(self): + self._zcmlConfigure() + from zope.component import queryUtility + from repoze.bfg.interfaces import ITemplate minimal = self._getTemplatePath('minimal.pt') - self.assertEqual(queryUtility(IView, minimal), None) + self.assertEqual(queryUtility(ITemplate, minimal), None) render = self._getFUT() result = render(minimal) from webob import Response @@ -86,7 +119,7 @@ class RenderTemplateTests(unittest.TestCase, Base): self.assertEqual(result.status, '200 OK') self.assertEqual(len(result.headerlist), 2) from repoze.bfg.template import Z3CPTTemplateFactory - self.failUnless(isinstance(queryUtility(IView, minimal), + self.failUnless(isinstance(queryUtility(ITemplate, minimal), Z3CPTTemplateFactory)) def test_nonabs_registered(self): @@ -94,11 +127,11 @@ class RenderTemplateTests(unittest.TestCase, Base): from zope.component import getGlobalSiteManager from zope.component import queryUtility from repoze.bfg.template import Z3CPTTemplateFactory - from repoze.bfg.interfaces import IView + from repoze.bfg.interfaces import ITemplate minimal = self._getTemplatePath('minimal.pt') utility = Z3CPTTemplateFactory(minimal) gsm = getGlobalSiteManager() - gsm.registerUtility(utility, IView, name=minimal) + gsm.registerUtility(utility, ITemplate, name=minimal) render = self._getFUT() result = render(minimal) from webob import Response @@ -106,9 +139,6 @@ class RenderTemplateTests(unittest.TestCase, Base): self.assertEqual(result.app_iter, ['
\n
']) self.assertEqual(result.status, '200 OK') self.assertEqual(len(result.headerlist), 2) - self.assertEqual(queryUtility(IView, minimal), utility) + self.assertEqual(queryUtility(ITemplate, minimal), utility) -class DummyView: - context = 'context' - request = 'request' diff --git a/repoze/bfg/tests/test_traversal.py b/repoze/bfg/tests/test_traversal.py index 528ca0bf4..61dff6d88 100644 --- a/repoze/bfg/tests/test_traversal.py +++ b/repoze/bfg/tests/test_traversal.py @@ -36,8 +36,8 @@ class NaivePublishTraverserTests(unittest.TestCase, PlacelessSetup): PlacelessSetup.tearDown(self) def _getTargetClass(self): - from repoze.bfg.traversal import NaivePublishTraverser - return NaivePublishTraverser + from repoze.bfg.traversal import NaiveTraverser + return NaiveTraverser def _makeOne(self, *arg, **kw): klass = self._getTargetClass() @@ -45,15 +45,15 @@ class NaivePublishTraverserTests(unittest.TestCase, PlacelessSetup): def test_class_conforms_to_IPublishTraverser(self): from zope.interface.verify import verifyClass - from repoze.bfg.interfaces import IPublishTraverser - verifyClass(IPublishTraverser, self._getTargetClass()) + from repoze.bfg.interfaces import ITraverser + verifyClass(ITraverser, self._getTargetClass()) def test_instance_conforms_to_IPublishTraverser(self): from zope.interface.verify import verifyObject - from repoze.bfg.interfaces import IPublishTraverser + from repoze.bfg.interfaces import ITraverser context = DummyContext() request = DummyRequest() - verifyObject(IPublishTraverser, self._makeOne(context, request)) + verifyObject(ITraverser, self._makeOne(context, request)) def test_call_pathel_with_no_getitem(self): request = DummyRequest() diff --git a/repoze/bfg/tests/test_view.py b/repoze/bfg/tests/test_view.py deleted file mode 100644 index a78fe514a..000000000 --- a/repoze/bfg/tests/test_view.py +++ /dev/null @@ -1,34 +0,0 @@ -import unittest - -from zope.component.testing import PlacelessSetup - -class Base(PlacelessSetup): - def setUp(self): - PlacelessSetup.setUp(self) - - def tearDown(self): - PlacelessSetup.tearDown(self) - - def _zcmlConfigure(self): - import repoze.bfg - import zope.configuration.xmlconfig - zope.configuration.xmlconfig.file('configure.zcml', package=repoze.bfg) - - def _getTemplatePath(self, name): - import os - here = os.path.abspath(os.path.dirname(__file__)) - return os.path.join(here, 'fixtures', name) - -class ViewFactoryTests(unittest.TestCase): - def _getTargetClass(self): - from repoze.bfg.view import ViewFactory - return ViewFactory - - def _makeOne(self, *arg, **kw): - klass = self._getTargetClass() - return klass(*arg, **kw) - - def test_call(self): - view = self._makeOne(None, None) - self.assertRaises(NotImplementedError, view) - diff --git a/repoze/bfg/tests/test_wsgiadapter.py b/repoze/bfg/tests/test_wsgiadapter.py deleted file mode 100644 index 217d43427..000000000 --- a/repoze/bfg/tests/test_wsgiadapter.py +++ /dev/null @@ -1,113 +0,0 @@ -import unittest - -from zope.component.testing import PlacelessSetup - -class NaiveWSGIAdapterTests(unittest.TestCase, PlacelessSetup): - def setUp(self): - PlacelessSetup.setUp(self) - - def tearDown(self): - PlacelessSetup.tearDown(self) - - def _getTargetClass(self): - from repoze.bfg.wsgiadapter import NaiveWSGIViewAdapter - return NaiveWSGIViewAdapter - - def _makeOne(self, *arg, **kw): - klass = self._getTargetClass() - return klass(*arg, **kw) - - def test_view_takes_no_args(self): - response = DummyResponse() - response.app_iter = ['Hello world'] - def view(): - return response - request = DummyRequest() - context = DummyContext() - adapter = self._makeOne(context, request, view) - environ = {} - start_response = DummyStartResponse() - result = adapter(environ, start_response) - self.assertEqual(result, ['Hello world']) - self.assertEqual(start_response.headers, ()) - self.assertEqual(start_response.status, '200 OK') - - def test_view_takes_pep_333_args(self): - response = DummyResponse() - response.app_iter = ['Hello world'] - def view(environ, start_response): - response.environ = environ - response.start_response = start_response - return response - request = DummyRequest() - context = DummyContext() - adapter = self._makeOne(context, request, view) - environ = {} - start_response = DummyStartResponse() - result = adapter(environ, start_response) - self.assertEqual(result, ['Hello world']) - self.assertEqual(start_response.headers, ()) - self.assertEqual(start_response.status, '200 OK') - self.assertEqual(response.environ, environ) - self.assertEqual(response.start_response, start_response) - - def test_view_takes_zopey_args(self): - request = DummyRequest() - response = DummyResponse() - response.app_iter = ['Hello world'] - def view(request): - response.request = request - return response - context = DummyContext() - adapter = self._makeOne(context, request, view) - environ = {} - start_response = DummyStartResponse() - result = adapter(environ, start_response) - self.assertEqual(result, ['Hello world']) - self.assertEqual(start_response.headers, ()) - self.assertEqual(start_response.status, '200 OK') - self.assertEqual(response.request, request) - - def test_view_is_response(self): - request = DummyRequest() - response = DummyResponse() - response.app_iter = ['Hello world'] - context = DummyContext() - adapter = self._makeOne(context, request, response) - environ = {} - start_response = DummyStartResponse() - result = adapter(environ, start_response) - self.assertEqual(result, ['Hello world']) - self.assertEqual(start_response.headers, ()) - self.assertEqual(start_response.status, '200 OK') - - def test_view_returns_nonresponse(self): - request = DummyRequest() - def view(request): - return None - context = DummyContext() - adapter = self._makeOne(context, request, view) - environ = {} - start_response = DummyStartResponse() - self.assertRaises(ValueError, adapter, environ, start_response) - - -class DummyContext: - pass - -class DummyRequest: - pass - -class DummyResponse: - status = '200 OK' - headerlist = () - app_iter = () - -class DummyStartResponse: - status = None - headers = None - def __call__(self, status, headers): - self.status = status - self.headers = headers - - diff --git a/repoze/bfg/tests/test_xslt.py b/repoze/bfg/tests/test_xslt.py index ebf0e625d..01e5befba 100644 --- a/repoze/bfg/tests/test_xslt.py +++ b/repoze/bfg/tests/test_xslt.py @@ -34,21 +34,16 @@ class XSLTemplateFactoryTests(unittest.TestCase, Base): klass = self._getTargetClass() return klass(*arg, **kw) - def test_instance_conforms_to_INodeView(self): + def test_instance_implements_INodeTemplate(self): from zope.interface.verify import verifyObject - from repoze.bfg.interfaces import INodeView + from repoze.bfg.interfaces import INodeTemplate path = self._getTemplatePath('minimal.xsl') - verifyObject(INodeView, self._makeOne(path)) + verifyObject(INodeTemplate, self._makeOne(path)) - def test_class_conforms_to_INodeView(self): + def test_class_implements_INodeTemplate(self): from zope.interface.verify import verifyClass - from repoze.bfg.interfaces import INodeView - verifyClass(INodeView, self._getTargetClass()) - - def test_class_conforms_to_ITemplateFactory(self): - from zope.interface.verify import verifyObject - from repoze.bfg.interfaces import ITemplateFactory - verifyObject(ITemplateFactory, self._getTargetClass()) + from repoze.bfg.interfaces import INodeTemplate + verifyClass(INodeTemplate, self._getTargetClass()) def test_call(self): self._zcmlConfigure() @@ -57,14 +52,11 @@ class XSLTemplateFactoryTests(unittest.TestCase, Base): from lxml import etree info = etree.Element("info") result = instance(node=info) - from webob import Response - self.failUnless(isinstance(result, Response)) + self.failUnless(isinstance(result, str)) resultstr = """\n
\n""" - self.assertEqual(result.app_iter, [resultstr]) - self.assertEqual(result.status, '200 OK') - self.assertEqual(len(result.headerlist), 2) + self.assertEqual(result, resultstr) -class RenderTemplateTests(unittest.TestCase, Base): +class RenderTransformToResponseTests(unittest.TestCase, Base): def setUp(self): Base.setUp(self) @@ -72,15 +64,15 @@ class RenderTemplateTests(unittest.TestCase, Base): Base.tearDown(self) def _getFUT(self): - from repoze.bfg.template import render_transform - return render_transform + from repoze.bfg.template import render_transform_to_response + return render_transform_to_response def test_nonabs_unregistered(self): self._zcmlConfigure() from zope.component import queryUtility - from repoze.bfg.interfaces import IView + from repoze.bfg.interfaces import INodeTemplate minimal = self._getTemplatePath('minimal.xsl') - self.assertEqual(queryUtility(IView, minimal), None) + self.assertEqual(queryUtility(INodeTemplate, minimal), None) render = self._getFUT() from lxml import etree info = etree.Element("info") @@ -92,7 +84,7 @@ class RenderTemplateTests(unittest.TestCase, Base): self.assertEqual(result.status, '200 OK') self.assertEqual(len(result.headerlist), 2) from repoze.bfg.template import XSLTemplateFactory - self.failUnless(isinstance(queryUtility(IView, minimal), + self.failUnless(isinstance(queryUtility(INodeTemplate, minimal), XSLTemplateFactory)) def test_nonabs_registered(self): @@ -100,11 +92,11 @@ class RenderTemplateTests(unittest.TestCase, Base): from zope.component import getGlobalSiteManager from zope.component import queryUtility from repoze.bfg.template import XSLTemplateFactory - from repoze.bfg.interfaces import IView + from repoze.bfg.interfaces import INodeTemplate minimal = self._getTemplatePath('minimal.xsl') utility = XSLTemplateFactory(minimal) gsm = getGlobalSiteManager() - gsm.registerUtility(utility, IView, name=minimal) + gsm.registerUtility(utility, INodeTemplate, name=minimal) render = self._getFUT() from lxml import etree info = etree.Element("info") @@ -115,9 +107,52 @@ class RenderTemplateTests(unittest.TestCase, Base): self.assertEqual(result.app_iter, [resultstr]) self.assertEqual(result.status, '200 OK') self.assertEqual(len(result.headerlist), 2) - self.assertEqual(queryUtility(IView, minimal), utility) - -class DummyView: - context = 'context' - request = 'request' - + self.assertEqual(queryUtility(INodeTemplate, minimal), utility) + +class RenderTransformTests(unittest.TestCase, Base): + def setUp(self): + Base.setUp(self) + + def tearDown(self): + Base.tearDown(self) + + def _getFUT(self): + from repoze.bfg.template import render_transform + return render_transform + + def test_nonabs_unregistered(self): + self._zcmlConfigure() + from zope.component import queryUtility + from repoze.bfg.interfaces import INodeTemplate + minimal = self._getTemplatePath('minimal.xsl') + self.assertEqual(queryUtility(INodeTemplate, minimal), None) + render = self._getFUT() + from lxml import etree + info = etree.Element("info") + result = render(minimal, node=info) + self.failUnless(isinstance(result, str)) + resultstr = """\n
\n""" + self.assertEqual(result, resultstr) + from repoze.bfg.template import XSLTemplateFactory + self.failUnless(isinstance(queryUtility(INodeTemplate, minimal), + XSLTemplateFactory)) + + def test_nonabs_registered(self): + self._zcmlConfigure() + from zope.component import getGlobalSiteManager + from zope.component import queryUtility + from repoze.bfg.template import XSLTemplateFactory + from repoze.bfg.interfaces import INodeTemplate + minimal = self._getTemplatePath('minimal.xsl') + utility = XSLTemplateFactory(minimal) + gsm = getGlobalSiteManager() + gsm.registerUtility(utility, INodeTemplate, name=minimal) + render = self._getFUT() + from lxml import etree + info = etree.Element("info") + result = render(minimal, node=info) + self.failUnless(isinstance(result, str)) + resultstr = """\n
\n""" + self.assertEqual(result, resultstr) + self.assertEqual(queryUtility(INodeTemplate, minimal), utility) + diff --git a/repoze/bfg/tests/test_zcml.py b/repoze/bfg/tests/test_zcml.py index a2602b9c1..f8ef78ff8 100644 --- a/repoze/bfg/tests/test_zcml.py +++ b/repoze/bfg/tests/test_zcml.py @@ -33,9 +33,9 @@ class TestViewDirective(unittest.TestCase, PlacelessSetup): pass f(context, 'repoze.view', IFoo, template='minimal.pt') actions = context.actions + from repoze.bfg.interfaces import ITemplate from repoze.bfg.interfaces import IView from repoze.bfg.interfaces import IRequest - from repoze.bfg.interfaces import IViewFactory from repoze.bfg.interfaces import IViewPermission from repoze.bfg.security import ViewPermissionFactory from zope.component.zcml import handler @@ -43,14 +43,15 @@ class TestViewDirective(unittest.TestCase, PlacelessSetup): self.assertEqual(len(actions), 4) - regutil_discriminator = ('utility', IView, context.path('minimal.pt')) + regutil_discriminator = ('utility', ITemplate, + context.path('minimal.pt')) regutil = actions[0] self.assertEqual(regutil['discriminator'], regutil_discriminator) self.assertEqual(regutil['callable'], handler) self.assertEqual(regutil['args'][0], 'registerUtility') self.assertEqual(regutil['args'][1].template.filename, context.path('minimal.pt')) - self.assertEqual(regutil['args'][2], IView) + self.assertEqual(regutil['args'][2], ITemplate) self.assertEqual(regutil['args'][3], context.path('minimal.pt')) provide = actions[1] @@ -73,14 +74,14 @@ class TestViewDirective(unittest.TestCase, PlacelessSetup): self.assertEqual(permission['args'][5], None) regadapt = actions[3] - regadapt_discriminator = ('view', IFoo, '', IRequest, IViewFactory) + regadapt_discriminator = ('view', IFoo, '', IRequest, IView) self.assertEqual(regadapt['discriminator'], regadapt_discriminator) self.assertEqual(regadapt['callable'], handler) self.assertEqual(regadapt['args'][0], 'registerAdapter') self.assertEqual(regadapt['args'][1].template, context.path('minimal.pt')) self.assertEqual(regadapt['args'][2], (IFoo, IRequest)) - self.assertEqual(regadapt['args'][3], IViewFactory) + self.assertEqual(regadapt['args'][3], IView) self.assertEqual(regadapt['args'][4], '') self.assertEqual(regadapt['args'][5], None) @@ -89,10 +90,12 @@ class TestViewDirective(unittest.TestCase, PlacelessSetup): context = DummyContext() class IFoo: pass - f(context, 'repoze.view', IFoo, factory=Dummy) + def view(context, request): + pass + f(context, 'repoze.view', IFoo, view=view) actions = context.actions from repoze.bfg.interfaces import IRequest - from repoze.bfg.interfaces import IViewFactory + from repoze.bfg.interfaces import IView from repoze.bfg.interfaces import IViewPermission from repoze.bfg.security import ViewPermissionFactory from zope.component.zcml import handler @@ -120,13 +123,13 @@ class TestViewDirective(unittest.TestCase, PlacelessSetup): self.assertEqual(permission['args'][5], None) regadapt = actions[2] - regadapt_discriminator = ('view', IFoo, '', IRequest, IViewFactory) + regadapt_discriminator = ('view', IFoo, '', IRequest, IView) self.assertEqual(regadapt['discriminator'], regadapt_discriminator) self.assertEqual(regadapt['callable'], handler) self.assertEqual(regadapt['args'][0], 'registerAdapter') - self.assertEqual(regadapt['args'][1], Dummy) + self.assertEqual(regadapt['args'][1], view) self.assertEqual(regadapt['args'][2], (IFoo, IRequest)) - self.assertEqual(regadapt['args'][3], IViewFactory) + self.assertEqual(regadapt['args'][3], IView) self.assertEqual(regadapt['args'][4], '') self.assertEqual(regadapt['args'][5], None) @@ -135,31 +138,9 @@ class TestViewDirective(unittest.TestCase, PlacelessSetup): context = DummyContext() from zope.configuration.exceptions import ConfigurationError self.assertRaises(ConfigurationError, f, context, 'repoze.view', - None, factory=object, template='minimal.pt') - -class TestTemplateOnlyViewFactory(unittest.TestCase): - def _getTargetClass(self): - from repoze.bfg.zcml import TemplateOnlyViewFactory - return TemplateOnlyViewFactory + None, view=object, template='minimal.pt') - def _makeOne(self, template): - return self._getTargetClass()(template) - - def test_instance_conforms_to_IViewFactory(self): - from zope.interface.verify import verifyObject - from repoze.bfg.interfaces import IViewFactory - verifyObject(IViewFactory, self._makeOne('a')) - - def test_call(self): - context = DummyContext() - template = context.path('minimal.pt') - factory = self._makeOne(template) - view = factory(None, None) - from repoze.bfg.zcml import TemplateOnlyView - self.failUnless(isinstance(view, TemplateOnlyView)) - self.assertEqual(view.template, template) - -class TemplateOnlyViewTests(unittest.TestCase, PlacelessSetup): +class TemplateOnlyViewFactoryTests(unittest.TestCase, PlacelessSetup): def setUp(self): PlacelessSetup.setUp(self) @@ -167,8 +148,8 @@ class TemplateOnlyViewTests(unittest.TestCase, PlacelessSetup): PlacelessSetup.tearDown(self) def _getTargetClass(self): - from repoze.bfg.zcml import TemplateOnlyView - return TemplateOnlyView + from repoze.bfg.zcml import TemplateOnlyViewFactory + return TemplateOnlyViewFactory def _zcmlConfigure(self): import repoze.bfg @@ -186,9 +167,9 @@ class TemplateOnlyViewTests(unittest.TestCase, PlacelessSetup): def test_call(self): self._zcmlConfigure() - view = self._makeOne(None, None) - view.template = self._getTemplatePath('minimal.pt') - result = view(foo='foo') + path = self._getTemplatePath('minimal.pt') + view = self._makeOne(path) + result = view(None, None) from webob import Response self.failUnless(isinstance(result, Response)) self.assertEqual(result.app_iter, ['
\n
']) @@ -197,8 +178,8 @@ class TemplateOnlyViewTests(unittest.TestCase, PlacelessSetup): def test_call_no_template(self): self._zcmlConfigure() - view = self._makeOne(None, None) - self.assertRaises(ValueError, view) + view = self._makeOne('nosuch') + self.assertRaises(ValueError, view, None, None) class TestSampleApp(unittest.TestCase, PlacelessSetup): def setUp(self): diff --git a/repoze/bfg/traversal.py b/repoze/bfg/traversal.py index b59379db7..a9f127841 100644 --- a/repoze/bfg/traversal.py +++ b/repoze/bfg/traversal.py @@ -5,8 +5,8 @@ from zope.interface import implements from zope.location.location import located from zope.location.interfaces import ILocation -from repoze.bfg.interfaces import IPublishTraverser -from repoze.bfg.interfaces import IPublishTraverserFactory +from repoze.bfg.interfaces import ITraverser +from repoze.bfg.interfaces import ITraverserFactory def split_path(path): if path.startswith('/'): @@ -36,9 +36,9 @@ def step(ob, name, default): _marker = () -class NaivePublishTraverser(object): - classProvides(IPublishTraverserFactory) - implements(IPublishTraverser) +class NaiveTraverser(object): + classProvides(ITraverserFactory) + implements(ITraverser) def __init__(self, root, request): self.root = root self.locatable = ILocation.providedBy(root) diff --git a/repoze/bfg/view.py b/repoze/bfg/view.py deleted file mode 100644 index 6a7fccdcc..000000000 --- a/repoze/bfg/view.py +++ /dev/null @@ -1,20 +0,0 @@ -from zope.interface import implements -from zope.interface import classProvides - -from repoze.bfg.interfaces import IView -from repoze.bfg.interfaces import IViewFactory - -class ViewFactory(object): - """ Convenience base class for user-defined view factories (just accepts - context and request)""" - implements(IView) - classProvides(IViewFactory) - def __init__(self, context, request): - self.context = context - self.request = request - - def __call__(self, **kw): - raise NotImplementedError - - - diff --git a/repoze/bfg/wsgiadapter.py b/repoze/bfg/wsgiadapter.py deleted file mode 100644 index 0a4803f74..000000000 --- a/repoze/bfg/wsgiadapter.py +++ /dev/null @@ -1,48 +0,0 @@ -from zope.interface import classProvides -from zope.interface import implements - -from repoze.bfg.interfaces import IWSGIApplicationFactory -from repoze.bfg.interfaces import IWSGIApplication -from repoze.bfg.mapply import mapply - -def isResponse(ob): - 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 - -class NaiveWSGIViewAdapter: - classProvides(IWSGIApplicationFactory) - implements(IWSGIApplication) - - def __init__(self, context, request, view): - self.context = context - self.request = request - self.view = view - - def __call__(self, environ, start_response): - context = self.context - request = self.request - view = self.view - - catch_response = [] - def replace_start_response(status, headers): - catch_response[:] = (status, headers) - kwdict = { - 'request':self.request, - 'environ':environ, - 'start_response':start_response, - } - - if isResponse(view): - response = view - else: - response = mapply(view, positional = (), keyword = kwdict) - if not isResponse(response): - raise ValueError('response was not IResponse: %s' % response) - if not catch_response: - catch_response = (response.status, response.headerlist) - start_response(*catch_response) - return response.app_iter diff --git a/repoze/bfg/zcml.py b/repoze/bfg/zcml.py index 71a07daec..7d81527d2 100644 --- a/repoze/bfg/zcml.py +++ b/repoze/bfg/zcml.py @@ -13,63 +13,39 @@ from zope.interface import classProvides from zope.schema import TextLine from repoze.bfg.interfaces import IRequest -from repoze.bfg.interfaces import IViewFactory +from repoze.bfg.interfaces import ITemplateFactory +from repoze.bfg.interfaces import ITemplate from repoze.bfg.interfaces import IViewPermission from repoze.bfg.interfaces import IView from repoze.bfg.template import Z3CPTTemplateFactory -from repoze.bfg.template import render_template +from repoze.bfg.template import render_template_to_response from repoze.bfg.security import ViewPermissionFactory -class TemplateOnlyView(object): - implements(IView) - classProvides(IViewFactory) - template = None - - def __init__(self, context, request): - self.context = context - self.request = request - - def __call__(self, **kw): - if self.template is None: - raise ValueError('a "template" attribute must be attached to ' - 'a TemplateOnlyView') - kw = dict(view=self, context=self.context, request=self.request, - options=kw) - return render_template(self.template, **kw) - - def __repr__(self): - klass = self.__class__ - return '<%s.%s object at %s for %s>' % (klass.__module__, - klass.__mame__, - id(self), - self.template) - class TemplateOnlyViewFactory(object): """ Pickleable template-only view factory """ - - implements(IViewFactory) + classProvides(ITemplateFactory) + implements(IView) def __init__(self, template): self.template = template def __call__(self, context, request): - factory = TemplateOnlyView(context, request) - factory.template = self.template - return factory + kw = dict(view=self, context=context, request=request) + return render_template_to_response(self.template, **kw) def view(_context, permission=None, for_=None, - factory=None, + view=None, name="", template=None, ): - if (template and factory): + if (template and view): raise ConfigurationError( - 'One of template or factory must be specified, not both') + 'One of template or view must be specified, not both') if template: template_abs = os.path.abspath(str(_context.path(template))) @@ -77,13 +53,13 @@ def view(_context, raise ConfigurationError('No template file named %s' % template_abs) utility = Z3CPTTemplateFactory(template_abs) _context.action( - discriminator = ('utility', IView, template_abs), + discriminator = ('utility', ITemplate, template_abs), callable = handler, - args = ('registerUtility', utility, IView, template_abs), + args = ('registerUtility', utility, ITemplate, template_abs), ) - factory = TemplateOnlyViewFactory(template_abs) + view = TemplateOnlyViewFactory(template_abs) - if not factory: + if not view: raise ConfigurationError( 'Neither template nor factory was specified, though one must be ' 'specified.') @@ -106,10 +82,10 @@ def view(_context, ) _context.action( - discriminator = ('view', for_, name, IRequest, IViewFactory), + discriminator = ('view', for_, name, IRequest, IView), callable = handler, args = ('registerAdapter', - factory, (for_, IRequest), IViewFactory, name, + view, (for_, IRequest), IView, name, _context.info), ) @@ -125,14 +101,14 @@ class IViewDirective(Interface): required=False ) - factory = GlobalObject( - title=u"Class", - description=u"A class that provides a __call__ used by the view.", + view = GlobalObject( + title=u"", + description=u"The view function", required=False, ) name = TextLine( - title=u"The name of the page (view)", + title=u"The name of the view", description=u""" The name shows up in URLs/paths. For example 'foo' or 'foo.html'.""", @@ -140,7 +116,7 @@ class IViewDirective(Interface): ) template = Path( - title=u"The name of a template that implements the page.", + title=u"The name of a template that implements the view.", description=u"""Refers to a file containing a z3c.pt page template""", required=False ) -- cgit v1.2.3