diff --git a/CHANGES b/CHANGES index fa8c00bf..b39a2001 100644 --- a/CHANGES +++ b/CHANGES @@ -40,6 +40,8 @@ Relase date to be decided, codename to be chosen. as defaults. - Added :attr:`flask.views.View.decorators` to support simpler decorating of pluggable (class based) views. +- Fixed an issue where the test client if used with the with statement did not + trigger the execution of the teardown handlers. Version 0.7.3 ------------- diff --git a/docs/upgrading.rst b/docs/upgrading.rst index b318292c..0ba46c13 100644 --- a/docs/upgrading.rst +++ b/docs/upgrading.rst @@ -36,6 +36,11 @@ longer have to handle that error to avoid an internal server error showing up for the user. If you were catching this down explicitly in the past as `ValueError` you will need to change this. +Due to a bug in the test client Flask 0.7 did not trigger teardown +handlers when the test client was used in a with statement. This was +since fixed but might require some changes in your testsuites if you +relied on this behavior. + Version 0.7 ----------- diff --git a/flask/testing.py b/flask/testing.py index 6ce96163..612b4d4d 100644 --- a/flask/testing.py +++ b/flask/testing.py @@ -86,9 +86,7 @@ class FlaskClient(Client): self.cookie_jar.extract_wsgi(c.request.environ, headers) def open(self, *args, **kwargs): - if self.context_preserved: - _request_ctx_stack.pop() - self.context_preserved = False + self._pop_reqctx_if_necessary() kwargs.setdefault('environ_overrides', {}) \ ['flask._preserve_context'] = self.preserve_context @@ -114,5 +112,12 @@ class FlaskClient(Client): def __exit__(self, exc_type, exc_value, tb): self.preserve_context = False + self._pop_reqctx_if_necessary() + + def _pop_reqctx_if_necessary(self): if self.context_preserved: - _request_ctx_stack.pop() + # we have to use _request_ctx_stack.top.pop instead of + # _request_ctx_stack.pop since we want teardown handlers + # to be executed. + _request_ctx_stack.top.pop() + self.context_preserved = False diff --git a/flask/testsuite/testing.py b/flask/testsuite/testing.py index b7a71b1a..32867c3f 100644 --- a/flask/testsuite/testing.py +++ b/flask/testsuite/testing.py @@ -126,6 +126,38 @@ class TestToolsTestCase(FlaskTestCase): else: raise AssertionError('some kind of exception expected') + def test_reuse_client(self): + app = flask.Flask(__name__) + c = app.test_client() + + with c: + self.assert_equal(c.get('/').status_code, 404) + + with c: + self.assert_equal(c.get('/').status_code, 404) + + def test_test_client_calls_teardown_handlers(self): + app = flask.Flask(__name__) + called = [] + @app.teardown_request + def remember(error): + called.append(error) + + with app.test_client() as c: + self.assert_equal(called, []) + c.get('/') + self.assert_equal(called, []) + self.assert_equal(called, [None]) + + del called[:] + with app.test_client() as c: + self.assert_equal(called, []) + c.get('/') + self.assert_equal(called, []) + c.get('/') + self.assert_equal(called, [None]) + self.assert_equal(called, [None, None]) + def suite(): suite = unittest.TestSuite()