Browse Source

DRYing up the test suite using pytest fixtures (#2306)

* add fixtures to conftest.py

* use fixtures in test_appctx.py

* use fixtures in test_blueprints.py

* use fixtures in test_depreciations.py

* use fixtures in test_regressions.py

* use fixtures in test_reqctx.py

* use fixtures in test_templating.py

* use fixtures in test_user_error_handler.py

* use fixtures in test_views.py

* use fixtures in test_basics.py

* use fixtures in test_helpers.py

* use fixtures in test_testing.py

* update conftest.py

* make docstrings  PEP-257 compliant

* cleanup

* switch dictonary format

* use pytest parameterization for test_json_as_unicode
pull/2324/head
Christian Stade-Schuldt 7 years ago committed by David Lord
parent
commit
5b0b9717da
  1. 52
      tests/conftest.py
  2. 96
      tests/test_appctx.py
  3. 487
      tests/test_basic.py
  4. 280
      tests/test_blueprints.py
  5. 13
      tests/test_deprecations.py
  6. 615
      tests/test_helpers.py
  7. 7
      tests/test_regression.py
  8. 51
      tests/test_reqctx.py
  9. 210
      tests/test_templating.py
  10. 96
      tests/test_testing.py
  11. 22
      tests/test_user_error_handler.py
  12. 44
      tests/test_views.py

52
tests/conftest.py

@ -13,6 +13,40 @@ import sys
import pkgutil import pkgutil
import pytest import pytest
import textwrap import textwrap
from flask import Flask as _Flask
class Flask(_Flask):
testing = True
secret_key = __name__
def make_response(self, rv):
if rv is None:
rv = ''
return super(Flask, self).make_response(rv)
@pytest.fixture
def app():
app = Flask(__name__)
return app
@pytest.fixture
def app_ctx(app):
with app.app_context() as ctx:
yield ctx
@pytest.fixture
def req_ctx(app):
with app.test_request_context() as ctx:
yield ctx
@pytest.fixture
def client(app):
return app.test_client()
@pytest.fixture @pytest.fixture
@ -63,12 +97,13 @@ def limit_loader(request, monkeypatch):
def get_loader(*args, **kwargs): def get_loader(*args, **kwargs):
return LimitedLoader(old_get_loader(*args, **kwargs)) return LimitedLoader(old_get_loader(*args, **kwargs))
monkeypatch.setattr(pkgutil, 'get_loader', get_loader) monkeypatch.setattr(pkgutil, 'get_loader', get_loader)
@pytest.fixture @pytest.fixture
def modules_tmpdir(tmpdir, monkeypatch): def modules_tmpdir(tmpdir, monkeypatch):
'''A tmpdir added to sys.path''' """A tmpdir added to sys.path."""
rv = tmpdir.mkdir('modules_tmpdir') rv = tmpdir.mkdir('modules_tmpdir')
monkeypatch.syspath_prepend(str(rv)) monkeypatch.syspath_prepend(str(rv))
return rv return rv
@ -82,10 +117,10 @@ def modules_tmpdir_prefix(modules_tmpdir, monkeypatch):
@pytest.fixture @pytest.fixture
def site_packages(modules_tmpdir, monkeypatch): def site_packages(modules_tmpdir, monkeypatch):
'''Create a fake site-packages''' """Create a fake site-packages."""
rv = modules_tmpdir \ rv = modules_tmpdir \
.mkdir('lib')\ .mkdir('lib') \
.mkdir('python{x[0]}.{x[1]}'.format(x=sys.version_info))\ .mkdir('python{x[0]}.{x[1]}'.format(x=sys.version_info)) \
.mkdir('site-packages') .mkdir('site-packages')
monkeypatch.syspath_prepend(str(rv)) monkeypatch.syspath_prepend(str(rv))
return rv return rv
@ -93,8 +128,9 @@ def site_packages(modules_tmpdir, monkeypatch):
@pytest.fixture @pytest.fixture
def install_egg(modules_tmpdir, monkeypatch): def install_egg(modules_tmpdir, monkeypatch):
'''Generate egg from package name inside base and put the egg into """Generate egg from package name inside base and put the egg into
sys.path''' sys.path."""
def inner(name, base=modules_tmpdir): def inner(name, base=modules_tmpdir):
if not isinstance(name, str): if not isinstance(name, str):
raise ValueError(name) raise ValueError(name)
@ -118,6 +154,7 @@ def install_egg(modules_tmpdir, monkeypatch):
egg_path, = modules_tmpdir.join('dist/').listdir() egg_path, = modules_tmpdir.join('dist/').listdir()
monkeypatch.syspath_prepend(str(egg_path)) monkeypatch.syspath_prepend(str(egg_path))
return egg_path return egg_path
return inner return inner
@ -125,6 +162,7 @@ def install_egg(modules_tmpdir, monkeypatch):
def purge_module(request): def purge_module(request):
def inner(name): def inner(name):
request.addfinalizer(lambda: sys.modules.pop(name, None)) request.addfinalizer(lambda: sys.modules.pop(name, None))
return inner return inner
@ -132,4 +170,4 @@ def purge_module(request):
def catch_deprecation_warnings(recwarn): def catch_deprecation_warnings(recwarn):
yield yield
gc.collect() gc.collect()
assert not recwarn.list assert not recwarn.list, '\n'.join(str(w.message) for w in recwarn.list)

96
tests/test_appctx.py

@ -14,8 +14,7 @@ import pytest
import flask import flask
def test_basic_url_generation(): def test_basic_url_generation(app):
app = flask.Flask(__name__)
app.config['SERVER_NAME'] = 'localhost' app.config['SERVER_NAME'] = 'localhost'
app.config['PREFERRED_URL_SCHEME'] = 'https' app.config['PREFERRED_URL_SCHEME'] = 'https'
@ -27,31 +26,33 @@ def test_basic_url_generation():
rv = flask.url_for('index') rv = flask.url_for('index')
assert rv == 'https://localhost/' assert rv == 'https://localhost/'
def test_url_generation_requires_server_name():
app = flask.Flask(__name__) def test_url_generation_requires_server_name(app):
with app.app_context(): with app.app_context():
with pytest.raises(RuntimeError): with pytest.raises(RuntimeError):
flask.url_for('index') flask.url_for('index')
def test_url_generation_without_context_fails(): def test_url_generation_without_context_fails():
with pytest.raises(RuntimeError): with pytest.raises(RuntimeError):
flask.url_for('index') flask.url_for('index')
def test_request_context_means_app_context():
app = flask.Flask(__name__) def test_request_context_means_app_context(app):
with app.test_request_context(): with app.test_request_context():
assert flask.current_app._get_current_object() == app assert flask.current_app._get_current_object() == app
assert flask._app_ctx_stack.top is None assert flask._app_ctx_stack.top is None
def test_app_context_provides_current_app():
app = flask.Flask(__name__) def test_app_context_provides_current_app(app):
with app.app_context(): with app.app_context():
assert flask.current_app._get_current_object() == app assert flask.current_app._get_current_object() == app
assert flask._app_ctx_stack.top is None assert flask._app_ctx_stack.top is None
def test_app_tearing_down():
def test_app_tearing_down(app):
cleanup_stuff = [] cleanup_stuff = []
app = flask.Flask(__name__)
@app.teardown_appcontext @app.teardown_appcontext
def cleanup(exception): def cleanup(exception):
cleanup_stuff.append(exception) cleanup_stuff.append(exception)
@ -61,9 +62,10 @@ def test_app_tearing_down():
assert cleanup_stuff == [None] assert cleanup_stuff == [None]
def test_app_tearing_down_with_previous_exception():
def test_app_tearing_down_with_previous_exception(app):
cleanup_stuff = [] cleanup_stuff = []
app = flask.Flask(__name__)
@app.teardown_appcontext @app.teardown_appcontext
def cleanup(exception): def cleanup(exception):
cleanup_stuff.append(exception) cleanup_stuff.append(exception)
@ -78,9 +80,10 @@ def test_app_tearing_down_with_previous_exception():
assert cleanup_stuff == [None] assert cleanup_stuff == [None]
def test_app_tearing_down_with_handled_exception():
def test_app_tearing_down_with_handled_exception(app):
cleanup_stuff = [] cleanup_stuff = []
app = flask.Flask(__name__)
@app.teardown_appcontext @app.teardown_appcontext
def cleanup(exception): def cleanup(exception):
cleanup_stuff.append(exception) cleanup_stuff.append(exception)
@ -93,46 +96,49 @@ def test_app_tearing_down_with_handled_exception():
assert cleanup_stuff == [None] assert cleanup_stuff == [None]
def test_app_ctx_globals_methods():
app = flask.Flask(__name__) def test_app_ctx_globals_methods(app, app_ctx):
with app.app_context(): # get
# get assert flask.g.get('foo') is None
assert flask.g.get('foo') is None assert flask.g.get('foo', 'bar') == 'bar'
assert flask.g.get('foo', 'bar') == 'bar' # __contains__
# __contains__ assert 'foo' not in flask.g
assert 'foo' not in flask.g flask.g.foo = 'bar'
flask.g.foo = 'bar' assert 'foo' in flask.g
assert 'foo' in flask.g # setdefault
# setdefault flask.g.setdefault('bar', 'the cake is a lie')
flask.g.setdefault('bar', 'the cake is a lie') flask.g.setdefault('bar', 'hello world')
flask.g.setdefault('bar', 'hello world') assert flask.g.bar == 'the cake is a lie'
assert flask.g.bar == 'the cake is a lie' # pop
# pop assert flask.g.pop('bar') == 'the cake is a lie'
assert flask.g.pop('bar') == 'the cake is a lie' with pytest.raises(KeyError):
with pytest.raises(KeyError): flask.g.pop('bar')
flask.g.pop('bar') assert flask.g.pop('bar', 'more cake') == 'more cake'
assert flask.g.pop('bar', 'more cake') == 'more cake' # __iter__
# __iter__ assert list(flask.g) == ['foo']
assert list(flask.g) == ['foo']
def test_custom_app_ctx_globals_class(): def test_custom_app_ctx_globals_class(app):
class CustomRequestGlobals(object): class CustomRequestGlobals(object):
def __init__(self): def __init__(self):
self.spam = 'eggs' self.spam = 'eggs'
app = flask.Flask(__name__)
app.app_ctx_globals_class = CustomRequestGlobals app.app_ctx_globals_class = CustomRequestGlobals
with app.app_context(): with app.app_context():
assert flask.render_template_string('{{ g.spam }}') == 'eggs' assert flask.render_template_string('{{ g.spam }}') == 'eggs'
def test_context_refcounts():
def test_context_refcounts(app, client):
called = [] called = []
app = flask.Flask(__name__)
@app.teardown_request @app.teardown_request
def teardown_req(error=None): def teardown_req(error=None):
called.append('request') called.append('request')
@app.teardown_appcontext @app.teardown_appcontext
def teardown_app(error=None): def teardown_app(error=None):
called.append('app') called.append('app')
@app.route('/') @app.route('/')
def index(): def index():
with flask._app_ctx_stack.top: with flask._app_ctx_stack.top:
@ -141,16 +147,16 @@ def test_context_refcounts():
env = flask._request_ctx_stack.top.request.environ env = flask._request_ctx_stack.top.request.environ
assert env['werkzeug.request'] is not None assert env['werkzeug.request'] is not None
return u'' return u''
c = app.test_client()
res = c.get('/') res = client.get('/')
assert res.status_code == 200 assert res.status_code == 200
assert res.data == b'' assert res.data == b''
assert called == ['request', 'app'] assert called == ['request', 'app']
def test_clean_pop(): def test_clean_pop(app):
app.testing = False
called = [] called = []
app = flask.Flask(__name__)
@app.teardown_request @app.teardown_request
def teardown_req(error=None): def teardown_req(error=None):
@ -166,5 +172,5 @@ def test_clean_pop():
except ZeroDivisionError: except ZeroDivisionError:
pass pass
assert called == ['test_appctx', 'TEARDOWN'] assert called == ['conftest', 'TEARDOWN']
assert not flask.current_app assert not flask.current_app

487
tests/test_basic.py

File diff suppressed because it is too large Load Diff

280
tests/test_blueprints.py

@ -18,7 +18,7 @@ from werkzeug.http import parse_cache_control_header
from jinja2 import TemplateNotFound from jinja2 import TemplateNotFound
def test_blueprint_specific_error_handling(): def test_blueprint_specific_error_handling(app, client):
frontend = flask.Blueprint('frontend', __name__) frontend = flask.Blueprint('frontend', __name__)
backend = flask.Blueprint('backend', __name__) backend = flask.Blueprint('backend', __name__)
sideend = flask.Blueprint('sideend', __name__) sideend = flask.Blueprint('sideend', __name__)
@ -43,7 +43,6 @@ def test_blueprint_specific_error_handling():
def sideend_no(): def sideend_no():
flask.abort(403) flask.abort(403)
app = flask.Flask(__name__)
app.register_blueprint(frontend) app.register_blueprint(frontend)
app.register_blueprint(backend) app.register_blueprint(backend)
app.register_blueprint(sideend) app.register_blueprint(sideend)
@ -52,15 +51,15 @@ def test_blueprint_specific_error_handling():
def app_forbidden(e): def app_forbidden(e):
return 'application itself says no', 403 return 'application itself says no', 403
c = app.test_client() assert client.get('/frontend-no').data == b'frontend says no'
assert client.get('/backend-no').data == b'backend says no'
assert client.get('/what-is-a-sideend').data == b'application itself says no'
assert c.get('/frontend-no').data == b'frontend says no'
assert c.get('/backend-no').data == b'backend says no'
assert c.get('/what-is-a-sideend').data == b'application itself says no'
def test_blueprint_specific_user_error_handling(): def test_blueprint_specific_user_error_handling(app, client):
class MyDecoratorException(Exception): class MyDecoratorException(Exception):
pass pass
class MyFunctionException(Exception): class MyFunctionException(Exception):
pass pass
@ -74,32 +73,30 @@ def test_blueprint_specific_user_error_handling():
def my_function_exception_handler(e): def my_function_exception_handler(e):
assert isinstance(e, MyFunctionException) assert isinstance(e, MyFunctionException)
return 'bam' return 'bam'
blue.register_error_handler(MyFunctionException, my_function_exception_handler) blue.register_error_handler(MyFunctionException, my_function_exception_handler)
@blue.route('/decorator') @blue.route('/decorator')
def blue_deco_test(): def blue_deco_test():
raise MyDecoratorException() raise MyDecoratorException()
@blue.route('/function') @blue.route('/function')
def blue_func_test(): def blue_func_test():
raise MyFunctionException() raise MyFunctionException()
app = flask.Flask(__name__)
app.register_blueprint(blue) app.register_blueprint(blue)
c = app.test_client() assert client.get('/decorator').data == b'boom'
assert client.get('/function').data == b'bam'
assert c.get('/decorator').data == b'boom'
assert c.get('/function').data == b'bam'
def test_blueprint_app_error_handling(): def test_blueprint_app_error_handling(app, client):
errors = flask.Blueprint('errors', __name__) errors = flask.Blueprint('errors', __name__)
@errors.app_errorhandler(403) @errors.app_errorhandler(403)
def forbidden_handler(e): def forbidden_handler(e):
return 'you shall not pass', 403 return 'you shall not pass', 403
app = flask.Flask(__name__)
@app.route('/forbidden') @app.route('/forbidden')
def app_forbidden(): def app_forbidden():
flask.abort(403) flask.abort(403)
@ -113,12 +110,11 @@ def test_blueprint_app_error_handling():
app.register_blueprint(errors) app.register_blueprint(errors)
app.register_blueprint(forbidden_bp) app.register_blueprint(forbidden_bp)
c = app.test_client() assert client.get('/forbidden').data == b'you shall not pass'
assert client.get('/nope').data == b'you shall not pass'
assert c.get('/forbidden').data == b'you shall not pass'
assert c.get('/nope').data == b'you shall not pass'
def test_blueprint_url_definitions(): def test_blueprint_url_definitions(app, client):
bp = flask.Blueprint('test', __name__) bp = flask.Blueprint('test', __name__)
@bp.route('/foo', defaults={'baz': 42}) @bp.route('/foo', defaults={'baz': 42})
@ -129,17 +125,16 @@ def test_blueprint_url_definitions():
def bar(bar): def bar(bar):
return text_type(bar) return text_type(bar)
app = flask.Flask(__name__)
app.register_blueprint(bp, url_prefix='/1', url_defaults={'bar': 23}) app.register_blueprint(bp, url_prefix='/1', url_defaults={'bar': 23})
app.register_blueprint(bp, url_prefix='/2', url_defaults={'bar': 19}) app.register_blueprint(bp, url_prefix='/2', url_defaults={'bar': 19})
c = app.test_client() assert client.get('/1/foo').data == b'23/42'
assert c.get('/1/foo').data == b'23/42' assert client.get('/2/foo').data == b'19/42'
assert c.get('/2/foo').data == b'19/42' assert client.get('/1/bar').data == b'23'
assert c.get('/1/bar').data == b'23' assert client.get('/2/bar').data == b'19'
assert c.get('/2/bar').data == b'19'
def test_blueprint_url_processors():
def test_blueprint_url_processors(app, client):
bp = flask.Blueprint('frontend', __name__, url_prefix='/<lang_code>') bp = flask.Blueprint('frontend', __name__, url_prefix='/<lang_code>')
@bp.url_defaults @bp.url_defaults
@ -158,28 +153,26 @@ def test_blueprint_url_processors():
def about(): def about():
return flask.url_for('.index') return flask.url_for('.index')
app = flask.Flask(__name__)
app.register_blueprint(bp) app.register_blueprint(bp)
c = app.test_client() assert client.get('/de/').data == b'/de/about'
assert client.get('/de/about').data == b'/de/'
assert c.get('/de/').data == b'/de/about'
assert c.get('/de/about').data == b'/de/'
def test_templates_and_static(test_apps): def test_templates_and_static(test_apps):
from blueprintapp import app from blueprintapp import app
c = app.test_client() client = app.test_client()
rv = c.get('/') rv = client.get('/')
assert rv.data == b'Hello from the Frontend' assert rv.data == b'Hello from the Frontend'
rv = c.get('/admin/') rv = client.get('/admin/')
assert rv.data == b'Hello from the Admin' assert rv.data == b'Hello from the Admin'
rv = c.get('/admin/index2') rv = client.get('/admin/index2')
assert rv.data == b'Hello from the Admin' assert rv.data == b'Hello from the Admin'
rv = c.get('/admin/static/test.txt') rv = client.get('/admin/static/test.txt')
assert rv.data.strip() == b'Admin File' assert rv.data.strip() == b'Admin File'
rv.close() rv.close()
rv = c.get('/admin/static/css/test.css') rv = client.get('/admin/static/css/test.css')
assert rv.data.strip() == b'/* nested file */' assert rv.data.strip() == b'/* nested file */'
rv.close() rv.close()
@ -190,7 +183,7 @@ def test_templates_and_static(test_apps):
if app.config['SEND_FILE_MAX_AGE_DEFAULT'] == expected_max_age: if app.config['SEND_FILE_MAX_AGE_DEFAULT'] == expected_max_age:
expected_max_age = 7200 expected_max_age = 7200
app.config['SEND_FILE_MAX_AGE_DEFAULT'] = expected_max_age app.config['SEND_FILE_MAX_AGE_DEFAULT'] = expected_max_age
rv = c.get('/admin/static/css/test.css') rv = client.get('/admin/static/css/test.css')
cc = parse_cache_control_header(rv.headers['Cache-Control']) cc = parse_cache_control_header(rv.headers['Cache-Control'])
assert cc.max_age == expected_max_age assert cc.max_age == expected_max_age
rv.close() rv.close()
@ -208,8 +201,10 @@ def test_templates_and_static(test_apps):
with flask.Flask(__name__).test_request_context(): with flask.Flask(__name__).test_request_context():
assert flask.render_template('nested/nested.txt') == 'I\'m nested' assert flask.render_template('nested/nested.txt') == 'I\'m nested'
def test_default_static_cache_timeout(): def test_default_static_cache_timeout():
app = flask.Flask(__name__) app = flask.Flask(__name__)
class MyBlueprint(flask.Blueprint): class MyBlueprint(flask.Blueprint):
def get_send_file_max_age(self, filename): def get_send_file_max_age(self, filename):
return 100 return 100
@ -232,12 +227,14 @@ def test_default_static_cache_timeout():
finally: finally:
app.config['SEND_FILE_MAX_AGE_DEFAULT'] = max_age_default app.config['SEND_FILE_MAX_AGE_DEFAULT'] = max_age_default
def test_templates_list(test_apps): def test_templates_list(test_apps):
from blueprintapp import app from blueprintapp import app
templates = sorted(app.jinja_env.list_templates()) templates = sorted(app.jinja_env.list_templates())
assert templates == ['admin/index.html', 'frontend/index.html'] assert templates == ['admin/index.html', 'frontend/index.html']
def test_dotted_names():
def test_dotted_names(app, client):
frontend = flask.Blueprint('myapp.frontend', __name__) frontend = flask.Blueprint('myapp.frontend', __name__)
backend = flask.Blueprint('myapp.backend', __name__) backend = flask.Blueprint('myapp.backend', __name__)
@ -253,18 +250,15 @@ def test_dotted_names():
def backend_index(): def backend_index():
return flask.url_for('myapp.frontend.frontend_index') return flask.url_for('myapp.frontend.frontend_index')
app = flask.Flask(__name__)
app.register_blueprint(frontend) app.register_blueprint(frontend)
app.register_blueprint(backend) app.register_blueprint(backend)
c = app.test_client() assert client.get('/fe').data.strip() == b'/be'
assert c.get('/fe').data.strip() == b'/be' assert client.get('/fe2').data.strip() == b'/fe'
assert c.get('/fe2').data.strip() == b'/fe' assert client.get('/be').data.strip() == b'/fe'
assert c.get('/be').data.strip() == b'/fe'
def test_dotted_names_from_app():
app = flask.Flask(__name__) def test_dotted_names_from_app(app, client):
app.testing = True
test = flask.Blueprint('test', __name__) test = flask.Blueprint('test', __name__)
@app.route('/') @app.route('/')
@ -277,11 +271,11 @@ def test_dotted_names_from_app():
app.register_blueprint(test) app.register_blueprint(test)
with app.test_client() as c: rv = client.get('/')
rv = c.get('/') assert rv.data == b'/test/'
assert rv.data == b'/test/'
def test_empty_url_defaults():
def test_empty_url_defaults(app, client):
bp = flask.Blueprint('bp', __name__) bp = flask.Blueprint('bp', __name__)
@bp.route('/', defaults={'page': 1}) @bp.route('/', defaults={'page': 1})
@ -289,15 +283,13 @@ def test_empty_url_defaults():
def something(page): def something(page):
return str(page) return str(page)
app = flask.Flask(__name__)
app.register_blueprint(bp) app.register_blueprint(bp)
c = app.test_client() assert client.get('/').data == b'1'
assert c.get('/').data == b'1' assert client.get('/page/2').data == b'2'
assert c.get('/page/2').data == b'2'
def test_route_decorator_custom_endpoint():
def test_route_decorator_custom_endpoint(app, client):
bp = flask.Blueprint('bp', __name__) bp = flask.Blueprint('bp', __name__)
@bp.route('/foo') @bp.route('/foo')
@ -316,21 +308,20 @@ def test_route_decorator_custom_endpoint():
def bar_foo(): def bar_foo():
return flask.request.endpoint return flask.request.endpoint
app = flask.Flask(__name__)
app.register_blueprint(bp, url_prefix='/py') app.register_blueprint(bp, url_prefix='/py')
@app.route('/') @app.route('/')
def index(): def index():
return flask.request.endpoint return flask.request.endpoint
c = app.test_client() assert client.get('/').data == b'index'
assert c.get('/').data == b'index' assert client.get('/py/foo').data == b'bp.foo'
assert c.get('/py/foo').data == b'bp.foo' assert client.get('/py/bar').data == b'bp.bar'
assert c.get('/py/bar').data == b'bp.bar' assert client.get('/py/bar/123').data == b'bp.123'
assert c.get('/py/bar/123').data == b'bp.123' assert client.get('/py/bar/foo').data == b'bp.bar_foo'
assert c.get('/py/bar/foo').data == b'bp.bar_foo'
def test_route_decorator_custom_endpoint_with_dots(): def test_route_decorator_custom_endpoint_with_dots(app, client):
bp = flask.Blueprint('bp', __name__) bp = flask.Blueprint('bp', __name__)
@bp.route('/foo') @bp.route('/foo')
@ -371,21 +362,18 @@ def test_route_decorator_custom_endpoint_with_dots():
lambda: None lambda: None
) )
app = flask.Flask(__name__)
app.register_blueprint(bp, url_prefix='/py') app.register_blueprint(bp, url_prefix='/py')
c = app.test_client() assert client.get('/py/foo').data == b'bp.foo'
assert c.get('/py/foo').data == b'bp.foo'
# The rule's didn't actually made it through # The rule's didn't actually made it through
rv = c.get('/py/bar') rv = client.get('/py/bar')
assert rv.status_code == 404 assert rv.status_code == 404
rv = c.get('/py/bar/123') rv = client.get('/py/bar/123')
assert rv.status_code == 404 assert rv.status_code == 404
def test_endpoint_decorator(): def test_endpoint_decorator(app, client):
from werkzeug.routing import Rule from werkzeug.routing import Rule
app = flask.Flask(__name__)
app.url_map.add(Rule('/foo', endpoint='bar')) app.url_map.add(Rule('/foo', endpoint='bar'))
bp = flask.Blueprint('bp', __name__) bp = flask.Blueprint('bp', __name__)
@ -396,229 +384,282 @@ def test_endpoint_decorator():
app.register_blueprint(bp, url_prefix='/bp_prefix') app.register_blueprint(bp, url_prefix='/bp_prefix')
c = app.test_client() assert client.get('/foo').data == b'bar'
assert c.get('/foo').data == b'bar' assert client.get('/bp_prefix/bar').status_code == 404
assert c.get('/bp_prefix/bar').status_code == 404
def test_template_filter(): def test_template_filter(app):
bp = flask.Blueprint('bp', __name__) bp = flask.Blueprint('bp', __name__)
@bp.app_template_filter() @bp.app_template_filter()
def my_reverse(s): def my_reverse(s):
return s[::-1] return s[::-1]
app = flask.Flask(__name__)
app.register_blueprint(bp, url_prefix='/py') app.register_blueprint(bp, url_prefix='/py')
assert 'my_reverse' in app.jinja_env.filters.keys() assert 'my_reverse' in app.jinja_env.filters.keys()
assert app.jinja_env.filters['my_reverse'] == my_reverse assert app.jinja_env.filters['my_reverse'] == my_reverse
assert app.jinja_env.filters['my_reverse']('abcd') == 'dcba' assert app.jinja_env.filters['my_reverse']('abcd') == 'dcba'
def test_add_template_filter():
def test_add_template_filter(app):
bp = flask.Blueprint('bp', __name__) bp = flask.Blueprint('bp', __name__)
def my_reverse(s): def my_reverse(s):
return s[::-1] return s[::-1]
bp.add_app_template_filter(my_reverse) bp.add_app_template_filter(my_reverse)
app = flask.Flask(__name__)
app.register_blueprint(bp, url_prefix='/py') app.register_blueprint(bp, url_prefix='/py')
assert 'my_reverse' in app.jinja_env.filters.keys() assert 'my_reverse' in app.jinja_env.filters.keys()
assert app.jinja_env.filters['my_reverse'] == my_reverse assert app.jinja_env.filters['my_reverse'] == my_reverse
assert app.jinja_env.filters['my_reverse']('abcd') == 'dcba' assert app.jinja_env.filters['my_reverse']('abcd') == 'dcba'
def test_template_filter_with_name():
def test_template_filter_with_name(app):
bp = flask.Blueprint('bp', __name__) bp = flask.Blueprint('bp', __name__)
@bp.app_template_filter('strrev') @bp.app_template_filter('strrev')
def my_reverse(s): def my_reverse(s):
return s[::-1] return s[::-1]
app = flask.Flask(__name__)
app.register_blueprint(bp, url_prefix='/py') app.register_blueprint(bp, url_prefix='/py')
assert 'strrev' in app.jinja_env.filters.keys() assert 'strrev' in app.jinja_env.filters.keys()
assert app.jinja_env.filters['strrev'] == my_reverse assert app.jinja_env.filters['strrev'] == my_reverse
assert app.jinja_env.filters['strrev']('abcd') == 'dcba' assert app.jinja_env.filters['strrev']('abcd') == 'dcba'
def test_add_template_filter_with_name():
def test_add_template_filter_with_name(app):
bp = flask.Blueprint('bp', __name__) bp = flask.Blueprint('bp', __name__)
def my_reverse(s): def my_reverse(s):
return s[::-1] return s[::-1]
bp.add_app_template_filter(my_reverse, 'strrev') bp.add_app_template_filter(my_reverse, 'strrev')
app = flask.Flask(__name__)
app.register_blueprint(bp, url_prefix='/py') app.register_blueprint(bp, url_prefix='/py')
assert 'strrev' in app.jinja_env.filters.keys() assert 'strrev' in app.jinja_env.filters.keys()
assert app.jinja_env.filters['strrev'] == my_reverse assert app.jinja_env.filters['strrev'] == my_reverse
assert app.jinja_env.filters['strrev']('abcd') == 'dcba' assert app.jinja_env.filters['strrev']('abcd') == 'dcba'
def test_template_filter_with_template():
def test_template_filter_with_template(app, client):
bp = flask.Blueprint('bp', __name__) bp = flask.Blueprint('bp', __name__)
@bp.app_template_filter() @bp.app_template_filter()
def super_reverse(s): def super_reverse(s):
return s[::-1] return s[::-1]
app = flask.Flask(__name__)
app.register_blueprint(bp, url_prefix='/py') app.register_blueprint(bp, url_prefix='/py')
@app.route('/') @app.route('/')
def index(): def index():
return flask.render_template('template_filter.html', value='abcd') return flask.render_template('template_filter.html', value='abcd')
rv = app.test_client().get('/')
rv = client.get('/')
assert rv.data == b'dcba' assert rv.data == b'dcba'
def test_template_filter_after_route_with_template():
app = flask.Flask(__name__) def test_template_filter_after_route_with_template(app, client):
@app.route('/') @app.route('/')
def index(): def index():
return flask.render_template('template_filter.html', value='abcd') return flask.render_template('template_filter.html', value='abcd')
bp = flask.Blueprint('bp', __name__) bp = flask.Blueprint('bp', __name__)
@bp.app_template_filter() @bp.app_template_filter()
def super_reverse(s): def super_reverse(s):
return s[::-1] return s[::-1]
app.register_blueprint(bp, url_prefix='/py') app.register_blueprint(bp, url_prefix='/py')
rv = app.test_client().get('/') rv = client.get('/')
assert rv.data == b'dcba' assert rv.data == b'dcba'
def test_add_template_filter_with_template():
def test_add_template_filter_with_template(app, client):
bp = flask.Blueprint('bp', __name__) bp = flask.Blueprint('bp', __name__)
def super_reverse(s): def super_reverse(s):
return s[::-1] return s[::-1]
bp.add_app_template_filter(super_reverse) bp.add_app_template_filter(super_reverse)
app = flask.Flask(__name__)
app.register_blueprint(bp, url_prefix='/py') app.register_blueprint(bp, url_prefix='/py')
@app.route('/') @app.route('/')
def index(): def index():
return flask.render_template('template_filter.html', value='abcd') return flask.render_template('template_filter.html', value='abcd')
rv = app.test_client().get('/')
rv = client.get('/')
assert rv.data == b'dcba' assert rv.data == b'dcba'
def test_template_filter_with_name_and_template():
def test_template_filter_with_name_and_template(app, client):
bp = flask.Blueprint('bp', __name__) bp = flask.Blueprint('bp', __name__)
@bp.app_template_filter('super_reverse') @bp.app_template_filter('super_reverse')
def my_reverse(s): def my_reverse(s):
return s[::-1] return s[::-1]
app = flask.Flask(__name__)
app.register_blueprint(bp, url_prefix='/py') app.register_blueprint(bp, url_prefix='/py')
@app.route('/') @app.route('/')
def index(): def index():
return flask.render_template('template_filter.html', value='abcd') return flask.render_template('template_filter.html', value='abcd')
rv = app.test_client().get('/')
rv = client.get('/')
assert rv.data == b'dcba' assert rv.data == b'dcba'
def test_add_template_filter_with_name_and_template():
def test_add_template_filter_with_name_and_template(app, client):
bp = flask.Blueprint('bp', __name__) bp = flask.Blueprint('bp', __name__)
def my_reverse(s): def my_reverse(s):
return s[::-1] return s[::-1]
bp.add_app_template_filter(my_reverse, 'super_reverse') bp.add_app_template_filter(my_reverse, 'super_reverse')
app = flask.Flask(__name__)
app.register_blueprint(bp, url_prefix='/py') app.register_blueprint(bp, url_prefix='/py')
@app.route('/') @app.route('/')
def index(): def index():
return flask.render_template('template_filter.html', value='abcd') return flask.render_template('template_filter.html', value='abcd')
rv = app.test_client().get('/')
rv = client.get('/')
assert rv.data == b'dcba' assert rv.data == b'dcba'
def test_template_test():
def test_template_test(app):
bp = flask.Blueprint('bp', __name__) bp = flask.Blueprint('bp', __name__)
@bp.app_template_test() @bp.app_template_test()
def is_boolean(value): def is_boolean(value):
return isinstance(value, bool) return isinstance(value, bool)
app = flask.Flask(__name__)
app.register_blueprint(bp, url_prefix='/py') app.register_blueprint(bp, url_prefix='/py')
assert 'is_boolean' in app.jinja_env.tests.keys() assert 'is_boolean' in app.jinja_env.tests.keys()
assert app.jinja_env.tests['is_boolean'] == is_boolean assert app.jinja_env.tests['is_boolean'] == is_boolean
assert app.jinja_env.tests['is_boolean'](False) assert app.jinja_env.tests['is_boolean'](False)
def test_add_template_test():
def test_add_template_test(app):
bp = flask.Blueprint('bp', __name__) bp = flask.Blueprint('bp', __name__)
def is_boolean(value): def is_boolean(value):
return isinstance(value, bool) return isinstance(value, bool)
bp.add_app_template_test(is_boolean) bp.add_app_template_test(is_boolean)
app = flask.Flask(__name__)
app.register_blueprint(bp, url_prefix='/py') app.register_blueprint(bp, url_prefix='/py')
assert 'is_boolean' in app.jinja_env.tests.keys() assert 'is_boolean' in app.jinja_env.tests.keys()
assert app.jinja_env.tests['is_boolean'] == is_boolean assert app.jinja_env.tests['is_boolean'] == is_boolean
assert app.jinja_env.tests['is_boolean'](False) assert app.jinja_env.tests['is_boolean'](False)
def test_template_test_with_name():
def test_template_test_with_name(app):
bp = flask.Blueprint('bp', __name__) bp = flask.Blueprint('bp', __name__)
@bp.app_template_test('boolean') @bp.app_template_test('boolean')
def is_boolean(value): def is_boolean(value):
return isinstance(value, bool) return isinstance(value, bool)
app = flask.Flask(__name__)
app.register_blueprint(bp, url_prefix='/py') app.register_blueprint(bp, url_prefix='/py')
assert 'boolean' in app.jinja_env.tests.keys() assert 'boolean' in app.jinja_env.tests.keys()
assert app.jinja_env.tests['boolean'] == is_boolean assert app.jinja_env.tests['boolean'] == is_boolean
assert app.jinja_env.tests['boolean'](False) assert app.jinja_env.tests['boolean'](False)
def test_add_template_test_with_name():
def test_add_template_test_with_name(app):
bp = flask.Blueprint('bp', __name__) bp = flask.Blueprint('bp', __name__)
def is_boolean(value): def is_boolean(value):
return isinstance(value, bool) return isinstance(value, bool)
bp.add_app_template_test(is_boolean, 'boolean') bp.add_app_template_test(is_boolean, 'boolean')
app = flask.Flask(__name__)
app.register_blueprint(bp, url_prefix='/py') app.register_blueprint(bp, url_prefix='/py')
assert 'boolean' in app.jinja_env.tests.keys() assert 'boolean' in app.jinja_env.tests.keys()
assert app.jinja_env.tests['boolean'] == is_boolean assert app.jinja_env.tests['boolean'] == is_boolean
assert app.jinja_env.tests['boolean'](False) assert app.jinja_env.tests['boolean'](False)
def test_template_test_with_template():
def test_template_test_with_template(app, client):
bp = flask.Blueprint('bp', __name__) bp = flask.Blueprint('bp', __name__)
@bp.app_template_test() @bp.app_template_test()
def boolean(value): def boolean(value):
return isinstance(value, bool) return isinstance(value, bool)
app = flask.Flask(__name__)
app.register_blueprint(bp, url_prefix='/py') app.register_blueprint(bp, url_prefix='/py')
@app.route('/') @app.route('/')
def index(): def index():
return flask.render_template('template_test.html', value=False) return flask.render_template('template_test.html', value=False)
rv = app.test_client().get('/')
rv = client.get('/')
assert b'Success!' in rv.data assert b'Success!' in rv.data
def test_template_test_after_route_with_template():
app = flask.Flask(__name__) def test_template_test_after_route_with_template(app, client):
@app.route('/') @app.route('/')
def index(): def index():
return flask.render_template('template_test.html', value=False) return flask.render_template('template_test.html', value=False)
bp = flask.Blueprint('bp', __name__) bp = flask.Blueprint('bp', __name__)
@bp.app_template_test() @bp.app_template_test()
def boolean(value): def boolean(value):
return isinstance(value, bool) return isinstance(value, bool)
app.register_blueprint(bp, url_prefix='/py') app.register_blueprint(bp, url_prefix='/py')
rv = app.test_client().get('/') rv = client.get('/')
assert b'Success!' in rv.data assert b'Success!' in rv.data
def test_add_template_test_with_template():
def test_add_template_test_with_template(app, client):
bp = flask.Blueprint('bp', __name__) bp = flask.Blueprint('bp', __name__)
def boolean(value): def boolean(value):
return isinstance(value, bool) return isinstance(value, bool)
bp.add_app_template_test(boolean) bp.add_app_template_test(boolean)
app = flask.Flask(__name__)
app.register_blueprint(bp, url_prefix='/py') app.register_blueprint(bp, url_prefix='/py')
@app.route('/') @app.route('/')
def index(): def index():
return flask.render_template('template_test.html', value=False) return flask.render_template('template_test.html', value=False)
rv = app.test_client().get('/')
rv = client.get('/')
assert b'Success!' in rv.data assert b'Success!' in rv.data
def test_template_test_with_name_and_template():
def test_template_test_with_name_and_template(app, client):
bp = flask.Blueprint('bp', __name__) bp = flask.Blueprint('bp', __name__)
@bp.app_template_test('boolean') @bp.app_template_test('boolean')
def is_boolean(value): def is_boolean(value):
return isinstance(value, bool) return isinstance(value, bool)
app = flask.Flask(__name__)
app.register_blueprint(bp, url_prefix='/py') app.register_blueprint(bp, url_prefix='/py')
@app.route('/') @app.route('/')
def index(): def index():
return flask.render_template('template_test.html', value=False) return flask.render_template('template_test.html', value=False)
rv = app.test_client().get('/')
rv = client.get('/')
assert b'Success!' in rv.data assert b'Success!' in rv.data
def test_add_template_test_with_name_and_template():
def test_add_template_test_with_name_and_template(app, client):
bp = flask.Blueprint('bp', __name__) bp = flask.Blueprint('bp', __name__)
def is_boolean(value): def is_boolean(value):
return isinstance(value, bool) return isinstance(value, bool)
bp.add_app_template_test(is_boolean, 'boolean') bp.add_app_template_test(is_boolean, 'boolean')
app = flask.Flask(__name__)
app.register_blueprint(bp, url_prefix='/py') app.register_blueprint(bp, url_prefix='/py')
@app.route('/') @app.route('/')
def index(): def index():
return flask.render_template('template_test.html', value=False) return flask.render_template('template_test.html', value=False)
rv = app.test_client().get('/')
rv = client.get('/')
assert b'Success!' in rv.data assert b'Success!' in rv.data
def test_context_processing(): def test_context_processing():
app = flask.Flask(__name__) app = flask.Flask(__name__)
answer_bp = flask.Blueprint('answer_bp', __name__) answer_bp = flask.Blueprint('answer_bp', __name__)
@ -661,12 +702,15 @@ def test_context_processing():
assert b'42' in answer_page_bytes assert b'42' in answer_page_bytes
assert b'43' in answer_page_bytes assert b'43' in answer_page_bytes
def test_template_global(): def test_template_global():
app = flask.Flask(__name__) app = flask.Flask(__name__)
bp = flask.Blueprint('bp', __name__) bp = flask.Blueprint('bp', __name__)
@bp.app_template_global() @bp.app_template_global()
def get_answer(): def get_answer():
return 42 return 42
# Make sure the function is not in the jinja_env already # Make sure the function is not in the jinja_env already
assert 'get_answer' not in app.jinja_env.globals.keys() assert 'get_answer' not in app.jinja_env.globals.keys()
app.register_blueprint(bp) app.register_blueprint(bp)

13
tests/test_deprecations.py

@ -15,10 +15,8 @@ import flask
class TestRequestDeprecation(object): class TestRequestDeprecation(object):
def test_request_json(self, recwarn, app, client):
def test_request_json(self, recwarn):
"""Request.json is deprecated""" """Request.json is deprecated"""
app = flask.Flask(__name__)
app.testing = True app.testing = True
@app.route('/', methods=['POST']) @app.route('/', methods=['POST'])
@ -27,13 +25,11 @@ class TestRequestDeprecation(object):
print(flask.request.json) print(flask.request.json)
return 'OK' return 'OK'
c = app.test_client() client.post('/', data='{"spam": 42}', content_type='application/json')
c.post('/', data='{"spam": 42}', content_type='application/json')
recwarn.pop(DeprecationWarning) recwarn.pop(DeprecationWarning)
def test_request_module(self, recwarn): def test_request_module(self, recwarn, app, client):
"""Request.module is deprecated""" """Request.module is deprecated"""
app = flask.Flask(__name__)
app.testing = True app.testing = True
@app.route('/') @app.route('/')
@ -41,6 +37,5 @@ class TestRequestDeprecation(object):
assert flask.request.module is None assert flask.request.module is None
return 'OK' return 'OK'
c = app.test_client() client.get('/')
c.get('/')
recwarn.pop(DeprecationWarning) recwarn.pop(DeprecationWarning)

615
tests/test_helpers.py

File diff suppressed because it is too large Load Diff

7
tests/test_regression.py

@ -9,15 +9,14 @@
:license: BSD, see LICENSE for more details. :license: BSD, see LICENSE for more details.
""" """
import pytest
import os
import gc import gc
import sys import sys
import flask
import threading import threading
import pytest
from werkzeug.exceptions import NotFound from werkzeug.exceptions import NotFound
import flask
_gc_lock = threading.Lock() _gc_lock = threading.Lock()

51
tests/test_reqctx.py

@ -20,9 +20,9 @@ except ImportError:
greenlet = None greenlet = None
def test_teardown_on_pop(): def test_teardown_on_pop(app):
buffer = [] buffer = []
app = flask.Flask(__name__)
@app.teardown_request @app.teardown_request
def end_of_request(exception): def end_of_request(exception):
buffer.append(exception) buffer.append(exception)
@ -33,9 +33,10 @@ def test_teardown_on_pop():
ctx.pop() ctx.pop()
assert buffer == [None] assert buffer == [None]
def test_teardown_with_previous_exception():
def test_teardown_with_previous_exception(app):
buffer = [] buffer = []
app = flask.Flask(__name__)
@app.teardown_request @app.teardown_request
def end_of_request(exception): def end_of_request(exception):
buffer.append(exception) buffer.append(exception)
@ -49,9 +50,10 @@ def test_teardown_with_previous_exception():
assert buffer == [] assert buffer == []
assert buffer == [None] assert buffer == [None]
def test_teardown_with_handled_exception():
def test_teardown_with_handled_exception(app):
buffer = [] buffer = []
app = flask.Flask(__name__)
@app.teardown_request @app.teardown_request
def end_of_request(exception): def end_of_request(exception):
buffer.append(exception) buffer.append(exception)
@ -64,8 +66,8 @@ def test_teardown_with_handled_exception():
pass pass
assert buffer == [None] assert buffer == [None]
def test_proper_test_request_context():
app = flask.Flask(__name__) def test_proper_test_request_context(app):
app.config.update( app.config.update(
SERVER_NAME='localhost.localdomain:5000' SERVER_NAME='localhost.localdomain:5000'
) )
@ -80,11 +82,11 @@ def test_proper_test_request_context():
with app.test_request_context('/'): with app.test_request_context('/'):
assert flask.url_for('index', _external=True) == \ assert flask.url_for('index', _external=True) == \
'http://localhost.localdomain:5000/' 'http://localhost.localdomain:5000/'
with app.test_request_context('/'): with app.test_request_context('/'):
assert flask.url_for('sub', _external=True) == \ assert flask.url_for('sub', _external=True) == \
'http://foo.localhost.localdomain:5000/' 'http://foo.localhost.localdomain:5000/'
try: try:
with app.test_request_context('/', environ_overrides={'HTTP_HOST': 'localhost'}): with app.test_request_context('/', environ_overrides={'HTTP_HOST': 'localhost'}):
@ -104,11 +106,12 @@ def test_proper_test_request_context():
with app.test_request_context('/', environ_overrides={'SERVER_NAME': 'localhost:80'}): with app.test_request_context('/', environ_overrides={'SERVER_NAME': 'localhost:80'}):
pass pass
def test_context_binding():
app = flask.Flask(__name__) def test_context_binding(app):
@app.route('/') @app.route('/')
def index(): def index():
return 'Hello %s!' % flask.request.args['name'] return 'Hello %s!' % flask.request.args['name']
@app.route('/meh') @app.route('/meh')
def meh(): def meh():
return flask.request.url return flask.request.url
@ -119,8 +122,8 @@ def test_context_binding():
assert meh() == 'http://localhost/meh' assert meh() == 'http://localhost/meh'
assert flask._request_ctx_stack.top is None assert flask._request_ctx_stack.top is None
def test_context_test():
app = flask.Flask(__name__) def test_context_test(app):
assert not flask.request assert not flask.request
assert not flask.has_request_context() assert not flask.has_request_context()
ctx = app.test_request_context() ctx = app.test_request_context()
@ -131,8 +134,8 @@ def test_context_test():
finally: finally:
ctx.pop() ctx.pop()
def test_manual_context_binding():
app = flask.Flask(__name__) def test_manual_context_binding(app):
@app.route('/') @app.route('/')
def index(): def index():
return 'Hello %s!' % flask.request.args['name'] return 'Hello %s!' % flask.request.args['name']
@ -144,14 +147,15 @@ def test_manual_context_binding():
with pytest.raises(RuntimeError): with pytest.raises(RuntimeError):
index() index()
@pytest.mark.skipif(greenlet is None, reason='greenlet not installed') @pytest.mark.skipif(greenlet is None, reason='greenlet not installed')
def test_greenlet_context_copying(): def test_greenlet_context_copying(app, client):
app = flask.Flask(__name__)
greenlets = [] greenlets = []
@app.route('/') @app.route('/')
def index(): def index():
reqctx = flask._request_ctx_stack.top.copy() reqctx = flask._request_ctx_stack.top.copy()
def g(): def g():
assert not flask.request assert not flask.request
assert not flask.current_app assert not flask.current_app
@ -162,23 +166,25 @@ def test_greenlet_context_copying():
assert flask.request.args['foo'] == 'bar' assert flask.request.args['foo'] == 'bar'
assert not flask.request assert not flask.request
return 42 return 42
greenlets.append(greenlet(g)) greenlets.append(greenlet(g))
return 'Hello World!' return 'Hello World!'
rv = app.test_client().get('/?foo=bar') rv = client.get('/?foo=bar')
assert rv.data == b'Hello World!' assert rv.data == b'Hello World!'
result = greenlets[0].run() result = greenlets[0].run()
assert result == 42 assert result == 42
@pytest.mark.skipif(greenlet is None, reason='greenlet not installed') @pytest.mark.skipif(greenlet is None, reason='greenlet not installed')
def test_greenlet_context_copying_api(): def test_greenlet_context_copying_api(app, client):
app = flask.Flask(__name__)
greenlets = [] greenlets = []
@app.route('/') @app.route('/')
def index(): def index():
reqctx = flask._request_ctx_stack.top.copy() reqctx = flask._request_ctx_stack.top.copy()
@flask.copy_current_request_context @flask.copy_current_request_context
def g(): def g():
assert flask.request assert flask.request
@ -186,10 +192,11 @@ def test_greenlet_context_copying_api():
assert flask.request.path == '/' assert flask.request.path == '/'
assert flask.request.args['foo'] == 'bar' assert flask.request.args['foo'] == 'bar'
return 42 return 42
greenlets.append(greenlet(g)) greenlets.append(greenlet(g))
return 'Hello World!' return 'Hello World!'
rv = app.test_client().get('/?foo=bar') rv = client.get('/?foo=bar')
assert rv.data == b'Hello World!' assert rv.data == b'Hello World!'
result = greenlets[0].run() result = greenlets[0].run()

210
tests/test_templating.py

@ -16,40 +16,43 @@ import logging
from jinja2 import TemplateNotFound from jinja2 import TemplateNotFound
def test_context_processing(): def test_context_processing(app):
app = flask.Flask(__name__)
@app.context_processor @app.context_processor
def context_processor(): def context_processor():
return {'injected_value': 42} return {'injected_value': 42}
@app.route('/') @app.route('/')
def index(): def index():
return flask.render_template('context_template.html', value=23) return flask.render_template('context_template.html', value=23)
rv = app.test_client().get('/') rv = app.test_client().get('/')
assert rv.data == b'<p>23|42' assert rv.data == b'<p>23|42'
def test_original_win():
app = flask.Flask(__name__) def test_original_win(app, client):
@app.route('/') @app.route('/')
def index(): def index():
return flask.render_template_string('{{ config }}', config=42) return flask.render_template_string('{{ config }}', config=42)
rv = app.test_client().get('/')
rv = client.get('/')
assert rv.data == b'42' assert rv.data == b'42'
def test_request_less_rendering():
app = flask.Flask(__name__) def test_request_less_rendering(app, app_ctx):
app.config['WORLD_NAME'] = 'Special World' app.config['WORLD_NAME'] = 'Special World'
@app.context_processor @app.context_processor
def context_processor(): def context_processor():
return dict(foo=42) return dict(foo=42)
with app.app_context(): rv = flask.render_template_string('Hello {{ config.WORLD_NAME }} '
rv = flask.render_template_string('Hello {{ config.WORLD_NAME }} ' '{{ foo }}')
'{{ foo }}') assert rv == 'Hello Special World 42'
assert rv == 'Hello Special World 42'
def test_standard_context():
app = flask.Flask(__name__) def test_standard_context(app, client):
app.secret_key = 'development key' app.secret_key = 'development key'
@app.route('/') @app.route('/')
def index(): def index():
flask.g.foo = 23 flask.g.foo = 23
@ -60,17 +63,20 @@ def test_standard_context():
{{ config.DEBUG }} {{ config.DEBUG }}
{{ session.test }} {{ session.test }}
''') ''')
rv = app.test_client().get('/?foo=42')
rv = client.get('/?foo=42')
assert rv.data.split() == [b'42', b'23', b'False', b'aha'] assert rv.data.split() == [b'42', b'23', b'False', b'aha']
def test_escaping():
def test_escaping(app, client):
text = '<p>Hello World!' text = '<p>Hello World!'
app = flask.Flask(__name__)
@app.route('/') @app.route('/')
def index(): def index():
return flask.render_template('escaping_template.html', text=text, return flask.render_template('escaping_template.html', text=text,
html=flask.Markup(text)) html=flask.Markup(text))
lines = app.test_client().get('/').data.splitlines()
lines = client.get('/').data.splitlines()
assert lines == [ assert lines == [
b'&lt;p&gt;Hello World!', b'&lt;p&gt;Hello World!',
b'<p>Hello World!', b'<p>Hello World!',
@ -80,14 +86,16 @@ def test_escaping():
b'<p>Hello World!' b'<p>Hello World!'
] ]
def test_no_escaping():
def test_no_escaping(app, client):
text = '<p>Hello World!' text = '<p>Hello World!'
app = flask.Flask(__name__)
@app.route('/') @app.route('/')
def index(): def index():
return flask.render_template('non_escaping_template.txt', text=text, return flask.render_template('non_escaping_template.txt', text=text,
html=flask.Markup(text)) html=flask.Markup(text))
lines = app.test_client().get('/').data.splitlines()
lines = client.get('/').data.splitlines()
assert lines == [ assert lines == [
b'<p>Hello World!', b'<p>Hello World!',
b'<p>Hello World!', b'<p>Hello World!',
@ -99,224 +107,255 @@ def test_no_escaping():
b'<p>Hello World!' b'<p>Hello World!'
] ]
def test_escaping_without_template_filename():
app = flask.Flask(__name__)
with app.test_request_context():
assert flask.render_template_string(
'{{ foo }}', foo='<test>') == '&lt;test&gt;'
assert flask.render_template('mail.txt', foo='<test>') == \
'<test> Mail'
def test_macros(): def test_escaping_without_template_filename(app, client, req_ctx):
app = flask.Flask(__name__) assert flask.render_template_string(
with app.test_request_context(): '{{ foo }}', foo='<test>') == '&lt;test&gt;'
macro = flask.get_template_attribute('_macro.html', 'hello') assert flask.render_template('mail.txt', foo='<test>') == '<test> Mail'
assert macro('World') == 'Hello World!'
def test_template_filter():
app = flask.Flask(__name__) def test_macros(app, req_ctx):
macro = flask.get_template_attribute('_macro.html', 'hello')
assert macro('World') == 'Hello World!'
def test_template_filter(app):
@app.template_filter() @app.template_filter()
def my_reverse(s): def my_reverse(s):
return s[::-1] return s[::-1]
assert 'my_reverse' in app.jinja_env.filters.keys() assert 'my_reverse' in app.jinja_env.filters.keys()
assert app.jinja_env.filters['my_reverse'] == my_reverse assert app.jinja_env.filters['my_reverse'] == my_reverse
assert app.jinja_env.filters['my_reverse']('abcd') == 'dcba' assert app.jinja_env.filters['my_reverse']('abcd') == 'dcba'
def test_add_template_filter():
app = flask.Flask(__name__) def test_add_template_filter(app):
def my_reverse(s): def my_reverse(s):
return s[::-1] return s[::-1]
app.add_template_filter(my_reverse) app.add_template_filter(my_reverse)
assert 'my_reverse' in app.jinja_env.filters.keys() assert 'my_reverse' in app.jinja_env.filters.keys()
assert app.jinja_env.filters['my_reverse'] == my_reverse assert app.jinja_env.filters['my_reverse'] == my_reverse
assert app.jinja_env.filters['my_reverse']('abcd') == 'dcba' assert app.jinja_env.filters['my_reverse']('abcd') == 'dcba'
def test_template_filter_with_name():
app = flask.Flask(__name__) def test_template_filter_with_name(app):
@app.template_filter('strrev') @app.template_filter('strrev')
def my_reverse(s): def my_reverse(s):
return s[::-1] return s[::-1]
assert 'strrev' in app.jinja_env.filters.keys() assert 'strrev' in app.jinja_env.filters.keys()
assert app.jinja_env.filters['strrev'] == my_reverse assert app.jinja_env.filters['strrev'] == my_reverse
assert app.jinja_env.filters['strrev']('abcd') == 'dcba' assert app.jinja_env.filters['strrev']('abcd') == 'dcba'
def test_add_template_filter_with_name():
app = flask.Flask(__name__) def test_add_template_filter_with_name(app):
def my_reverse(s): def my_reverse(s):
return s[::-1] return s[::-1]
app.add_template_filter(my_reverse, 'strrev') app.add_template_filter(my_reverse, 'strrev')
assert 'strrev' in app.jinja_env.filters.keys() assert 'strrev' in app.jinja_env.filters.keys()
assert app.jinja_env.filters['strrev'] == my_reverse assert app.jinja_env.filters['strrev'] == my_reverse
assert app.jinja_env.filters['strrev']('abcd') == 'dcba' assert app.jinja_env.filters['strrev']('abcd') == 'dcba'
def test_template_filter_with_template():
app = flask.Flask(__name__) def test_template_filter_with_template(app, client):
@app.template_filter() @app.template_filter()
def super_reverse(s): def super_reverse(s):
return s[::-1] return s[::-1]
@app.route('/') @app.route('/')
def index(): def index():
return flask.render_template('template_filter.html', value='abcd') return flask.render_template('template_filter.html', value='abcd')
rv = app.test_client().get('/')
rv = client.get('/')
assert rv.data == b'dcba' assert rv.data == b'dcba'
def test_add_template_filter_with_template():
app = flask.Flask(__name__) def test_add_template_filter_with_template(app, client):
def super_reverse(s): def super_reverse(s):
return s[::-1] return s[::-1]
app.add_template_filter(super_reverse) app.add_template_filter(super_reverse)
@app.route('/') @app.route('/')
def index(): def index():
return flask.render_template('template_filter.html', value='abcd') return flask.render_template('template_filter.html', value='abcd')
rv = app.test_client().get('/')
rv = client.get('/')
assert rv.data == b'dcba' assert rv.data == b'dcba'
def test_template_filter_with_name_and_template():
app = flask.Flask(__name__) def test_template_filter_with_name_and_template(app, client):
@app.template_filter('super_reverse') @app.template_filter('super_reverse')
def my_reverse(s): def my_reverse(s):
return s[::-1] return s[::-1]
@app.route('/') @app.route('/')
def index(): def index():
return flask.render_template('template_filter.html', value='abcd') return flask.render_template('template_filter.html', value='abcd')
rv = app.test_client().get('/')
rv = client.get('/')
assert rv.data == b'dcba' assert rv.data == b'dcba'
def test_add_template_filter_with_name_and_template():
app = flask.Flask(__name__) def test_add_template_filter_with_name_and_template(app, client):
def my_reverse(s): def my_reverse(s):
return s[::-1] return s[::-1]
app.add_template_filter(my_reverse, 'super_reverse') app.add_template_filter(my_reverse, 'super_reverse')
@app.route('/') @app.route('/')
def index(): def index():
return flask.render_template('template_filter.html', value='abcd') return flask.render_template('template_filter.html', value='abcd')
rv = app.test_client().get('/')
rv = client.get('/')
assert rv.data == b'dcba' assert rv.data == b'dcba'
def test_template_test():
app = flask.Flask(__name__) def test_template_test(app):
@app.template_test() @app.template_test()
def boolean(value): def boolean(value):
return isinstance(value, bool) return isinstance(value, bool)
assert 'boolean' in app.jinja_env.tests.keys() assert 'boolean' in app.jinja_env.tests.keys()
assert app.jinja_env.tests['boolean'] == boolean assert app.jinja_env.tests['boolean'] == boolean
assert app.jinja_env.tests['boolean'](False) assert app.jinja_env.tests['boolean'](False)
def test_add_template_test():
app = flask.Flask(__name__) def test_add_template_test(app):
def boolean(value): def boolean(value):
return isinstance(value, bool) return isinstance(value, bool)
app.add_template_test(boolean) app.add_template_test(boolean)
assert 'boolean' in app.jinja_env.tests.keys() assert 'boolean' in app.jinja_env.tests.keys()
assert app.jinja_env.tests['boolean'] == boolean assert app.jinja_env.tests['boolean'] == boolean
assert app.jinja_env.tests['boolean'](False) assert app.jinja_env.tests['boolean'](False)
def test_template_test_with_name():
app = flask.Flask(__name__) def test_template_test_with_name(app):
@app.template_test('boolean') @app.template_test('boolean')
def is_boolean(value): def is_boolean(value):
return isinstance(value, bool) return isinstance(value, bool)
assert 'boolean' in app.jinja_env.tests.keys() assert 'boolean' in app.jinja_env.tests.keys()
assert app.jinja_env.tests['boolean'] == is_boolean assert app.jinja_env.tests['boolean'] == is_boolean
assert app.jinja_env.tests['boolean'](False) assert app.jinja_env.tests['boolean'](False)
def test_add_template_test_with_name():
app = flask.Flask(__name__) def test_add_template_test_with_name(app):
def is_boolean(value): def is_boolean(value):
return isinstance(value, bool) return isinstance(value, bool)
app.add_template_test(is_boolean, 'boolean') app.add_template_test(is_boolean, 'boolean')
assert 'boolean' in app.jinja_env.tests.keys() assert 'boolean' in app.jinja_env.tests.keys()
assert app.jinja_env.tests['boolean'] == is_boolean assert app.jinja_env.tests['boolean'] == is_boolean
assert app.jinja_env.tests['boolean'](False) assert app.jinja_env.tests['boolean'](False)
def test_template_test_with_template():
app = flask.Flask(__name__) def test_template_test_with_template(app):
@app.template_test() @app.template_test()
def boolean(value): def boolean(value):
return isinstance(value, bool) return isinstance(value, bool)
@app.route('/') @app.route('/')
def index(): def index():
return flask.render_template('template_test.html', value=False) return flask.render_template('template_test.html', value=False)
rv = app.test_client().get('/') rv = app.test_client().get('/')
assert b'Success!' in rv.data assert b'Success!' in rv.data
def test_add_template_test_with_template():
app = flask.Flask(__name__) def test_add_template_test_with_template(app, client):
def boolean(value): def boolean(value):
return isinstance(value, bool) return isinstance(value, bool)
app.add_template_test(boolean) app.add_template_test(boolean)
@app.route('/') @app.route('/')
def index(): def index():
return flask.render_template('template_test.html', value=False) return flask.render_template('template_test.html', value=False)
rv = app.test_client().get('/')
rv = client.get('/')
assert b'Success!' in rv.data assert b'Success!' in rv.data
def test_template_test_with_name_and_template():
app = flask.Flask(__name__) def test_template_test_with_name_and_template(app, client):
@app.template_test('boolean') @app.template_test('boolean')
def is_boolean(value): def is_boolean(value):
return isinstance(value, bool) return isinstance(value, bool)
@app.route('/') @app.route('/')
def index(): def index():
return flask.render_template('template_test.html', value=False) return flask.render_template('template_test.html', value=False)
rv = app.test_client().get('/')
rv = client.get('/')
assert b'Success!' in rv.data assert b'Success!' in rv.data
def test_add_template_test_with_name_and_template():
app = flask.Flask(__name__) def test_add_template_test_with_name_and_template(app, client):
def is_boolean(value): def is_boolean(value):
return isinstance(value, bool) return isinstance(value, bool)
app.add_template_test(is_boolean, 'boolean') app.add_template_test(is_boolean, 'boolean')
@app.route('/') @app.route('/')
def index(): def index():
return flask.render_template('template_test.html', value=False) return flask.render_template('template_test.html', value=False)
rv = app.test_client().get('/')
rv = client.get('/')
assert b'Success!' in rv.data assert b'Success!' in rv.data
def test_add_template_global():
app = flask.Flask(__name__) def test_add_template_global(app, app_ctx):
@app.template_global() @app.template_global()
def get_stuff(): def get_stuff():
return 42 return 42
assert 'get_stuff' in app.jinja_env.globals.keys() assert 'get_stuff' in app.jinja_env.globals.keys()
assert app.jinja_env.globals['get_stuff'] == get_stuff assert app.jinja_env.globals['get_stuff'] == get_stuff
assert app.jinja_env.globals['get_stuff'](), 42 assert app.jinja_env.globals['get_stuff'](), 42
with app.app_context():
rv = flask.render_template_string('{{ get_stuff() }}')
assert rv == '42'
def test_custom_template_loader(): rv = flask.render_template_string('{{ get_stuff() }}')
assert rv == '42'
def test_custom_template_loader(client):
class MyFlask(flask.Flask): class MyFlask(flask.Flask):
def create_global_jinja_loader(self): def create_global_jinja_loader(self):
from jinja2 import DictLoader from jinja2 import DictLoader
return DictLoader({'index.html': 'Hello Custom World!'}) return DictLoader({'index.html': 'Hello Custom World!'})
app = MyFlask(__name__) app = MyFlask(__name__)
@app.route('/') @app.route('/')
def index(): def index():
return flask.render_template('index.html') return flask.render_template('index.html')
c = app.test_client() c = app.test_client()
rv = c.get('/') rv = c.get('/')
assert rv.data == b'Hello Custom World!' assert rv.data == b'Hello Custom World!'
def test_iterable_loader():
app = flask.Flask(__name__) def test_iterable_loader(app, client):
@app.context_processor @app.context_processor
def context_processor(): def context_processor():
return {'whiskey': 'Jameson'} return {'whiskey': 'Jameson'}
@app.route('/') @app.route('/')
def index(): def index():
return flask.render_template( return flask.render_template(
['no_template.xml', # should skip this one ['no_template.xml', # should skip this one
'simple_template.html', # should render this 'simple_template.html', # should render this
'context_template.html'], 'context_template.html'],
value=23) value=23)
rv = app.test_client().get('/') rv = client.get('/')
assert rv.data == b'<h1>Jameson</h1>' assert rv.data == b'<h1>Jameson</h1>'
def test_templates_auto_reload():
def test_templates_auto_reload(app):
# debug is False, config option is None # debug is False, config option is None
app = flask.Flask(__name__)
assert app.debug is False assert app.debug is False
assert app.config['TEMPLATES_AUTO_RELOAD'] is None assert app.config['TEMPLATES_AUTO_RELOAD'] is None
assert app.jinja_env.auto_reload is False assert app.jinja_env.auto_reload is False
@ -346,10 +385,12 @@ def test_templates_auto_reload():
app.config['TEMPLATES_AUTO_RELOAD'] = True app.config['TEMPLATES_AUTO_RELOAD'] = True
assert app.jinja_env.auto_reload is True assert app.jinja_env.auto_reload is True
def test_template_loader_debugging(test_apps): def test_template_loader_debugging(test_apps):
from blueprintapp import app from blueprintapp import app
called = [] called = []
class _TestHandler(logging.Handler): class _TestHandler(logging.Handler):
def handle(x, record): def handle(x, record):
called.append(True) called.append(True)
@ -381,6 +422,7 @@ def test_template_loader_debugging(test_apps):
assert len(called) == 1 assert len(called) == 1
def test_custom_jinja_env(): def test_custom_jinja_env():
class CustomEnvironment(flask.templating.Environment): class CustomEnvironment(flask.templating.Environment):
pass pass

96
tests/test_testing.py

@ -16,24 +16,22 @@ import werkzeug
from flask._compat import text_type from flask._compat import text_type
def test_environ_defaults_from_config(): def test_environ_defaults_from_config(app, client):
app = flask.Flask(__name__)
app.testing = True
app.config['SERVER_NAME'] = 'example.com:1234' app.config['SERVER_NAME'] = 'example.com:1234'
app.config['APPLICATION_ROOT'] = '/foo' app.config['APPLICATION_ROOT'] = '/foo'
@app.route('/') @app.route('/')
def index(): def index():
return flask.request.url return flask.request.url
ctx = app.test_request_context() ctx = app.test_request_context()
assert ctx.request.url == 'http://example.com:1234/foo/' assert ctx.request.url == 'http://example.com:1234/foo/'
with app.test_client() as c:
rv = c.get('/')
assert rv.data == b'http://example.com:1234/foo/'
def test_environ_defaults(): rv = client.get('/')
app = flask.Flask(__name__) assert rv.data == b'http://example.com:1234/foo/'
app.testing = True
def test_environ_defaults(app, client, app_ctx, req_ctx):
@app.route('/') @app.route('/')
def index(): def index():
return flask.request.url return flask.request.url
@ -44,42 +42,40 @@ def test_environ_defaults():
rv = c.get('/') rv = c.get('/')
assert rv.data == b'http://localhost/' assert rv.data == b'http://localhost/'
def test_environ_base_default():
app = flask.Flask(__name__) def test_environ_base_default(app, client, app_ctx):
app.testing = True app.testing = True
@app.route('/') @app.route('/')
def index(): def index():
flask.g.user_agent = flask.request.headers["User-Agent"] flask.g.user_agent = flask.request.headers["User-Agent"]
return flask.request.remote_addr return flask.request.remote_addr
with app.test_client() as c: rv = client.get('/')
rv = c.get('/') assert rv.data == b'127.0.0.1'
assert rv.data == b'127.0.0.1' assert flask.g.user_agent == 'werkzeug/' + werkzeug.__version__
assert flask.g.user_agent == 'werkzeug/' + werkzeug.__version__
def test_environ_base_modified():
app = flask.Flask(__name__) def test_environ_base_modified(app, client, app_ctx):
app.testing = True
@app.route('/') @app.route('/')
def index(): def index():
flask.g.user_agent = flask.request.headers["User-Agent"] flask.g.user_agent = flask.request.headers["User-Agent"]
return flask.request.remote_addr return flask.request.remote_addr
with app.test_client() as c: client.environ_base['REMOTE_ADDR'] = '0.0.0.0'
c.environ_base['REMOTE_ADDR'] = '0.0.0.0' client.environ_base['HTTP_USER_AGENT'] = 'Foo'
c.environ_base['HTTP_USER_AGENT'] = 'Foo' rv = client.get('/')
rv = c.get('/') assert rv.data == b'0.0.0.0'
assert rv.data == b'0.0.0.0' assert flask.g.user_agent == 'Foo'
assert flask.g.user_agent == 'Foo'
c.environ_base['REMOTE_ADDR'] = '0.0.0.1' client.environ_base['REMOTE_ADDR'] = '0.0.0.1'
c.environ_base['HTTP_USER_AGENT'] = 'Bar' client.environ_base['HTTP_USER_AGENT'] = 'Bar'
rv = c.get('/') rv = client.get('/')
assert rv.data == b'0.0.0.1' assert rv.data == b'0.0.0.1'
assert flask.g.user_agent == 'Bar' assert flask.g.user_agent == 'Bar'
def test_redirect_keep_session():
app = flask.Flask(__name__) def test_redirect_keep_session(app, client, app_ctx):
app.secret_key = 'testing' app.secret_key = 'testing'
@app.route('/', methods=['GET', 'POST']) @app.route('/', methods=['GET', 'POST'])
@ -93,7 +89,7 @@ def test_redirect_keep_session():
def get_session(): def get_session():
return flask.session.get('data', '<missing>') return flask.session.get('data', '<missing>')
with app.test_client() as c: with client as c:
rv = c.get('/getsession') rv = c.get('/getsession')
assert rv.data == b'<missing>' assert rv.data == b'<missing>'
@ -110,9 +106,8 @@ def test_redirect_keep_session():
rv = c.get('/getsession') rv = c.get('/getsession')
assert rv.data == b'foo' assert rv.data == b'foo'
def test_session_transactions():
app = flask.Flask(__name__) def test_session_transactions(app):
app.testing = True
app.secret_key = 'testing' app.secret_key = 'testing'
@app.route('/') @app.route('/')
@ -130,6 +125,7 @@ def test_session_transactions():
assert len(sess) == 1 assert len(sess) == 1
assert sess['foo'] == [42] assert sess['foo'] == [42]
def test_session_transactions_no_null_sessions(): def test_session_transactions_no_null_sessions():
app = flask.Flask(__name__) app = flask.Flask(__name__)
app.testing = True app.testing = True
@ -140,30 +136,28 @@ def test_session_transactions_no_null_sessions():
pass pass
assert 'Session backend did not open a session' in str(e.value) assert 'Session backend did not open a session' in str(e.value)
def test_session_transactions_keep_context():
app = flask.Flask(__name__) def test_session_transactions_keep_context(app, client, req_ctx):
app.testing = True
app.secret_key = 'testing' app.secret_key = 'testing'
with app.test_client() as c: rv = client.get('/')
rv = c.get('/') req = flask.request._get_current_object()
req = flask.request._get_current_object() assert req is not None
assert req is not None with client.session_transaction():
with c.session_transaction(): assert req is flask.request._get_current_object()
assert req is flask.request._get_current_object()
def test_session_transaction_needs_cookies(): def test_session_transaction_needs_cookies(app):
app = flask.Flask(__name__)
app.testing = True
c = app.test_client(use_cookies=False) c = app.test_client(use_cookies=False)
with pytest.raises(RuntimeError) as e: with pytest.raises(RuntimeError) as e:
with c.session_transaction() as s: with c.session_transaction() as s:
pass pass
assert 'cookies' in str(e.value) assert 'cookies' in str(e.value)
def test_test_client_context_binding(): def test_test_client_context_binding():
app = flask.Flask(__name__) app = flask.Flask(__name__)
app.config['LOGGER_HANDLER_POLICY'] = 'never' app.config['LOGGER_HANDLER_POLICY'] = 'never'
@app.route('/') @app.route('/')
def index(): def index():
flask.g.value = 42 flask.g.value = 42
@ -192,6 +186,7 @@ def test_test_client_context_binding():
else: else:
raise AssertionError('some kind of exception expected') raise AssertionError('some kind of exception expected')
def test_reuse_client(): def test_reuse_client():
app = flask.Flask(__name__) app = flask.Flask(__name__)
c = app.test_client() c = app.test_client()
@ -202,9 +197,11 @@ def test_reuse_client():
with c: with c:
assert c.get('/').status_code == 404 assert c.get('/').status_code == 404
def test_test_client_calls_teardown_handlers(): def test_test_client_calls_teardown_handlers():
app = flask.Flask(__name__) app = flask.Flask(__name__)
called = [] called = []
@app.teardown_request @app.teardown_request
def remember(error): def remember(error):
called.append(error) called.append(error)
@ -224,6 +221,7 @@ def test_test_client_calls_teardown_handlers():
assert called == [None] assert called == [None]
assert called == [None, None] assert called == [None, None]
def test_full_url_request(): def test_full_url_request():
app = flask.Flask(__name__) app = flask.Flask(__name__)
app.testing = True app.testing = True
@ -238,9 +236,11 @@ def test_full_url_request():
assert 'gin' in flask.request.form assert 'gin' in flask.request.form
assert 'vodka' in flask.request.args assert 'vodka' in flask.request.args
def test_subdomain(): def test_subdomain():
app = flask.Flask(__name__) app = flask.Flask(__name__)
app.config['SERVER_NAME'] = 'example.com' app.config['SERVER_NAME'] = 'example.com'
@app.route('/', subdomain='<company_id>') @app.route('/', subdomain='<company_id>')
def view(company_id): def view(company_id):
return company_id return company_id
@ -254,9 +254,11 @@ def test_subdomain():
assert 200 == response.status_code assert 200 == response.status_code
assert b'xxx' == response.data assert b'xxx' == response.data
def test_nosubdomain(): def test_nosubdomain():
app = flask.Flask(__name__) app = flask.Flask(__name__)
app.config['SERVER_NAME'] = 'example.com' app.config['SERVER_NAME'] = 'example.com'
@app.route('/<company_id>') @app.route('/<company_id>')
def view(company_id): def view(company_id):
return company_id return company_id

22
tests/test_user_error_handler.py

@ -8,8 +8,7 @@ from werkzeug.exceptions import (
import flask import flask
def test_error_handler_no_match(): def test_error_handler_no_match(app, client):
app = flask.Flask(__name__)
class CustomException(Exception): class CustomException(Exception):
pass pass
@ -31,15 +30,12 @@ def test_error_handler_no_match():
def key_error(): def key_error():
raise KeyError() raise KeyError()
c = app.test_client() app.testing = False
assert client.get('/custom').data == b'custom'
assert c.get('/custom').data == b'custom' assert client.get('/keyerror').data == b'KeyError'
assert c.get('/keyerror').data == b'KeyError'
def test_error_handler_subclass(): def test_error_handler_subclass(app):
app = flask.Flask(__name__)
class ParentException(Exception): class ParentException(Exception):
pass pass
@ -78,9 +74,7 @@ def test_error_handler_subclass():
assert c.get('/child-registered').data == b'child-registered' assert c.get('/child-registered').data == b'child-registered'
def test_error_handler_http_subclass(): def test_error_handler_http_subclass(app):
app = flask.Flask(__name__)
class ForbiddenSubclassRegistered(Forbidden): class ForbiddenSubclassRegistered(Forbidden):
pass pass
@ -116,7 +110,7 @@ def test_error_handler_http_subclass():
assert c.get('/forbidden-registered').data == b'forbidden-registered' assert c.get('/forbidden-registered').data == b'forbidden-registered'
def test_error_handler_blueprint(): def test_error_handler_blueprint(app):
bp = flask.Blueprint('bp', __name__) bp = flask.Blueprint('bp', __name__)
@bp.errorhandler(500) @bp.errorhandler(500)
@ -127,8 +121,6 @@ def test_error_handler_blueprint():
def bp_test(): def bp_test():
raise InternalServerError() raise InternalServerError()
app = flask.Flask(__name__)
@app.errorhandler(500) @app.errorhandler(500)
def app_exception_handler(e): def app_exception_handler(e):
return 'app-error' return 'app-error'

44
tests/test_views.py

@ -16,6 +16,7 @@ import flask.views
from werkzeug.http import parse_set_header from werkzeug.http import parse_set_header
def common_test(app): def common_test(app):
c = app.test_client() c = app.test_client()
@ -25,23 +26,23 @@ def common_test(app):
meths = parse_set_header(c.open('/', method='OPTIONS').headers['Allow']) meths = parse_set_header(c.open('/', method='OPTIONS').headers['Allow'])
assert sorted(meths) == ['GET', 'HEAD', 'OPTIONS', 'POST'] assert sorted(meths) == ['GET', 'HEAD', 'OPTIONS', 'POST']
def test_basic_view():
app = flask.Flask(__name__)
def test_basic_view(app):
class Index(flask.views.View): class Index(flask.views.View):
methods = ['GET', 'POST'] methods = ['GET', 'POST']
def dispatch_request(self): def dispatch_request(self):
return flask.request.method return flask.request.method
app.add_url_rule('/', view_func=Index.as_view('index')) app.add_url_rule('/', view_func=Index.as_view('index'))
common_test(app) common_test(app)
def test_method_based_view():
app = flask.Flask(__name__)
def test_method_based_view(app):
class Index(flask.views.MethodView): class Index(flask.views.MethodView):
def get(self): def get(self):
return 'GET' return 'GET'
def post(self): def post(self):
return 'POST' return 'POST'
@ -49,18 +50,19 @@ def test_method_based_view():
common_test(app) common_test(app)
def test_view_patching():
app = flask.Flask(__name__)
def test_view_patching(app):
class Index(flask.views.MethodView): class Index(flask.views.MethodView):
def get(self): def get(self):
1 // 0 1 // 0
def post(self): def post(self):
1 // 0 1 // 0
class Other(Index): class Other(Index):
def get(self): def get(self):
return 'GET' return 'GET'
def post(self): def post(self):
return 'POST' return 'POST'
@ -69,12 +71,12 @@ def test_view_patching():
app.add_url_rule('/', view_func=view) app.add_url_rule('/', view_func=view)
common_test(app) common_test(app)
def test_view_inheritance():
app = flask.Flask(__name__)
def test_view_inheritance(app):
class Index(flask.views.MethodView): class Index(flask.views.MethodView):
def get(self): def get(self):
return 'GET' return 'GET'
def post(self): def post(self):
return 'POST' return 'POST'
@ -88,18 +90,19 @@ def test_view_inheritance():
meths = parse_set_header(c.open('/', method='OPTIONS').headers['Allow']) meths = parse_set_header(c.open('/', method='OPTIONS').headers['Allow'])
assert sorted(meths) == ['DELETE', 'GET', 'HEAD', 'OPTIONS', 'POST'] assert sorted(meths) == ['DELETE', 'GET', 'HEAD', 'OPTIONS', 'POST']
def test_view_decorators():
app = flask.Flask(__name__)
def test_view_decorators(app):
def add_x_parachute(f): def add_x_parachute(f):
def new_function(*args, **kwargs): def new_function(*args, **kwargs):
resp = flask.make_response(f(*args, **kwargs)) resp = flask.make_response(f(*args, **kwargs))
resp.headers['X-Parachute'] = 'awesome' resp.headers['X-Parachute'] = 'awesome'
return resp return resp
return new_function return new_function
class Index(flask.views.View): class Index(flask.views.View):
decorators = [add_x_parachute] decorators = [add_x_parachute]
def dispatch_request(self): def dispatch_request(self):
return 'Awesome' return 'Awesome'
@ -109,11 +112,13 @@ def test_view_decorators():
assert rv.headers['X-Parachute'] == 'awesome' assert rv.headers['X-Parachute'] == 'awesome'
assert rv.data == b'Awesome' assert rv.data == b'Awesome'
def test_view_provide_automatic_options_attr(): def test_view_provide_automatic_options_attr():
app = flask.Flask(__name__) app = flask.Flask(__name__)
class Index1(flask.views.View): class Index1(flask.views.View):
provide_automatic_options = False provide_automatic_options = False
def dispatch_request(self): def dispatch_request(self):
return 'Hello World!' return 'Hello World!'
@ -127,6 +132,7 @@ def test_view_provide_automatic_options_attr():
class Index2(flask.views.View): class Index2(flask.views.View):
methods = ['OPTIONS'] methods = ['OPTIONS']
provide_automatic_options = True provide_automatic_options = True
def dispatch_request(self): def dispatch_request(self):
return 'Hello World!' return 'Hello World!'
@ -146,9 +152,8 @@ def test_view_provide_automatic_options_attr():
rv = c.open('/', method='OPTIONS') rv = c.open('/', method='OPTIONS')
assert 'OPTIONS' in rv.allow assert 'OPTIONS' in rv.allow
def test_implicit_head():
app = flask.Flask(__name__)
def test_implicit_head(app):
class Index(flask.views.MethodView): class Index(flask.views.MethodView):
def get(self): def get(self):
return flask.Response('Blub', headers={ return flask.Response('Blub', headers={
@ -164,12 +169,12 @@ def test_implicit_head():
assert rv.data == b'' assert rv.data == b''
assert rv.headers['X-Method'] == 'HEAD' assert rv.headers['X-Method'] == 'HEAD'
def test_explicit_head():
app = flask.Flask(__name__)
def test_explicit_head(app):
class Index(flask.views.MethodView): class Index(flask.views.MethodView):
def get(self): def get(self):
return 'GET' return 'GET'
def head(self): def head(self):
return flask.Response('', headers={'X-Method': 'HEAD'}) return flask.Response('', headers={'X-Method': 'HEAD'})
@ -181,12 +186,13 @@ def test_explicit_head():
assert rv.data == b'' assert rv.data == b''
assert rv.headers['X-Method'] == 'HEAD' assert rv.headers['X-Method'] == 'HEAD'
def test_endpoint_override():
app = flask.Flask(__name__) def test_endpoint_override(app):
app.debug = True app.debug = True
class Index(flask.views.View): class Index(flask.views.View):
methods = ['GET', 'POST'] methods = ['GET', 'POST']
def dispatch_request(self): def dispatch_request(self):
return flask.request.method return flask.request.method
@ -198,9 +204,8 @@ def test_endpoint_override():
# But these tests should still pass. We just log a warning. # But these tests should still pass. We just log a warning.
common_test(app) common_test(app)
def test_multiple_inheritance():
app = flask.Flask(__name__)
def test_multiple_inheritance(app):
class GetView(flask.views.MethodView): class GetView(flask.views.MethodView):
def get(self): def get(self):
return 'GET' return 'GET'
@ -219,9 +224,8 @@ def test_multiple_inheritance():
assert c.delete('/').data == b'DELETE' assert c.delete('/').data == b'DELETE'
assert sorted(GetDeleteView.methods) == ['DELETE', 'GET'] assert sorted(GetDeleteView.methods) == ['DELETE', 'GET']
def test_remove_method_from_parent():
app = flask.Flask(__name__)
def test_remove_method_from_parent(app):
class GetView(flask.views.MethodView): class GetView(flask.views.MethodView):
def get(self): def get(self):
return 'GET' return 'GET'

Loading…
Cancel
Save