Skip to content

Commit a19d244

Browse files
TST: refactor to use sphinx test fixtures (#308)
1 parent d2211c3 commit a19d244

File tree

2 files changed

+87
-68
lines changed

2 files changed

+87
-68
lines changed

tests/conftest.py

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pytest_plugins = "sphinx.testing.fixtures"

tests/test_build.py

+86-68
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,69 @@
1-
from bs4 import BeautifulSoup
1+
import os
22
from pathlib import Path
3-
from subprocess import run
4-
from shutil import copytree, rmtree
3+
from shutil import copytree
4+
5+
from bs4 import BeautifulSoup
6+
7+
from sphinx.testing.util import SphinxTestApp
8+
from sphinx.testing.path import path as sphinx_path
9+
510
import pytest
611

712

8-
path_tests = Path(__file__).parent.resolve()
9-
path_base = path_tests.joinpath("sites", "base")
13+
path_tests = Path(__file__).parent
14+
1015

16+
class SphinxBuild:
17+
def __init__(self, app: SphinxTestApp, src: Path):
18+
self.app = app
19+
self.src = src
1120

12-
@pytest.fixture(scope="session")
13-
def sphinx_build(tmpdir_factory):
14-
class SphinxBuild:
15-
path_tmp = Path(tmpdir_factory.mktemp("build"))
16-
path_docs = path_tmp.joinpath("testdocs")
17-
path_build = path_docs.joinpath("_build")
18-
path_html = path_build.joinpath("html")
19-
path_pg_index = path_html.joinpath("index.html")
20-
cmd_base = ["sphinx-build", ".", "_build/html", "-a", "-W"]
21+
def build(self):
22+
self.app.build()
23+
assert self.warnings == "", self.status
24+
return self
2125

22-
def copy(self, path=None):
23-
"""Copy the specified book to our tests folder for building."""
24-
if path is None:
25-
path = path_base
26-
if not self.path_docs.exists():
27-
copytree(path, self.path_docs)
26+
@property
27+
def status(self):
28+
return self.app._status.getvalue()
2829

29-
def build(self, cmd=None):
30-
"""Build the test book"""
31-
cmd = [] if cmd is None else cmd
32-
run(self.cmd_base + cmd, cwd=self.path_docs, check=True)
30+
@property
31+
def warnings(self):
32+
return self.app._warning.getvalue()
3333

34-
def get(self, pagename):
35-
path_page = self.path_html.joinpath(pagename)
36-
if not path_page.exists():
37-
raise ValueError(f"{path_page} does not exist")
38-
return BeautifulSoup(path_page.read_text(), "html.parser")
34+
@property
35+
def outdir(self):
36+
return Path(self.app.outdir)
3937

40-
def clean(self):
41-
"""Clean the _build folder so files don't clash with new tests."""
42-
rmtree(self.path_build)
38+
def html_tree(self, *path):
39+
path_page = self.outdir.joinpath(*path)
40+
if not path_page.exists():
41+
raise ValueError(f"{path_page} does not exist")
42+
return BeautifulSoup(path_page.read_text("utf8"), "html.parser")
4343

44-
return SphinxBuild()
4544

45+
@pytest.fixture()
46+
def sphinx_build_factory(make_app, tmp_path):
47+
def _func(src_folder, **kwargs):
48+
copytree(path_tests / "sites" / src_folder, tmp_path / src_folder)
49+
app = make_app(
50+
srcdir=sphinx_path(os.path.abspath((tmp_path / src_folder))), **kwargs
51+
)
52+
return SphinxBuild(app, tmp_path / src_folder)
4653

47-
def test_build_book(file_regression, sphinx_build):
48-
"""Test building the base book template and config."""
49-
sphinx_build.copy()
54+
yield _func
55+
56+
57+
def test_build_html(sphinx_build_factory, file_regression):
58+
"""Test building the base html template and config."""
59+
sphinx_build = sphinx_build_factory("base") # type: SphinxBuild
5060

5161
# Basic build with defaults
5262
sphinx_build.build()
53-
index_html = sphinx_build.get("index.html")
54-
subpage_html = sphinx_build.get("section1/index.html")
63+
assert (sphinx_build.outdir / "index.html").exists(), sphinx_build.outdir.glob("*")
64+
65+
index_html = sphinx_build.html_tree("index.html")
66+
subpage_html = sphinx_build.html_tree("section1/index.html")
5567

5668
# Navbar structure
5769
navbar = index_html.select("div#navbar-menu")[0]
@@ -67,63 +79,69 @@ def test_build_book(file_regression, sphinx_build):
6779
sidebar.prettify(), basename="sidebar_subpage", extension=".html"
6880
)
6981

