From 5a7f9a4d57424f14a1e072cc06b6bf7a191a7d08 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 16 Jan 2009 18:58:16 +0000 Subject: Features -------- - The functionality of ``repoze.bfg.convention`` has been merged into the core. Applications which make use of ``repoze.bfg.convention`` will continue to work indefinitely, but it is recommended that apps stop depending upon it. To do so, substitute imports of ``repoze.bfg.convention.bfg_view`` with imports of ``repoze.bfg.view.bfg_view``, and change the stanza in ZCML from ```` to ````. As a result of the merge, bfg has grown a new dependency: ``martian``. - View functions which use the pushpage decorator are now pickleable (meaning their use won't prevent a ``configure.zcml.cache`` file from being written to disk). Implementation Changes ---------------------- - The ``wsgiapp`` decorator now uses ``webob.Request.get_response`` to do its work rather than relying on howgrown WSGI code. --- repoze/bfg/tests/grokkedapp/__init__.py | 11 +++ repoze/bfg/tests/grokkedapp/configure.zcml | 6 ++ repoze/bfg/tests/test_integration.py | 152 +++++++++++++++++++++++++++++ repoze/bfg/tests/test_push.py | 2 +- repoze/bfg/tests/test_view.py | 48 +++++++++ repoze/bfg/tests/test_wsgi.py | 55 ++--------- repoze/bfg/tests/test_zcml.py | 142 ++++++++++++++++++++++----- 7 files changed, 343 insertions(+), 73 deletions(-) create mode 100644 repoze/bfg/tests/grokkedapp/__init__.py create mode 100644 repoze/bfg/tests/grokkedapp/configure.zcml create mode 100644 repoze/bfg/tests/test_integration.py (limited to 'repoze/bfg/tests') diff --git a/repoze/bfg/tests/grokkedapp/__init__.py b/repoze/bfg/tests/grokkedapp/__init__.py new file mode 100644 index 000000000..9d91eb80f --- /dev/null +++ b/repoze/bfg/tests/grokkedapp/__init__.py @@ -0,0 +1,11 @@ +from repoze.bfg.view import bfg_view +from zope.interface import Interface + +class INothing(Interface): + pass + +@bfg_view(for_=INothing) +def grokked(context, request): + """ """ + + diff --git a/repoze/bfg/tests/grokkedapp/configure.zcml b/repoze/bfg/tests/grokkedapp/configure.zcml new file mode 100644 index 000000000..be7226afd --- /dev/null +++ b/repoze/bfg/tests/grokkedapp/configure.zcml @@ -0,0 +1,6 @@ + + + + + + diff --git a/repoze/bfg/tests/test_integration.py b/repoze/bfg/tests/test_integration.py new file mode 100644 index 000000000..76004af7b --- /dev/null +++ b/repoze/bfg/tests/test_integration.py @@ -0,0 +1,152 @@ +import unittest + +from repoze.bfg.wsgi import wsgiapp +from repoze.bfg.view import bfg_view +from repoze.bfg.push import pushpage + +from zope.interface import Interface + +from zope.testing.cleanup import cleanUp + +class INothing(Interface): + pass + +@bfg_view(for_=INothing) +@wsgiapp +def wsgiapptest(environ, start_response): + """ """ + return '123' + +class WGSIAppPlusBFGViewTests(unittest.TestCase): + def setUp(self): + cleanUp() + + def tearDown(self): + cleanUp() + + def test_it(self): + import types + self.assertEqual(wsgiapptest.__is_bfg_view__, True) + self.failUnless(type(wsgiapptest) is types.FunctionType) + context = DummyContext() + request = DummyRequest() + result = wsgiapptest(context, request) + self.assertEqual(result, '123') + + def test_grokkage(self): + from repoze.bfg.interfaces import IRequest + from repoze.bfg.interfaces import IView + from repoze.bfg.zcml import grok + context = DummyContext() + from repoze.bfg.tests import test_integration + grok(context, test_integration) + actions = context.actions + self.assertEqual(len(actions), 2) + action = actions[1] + self.assertEqual(action['args'], + ('registerAdapter', + wsgiapptest, (INothing, IRequest), IView, '', None)) + +@bfg_view(for_=INothing) +@pushpage('fake.pt') +def pushtest(context, request): + """ """ + return {'a':1} + +class PushPagePlusBFGViewTests(unittest.TestCase): + def setUp(self): + cleanUp() + + def tearDown(self): + cleanUp() + + def test_it(self): + import types + import os + from repoze.bfg.testing import registerDummyRenderer + path = os.path.join(os.path.dirname(__file__), 'fake.pt') + renderer = registerDummyRenderer(path) + self.assertEqual(pushtest.__is_bfg_view__, True) + self.failUnless(type(pushtest) is types.FunctionType) + context = DummyContext() + request = DummyRequest() + result = pushtest(context, request) + self.assertEqual(result.status, '200 OK') + + def test_grokkage(self): + from repoze.bfg.interfaces import IRequest + from repoze.bfg.interfaces import IView + from repoze.bfg.zcml import grok + context = DummyContext() + from repoze.bfg.tests import test_integration + grok(context, test_integration) + actions = context.actions + self.assertEqual(len(actions), 2) + action = actions[0] + self.assertEqual(action['args'], + ('registerAdapter', + pushtest, (INothing, IRequest), IView, '', None)) + +class TestFixtureApp(unittest.TestCase): + def setUp(self): + cleanUp() + + def tearDown(self): + cleanUp() + + def test_registry_actions_can_be_pickled_and_unpickled(self): + import repoze.bfg.tests.fixtureapp as package + from zope.configuration import config + from zope.configuration import xmlconfig + context = config.ConfigurationMachine() + xmlconfig.registerCommonDirectives(context) + context.package = package + xmlconfig.include(context, 'configure.zcml', package) + context.execute_actions(clear=False) + actions = context.actions + import cPickle + dumped = cPickle.dumps(actions, -1) + new = cPickle.loads(dumped) + self.assertEqual(len(actions), len(new)) + +class TestGrokkedApp(unittest.TestCase): + def setUp(self): + cleanUp() + + def tearDown(self): + cleanUp() + + def test_registry_actions_cannot_be_pickled_and_unpickled(self): + import repoze.bfg.tests.grokkedapp as package + + from zope.configuration import config + from zope.configuration import xmlconfig + context = config.ConfigurationMachine() + xmlconfig.registerCommonDirectives(context) + context.package = package + xmlconfig.include(context, 'configure.zcml', package) + actions = context.actions + import cPickle + self.assertRaises(cPickle.PicklingError, cPickle.dumps, actions, -1) + self.assertEqual(len(actions), 5) + +class DummyContext: + pass + +class DummyRequest: + subpath = ('__init__.py',) + environ = {'REQUEST_METHOD':'GET', 'wsgi.version':(1,0)} + def get_response(self, application): + return application(None, None) + +class DummyContext: + def __init__(self): + self.actions = [] + self.info = None + + def action(self, discriminator, callable, args): + self.actions.append( + {'discriminator':discriminator, + 'callable':callable, + 'args':args} + ) diff --git a/repoze/bfg/tests/test_push.py b/repoze/bfg/tests/test_push.py index 4220d9a5a..3cfe5a4c4 100644 --- a/repoze/bfg/tests/test_push.py +++ b/repoze/bfg/tests/test_push.py @@ -26,7 +26,7 @@ class Test_pushpage(unittest.TestCase): pp = self._makeOne('pp.pt') wrapped = pp(to_wrap) self.assertEqual(wrapped.__name__, 'to_wrap') - self.assertEqual(wrapped.__grok_module__, to_wrap.__module__) + self.assertEqual(wrapped.__module__, to_wrap.__module__) def test___call___passes_names_from_wrapped(self): self._zcmlConfigure() diff --git a/repoze/bfg/tests/test_view.py b/repoze/bfg/tests/test_view.py index 3210e6940..6fa7a920d 100644 --- a/repoze/bfg/tests/test_view.py +++ b/repoze/bfg/tests/test_view.py @@ -471,6 +471,54 @@ class TestStaticView(unittest.TestCase, BaseTest): response = view(context, request) self.failUnless(isinstance(response, Response2)) +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): + from repoze.bfg.interfaces import IRequest + from zope.interface import Interface + decorator = self._makeOne() + self.assertEqual(decorator.name, '') + self.assertEqual(decorator.request_type, IRequest) + self.assertEqual(decorator.for_, Interface) + 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.for_, None) + self.assertEqual(decorator.permission, 'foo') + + def test_call(self): + from repoze.bfg.interfaces import IRequest + from zope.interface import Interface + decorator = self._makeOne() + class foo: + """ docstring """ + wrapped = decorator(foo) + self.assertEqual(wrapped.__is_bfg_view__, True) + self.assertEqual(wrapped.__permission__, None) + self.assertEqual(wrapped.__for__, Interface) + self.assertEqual(wrapped.__request_type__, IRequest) + self.assertEqual(wrapped.__grok_module__, foo.__module__) + self.assertEqual(wrapped.__name__, foo.__name__) + self.assertEqual(wrapped.__doc__, foo.__doc__) + for k, v in foo.__dict__.items(): + self.assertEqual(v, wrapped.__dict__[k]) + class DummyContext: pass diff --git a/repoze/bfg/tests/test_wsgi.py b/repoze/bfg/tests/test_wsgi.py index ac02ec49f..e19e65044 100644 --- a/repoze/bfg/tests/test_wsgi.py +++ b/repoze/bfg/tests/test_wsgi.py @@ -9,63 +9,22 @@ class WSGIAppTests(unittest.TestCase): cleanUp() def test_decorator(self): - body = 'Unauthorized' - headerlist = [ ('Content-Type', 'text/plain'), - ('Content-Length', len(body)) ] - status = '401 Unauthorized' - def real_wsgiapp(environ, start_response): - start_response(status, headerlist) - return [body] from repoze.bfg.wsgi import wsgiapp - wrapped = wsgiapp(real_wsgiapp) + wrapped = wsgiapp(dummyapp) context = DummyContext() - request = DummyRequest({}) + request = DummyRequest() response = wrapped(context, request) - self.assertEqual(response.status, status) - self.assertEqual(response.headerlist, headerlist) - self.assertEqual(response.app_iter, [body]) + self.assertEqual(response, dummyapp) - def test_decorator_alternate_iresponsefactory(self): - body = 'Unauthorized' - headerlist = [ ('Content-Type', 'text/plain'), - ('Content-Length', len(body)) ] - status = '401 Unauthorized' - def real_wsgiapp(environ, start_response): - start_response(status, headerlist) - return [body] - from repoze.bfg.wsgi import wsgiapp - wrapped = wsgiapp(real_wsgiapp) - context = DummyContext() - request = DummyRequest({}) - from repoze.bfg.interfaces import IResponseFactory - from zope.component import getGlobalSiteManager - from webob import Response - class Response2(Response): - pass - gsm = getGlobalSiteManager() - gsm.registerUtility(Response2, IResponseFactory) - response = wrapped(context, request) - self.failUnless(isinstance(response, Response2)) - - def test_decorator_startresponse_uncalled(self): - body = 'Unauthorized' - headerlist = [ ('Content-Type', 'text/plain'), - ('Content-Length', len(body)) ] - status = '401 Unauthorized' - def real_wsgiapp(environ, start_response): - return [body] - from repoze.bfg.wsgi import wsgiapp - wrapped = wsgiapp(real_wsgiapp) - context = DummyContext() - request = DummyRequest({}) - self.assertRaises(RuntimeError, wrapped, context, request) +def dummyapp(environ, start_response): + """ """ class DummyContext: pass class DummyRequest: - def __init__(self, environ): - self.environ = environ + def get_response(self, application): + return application diff --git a/repoze/bfg/tests/test_zcml.py b/repoze/bfg/tests/test_zcml.py index 260a73c02..1d7f42098 100644 --- a/repoze/bfg/tests/test_zcml.py +++ b/repoze/bfg/tests/test_zcml.py @@ -229,28 +229,6 @@ class TestViewDirective(unittest.TestCase): self.assertEqual(regadapt['args'][5], None) -class TestFixtureApp(unittest.TestCase): - def setUp(self): - cleanUp() - - def tearDown(self): - cleanUp() - - def test_registry_actions_can_be_pickled_and_unpickled(self): - import repoze.bfg.tests.fixtureapp as package - from zope.configuration import config - from zope.configuration import xmlconfig - context = config.ConfigurationMachine() - xmlconfig.registerCommonDirectives(context) - context.package = package - xmlconfig.include(context, 'configure.zcml', package) - context.execute_actions(clear=False) - actions = context.actions - import cPickle - dumped = cPickle.dumps(actions, -1) - new = cPickle.loads(dumped) - self.assertEqual(len(actions), len(new)) - class TestZCMLPickling(unittest.TestCase): i = 0 def setUp(self): @@ -456,8 +434,121 @@ class TestZCMLPickling(unittest.TestCase): cPickle.dump(actions, open(picklename, 'wb')) self.assertEqual(True, zcml_configure('configure.zcml', self.module)) -class Dummy: - pass +class TestRemove(unittest.TestCase): + def _callFUT(self, name, os): + from repoze.bfg.zcml import remove + return remove(name, os) + + def test_fail(self): + class FakeOS: + def remove(self, name): + raise IOError('foo') + self.assertEqual(self._callFUT('name', FakeOS()), False) + + def test_succeed(self): + class FakeOS: + def remove(self, name): + pass + self.assertEqual(self._callFUT('name', FakeOS()), True) + +class TestBFGViewFunctionGrokker(unittest.TestCase): + def setUp(self): + cleanUp() + + def tearDown(self): + cleanUp() + + def _getTargetClass(self): + from repoze.bfg.zcml import BFGViewFunctionGrokker + return BFGViewFunctionGrokker + + def _makeOne(self, *arg, **kw): + return self._getTargetClass()(*arg, **kw) + + def test_grok_is_bfg_view(self): + from repoze.bfg.interfaces import IRequest + from zope.interface import Interface + grokker = self._makeOne() + class obj: + pass + obj.__is_bfg_view__ = True + obj.__permission__ = 'foo' + obj.__for__ = Interface + obj.__view_name__ = 'foo.html' + obj.__request_type__ = IRequest + context = DummyContext() + result = grokker.grok('name', obj, context=context) + self.assertEqual(result, True) + actions = context.actions + self.assertEqual(len(actions), 2) + + def test_grok_is_not_bfg_view(self): + grokker = self._makeOne() + class obj: + pass + context = DummyContext() + result = grokker.grok('name', obj, context=context) + self.assertEqual(result, False) + actions = context.actions + self.assertEqual(len(actions), 0) + +class TestZCMLGrokFunction(unittest.TestCase): + def setUp(self): + cleanUp() + + def tearDown(self): + cleanUp() + + def _callFUT(self, context, package, martian): + from repoze.bfg.zcml import grok + return grok(context, package, martian) + + def test_it(self): + martian = DummyMartianModule() + module_grokker = DummyModuleGrokker() + dummy_module = DummyModule() + from repoze.bfg.zcml import exclude + self._callFUT(None, dummy_module, martian) + self.assertEqual(martian.name, 'dummy') + self.assertEqual(len(martian.module_grokker.registered), 1) + self.assertEqual(martian.context, None) + self.assertEqual(martian.exclude_filter, exclude) + +class TestExcludeFunction(unittest.TestCase): + def setUp(self): + cleanUp() + + def tearDown(self): + cleanUp() + + def _callFUT(self, name): + from repoze.bfg.zcml import exclude + return exclude(name) + + def test_it(self): + self.assertEqual(self._callFUT('.foo'), True) + self.assertEqual(self._callFUT('foo'), False) + +class DummyModule: + __name__ = 'dummy' + +class DummyModuleGrokker: + def __init__(self): + self.registered = [] + + def register(self, other): + self.registered.append(other) + +class DummyMartianModule: + def grok_dotted_name(self, name, grokker, context, exclude_filter=None): + self.name = name + self.context = context + self.exclude_filter = exclude_filter + return True + + def ModuleGrokker(self): + self.module_grokker = DummyModuleGrokker() + return self.module_grokker class DummyContext: def __init__(self): @@ -471,6 +562,9 @@ class DummyContext: 'args':args} ) +class Dummy: + pass + from zope.interface import Interface class IDummy(Interface): pass -- cgit v1.2.3