-
Notifications
You must be signed in to change notification settings - Fork 229
Expand file tree
/
Copy pathconftest.py
More file actions
137 lines (108 loc) · 4.11 KB
/
conftest.py
File metadata and controls
137 lines (108 loc) · 4.11 KB
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
130
131
132
133
134
135
136
137
"""
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 docutils import nodes
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 = pathlib.Path(str(app.srcdir), "_build", buildername, filename)
if not outpath.exists():
raise OSError(f"no output file exists: {outpath}")
content = outpath.read_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)
# something changed in sphinx 8 (or new docutils) to introduce this, although I couldn't find the actual commit,
# but in any case, it's not important for the regression test
for clearer_div in doc_div.findAll("div", {"class": "clearer"}):
clearer_div.decompose()
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, normalize_doctree_xml):
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
doctree = doctree.deepcopy()
# remove attrs added in sphinx 7.1
doctree.attributes.pop("translation_progress", None)
for node in findall(doctree)(nodes.Element):
node.attributes.pop("translated", None)
if regress:
text = normalize_doctree_xml(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