The test client now properly pops response contexts on __exit__

This commit is contained in:
Armin Ronacher 2011-08-26 14:01:46 +01:00
parent c8ec453d86
commit d49221bf2e
4 changed files with 48 additions and 4 deletions

View file

@ -40,6 +40,8 @@ Relase date to be decided, codename to be chosen.
as defaults. as defaults.
- Added :attr:`flask.views.View.decorators` to support simpler decorating of - Added :attr:`flask.views.View.decorators` to support simpler decorating of
pluggable (class based) views. 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 Version 0.7.3
------------- -------------

View file

@ -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 up for the user. If you were catching this down explicitly in the past
as `ValueError` you will need to change this. 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 Version 0.7
----------- -----------

View file

@ -86,9 +86,7 @@ class FlaskClient(Client):
self.cookie_jar.extract_wsgi(c.request.environ, headers) self.cookie_jar.extract_wsgi(c.request.environ, headers)
def open(self, *args, **kwargs): def open(self, *args, **kwargs):
if self.context_preserved: self._pop_reqctx_if_necessary()
_request_ctx_stack.pop()
self.context_preserved = False
kwargs.setdefault('environ_overrides', {}) \ kwargs.setdefault('environ_overrides', {}) \
['flask._preserve_context'] = self.preserve_context ['flask._preserve_context'] = self.preserve_context
@ -114,5 +112,12 @@ class FlaskClient(Client):
def __exit__(self, exc_type, exc_value, tb): def __exit__(self, exc_type, exc_value, tb):
self.preserve_context = False self.preserve_context = False
self._pop_reqctx_if_necessary()
def _pop_reqctx_if_necessary(self):
if self.context_preserved: 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

View file

@ -126,6 +126,38 @@ class TestToolsTestCase(FlaskTestCase):
else: else:
raise AssertionError('some kind of exception expected') 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(): def suite():
suite = unittest.TestSuite() suite = unittest.TestSuite()