You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

150 lines
3.9 KiB

# -*- coding: utf-8 -*-
"""
tests
~~~~~~~~~~~~~~~
Tests Flask itself. The majority of Flask is already tested
as part of Werkzeug.
:copyright: (c) 2014 by Armin Ronacher.
:license: BSD, see LICENSE for more details.
"""
from __future__ import print_function
import pytest
import os
import sys
import flask
import warnings
from functools import update_wrapper
from contextlib import contextmanager
from flask._compat import StringIO
def add_to_path(path):
"""Adds an entry to sys.path if it's not already there. This does
not append it but moves it to the front so that we can be sure it
is loaded.
"""
if not os.path.isdir(path):
raise RuntimeError('Tried to add nonexisting path')
def _samefile(x, y):
if x == y:
return True
try:
return os.path.samefile(x, y)
except (IOError, OSError, AttributeError):
# Windows has no samefile
return False
sys.path[:] = [x for x in sys.path if not _samefile(path, x)]
sys.path.insert(0, path)
@contextmanager
def catch_warnings():
"""Catch warnings in a with block in a list"""
# make sure deprecation warnings are active in tests
warnings.simplefilter('default', category=DeprecationWarning)
filters = warnings.filters
warnings.filters = filters[:]
old_showwarning = warnings.showwarning
log = []
def showwarning(message, category, filename, lineno, file=None, line=None):
log.append(locals())
try:
warnings.showwarning = showwarning
yield log
finally:
warnings.filters = filters
warnings.showwarning = old_showwarning
@contextmanager
def catch_stderr():
"""Catch stderr in a StringIO"""
old_stderr = sys.stderr
sys.stderr = rv = StringIO()
try:
yield rv
finally:
sys.stderr = old_stderr
def emits_module_deprecation_warning(f):
def new_f(self, *args, **kwargs):
with catch_warnings() as log:
f(self, *args, **kwargs)
self.assert_true(log, 'expected deprecation warning')
for entry in log:
self.assert_in('Modules are deprecated', str(entry['message']))
return update_wrapper(new_f, f)
class TestFlask(object):
"""Baseclass for all the tests that Flask uses. Use these methods
for testing instead of the camelcased ones in the baseclass for
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())
self.assert_equal(leaks, [])
def setup_method(self, method):
self.setup()
def teardown_method(self, method):
self.teardown()
def setup(self):
pass
def teardown(self):
pass
def assert_equal(self, x, y):
assert x == y
def assert_raises(self, exc_type, callable=None, *args, **kwargs):
if callable:
return pytest.raises(exc_type, callable, *args, **kwargs)
else:
return pytest.raises(exc_type)
def assert_true(self, x, msg=None):
assert x
assert_ = assert_true
def assert_false(self, x, msg=None):
assert not x
def assert_in(self, x, y):
assert x in y
def assert_not_in(self, x, y):
assert x not in y
def assert_isinstance(self, obj, cls):
assert isinstance(obj, cls)
def fail(self, msg):
raise AssertionError(msg)