summaryrefslogtreecommitdiff
path: root/tests/conftest.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/conftest.py')
-rw-r--r--tests/conftest.py140
1 files changed, 131 insertions, 9 deletions
diff --git a/tests/conftest.py b/tests/conftest.py
index c83c3f94b..6fab88b12 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -1,19 +1,25 @@
# -*- coding: utf-8 -*-
+from __future__ import print_function
+
import sys
import subprocess
+from collections import namedtuple
import pytest
-from six import StringIO
+from six import StringIO, string_types
-from util import SphinxTestApp, path
+import util
@pytest.fixture
-def app_params(request):
+def app_params(request, test_params, shared_result):
"""
parameters that is specified by 'pytest.mark.sphinx' for
sphinx.application.Sphinx initialization
"""
+
+ # ##### process pytest.mark.sphinx
+
markers = request.node.get_marker("sphinx")
pargs = {}
kwargs = {}
@@ -26,17 +32,99 @@ def app_params(request):
kwargs.update(info.kwargs)
args = [pargs[i] for i in sorted(pargs.keys())]
- return args, kwargs
+
+ # ##### process pytest.mark.test_params
+
+ if test_params['shared_result']:
+ if 'srcdir' in kwargs:
+ raise pytest.Exception('You can not spcify shared_result and '
+ 'srcdir in same time.')
+ kwargs['srcdir'] = test_params['shared_result']
+ restore = shared_result.restore(test_params['shared_result'])
+ kwargs.update(restore)
+
+ # ##### prepare Application params
+
+ if 'srcdir' in kwargs:
+ srcdir = util.tempdir / kwargs['srcdir']
+ else:
+ srcdir = util.tempdir / kwargs.get('testroot', 'root')
+ kwargs['srcdir'] = srcdir
+
+ if kwargs.get('testroot') is None:
+ testroot_path = util.rootdir / 'root'
+ else:
+ testroot_path = util.rootdir / 'roots' / ('test-' + kwargs['testroot'])
+
+ if not srcdir.exists():
+ testroot_path.copytree(srcdir)
+
+ return namedtuple('app_params', 'args,kwargs')(args, kwargs)
+
+
+@pytest.fixture
+def test_params(request):
+ """
+ test parameters that is specified by 'pytest.mark.test_params'
+
+ :param Union[str] shared_result:
+ If the value is provided, app._status and app._warning objects will be
+ shared in the parametrized test functions and/or test functions that
+ have same 'shared_result' value.
+ **NOTE**: You can not specify shared_result and srcdir in same time.
+ """
+ env = request.node.get_marker('test_params')
+ kwargs = env.kwargs if env else {}
+ result = {
+ 'shared_result': None,
+ }
+ result.update(kwargs)
+
+ if (result['shared_result'] and
+ not isinstance(result['shared_result'], string_types)):
+ raise pytest.Exception('You can only provide a string type of value '
+ 'for "shared_result" ')
+ return result
+
+
+class SphinxTestAppWrapperForSkipBuilding(object):
+ """
+ This class is a wrapper for SphinxTestApp to speed up the test by skipping
+ `app.build` process if it is already built and there is even one output
+ file.
+ """
+
+ def __init__(self, app_):
+ self.app = app_
+
+ def __getattr__(self, name):
+ return getattr(self.app, name)
+
+ def build(self, *args, **kw):
+ if not self.app.outdir.listdir():
+ # if listdir is empty, do build.
+ self.app.build(*args, **kw)
+ # otherwise, we can use built cache
@pytest.fixture(scope='function')
-def app(app_params, make_app):
+def app(test_params, app_params, make_app, shared_result):
"""
provides sphinx.application.Sphinx object
"""
args, kwargs = app_params
app_ = make_app(*args, **kwargs)
- return app_
+ yield app_
+
+ print('# testroot:', kwargs.get('testroot', 'root'))
+ print('# builder:', app_.buildername)
+ print('# srcdir:', app_.srcdir)
+ print('# outdir:', app_.outdir)
+ print('# status:', '\n' + app_._status.getvalue())
+ print('# warning:', '\n' + app_._warning.getvalue())
+
+ if test_params['shared_result']:
+ shared_result.store(test_params['shared_result'], app_)
@pytest.fixture(scope='function')
@@ -56,7 +144,7 @@ def warning(app):
@pytest.fixture()
-def make_app():
+def make_app(test_params):
"""
provides make_app function to initialize SphinxTestApp instance.
if you want to initialize 'app' in your test function. please use this
@@ -69,8 +157,10 @@ def make_app():
status, warning = StringIO(), StringIO()
kwargs.setdefault('status', status)
kwargs.setdefault('warning', warning)
- app_ = SphinxTestApp(*args, **kwargs)
+ app_ = util.SphinxTestApp(*args, **kwargs)
apps.append(app_)
+ if test_params['shared_result']:
+ app_ = SphinxTestAppWrapperForSkipBuilding(app_)
return app_
yield make
@@ -79,6 +169,38 @@ def make_app():
app_.cleanup()
+class SharedResult(object):
+ cache = {}
+
+ def store(self, key, app_):
+ if key in self.cache:
+ return
+ data = {
+ 'status': app_._status.getvalue(),
+ 'warning': app_._warning.getvalue(),
+ }
+ self.cache[key] = data
+
+ def restore(self, key):
+ if key not in self.cache:
+ return {}
+ data = self.cache[key]
+ return {
+ 'status': StringIO(data['status']),
+ 'warning': StringIO(data['warning']),
+ }
+
+
+@pytest.fixture
+def shared_result():
+ return SharedResult()
+
+
+@pytest.fixture(scope='module', autouse=True)
+def _shared_result_cache():
+ SharedResult.cache.clear()
+
+
@pytest.fixture
def if_graphviz_found(app):
"""
@@ -105,4 +227,4 @@ def tempdir(tmpdir):
temporary directory that wrapped with `path` class.
this fixture is for compat with old test implementation.
"""
- return path(tmpdir)
+ return util.path(tmpdir)