diff --git a/tests/__init__.py b/tests/__init__.py index 30024d10..aa52c18a 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -90,25 +90,6 @@ class TestFlask(object): consistency. """ - @pytest.fixture(autouse=True) - def setup_path(self, monkeypatch): - monkeypatch.syspath_prepend( - os.path.abspath(os.path.join( - os.path.dirname(__file__), 'test_apps')) - ) - - @pytest.fixture(autouse=True) - def leak_detector(self, request): - request.addfinalizer(self.ensure_clean_request_context) - - def ensure_clean_request_context(self): - # make sure we're not leaking a request context since we are - # testing flask internally in debug mode in a few cases - leaks = [] - while flask._request_ctx_stack.top is not None: - leaks.append(flask._request_ctx_stack.pop()) - assert leaks == [] - def setup_method(self, method): self.setup() diff --git a/tests/conftest.py b/tests/conftest.py index ed11084b..cd3fe46e 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -6,12 +6,34 @@ :copyright: (c) 2014 by the Flask Team, see AUTHORS for more details. :license: BSD, see LICENSE for more details. """ +import flask +import os +import sys import pkgutil import pytest -import sys import textwrap +@pytest.fixture(autouse=True) +def setup_path(monkeypatch): + monkeypatch.syspath_prepend( + os.path.abspath(os.path.join( + os.path.dirname(__file__), 'test_apps')) + ) + +@pytest.fixture(autouse=True) +def leak_detector(request): + def ensure_clean_request_context(): + # make sure we're not leaking a request context since we are + # testing flask internally in debug mode in a few cases + leaks = [] + while flask._request_ctx_stack.top is not None: + leaks.append(flask._request_ctx_stack.pop()) + assert leaks == [] + request.addfinalizer(ensure_clean_request_context) + + + @pytest.fixture(params=(True, False)) def limit_loader(request, monkeypatch): """Patch pkgutil.get_loader to give loader without get_filename or archive. diff --git a/tests/test_appctx.py b/tests/test_appctx.py index 0146583f..57b4ede8 100644 --- a/tests/test_appctx.py +++ b/tests/test_appctx.py @@ -16,106 +16,98 @@ import unittest from tests import TestFlask -class TestAppContext(TestFlask): - - def test_basic_url_generation(self): - app = flask.Flask(__name__) - app.config['SERVER_NAME'] = 'localhost' - app.config['PREFERRED_URL_SCHEME'] = 'https' - - @app.route('/') - def index(): - pass - - with app.app_context(): - rv = flask.url_for('index') - assert rv == 'https://localhost/' - - def test_url_generation_requires_server_name(self): - app = flask.Flask(__name__) - with app.app_context(): - with pytest.raises(RuntimeError): - flask.url_for('index') - - def test_url_generation_without_context_fails(self): +def test_basic_url_generation(): + app = flask.Flask(__name__) + app.config['SERVER_NAME'] = 'localhost' + app.config['PREFERRED_URL_SCHEME'] = 'https' + + @app.route('/') + def index(): + pass + + with app.app_context(): + rv = flask.url_for('index') + assert rv == 'https://localhost/' + +def test_url_generation_requires_server_name(): + app = flask.Flask(__name__) + with app.app_context(): with pytest.raises(RuntimeError): flask.url_for('index') - def test_request_context_means_app_context(self): - app = flask.Flask(__name__) - with app.test_request_context(): - assert flask.current_app._get_current_object() == app - assert flask._app_ctx_stack.top == None - - def test_app_context_provides_current_app(self): - app = flask.Flask(__name__) - with app.app_context(): - assert flask.current_app._get_current_object() == app - assert flask._app_ctx_stack.top == None - - def test_app_tearing_down(self): - cleanup_stuff = [] - app = flask.Flask(__name__) - @app.teardown_appcontext - def cleanup(exception): - cleanup_stuff.append(exception) - - with app.app_context(): - pass - - assert cleanup_stuff == [None] - - def test_app_tearing_down_with_previous_exception(self): - cleanup_stuff = [] - app = flask.Flask(__name__) - @app.teardown_appcontext - def cleanup(exception): - cleanup_stuff.append(exception) - - try: - raise Exception('dummy') - except Exception: - pass - - with app.app_context(): - pass - - assert cleanup_stuff == [None] - - def test_custom_app_ctx_globals_class(self): - class CustomRequestGlobals(object): - def __init__(self): - self.spam = 'eggs' - app = flask.Flask(__name__) - app.app_ctx_globals_class = CustomRequestGlobals - with app.app_context(): - assert flask.render_template_string('{{ g.spam }}') == 'eggs' - - def test_context_refcounts(self): - called = [] - app = flask.Flask(__name__) - @app.teardown_request - def teardown_req(error=None): - called.append('request') - @app.teardown_appcontext - def teardown_app(error=None): - called.append('app') - @app.route('/') - def index(): - with flask._app_ctx_stack.top: - with flask._request_ctx_stack.top: - pass - env = flask._request_ctx_stack.top.request.environ - assert env['werkzeug.request'] is not None - return u'' - c = app.test_client() - res = c.get('/') - assert res.status_code == 200 - assert res.data == b'' - assert called == ['request', 'app'] - - -def suite(): - suite = unittest.TestSuite() - suite.addTest(unittest.makeSuite(TestAppContext)) - return suite +def test_url_generation_without_context_fails(): + with pytest.raises(RuntimeError): + flask.url_for('index') + +def test_request_context_means_app_context(): + app = flask.Flask(__name__) + with app.test_request_context(): + assert flask.current_app._get_current_object() == app + assert flask._app_ctx_stack.top == None + +def test_app_context_provides_current_app(): + app = flask.Flask(__name__) + with app.app_context(): + assert flask.current_app._get_current_object() == app + assert flask._app_ctx_stack.top == None + +def test_app_tearing_down(): + cleanup_stuff = [] + app = flask.Flask(__name__) + @app.teardown_appcontext + def cleanup(exception): + cleanup_stuff.append(exception) + + with app.app_context(): + pass + + assert cleanup_stuff == [None] + +def test_app_tearing_down_with_previous_exception(): + cleanup_stuff = [] + app = flask.Flask(__name__) + @app.teardown_appcontext + def cleanup(exception): + cleanup_stuff.append(exception) + + try: + raise Exception('dummy') + except Exception: + pass + + with app.app_context(): + pass + + assert cleanup_stuff == [None] + +def test_custom_app_ctx_globals_class(): + class CustomRequestGlobals(object): + def __init__(self): + self.spam = 'eggs' + app = flask.Flask(__name__) + app.app_ctx_globals_class = CustomRequestGlobals + with app.app_context(): + assert flask.render_template_string('{{ g.spam }}') == 'eggs' + +def test_context_refcounts(): + called = [] + app = flask.Flask(__name__) + @app.teardown_request + def teardown_req(error=None): + called.append('request') + @app.teardown_appcontext + def teardown_app(error=None): + called.append('app') + @app.route('/') + def index(): + with flask._app_ctx_stack.top: + with flask._request_ctx_stack.top: + pass + env = flask._request_ctx_stack.top.request.environ + assert env['werkzeug.request'] is not None + return u'' + c = app.test_client() + res = c.get('/') + assert res.status_code == 200 + assert res.data == b'' + assert called == ['request', 'app'] diff --git a/tests/test_ext.py b/tests/test_ext.py index 1bec1b62..dad0d585 100644 --- a/tests/test_ext.py +++ b/tests/test_ext.py @@ -20,120 +20,118 @@ except ImportError: from tests import TestFlask from flask._compat import PY2 -class TestExtImportHook(TestFlask): - - def setup(self): - # we clear this out for various reasons. The most important one is - # that a real flaskext could be in there which would disable our - # fake package. Secondly we want to make sure that the flaskext - # import hook does not break on reloading. - for entry, value in list(sys.modules.items()): - if (entry.startswith('flask.ext.') or - entry.startswith('flask_') or - entry.startswith('flaskext.') or - entry == 'flaskext') and value is not None: - sys.modules.pop(entry, None) - from flask import ext - reload_module(ext) - - # reloading must not add more hooks - import_hooks = 0 - for item in sys.meta_path: - cls = type(item) - if cls.__module__ == 'flask.exthook' and \ - cls.__name__ == 'ExtensionImporter': - import_hooks += 1 - assert import_hooks == 1 - - def teardown(self): + +@pytest.fixture(autouse=True) +def importhook_setup(monkeypatch, request): + # we clear this out for various reasons. The most important one is + # that a real flaskext could be in there which would disable our + # fake package. Secondly we want to make sure that the flaskext + # import hook does not break on reloading. + for entry, value in list(sys.modules.items()): + if (entry.startswith('flask.ext.') or + entry.startswith('flask_') or + entry.startswith('flaskext.') or + entry == 'flaskext') and value is not None: + monkeypatch.delitem(sys.modules, entry) + from flask import ext + reload_module(ext) + + # reloading must not add more hooks + import_hooks = 0 + for item in sys.meta_path: + cls = type(item) + if cls.__module__ == 'flask.exthook' and \ + cls.__name__ == 'ExtensionImporter': + import_hooks += 1 + assert import_hooks == 1 + + def teardown(): from flask import ext for key in ext.__dict__: assert '.' not in key - def test_flaskext_new_simple_import_normal(self): - from flask.ext.newext_simple import ext_id - assert ext_id == 'newext_simple' - - def test_flaskext_new_simple_import_module(self): - from flask.ext import newext_simple - assert newext_simple.ext_id == 'newext_simple' - assert newext_simple.__name__ == 'flask_newext_simple' - - def test_flaskext_new_package_import_normal(self): - from flask.ext.newext_package import ext_id - assert ext_id == 'newext_package' - - def test_flaskext_new_package_import_module(self): - from flask.ext import newext_package - assert newext_package.ext_id == 'newext_package' - assert newext_package.__name__ == 'flask_newext_package' - - def test_flaskext_new_package_import_submodule_function(self): - from flask.ext.newext_package.submodule import test_function - assert test_function() == 42 - - def test_flaskext_new_package_import_submodule(self): - from flask.ext.newext_package import submodule - assert submodule.__name__ == 'flask_newext_package.submodule' - assert submodule.test_function() == 42 - - def test_flaskext_old_simple_import_normal(self): - from flask.ext.oldext_simple import ext_id - assert ext_id == 'oldext_simple' - - def test_flaskext_old_simple_import_module(self): - from flask.ext import oldext_simple - assert oldext_simple.ext_id == 'oldext_simple' - assert oldext_simple.__name__ == 'flaskext.oldext_simple' - - def test_flaskext_old_package_import_normal(self): - from flask.ext.oldext_package import ext_id - assert ext_id == 'oldext_package' - - def test_flaskext_old_package_import_module(self): - from flask.ext import oldext_package - assert oldext_package.ext_id == 'oldext_package' - assert oldext_package.__name__ == 'flaskext.oldext_package' - - def test_flaskext_old_package_import_submodule(self): - from flask.ext.oldext_package import submodule - assert submodule.__name__ == 'flaskext.oldext_package.submodule' - assert submodule.test_function() == 42 - - def test_flaskext_old_package_import_submodule_function(self): - from flask.ext.oldext_package.submodule import test_function - assert test_function() == 42 - - def test_flaskext_broken_package_no_module_caching(self): - for x in range(2): - with pytest.raises(ImportError): - import flask.ext.broken - - def test_no_error_swallowing(self): - try: + request.addfinalizer(teardown) + +def test_flaskext_new_simple_import_normal(): + from flask.ext.newext_simple import ext_id + assert ext_id == 'newext_simple' + +def test_flaskext_new_simple_import_module(): + from flask.ext import newext_simple + assert newext_simple.ext_id == 'newext_simple' + assert newext_simple.__name__ == 'flask_newext_simple' + +def test_flaskext_new_package_import_normal(): + from flask.ext.newext_package import ext_id + assert ext_id == 'newext_package' + +def test_flaskext_new_package_import_module(): + from flask.ext import newext_package + assert newext_package.ext_id == 'newext_package' + assert newext_package.__name__ == 'flask_newext_package' + +def test_flaskext_new_package_import_submodule_function(): + from flask.ext.newext_package.submodule import test_function + assert test_function() == 42 + +def test_flaskext_new_package_import_submodule(): + from flask.ext.newext_package import submodule + assert submodule.__name__ == 'flask_newext_package.submodule' + assert submodule.test_function() == 42 + +def test_flaskext_old_simple_import_normal(): + from flask.ext.oldext_simple import ext_id + assert ext_id == 'oldext_simple' + +def test_flaskext_old_simple_import_module(): + from flask.ext import oldext_simple + assert oldext_simple.ext_id == 'oldext_simple' + assert oldext_simple.__name__ == 'flaskext.oldext_simple' + +def test_flaskext_old_package_import_normal(): + from flask.ext.oldext_package import ext_id + assert ext_id == 'oldext_package' + +def test_flaskext_old_package_import_module(): + from flask.ext import oldext_package + assert oldext_package.ext_id == 'oldext_package' + assert oldext_package.__name__ == 'flaskext.oldext_package' + +def test_flaskext_old_package_import_submodule(): + from flask.ext.oldext_package import submodule + assert submodule.__name__ == 'flaskext.oldext_package.submodule' + assert submodule.test_function() == 42 + +def test_flaskext_old_package_import_submodule_function(): + from flask.ext.oldext_package.submodule import test_function + assert test_function() == 42 + +def test_flaskext_broken_package_no_module_caching(): + for x in range(2): + with pytest.raises(ImportError): import flask.ext.broken - except ImportError: - exc_type, exc_value, tb = sys.exc_info() - assert exc_type is ImportError - if PY2: - message = 'No module named missing_module' - else: - message = 'No module named \'missing_module\'' - assert str(exc_value) == message - assert tb.tb_frame.f_globals is globals() - - # reraise() adds a second frame so we need to skip that one too. - # On PY3 we even have another one :( - next = tb.tb_next.tb_next - if not PY2: - next = next.tb_next - - import os.path - assert os.path.join('flask_broken', '__init__.py') in \ - next.tb_frame.f_code.co_filename - - -def suite(): - suite = unittest.TestSuite() - suite.addTest(unittest.makeSuite(TestExtImportHook)) - return suite + +def test_no_error_swallowing(): + try: + import flask.ext.broken + except ImportError: + exc_type, exc_value, tb = sys.exc_info() + assert exc_type is ImportError + if PY2: + message = 'No module named missing_module' + else: + message = 'No module named \'missing_module\'' + assert str(exc_value) == message + assert tb.tb_frame.f_globals is globals() + + # reraise() adds a second frame so we need to skip that one too. + # On PY3 we even have another one :( + next = tb.tb_next.tb_next + if not PY2: + next = next.tb_next + + import os.path + assert os.path.join('flask_broken', '__init__.py') in \ + next.tb_frame.f_code.co_filename + else: + 1/0 # XXX diff --git a/tests/test_subclassing.py b/tests/test_subclassing.py index 88df7d94..bd953781 100644 --- a/tests/test_subclassing.py +++ b/tests/test_subclassing.py @@ -16,31 +16,23 @@ from tests import TestFlask from flask._compat import StringIO -class TestFlaskSubclassing(TestFlask): - - def test_suppressed_exception_logging(self): - class SuppressedFlask(flask.Flask): - def log_exception(self, exc_info): - pass - - out = StringIO() - app = SuppressedFlask(__name__) - app.logger_name = 'flask_tests/test_suppressed_exception_logging' - app.logger.addHandler(StreamHandler(out)) - - @app.route('/') - def index(): - 1 // 0 - - rv = app.test_client().get('/') - assert rv.status_code == 500 - assert b'Internal Server Error' in rv.data - - err = out.getvalue() - assert err == '' - - -def suite(): - suite = unittest.TestSuite() - suite.addTest(unittest.makeSuite(TestFlaskSubclassing)) - return suite +def test_suppressed_exception_logging(): + class SuppressedFlask(flask.Flask): + def log_exception(self, exc_info): + pass + + out = StringIO() + app = SuppressedFlask(__name__) + app.logger_name = 'flask_tests/test_suppressed_exception_logging' + app.logger.addHandler(StreamHandler(out)) + + @app.route('/') + def index(): + 1 // 0 + + rv = app.test_client().get('/') + assert rv.status_code == 500 + assert b'Internal Server Error' in rv.data + + err = out.getvalue() + assert err == '' diff --git a/tests/test_templating.py b/tests/test_templating.py index 6ba6541e..f05418fb 100644 --- a/tests/test_templating.py +++ b/tests/test_templating.py @@ -9,6 +9,8 @@ :license: BSD, see LICENSE for more details. """ +import pytest + import flask import unittest import logging @@ -17,334 +19,324 @@ from jinja2 import TemplateNotFound from tests import TestFlask -class TestTemplating(TestFlask): - - def test_context_processing(self): - app = flask.Flask(__name__) - @app.context_processor - def context_processor(): - return {'injected_value': 42} - @app.route('/') - def index(): - return flask.render_template('context_template.html', value=23) - rv = app.test_client().get('/') - assert rv.data == b'

