flask/tests/conftest.py

169 lines
4.1 KiB
Python
Raw Normal View History

2014-09-02 01:06:32 +08:00
# -*- coding: utf-8 -*-
"""
tests.conftest
~~~~~~~~~~~~~~
2015-01-02 10:35:00 +08:00
:copyright: (c) 2015 by the Flask Team, see AUTHORS for more details.
2014-09-02 01:06:32 +08:00
:license: BSD, see LICENSE for more details.
"""
2014-09-04 02:50:54 +08:00
import flask
2016-06-03 20:19:25 +08:00
import gc
2014-09-04 02:50:54 +08:00
import os
import sys
2014-09-02 01:06:32 +08:00
import pkgutil
import pytest
import textwrap
from flask import Flask as _Flask
class Flask(_Flask):
testing = True
secret_key = 'test key'
@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()
2014-09-02 01:06:32 +08:00
2014-09-04 20:37:48 +08:00
@pytest.fixture
def test_apps(monkeypatch):
2014-09-04 02:50:54 +08:00
monkeypatch.syspath_prepend(
os.path.abspath(os.path.join(
os.path.dirname(__file__), 'test_apps'))
)
2014-09-04 02:50:54 +08:00
@pytest.fixture(autouse=True)
def leak_detector():
yield
# 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 == []
2014-09-04 02:50:54 +08:00
2014-09-02 01:06:32 +08:00
@pytest.fixture(params=(True, False))
def limit_loader(request, monkeypatch):
"""Patch pkgutil.get_loader to give loader without get_filename or archive.
This provides for tests where a system has custom loaders, e.g. Google App
Engine's HardenedModulesHook, which have neither the `get_filename` method
nor the `archive` attribute.
This fixture will run the testcase twice, once with and once without the
limitation/mock.
"""
if not request.param:
return
class LimitedLoader(object):
def __init__(self, loader):
self.loader = loader
def __getattr__(self, name):
if name in ('archive', 'get_filename'):
msg = 'Mocking a loader which does not have `%s.`' % name
raise AttributeError(msg)
return getattr(self.loader, name)
old_get_loader = pkgutil.get_loader
def get_loader(*args, **kwargs):
return LimitedLoader(old_get_loader(*args, **kwargs))
2014-09-02 01:06:32 +08:00
monkeypatch.setattr(pkgutil, 'get_loader', get_loader)
@pytest.fixture
2014-09-04 21:22:57 +08:00
def modules_tmpdir(tmpdir, monkeypatch):
"""A tmpdir added to sys.path."""
2014-09-04 21:22:57 +08:00
rv = tmpdir.mkdir('modules_tmpdir')
2014-09-02 01:06:32 +08:00
monkeypatch.syspath_prepend(str(rv))
return rv
@pytest.fixture
2014-09-04 21:22:57 +08:00
def modules_tmpdir_prefix(modules_tmpdir, monkeypatch):
monkeypatch.setattr(sys, 'prefix', str(modules_tmpdir))
return modules_tmpdir
2014-09-02 01:06:32 +08:00
@pytest.fixture
2014-09-04 21:22:57 +08:00
def site_packages(modules_tmpdir, monkeypatch):
"""Create a fake site-packages."""
2014-09-04 21:22:57 +08:00
rv = modules_tmpdir \
.mkdir('lib') \
.mkdir('python{x[0]}.{x[1]}'.format(x=sys.version_info)) \
2014-09-02 01:06:32 +08:00
.mkdir('site-packages')
monkeypatch.syspath_prepend(str(rv))
return rv
@pytest.fixture
2014-09-04 21:22:57 +08:00
def install_egg(modules_tmpdir, monkeypatch):
"""Generate egg from package name inside base and put the egg into
sys.path."""
2014-09-04 21:22:57 +08:00
def inner(name, base=modules_tmpdir):
2014-09-02 01:06:32 +08:00
if not isinstance(name, str):
raise ValueError(name)
base.join(name).ensure_dir()
base.join(name).join('__init__.py').ensure()
egg_setup = base.join('setup.py')
egg_setup.write(textwrap.dedent("""
from setuptools import setup
setup(name='{0}',
version='1.0',
packages=['site_egg'],
zip_safe=True)
""".format(name)))
import subprocess
subprocess.check_call(
[sys.executable, 'setup.py', 'bdist_egg'],
2014-09-04 21:22:57 +08:00
cwd=str(modules_tmpdir)
2014-09-02 01:06:32 +08:00
)
2014-09-04 21:22:57 +08:00
egg_path, = modules_tmpdir.join('dist/').listdir()
2014-09-02 01:06:32 +08:00
monkeypatch.syspath_prepend(str(egg_path))
return egg_path
2014-09-02 01:06:32 +08:00
return inner
@pytest.fixture
def purge_module(request):
def inner(name):
request.addfinalizer(lambda: sys.modules.pop(name, None))
2014-09-02 01:06:32 +08:00
return inner
2014-09-06 08:20:00 +08:00
@pytest.fixture(autouse=True)
def catch_deprecation_warnings(recwarn):
yield
2016-06-03 20:19:25 +08:00
gc.collect()
assert not recwarn.list, '\n'.join(str(w.message) for w in recwarn.list)