diff --git a/.ruff.toml b/.ruff.toml index ba7856b41..c99033d0e 100644 --- a/.ruff.toml +++ b/.ruff.toml @@ -465,7 +465,6 @@ exclude = [ "tests/test_quickstart.py", "tests/test_roles.py", "tests/test_search.py", - "tests/test_theming/**/*", "tests/test_toctree.py", "tests/test_transforms/**/*", "tests/test_util/**/*", diff --git a/pyproject.toml b/pyproject.toml index 86f805b7b..3327667e3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -92,6 +92,7 @@ lint = [ test = [ "pytest>=6.0", "html5lib", + "defusedxml>=0.7.1", # for secure XML/HTML parsing "cython>=3.0", "setuptools>=67.0", # for Cython compilation "filelock", diff --git a/sphinx/themes/basic/search.html b/sphinx/themes/basic/search.html index d10036a2d..8bad82a51 100644 --- a/sphinx/themes/basic/search.html +++ b/sphinx/themes/basic/search.html @@ -15,7 +15,7 @@ {%- endblock %} {% block extrahead %} - + {{ super() }} {% endblock %} diff --git a/sphinx/themes/bizstyle/layout.html b/sphinx/themes/bizstyle/layout.html index 36f6fd3bd..226c7878d 100644 --- a/sphinx/themes/bizstyle/layout.html +++ b/sphinx/themes/bizstyle/layout.html @@ -14,11 +14,6 @@ {%- endblock %} -{# doctype override #} -{%- block doctype %} - -{%- endblock %} - {%- block extrahead %} \n' - 'Python' + '\nPython' ) result = (app.outdir / 'index.html').read_text(encoding='utf8') assert '' in result -@pytest.mark.sphinx(testroot='theming', - confoverrides={'html_theme': 'test-theme'}) +@pytest.mark.sphinx(testroot='theming', confoverrides={'html_theme': 'test-theme'}) def test_dark_style(app, monkeypatch): monkeypatch.setattr(sphinx.builders.html, '_file_checksum', lambda o, f: '') @@ -100,8 +121,8 @@ def test_dark_style(app, monkeypatch): css_file, properties = app.registry.css_files[0] assert css_file == 'pygments_dark.css' - assert "media" in properties - assert properties["media"] == '(prefers-color-scheme: dark)' + assert 'media' in properties + assert properties['media'] == '(prefers-color-scheme: dark)' assert sorted(f.filename for f in app.builder._css_files) == [ '_static/classic.css', @@ -111,9 +132,11 @@ def test_dark_style(app, monkeypatch): result = (app.outdir / 'index.html').read_text(encoding='utf8') assert '' in result - assert ('') in result + assert ( + '' + ) in result @pytest.mark.sphinx(testroot='theming') @@ -126,3 +149,41 @@ def test_theme_sidebars(app, status, warning): assert '

Related Topics

' not in result assert '

This Page

' not in result assert '

Quick search

' in result + + +@pytest.mark.parametrize( + 'theme_name', + [ + 'alabaster', + 'agogo', + 'basic', + 'bizstyle', + 'classic', + 'default', + 'epub', + 'haiku', + 'nature', + 'nonav', + 'pyramid', + 'scrolls', + 'sphinxdoc', + 'traditional', + ], +) +def test_theme_builds(make_app, rootdir, sphinx_test_tempdir, theme_name): + """Test all the themes included with Sphinx build a simple project and produce valid XML.""" + testroot_path = rootdir / 'test-basic' + srcdir = sphinx_test_tempdir / f'test-theme-{theme_name}' + shutil.copytree(testroot_path, srcdir) + + app = make_app(srcdir=srcdir, confoverrides={'html_theme': theme_name}) + app.build() + assert not app.warning.getvalue().strip() + assert app.outdir.joinpath('index.html').exists() + + # check that the generated HTML files are well-formed (as strict XML) + for html_file in app.outdir.rglob('*.html'): + try: + xml_parse(html_file) + except ParseError as exc: + pytest.fail(f'Failed to parse {html_file.relative_to(app.outdir)}: {exc}')