23|42' - - def test_original_win(self): - app = flask.Flask(__name__) - @app.route('/') - def index(): - return flask.render_template_string('{{ config }}', config=42) - rv = app.test_client().get('/') - assert rv.data == b'42' - - def test_request_less_rendering(self): - app = flask.Flask(__name__) - app.config['WORLD_NAME'] = 'Special World' - @app.context_processor - def context_processor(): - return dict(foo=42) - - with app.app_context(): - rv = flask.render_template_string('Hello {{ config.WORLD_NAME }} ' - '{{ foo }}') - assert rv == 'Hello Special World 42' - - def test_standard_context(self): - app = flask.Flask(__name__) - app.secret_key = 'development key' - @app.route('/') - def index(): - flask.g.foo = 23 - flask.session['test'] = 'aha' - return flask.render_template_string(''' - {{ request.args.foo }} - {{ g.foo }} - {{ config.DEBUG }} - {{ session.test }} - ''') - rv = app.test_client().get('/?foo=42') - assert rv.data.split() == [b'42', b'23', b'False', b'aha'] - - def test_escaping(self): - text = '

Hello World!' - app = flask.Flask(__name__) - @app.route('/') - def index(): - return flask.render_template('escaping_template.html', text=text, - html=flask.Markup(text)) - lines = app.test_client().get('/').data.splitlines() - assert lines == [ - b'<p>Hello World!', - b'

Hello World!', - b'

Hello World!', - b'

Hello World!', - b'<p>Hello World!', - b'

Hello World!' - ] - - def test_no_escaping(self): - app = flask.Flask(__name__) - with app.test_request_context(): - assert flask.render_template_string( - '{{ foo }}', foo='') == '' - assert flask.render_template('mail.txt', foo='') == \ - ' Mail' - - def test_macros(self): - app = flask.Flask(__name__) - with app.test_request_context(): - macro = flask.get_template_attribute('_macro.html', 'hello') - assert macro('World') == 'Hello World!' - - def test_template_filter(self): - app = flask.Flask(__name__) - @app.template_filter() - def my_reverse(s): - return s[::-1] - 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']('abcd') == 'dcba' - - def test_add_template_filter(self): - app = flask.Flask(__name__) - def my_reverse(s): - return s[::-1] - app.add_template_filter(my_reverse) - 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']('abcd') == 'dcba' - - def test_template_filter_with_name(self): - app = flask.Flask(__name__) - @app.template_filter('strrev') - def my_reverse(s): - return s[::-1] - assert 'strrev' in app.jinja_env.filters.keys() - assert app.jinja_env.filters['strrev'] == my_reverse - assert app.jinja_env.filters['strrev']('abcd') == 'dcba' - - def test_add_template_filter_with_name(self): - app = flask.Flask(__name__) - def my_reverse(s): - return s[::-1] - app.add_template_filter(my_reverse, 'strrev') - assert 'strrev' in app.jinja_env.filters.keys() - assert app.jinja_env.filters['strrev'] == my_reverse - assert app.jinja_env.filters['strrev']('abcd') == 'dcba' - - def test_template_filter_with_template(self): - app = flask.Flask(__name__) - @app.template_filter() - def super_reverse(s): - return s[::-1] - @app.route('/') - def index(): - return flask.render_template('template_filter.html', value='abcd') - rv = app.test_client().get('/') - assert rv.data == b'dcba' - - def test_add_template_filter_with_template(self): - app = flask.Flask(__name__) - def super_reverse(s): - return s[::-1] - app.add_template_filter(super_reverse) - @app.route('/') - def index(): - return flask.render_template('template_filter.html', value='abcd') - rv = app.test_client().get('/') - assert rv.data == b'dcba' - - def test_template_filter_with_name_and_template(self): - app = flask.Flask(__name__) - @app.template_filter('super_reverse') - def my_reverse(s): - return s[::-1] - @app.route('/') - def index(): - return flask.render_template('template_filter.html', value='abcd') - rv = app.test_client().get('/') - assert rv.data == b'dcba' - - def test_add_template_filter_with_name_and_template(self): - app = flask.Flask(__name__) - def my_reverse(s): - return s[::-1] - app.add_template_filter(my_reverse, 'super_reverse') - @app.route('/') - def index(): - return flask.render_template('template_filter.html', value='abcd') - rv = app.test_client().get('/') - assert rv.data == b'dcba' - - def test_template_test(self): - app = flask.Flask(__name__) - @app.template_test() - def boolean(value): - return isinstance(value, bool) - assert 'boolean' in app.jinja_env.tests.keys() - assert app.jinja_env.tests['boolean'] == boolean - assert app.jinja_env.tests['boolean'](False) - - def test_add_template_test(self): - app = flask.Flask(__name__) - def boolean(value): - return isinstance(value, bool) - app.add_template_test(boolean) - assert 'boolean' in app.jinja_env.tests.keys() - assert app.jinja_env.tests['boolean'] == boolean - assert app.jinja_env.tests['boolean'](False) - - def test_template_test_with_name(self): - app = flask.Flask(__name__) - @app.template_test('boolean') - def is_boolean(value): - return isinstance(value, bool) - assert 'boolean' in app.jinja_env.tests.keys() - assert app.jinja_env.tests['boolean'] == is_boolean - assert app.jinja_env.tests['boolean'](False) - - def test_add_template_test_with_name(self): - app = flask.Flask(__name__) - def is_boolean(value): - return isinstance(value, bool) - app.add_template_test(is_boolean, 'boolean') - assert 'boolean' in app.jinja_env.tests.keys() - assert app.jinja_env.tests['boolean'] == is_boolean - assert app.jinja_env.tests['boolean'](False) - - def test_template_test_with_template(self): - app = flask.Flask(__name__) - @app.template_test() - def boolean(value): - return isinstance(value, bool) - @app.route('/') - def index(): - return flask.render_template('template_test.html', value=False) - rv = app.test_client().get('/') - assert b'Success!' in rv.data - - def test_add_template_test_with_template(self): - app = flask.Flask(__name__) - def boolean(value): - return isinstance(value, bool) - app.add_template_test(boolean) - @app.route('/') - def index(): - return flask.render_template('template_test.html', value=False) - rv = app.test_client().get('/') - assert b'Success!' in rv.data - - def test_template_test_with_name_and_template(self): - app = flask.Flask(__name__) - @app.template_test('boolean') - def is_boolean(value): - return isinstance(value, bool) - @app.route('/') - def index(): - return flask.render_template('template_test.html', value=False) - rv = app.test_client().get('/') - assert b'Success!' in rv.data - - def test_add_template_test_with_name_and_template(self): - app = flask.Flask(__name__) - def is_boolean(value): - return isinstance(value, bool) - app.add_template_test(is_boolean, 'boolean') - @app.route('/') - def index(): - return flask.render_template('template_test.html', value=False) - rv = app.test_client().get('/') - assert b'Success!' in rv.data - - def test_add_template_global(self): - app = flask.Flask(__name__) - @app.template_global() - def get_stuff(): - return 42 - 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'](), 42 - with app.app_context(): - rv = flask.render_template_string('{{ get_stuff() }}') - assert rv == '42' - - def test_custom_template_loader(self): - class MyFlask(flask.Flask): - def create_global_jinja_loader(self): - from jinja2 import DictLoader - return DictLoader({'index.html': 'Hello Custom World!'}) - app = MyFlask(__name__) - @app.route('/') - def index(): - return flask.render_template('index.html') - c = app.test_client() - rv = c.get('/') - assert rv.data == b'Hello Custom World!' - - def test_iterable_loader(self): - app = flask.Flask(__name__) - @app.context_processor - def context_processor(): - return {'whiskey': 'Jameson'} - @app.route('/') - def index(): - return flask.render_template( - ['no_template.xml', # should skip this one - 'simple_template.html', # should render this - 'context_template.html'], - value=23) - - rv = app.test_client().get('/') - assert rv.data == b'

Jameson

' - - def test_templates_auto_reload(self): - app = flask.Flask(__name__) - assert app.config['TEMPLATES_AUTO_RELOAD'] - assert app.jinja_env.auto_reload - app = flask.Flask(__name__) - app.config['TEMPLATES_AUTO_RELOAD'] = False - assert not app.jinja_env.auto_reload - - def test_template_loader_debugging(self): - from blueprintapp import app - - called = [] - class _TestHandler(logging.Handler): - def handle(x, record): - called.append(True) - text = str(record.msg) - assert '1: trying loader of application "blueprintapp"' in text - assert ('2: trying loader of blueprint "admin" ' - '(blueprintapp.apps.admin)') in text - assert ('trying loader of blueprint "frontend" ' - '(blueprintapp.apps.frontend)') in text - assert 'Error: the template could not be found' in text - assert ('looked up from an endpoint that belongs to ' - 'the blueprint "frontend"') in text - assert 'See http://flask.pocoo.org/docs/blueprints/#templates' in text - - with app.test_client() as c: - try: - old_load_setting = app.config['EXPLAIN_TEMPLATE_LOADING'] - old_handlers = app.logger.handlers[:] - app.logger.handlers = [_TestHandler()] - app.config['EXPLAIN_TEMPLATE_LOADING'] = True - - try: - c.get('/missing') - except TemplateNotFound as e: - assert 'missing_template.html' in str(e) - else: - self.fail('Expected template not found exception.') - finally: - app.logger.handlers[:] = old_handlers - app.config['EXPLAIN_TEMPLATE_LOADING'] = old_load_setting - - assert len(called) == 1 - - -def suite(): - suite = unittest.TestSuite() - suite.addTest(unittest.makeSuite(TestTemplating)) - return suite +def test_context_processing(): + app = flask.Flask(__name__) + @app.context_processor + def context_processor(): + return {'injected_value': 42} + @app.route('/') + def index(): + return flask.render_template('context_template.html', value=23) + rv = app.test_client().get('/') + assert rv.data == b'

23|42' + +def test_original_win(): + app = flask.Flask(__name__) + @app.route('/') + def index(): + return flask.render_template_string('{{ config }}', config=42) + rv = app.test_client().get('/') + assert rv.data == b'42' + +def test_request_less_rendering(): + app = flask.Flask(__name__) + app.config['WORLD_NAME'] = 'Special World' + @app.context_processor + def context_processor(): + return dict(foo=42) + + with app.app_context(): + rv = flask.render_template_string('Hello {{ config.WORLD_NAME }} ' + '{{ foo }}') + assert rv == 'Hello Special World 42' + +def test_standard_context(): + app = flask.Flask(__name__) + app.secret_key = 'development key' + @app.route('/') + def index(): + flask.g.foo = 23 + flask.session['test'] = 'aha' + return flask.render_template_string(''' + {{ request.args.foo }} + {{ g.foo }} + {{ config.DEBUG }} + {{ session.test }} + ''') + rv = app.test_client().get('/?foo=42') + assert rv.data.split() == [b'42', b'23', b'False', b'aha'] + +def test_escaping(): + text = '

Hello World!' + app = flask.Flask(__name__) + @app.route('/') + def index(): + return flask.render_template('escaping_template.html', text=text, + html=flask.Markup(text)) + lines = app.test_client().get('/').data.splitlines() + assert lines == [ + b'<p>Hello World!', + b'

Hello World!', + b'

Hello World!', + b'

Hello World!', + b'<p>Hello World!', + b'

Hello World!' + ] + +def test_no_escaping(): + app = flask.Flask(__name__) + with app.test_request_context(): + assert flask.render_template_string( + '{{ foo }}', foo='') == '' + assert flask.render_template('mail.txt', foo='') == \ + ' Mail' + +def test_macros(): + app = flask.Flask(__name__) + with app.test_request_context(): + macro = flask.get_template_attribute('_macro.html', 'hello') + assert macro('World') == 'Hello World!' + +def test_template_filter(): + app = flask.Flask(__name__) + @app.template_filter() + def my_reverse(s): + return s[::-1] + 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']('abcd') == 'dcba' + +def test_add_template_filter(): + app = flask.Flask(__name__) + def my_reverse(s): + return s[::-1] + app.add_template_filter(my_reverse) + 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']('abcd') == 'dcba' + +def test_template_filter_with_name(): + app = flask.Flask(__name__) + @app.template_filter('strrev') + def my_reverse(s): + return s[::-1] + assert 'strrev' in app.jinja_env.filters.keys() + assert app.jinja_env.filters['strrev'] == my_reverse + assert app.jinja_env.filters['strrev']('abcd') == 'dcba' + +def test_add_template_filter_with_name(): + app = flask.Flask(__name__) + def my_reverse(s): + return s[::-1] + app.add_template_filter(my_reverse, 'strrev') + assert 'strrev' in app.jinja_env.filters.keys() + assert app.jinja_env.filters['strrev'] == my_reverse + assert app.jinja_env.filters['strrev']('abcd') == 'dcba' + +def test_template_filter_with_template(): + app = flask.Flask(__name__) + @app.template_filter() + def super_reverse(s): + return s[::-1] + @app.route('/') + def index(): + return flask.render_template('template_filter.html', value='abcd') + rv = app.test_client().get('/') + assert rv.data == b'dcba' + +def test_add_template_filter_with_template(): + app = flask.Flask(__name__) + def super_reverse(s): + return s[::-1] + app.add_template_filter(super_reverse) + @app.route('/') + def index(): + return flask.render_template('template_filter.html', value='abcd') + rv = app.test_client().get('/') + assert rv.data == b'dcba' + +def test_template_filter_with_name_and_template(): + app = flask.Flask(__name__) + @app.template_filter('super_reverse') + def my_reverse(s): + return s[::-1] + @app.route('/') + def index(): + return flask.render_template('template_filter.html', value='abcd') + rv = app.test_client().get('/') + assert rv.data == b'dcba' + +def test_add_template_filter_with_name_and_template(): + app = flask.Flask(__name__) + def my_reverse(s): + return s[::-1] + app.add_template_filter(my_reverse, 'super_reverse') + @app.route('/') + def index(): + return flask.render_template('template_filter.html', value='abcd') + rv = app.test_client().get('/') + assert rv.data == b'dcba' + +def test_template_test(): + app = flask.Flask(__name__) + @app.template_test() + def boolean(value): + return isinstance(value, bool) + assert 'boolean' in app.jinja_env.tests.keys() + assert app.jinja_env.tests['boolean'] == boolean + assert app.jinja_env.tests['boolean'](False) + +def test_add_template_test(): + app = flask.Flask(__name__) + def boolean(value): + return isinstance(value, bool) + app.add_template_test(boolean) + assert 'boolean' in app.jinja_env.tests.keys() + assert app.jinja_env.tests['boolean'] == boolean + assert app.jinja_env.tests['boolean'](False) + +def test_template_test_with_name(): + app = flask.Flask(__name__) + @app.template_test('boolean') + def is_boolean(value): + return isinstance(value, bool) + assert 'boolean' in app.jinja_env.tests.keys() + assert app.jinja_env.tests['boolean'] == is_boolean + assert app.jinja_env.tests['boolean'](False) + +def test_add_template_test_with_name(): + app = flask.Flask(__name__) + def is_boolean(value): + return isinstance(value, bool) + app.add_template_test(is_boolean, 'boolean') + assert 'boolean' in app.jinja_env.tests.keys() + assert app.jinja_env.tests['boolean'] == is_boolean + assert app.jinja_env.tests['boolean'](False) + +def test_template_test_with_template(): + app = flask.Flask(__name__) + @app.template_test() + def boolean(value): + return isinstance(value, bool) + @app.route('/') + def index(): + return flask.render_template('template_test.html', value=False) + rv = app.test_client().get('/') + assert b'Success!' in rv.data + +def test_add_template_test_with_template(): + app = flask.Flask(__name__) + def boolean(value): + return isinstance(value, bool) + app.add_template_test(boolean) + @app.route('/') + def index(): + return flask.render_template('template_test.html', value=False) + rv = app.test_client().get('/') + assert b'Success!' in rv.data + +def test_template_test_with_name_and_template(): + app = flask.Flask(__name__) + @app.template_test('boolean') + def is_boolean(value): + return isinstance(value, bool) + @app.route('/') + def index(): + return flask.render_template('template_test.html', value=False) + rv = app.test_client().get('/') + assert b'Success!' in rv.data + +def test_add_template_test_with_name_and_template(): + app = flask.Flask(__name__) + def is_boolean(value): + return isinstance(value, bool) + app.add_template_test(is_boolean, 'boolean') + @app.route('/') + def index(): + return flask.render_template('template_test.html', value=False) + rv = app.test_client().get('/') + assert b'Success!' in rv.data + +def test_add_template_global(): + app = flask.Flask(__name__) + @app.template_global() + def get_stuff(): + return 42 + 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'](), 42 + with app.app_context(): + rv = flask.render_template_string('{{ get_stuff() }}') + assert rv == '42' + +def test_custom_template_loader(): + class MyFlask(flask.Flask): + def create_global_jinja_loader(self): + from jinja2 import DictLoader + return DictLoader({'index.html': 'Hello Custom World!'}) + app = MyFlask(__name__) + @app.route('/') + def index(): + return flask.render_template('index.html') + c = app.test_client() + rv = c.get('/') + assert rv.data == b'Hello Custom World!' + +def test_iterable_loader(): + app = flask.Flask(__name__) + @app.context_processor + def context_processor(): + return {'whiskey': 'Jameson'} + @app.route('/') + def index(): + return flask.render_template( + ['no_template.xml', # should skip this one + 'simple_template.html', # should render this + 'context_template.html'], + value=23) + + rv = app.test_client().get('/') + assert rv.data == b'

Jameson

' + +def test_templates_auto_reload(): + app = flask.Flask(__name__) + assert app.config['TEMPLATES_AUTO_RELOAD'] + assert app.jinja_env.auto_reload + app = flask.Flask(__name__) + app.config['TEMPLATES_AUTO_RELOAD'] = False + assert not app.jinja_env.auto_reload + +def test_template_loader_debugging(): + from blueprintapp import app + + called = [] + class _TestHandler(logging.Handler): + def handle(x, record): + called.append(True) + text = str(record.msg) + assert '1: trying loader of application "blueprintapp"' in text + assert ('2: trying loader of blueprint "admin" ' + '(blueprintapp.apps.admin)') in text + assert ('trying loader of blueprint "frontend" ' + '(blueprintapp.apps.frontend)') in text + assert 'Error: the template could not be found' in text + assert ('looked up from an endpoint that belongs to ' + 'the blueprint "frontend"') in text + assert 'See http://flask.pocoo.org/docs/blueprints/#templates' in text + + with app.test_client() as c: + try: + old_load_setting = app.config['EXPLAIN_TEMPLATE_LOADING'] + old_handlers = app.logger.handlers[:] + app.logger.handlers = [_TestHandler()] + app.config['EXPLAIN_TEMPLATE_LOADING'] = True + + with pytest.raises(TemplateNotFound) as excinfo: + c.get('/missing') + + assert 'missing_template.html' in str(excinfo.value) + finally: + app.logger.handlers[:] = old_handlers + app.config['EXPLAIN_TEMPLATE_LOADING'] = old_load_setting + + assert len(called) == 1