-
Notifications
You must be signed in to change notification settings - Fork 189
/
conftest.py
129 lines (103 loc) · 3.67 KB
/
conftest.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
"""
Uses sphinx's pytest fixture to run builds
usage:
.. code-block:: python
@pytest.mark.sphinx(
buildername='html',
srcdir='path/to/source')
def test_basic(app, status, warning, get_sphinx_app_output):
app.build()
assert 'build succeeded' in status.getvalue() # Build succeeded
warnings = warning.getvalue().strip()
assert warnings == ""
output = get_sphinx_app_output(app, buildername='html')
parameters available to parse to ``@pytest.mark.sphinx``:
- buildername='html'
- srcdir=None
- testroot='root' (only used if srcdir not set)
- freshenv=False
- confoverrides=None
- status=None
- warning=None
- tags=None
- docutilsconf=None
"""
import os
import pathlib
import shutil
import pytest
from bs4 import BeautifulSoup
from sphinx.testing.path import path
from myst_parser._compat import findall
SOURCE_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "sourcedirs"))
@pytest.fixture(scope="session", autouse=True)
def remove_sphinx_builds():
"""remove all build directories from the test folder"""
yield
srcdirs = pathlib.Path(SOURCE_DIR)
for entry in srcdirs.iterdir(): # type: pathlib.Path
if entry.is_dir() and entry.joinpath("_build").exists():
shutil.rmtree(str(entry.joinpath("_build")))
@pytest.fixture
def get_sphinx_app_output(file_regression):
def read(
app,
buildername="html",
filename="index.html",
encoding="utf-8",
regress_html=False,
regress_ext=".html",
replace=None,
):
outpath = path(os.path.join(str(app.srcdir), "_build", buildername, filename))
if not outpath.exists():
raise OSError(f"no output file exists: {outpath}")
try:
# introduced in sphinx 3.0
content = outpath.read_text(encoding=encoding)
except AttributeError:
content = outpath.text(encoding=encoding)
if regress_html:
# only regress the inner body, since other sections are non-deterministic
soup = BeautifulSoup(content, "html.parser")
doc_div = soup.findAll("div", {"class": "documentwrapper"})[0]
# pygments 2.11.0 introduces a whitespace tag
for pygment_whitespace in doc_div.select("pre > span.w"):
pygment_whitespace.replace_with(pygment_whitespace.text)
text = doc_div.prettify()
for find, rep in (replace or {}).items():
text = text.replace(find, rep)
file_regression.check(text, extension=regress_ext, encoding="utf8")
return content
return read
@pytest.fixture
def get_sphinx_app_doctree(file_regression):
def read(
app,
docname="index",
resolve=False,
regress=False,
replace=None,
rstrip_lines=False,
regress_ext=".xml",
):
if resolve:
doctree = app.env.get_and_resolve_doctree(docname, app.builder)
extension = f".resolved{regress_ext}"
else:
doctree = app.env.get_doctree(docname)
extension = regress_ext
# convert absolute filenames
for node in findall(doctree)(
lambda n: "source" in n and not isinstance(n, str)
):
node["source"] = pathlib.Path(node["source"]).name
if regress:
text = doctree.pformat() # type: str
for find, rep in (replace or {}).items():
text = text.replace(find, rep)
if rstrip_lines:
text = "\n".join([li.rstrip() for li in text.splitlines()])
file_regression.check(text, extension=extension)
return doctree
return read