From 426ac3328a3d2dfa2d1ac2d805f82ed9881c6232 Mon Sep 17 00:00:00 2001 From: Jonathan LaCour Date: Wed, 29 Sep 2010 00:24:58 -0400 Subject: [PATCH] Added coverage for hooks, and fixed a few bugs along the way. --- pecan/hooks.py | 5 +- pecan/pecan.py | 5 +- tests/test_hooks.py | 145 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 149 insertions(+), 6 deletions(-) create mode 100644 tests/test_hooks.py diff --git a/pecan/hooks.py b/pecan/hooks.py index 1dfc044..d742ac3 100644 --- a/pecan/hooks.py +++ b/pecan/hooks.py @@ -5,7 +5,7 @@ class PecanHook(object): def after(self, state): pass - def on_error(self, state): + def on_error(self, state, e): pass @@ -31,9 +31,8 @@ class TransactionHook(PecanHook): state.request.transactional = False self.start_ro() - def on_error(self, state): + def on_error(self, state, e): state.request.error = True - self.rollback() def after(self, state): if state.request.transactional: diff --git a/pecan/pecan.py b/pecan/pecan.py index 05adf8b..5f8d680 100644 --- a/pecan/pecan.py +++ b/pecan/pecan.py @@ -108,10 +108,9 @@ class Pecan(object): hook.on_error(state, e) raise else: + return response(environ, start_response) + finally: # handle "after" hooks for hook in self.hooks: hook.after(state) - - return response(environ, start_response) - finally: del state.request \ No newline at end of file diff --git a/tests/test_hooks.py b/tests/test_hooks.py new file mode 100644 index 0000000..20c77e6 --- /dev/null +++ b/tests/test_hooks.py @@ -0,0 +1,145 @@ +from pecan import Pecan, expose +from pecan.hooks import PecanHook, TransactionHook +from webtest import TestApp + + +class TestHooks(object): + + def test_basic_single_hook(self): + run_hook = [] + + class RootController(object): + @expose() + def index(self): + run_hook.append('inside') + return 'Hello, World!' + + class SimpleHook(PecanHook): + def before(self, state): + run_hook.append('before') + + def after(self, state): + run_hook.append('after') + + def on_error(self, state, e): + run_hook.append('error') + + app = TestApp(Pecan(RootController(), hooks=[SimpleHook()])) + response = app.get('/') + assert response.status_int == 200 + assert response.body == 'Hello, World!' + + assert len(run_hook) == 3 + assert run_hook[0] == 'before' + assert run_hook[1] == 'inside' + assert run_hook[2] == 'after' + + def test_basic_multi_hook(self): + run_hook = [] + + class RootController(object): + @expose() + def index(self): + run_hook.append('inside') + return 'Hello, World!' + + class SimpleHook(PecanHook): + def __init__(self, id): + self.id = str(id) + + def before(self, state): + run_hook.append('before'+self.id) + + def after(self, state): + run_hook.append('after'+self.id) + + def on_error(self, state, e): + run_hook.append('error'+self.id) + + app = TestApp(Pecan(RootController(), hooks=[ + SimpleHook(1), SimpleHook(2), SimpleHook(3) + ])) + response = app.get('/') + assert response.status_int == 200 + assert response.body == 'Hello, World!' + + assert len(run_hook) == 7 + assert run_hook[0] == 'before1' + assert run_hook[1] == 'before2' + assert run_hook[2] == 'before3' + assert run_hook[3] == 'inside' + assert run_hook[4] == 'after1' + assert run_hook[5] == 'after2' + assert run_hook[6] == 'after3' + + def test_transaction_hook(self): + run_hook = [] + + class RootController(object): + @expose() + def index(self): + run_hook.append('inside') + return 'Hello, World!' + + @expose() + def error(self): + return [][1] + + class SimpleHook(PecanHook): + def __init__(self, id): + self.id = str(id) + + def before(self, state): + run_hook.append('before'+self.id) + + def after(self, state): + run_hook.append('after'+self.id) + + def on_error(self, state, e): + run_hook.append('error'+self.id) + + def gen(event): + return lambda: run_hook.append(event) + + app = TestApp(Pecan(RootController(), hooks=[ + TransactionHook( + start = gen('start'), + start_ro = gen('start_ro'), + commit = gen('commit'), + rollback = gen('rollback'), + clear = gen('clear') + ) + ])) + + response = app.get('/') + assert response.status_int == 200 + assert response.body == 'Hello, World!' + + assert len(run_hook) == 3 + assert run_hook[0] == 'start_ro' + assert run_hook[1] == 'inside' + assert run_hook[2] == 'clear' + + for i in range(len(run_hook)): run_hook.pop() + + response = app.post('/') + assert response.status_int == 200 + assert response.body == 'Hello, World!' + + assert len(run_hook) == 4 + assert run_hook[0] == 'start' + assert run_hook[1] == 'inside' + assert run_hook[2] == 'commit' + assert run_hook[3] == 'clear' + + for i in range(len(run_hook)): run_hook.pop() + try: + response = app.post('/error') + except IndexError: + pass + + assert len(run_hook) == 3 + assert run_hook[0] == 'start' + assert run_hook[1] == 'rollback' + assert run_hook[2] == 'clear' + \ No newline at end of file