Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FIX: use warning instead of errors for version json tests #993

Merged
merged 10 commits into from
Nov 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions .flake8
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
[flake8]
max-line-length = 88
ignore =
E203, # space before : (needed for how black formats slicing)
W503, # line break before binary operator
# E203: space before ":" | needed for how black formats slicing
# E501: line too long | Black take care of it
# W503: line break before binary operator | Black take care of it
# W605: invalid escape sequence | we escape specific characters for sphinx
ignore = E203, E501, W503, W605
exclude = setup.py,docs/conf.py,node_modules,docs,build,dist
8 changes: 8 additions & 0 deletions docs/user_guide/version-dropdown.rst
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,14 @@ a few different ways:
}
}

By default the theme is testing the :code:`.json` file provided and outputs warnings in the Sphinx build. If this test breaks the pipeline of your docs, the test can be disabled by configuring the :code:`check_switcher` parameter in :code:`conf.py`:

.. code-block:: python

html_theme_options = {
# ...
"check_switcher": False
}

Configure ``switcher['version_match']``
---------------------------------------
Expand Down
48 changes: 33 additions & 15 deletions src/pydata_sphinx_theme/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from pygments.formatters import HtmlFormatter
from pygments.styles import get_all_styles
import requests
from requests.exceptions import ConnectionError, HTTPError, RetryError

from .bootstrap_html_translator import BootstrapHTML5Translator

Expand Down Expand Up @@ -82,8 +83,10 @@ def update_config(app, env):
" Set version URLs in JSON directly."
)

# check the validity of the theme swithcer file
if isinstance(theme_options.get("switcher"), dict):
# check the validity of the theme switcher file
is_dict = isinstance(theme_options.get("switcher"), dict)
should_test = theme_options.get("check_switcher", True)
if is_dict and should_test:
theme_switcher = theme_options.get("switcher")

# raise an error if one of these compulsory keys is missing
Expand All @@ -92,22 +95,37 @@ def update_config(app, env):

# try to read the json file. If it's a url we use request,
# else we simply read the local file from the source directory
# it will raise an error if the file does not exist
# display a log warning if the file cannot be reached
reading_error = None
if urlparse(json_url).scheme in ["http", "https"]:
content = requests.get(json_url).text
try:
request = requests.get(json_url)
request.raise_for_status()
content = request.text
except (ConnectionError, HTTPError, RetryError) as e:
reading_error = repr(e)
else:
content = Path(env.srcdir, json_url).read_text()

# check that the json file is not illformed
# it will throw an error if there is a an issue
switcher_content = json.loads(content)
missing_url = any(["url" not in e for e in switcher_content])
missing_version = any(["version" not in e for e in switcher_content])
if missing_url or missing_version:
raise AttributeError(
f'The version switcher "{json_url}" file is malformed'
' at least one of the items is missing the "url" or "version" key'
try:
content = Path(env.srcdir, json_url).read_text()
except FileNotFoundError as e:
reading_error = repr(e)

if reading_error is not None:
logger.warning(
f'The version switcher "{json_url}" file cannot be read due to the following error:\n'
f"{reading_error}"
)
else:
# check that the json file is not illformed,
# throw a warning if the file is ill formed and an error if it's not json
switcher_content = json.loads(content)
missing_url = any(["url" not in e for e in switcher_content])
missing_version = any(["version" not in e for e in switcher_content])
if missing_url or missing_version:
logger.warning(
f'The version switcher "{json_url}" file is malformed'
' at least one of the items is missing the "url" or "version" key'
)

# Add an analytics ID to the site if provided
analytics = theme_options.get("analytics", {})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ primary_sidebar_end = sidebar-ethical-ads.html
footer_items = copyright.html, sphinx-version.html
secondary_sidebar_items = page-toc.html, searchbox.html, edit-this-page.html, sourcelink.html
switcher =
check_switcher = True
pygment_light_style = tango
pygment_dark_style = monokai
logo =
Expand Down
14 changes: 14 additions & 0 deletions tests/sites/base/missing_url.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[
{
"name": "v0.7.1 (stable)",
"version": "0.7.1",
"url": "https://pydata-sphinx-theme.readthedocs.io/en/v0.7.1/"
},
{
"version": "0.7.0",
"url": "https://pydata-sphinx-theme.readthedocs.io/en/v0.7.0/"
},
{
"version": "0.6.3"
}
]
42 changes: 31 additions & 11 deletions tests/test_build.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import os
import re
from pathlib import Path
from shutil import copytree

Expand All @@ -11,6 +12,12 @@
path_tests = Path(__file__).parent


def escape_ansi(string):
"""helper function to remove ansi coloring from sphinx warnings"""
ansi_escape = re.compile(r"(\x9B|\x1B\[)[0-?]*[ -\/]*[@-~]")
return ansi_escape.sub("", string)


class SphinxBuild:
def __init__(self, app: SphinxTestApp, src: Path):
self.app = app
Expand Down Expand Up @@ -628,7 +635,12 @@ def test_show_nav_level(sphinx_build_factory):
assert "checked" in checkbox.attrs


def test_version_switcher(sphinx_build_factory, file_regression):
switcher_files = ["switcher.json", "http://a.b/switcher.json", "missing_url.json"]
"the switcher files tested in test_version_switcher, not all of them exist"


@pytest.mark.parametrize("url", switcher_files)
def test_version_switcher(sphinx_build_factory, file_regression, url):
"""Regression test the version switcher dropdown HTML.

Note that a lot of the switcher HTML gets populated by JavaScript,
Expand All @@ -641,20 +653,28 @@ def test_version_switcher(sphinx_build_factory, file_regression):
"html_theme_options": {
"navbar_end": ["version-switcher"],
"switcher": {
"json_url": "switcher.json",
"json_url": url,
"version_match": "0.7.1",
},
}
}
sphinx_build = sphinx_build_factory("base", confoverrides=confoverrides).build()
switcher = sphinx_build.html_tree("index.html").select(
".version-switcher__container"
)[
0
] # noqa
file_regression.check(
switcher.prettify(), basename="navbar_switcher", extension=".html"
)
factory = sphinx_build_factory("base", confoverrides=confoverrides)
sphinx_build = factory.build(no_warning=False)

if url == "switcher.json": # this should work
index = sphinx_build.html_tree("index.html")
switcher = index.select(".version-switcher__container")[0]
file_regression.check(
switcher.prettify(), basename="navbar_switcher", extension=".html"
)

elif url == "http://a.b/switcher.json": # this file doesn't exist"
not_read = 'WARNING: The version switcher "http://a.b/switcher.json" file cannot be read due to the following error:\n' # noqa
assert not_read in escape_ansi(sphinx_build.warnings).strip()

elif url == "missing_url.json": # this file is missing the url key for one version
missing_url = 'WARNING: The version switcher "missing_url.json" file is malformed at least one of the items is missing the "url" or "version" key' # noqa
assert escape_ansi(sphinx_build.warnings).strip() == missing_url


def test_theme_switcher(sphinx_build_factory, file_regression):
Expand Down