70-
sphinx_build.clean()
71-
72-
73-
def test_toc_visibility(file_regression, sphinx_build):
74-
sphinx_build.copy()
7582

83+
def test_toc_visibility(sphinx_build_factory):
7684
# Test that setting TOC level visibility works as expected
77-
sphinx_build.build(["-D", "html_theme_options.show_toc_level=2"])
78-
index_html = sphinx_build.get("index.html")
85+
confoverrides = {
86+
"html_theme_options.show_toc_level": 2,
87+
}
88+
sphinx_build = sphinx_build_factory("base", confoverrides=confoverrides).build()
89+
index_html = sphinx_build.html_tree("index.html")
7990

8091
# The 3rd level headers should be visible, but not the fourth-level
8192
assert "visible" in index_html.select(".toc-h2 ul")[0].attrs["class"]
8293
assert "visible" not in index_html.select(".toc-h3 ul")[0].attrs["class"]
8394

8495

85-
def test_logo_name(file_regression, sphinx_build):
96+
def test_logo(sphinx_build_factory):
8697
"""Test that the logo is shown by default, project title if no logo."""
87-
sphinx_build.copy()
98+
sphinx_build = sphinx_build_factory("base").build()
8899

89100
# By default logo is shown
90-
sphinx_build.build()
91-
index_html = sphinx_build.get("index.html")
101+
index_html = sphinx_build.html_tree("index.html")
92102
assert index_html.select(".navbar-brand img")
93103
assert not index_html.select(".navbar-brand")[0].text.strip()
94-
sphinx_build.clean()
95104

96-
# Test that setting TOC level visibility works as expected
97-
sphinx_build.build(["-D", "html_logo="])
98-
index_html = sphinx_build.get("index.html")
105+
106+
def test_logo_name(sphinx_build_factory):
107+
"""Test that the logo is shown by default, project title if no logo."""
108+
confoverrides = {"html_logo": ""}
109+
sphinx_build = sphinx_build_factory("base", confoverrides=confoverrides).build()
110+
111+
# if no logo is specified, use project title instead
112+
index_html = sphinx_build.html_tree("index.html")
99113
assert "PyData Tests" in index_html.select(".navbar-brand")[0].text.strip()
100114

101115

102-
def test_sidebar_visible(sphinx_build):
116+
def test_sidebar_default(sphinx_build_factory):
103117
"""The sidebar is shrunk when no sidebars specified in html_sidebars."""
104-
sphinx_build.copy()
118+
sphinx_build = sphinx_build_factory("base").build()
105119

106-
sphinx_build.build()
107-
index_html = sphinx_build.get("page1.html")
120+
index_html = sphinx_build.html_tree("page1.html")
108121
assert "col-md-3" in index_html.select(".bd-sidebar")[0].attrs["class"]
109122

110-
sphinx_build.build(["-D", "html_sidebars.page1="])
111-
index_html = sphinx_build.get("page1.html")
123+
124+
def test_sidebar_disabled(sphinx_build_factory):
125+
"""The sidebar is shrunk when no sidebars specified in html_sidebars."""
126+
confoverrides = {"html_sidebars.page1": ""}
127+
sphinx_build = sphinx_build_factory("base", confoverrides=confoverrides).build()
128+
index_html = sphinx_build.html_tree("page1.html")
112129
assert "col-md-1" in index_html.select(".bd-sidebar")[0].attrs["class"]
113-
sphinx_build.clean()
114130

115131

116-
def test_navbar_align(sphinx_build):
132+
def test_navbar_align_default(sphinx_build_factory):
117133
"""The navbar items align with the proper part of the page."""
118-
sphinx_build.copy()
119-
120-
sphinx_build.build()
121-
index_html = sphinx_build.get("index.html")
134+
sphinx_build = sphinx_build_factory("base").build()
135+
index_html = sphinx_build.html_tree("index.html")
122136
assert "col-lg-9" in index_html.select("div#navbar-menu")[0].attrs["class"]
123137

138+
139+
def test_navbar_align_right(sphinx_build_factory):
140+
"""The navbar items align with the proper part of the page."""
141+
confoverrides = {"html_theme_options.navbar_align": "right"}
142+
sphinx_build = sphinx_build_factory("base", confoverrides=confoverrides).build()
143+
124144
# Both the column alignment and the margin should be changed
125-
sphinx_build.build(["-D", "html_theme_options.navbar_align=right"])
126-
index_html = sphinx_build.get("index.html")
145+
index_html = sphinx_build.html_tree("index.html")
127146
assert "col-lg-9" not in index_html.select("div#navbar-menu")[0].attrs["class"]
128147
assert "ml-auto" in index_html.select("ul#navbar-main-elements")[0].attrs["class"]
129-
sphinx_build.clean()

0 commit comments

Comments
 (0)