1
- from bs4 import BeautifulSoup
1
+ import os
2
2
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
+
5
10
import pytest
6
11
7
12
8
- path_tests = Path (__file__ ).parent . resolve ()
9
- path_base = path_tests . joinpath ( "sites" , "base" )
13
+ path_tests = Path (__file__ ).parent
14
+
10
15
16
+ class SphinxBuild :
17
+ def __init__ (self , app : SphinxTestApp , src : Path ):
18
+ self .app = app
19
+ self .src = src
11
20
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
21
25
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 ()
28
29
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 ()
33
33
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 )
39
37
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" )
43
43
44
- return SphinxBuild ()
45
44
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 )
46
53
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
50
60
51
61
# Basic build with defaults
52
62
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" )
55
67
56
68
# Navbar structure
57
69
navbar = index_html .select ("div#navbar-menu" )[0 ]
@@ -67,63 +79,69 @@ def test_build_book(file_regression, sphinx_build):
67
79
sidebar .prettify (), basename = "sidebar_subpage" , extension = ".html"
68
80
)
69
81
70
- sphinx_build .clean ()
71
-
72
-
73
- def test_toc_visibility (file_regression , sphinx_build ):
74
- sphinx_build .copy ()
75
82
83
+ def test_toc_visibility (sphinx_build_factory ):
76
84
# 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" )
79
90
80
91
# The 3rd level headers should be visible, but not the fourth-level
81
92
assert "visible" in index_html .select (".toc-h2 ul" )[0 ].attrs ["class" ]
82
93
assert "visible" not in index_html .select (".toc-h3 ul" )[0 ].attrs ["class" ]
83
94
84
95
85
- def test_logo_name ( file_regression , sphinx_build ):
96
+ def test_logo ( sphinx_build_factory ):
86
97
"""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 ()
88
99
89
100
# 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" )
92
102
assert index_html .select (".navbar-brand img" )
93
103
assert not index_html .select (".navbar-brand" )[0 ].text .strip ()
94
- sphinx_build .clean ()
95
104
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" )
99
113
assert "PyData Tests" in index_html .select (".navbar-brand" )[0 ].text .strip ()
100
114
101
115
102
- def test_sidebar_visible ( sphinx_build ):
116
+ def test_sidebar_default ( sphinx_build_factory ):
103
117
"""The sidebar is shrunk when no sidebars specified in html_sidebars."""
104
- sphinx_build . copy ()
118
+ sphinx_build = sphinx_build_factory ( "base" ). build ()
105
119
106
- sphinx_build .build ()
107
- index_html = sphinx_build .get ("page1.html" )
120
+ index_html = sphinx_build .html_tree ("page1.html" )
108
121
assert "col-md-3" in index_html .select (".bd-sidebar" )[0 ].attrs ["class" ]
109
122
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" )
112
129
assert "col-md-1" in index_html .select (".bd-sidebar" )[0 ].attrs ["class" ]
113
- sphinx_build .clean ()
114
130
115
131
116
- def test_navbar_align ( sphinx_build ):
132
+ def test_navbar_align_default ( sphinx_build_factory ):
117
133
"""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" )
122
136
assert "col-lg-9" in index_html .select ("div#navbar-menu" )[0 ].attrs ["class" ]
123
137
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
+
124
144
# 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" )
127
146
assert "col-lg-9" not in index_html .select ("div#navbar-menu" )[0 ].attrs ["class" ]
128
147
assert "ml-auto" in index_html .select ("ul#navbar-main-elements" )[0 ].attrs ["class" ]
129
- sphinx_build .clean ()
0 commit comments