Skip to content

Commit 751fc99

Browse files
authored
Tests: Update Sphinx test matrix for EmbedAPI (#10655)
* Tests: Update Sphinx test matrix for EmbedAPI - Test only the latest minor version of each major version - Add newer versions we weren't testing * Run without migrations to speed things up * Update tests to work with Sphinx 7.x * Lint * Make explicit it requires Tox<4
1 parent 200f9a8 commit 751fc99

File tree

5 files changed

+61
-64
lines changed

5 files changed

+61
-64
lines changed

.circleci/config.yml

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ jobs:
3434
- run: git submodule sync
3535
- run: git submodule update --init
3636
- run: pip install --user 'tox<4'
37+
- run: tox --version
3738
- run: tox -c tox.embedapi.ini
3839

3940
checks:

readthedocs/embed/v3/tests/test_external_pages.py

+22-28
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from django.urls import reverse
66
from packaging.version import Version
77

8-
from .utils import srcdir
8+
from .utils import get_anchor_link_title, srcdir
99

1010

1111
@pytest.mark.django_db
@@ -36,11 +36,7 @@ def test_default_main_section(self, app, client, requests_mock):
3636
response = client.get(self.api_url, params)
3737
assert response.status_code == 200
3838

39-
# https://github.com/sphinx-doc/sphinx/commit/bc635627d32b52e8e1381f23cddecf26429db1ae
40-
if sphinx.version_info < (5, 0, 0):
41-
title = "Permalink to this headline"
42-
else:
43-
title = "Permalink to this heading"
39+
title = get_anchor_link_title("heading")
4440

4541
# The output is different because docutils is outputting this,
4642
# and we're not sanitizing it, but just passing it through.
@@ -70,11 +66,7 @@ def test_specific_identifier(self, app, client, requests_mock):
7066
response = client.get(self.api_url, params)
7167
assert response.status_code == 200
7268

73-
# https://github.com/sphinx-doc/sphinx/commit/bc635627d32b52e8e1381f23cddecf26429db1ae
74-
if sphinx.version_info < (5, 0, 0):
75-
title = "Permalink to this headline"
76-
else:
77-
title = "Permalink to this heading"
69+
title = get_anchor_link_title("heading")
7870

7971
if Version(docutils.__version__) >= Version("0.17"):
8072
content = f'<section id="sub-title">\n<h2>Sub-title<a class="headerlink" href="https://docs.project.com#sub-title" title="{title}">¶</a></h2>\n<p>This is a reference to <a class="reference internal" href="https://docs.project.com#sub-title"><span class="std std-ref">Sub-title</span></a>.</p>\n</section>'
@@ -102,12 +94,14 @@ def test_dl_identifier(self, app, client, requests_mock):
10294
response = client.get(self.api_url, params)
10395
assert response.status_code == 200
10496

97+
title = get_anchor_link_title("definition")
98+
10599
if sphinx.version_info < (3, 5, 0):
106-
content = '<dt id="confval-config1">\n<code class="sig-name descname">config1</code><a class="headerlink" href="https://docs.project.com/configuration.html#confval-config1" title="Permalink to this definition">¶</a></dt>'
100+
content = f'<dt id="confval-config1">\n<code class="sig-name descname">config1</code><a class="headerlink" href="https://docs.project.com/configuration.html#confval-config1" title="{title}">¶</a></dt>'
107101
elif sphinx.version_info[:2] == (3, 5):
108-
content = '<dt id="confval-config1">\n<code class="sig-name descname"><span class="pre">config1</span></code><a class="headerlink" href="https://docs.project.com/configuration.html#confval-config1" title="Permalink to this definition">¶</a></dt>'
102+
content = f'<dt id="confval-config1">\n<code class="sig-name descname"><span class="pre">config1</span></code><a class="headerlink" href="https://docs.project.com/configuration.html#confval-config1" title="{title}">¶</a></dt>'
109103
else:
110-
content = '<dt class="sig sig-object std" id="confval-config1">\n<span class="sig-name descname"><span class="pre">config1</span></span><a class="headerlink" href="https://docs.project.com/configuration.html#confval-config1" title="Permalink to this definition">¶</a></dt>'
104+
content = f'<dt class="sig sig-object std" id="confval-config1">\n<span class="sig-name descname"><span class="pre">config1</span></span><a class="headerlink" href="https://docs.project.com/configuration.html#confval-config1" title="{title}">¶</a></dt>'
111105

112106
assert response.json() == {
113107
"url": "https://docs.project.com/configuration.html#confval-config1",
@@ -131,12 +125,14 @@ def test_dl_identifier_doctool_sphinx(self, app, client, requests_mock):
131125
response = client.get(self.api_url, params)
132126
assert response.status_code == 200
133127

128+
title = get_anchor_link_title("definition")
129+
134130
if sphinx.version_info < (3, 5, 0):
135-
content = '<dt id="confval-config1">\n<code class="sig-name descname">config1</code><a class="headerlink" href="https://docs.project.com/configuration.html#confval-config1" title="Permalink to this definition">¶</a></dt>'
131+
content = f'<dt id="confval-config1">\n<code class="sig-name descname">config1</code><a class="headerlink" href="https://docs.project.com/configuration.html#confval-config1" title="{title}">¶</a></dt>'
136132
elif sphinx.version_info[:2] == (3, 5):
137-
content = '<dt id="confval-config1">\n<code class="sig-name descname"><span class="pre">config1</span></code><a class="headerlink" href="https://docs.project.com/configuration.html#confval-config1" title="Permalink to this definition">¶</a></dt>'
133+
content = f'<dt id="confval-config1">\n<code class="sig-name descname"><span class="pre">config1</span></code><a class="headerlink" href="https://docs.project.com/configuration.html#confval-config1" title="{title}">¶</a></dt>'
138134
else:
139-
content = '<dt class="sig sig-object std" id="confval-config1">\n<span class="sig-name descname"><span class="pre">config1</span></span><a class="headerlink" href="https://docs.project.com/configuration.html#confval-config1" title="Permalink to this definition">¶</a></dt>'
135+
content = f'<dt class="sig sig-object std" id="confval-config1">\n<span class="sig-name descname"><span class="pre">config1</span></span><a class="headerlink" href="https://docs.project.com/configuration.html#confval-config1" title="{title}">¶</a></dt>'
140136

141137
assert response.json() == {
142138
"url": "https://docs.project.com/configuration.html#confval-config1",
@@ -154,13 +150,13 @@ def test_dl_identifier_doctool_sphinx(self, app, client, requests_mock):
154150
assert response.status_code == 200
155151

156152
if sphinx.version_info < (3, 0, 0): # <3.0
157-
content = '<dl class="confval">\n<dt id="confval-config1">\n<code class="sig-name descname">config1</code><a class="headerlink" href="https://docs.project.com/configuration.html#confval-config1" title="Permalink to this definition">¶</a></dt>\n<dd><p>Description: This the description for config1</p>\n<p>Default: <code class="docutils literal notranslate"><span class="pre">\'Default</span> <span class="pre">value</span> <span class="pre">for</span> <span class="pre">config\'</span></code></p>\n<p>Type: bool</p>\n</dd></dl>'
153+
content = f'<dl class="confval">\n<dt id="confval-config1">\n<code class="sig-name descname">config1</code><a class="headerlink" href="https://docs.project.com/configuration.html#confval-config1" title="{title}">¶</a></dt>\n<dd><p>Description: This the description for config1</p>\n<p>Default: <code class="docutils literal notranslate"><span class="pre">\'Default</span> <span class="pre">value</span> <span class="pre">for</span> <span class="pre">config\'</span></code></p>\n<p>Type: bool</p>\n</dd></dl>'
158154
elif sphinx.version_info[:2] == (3, 5):
159-
content = '<dl class="std confval">\n<dt id="confval-config1">\n<code class="sig-name descname"><span class="pre">config1</span></code><a class="headerlink" href="https://docs.project.com/configuration.html#confval-config1" title="Permalink to this definition">¶</a></dt>\n<dd><p>Description: This the description for config1</p>\n<p>Default: <code class="docutils literal notranslate"><span class="pre">\'Default</span> <span class="pre">value</span> <span class="pre">for</span> <span class="pre">config\'</span></code></p>\n<p>Type: bool</p>\n</dd></dl>'
155+
content = f'<dl class="std confval">\n<dt id="confval-config1">\n<code class="sig-name descname"><span class="pre">config1</span></code><a class="headerlink" href="https://docs.project.com/configuration.html#confval-config1" title="{title}">¶</a></dt>\n<dd><p>Description: This the description for config1</p>\n<p>Default: <code class="docutils literal notranslate"><span class="pre">\'Default</span> <span class="pre">value</span> <span class="pre">for</span> <span class="pre">config\'</span></code></p>\n<p>Type: bool</p>\n</dd></dl>'
160156
elif sphinx.version_info < (4, 0, 0): # >3.0,=!3.5.x,<4.0
161-
content = '<dl class="std confval">\n<dt id="confval-config1">\n<code class="sig-name descname">config1</code><a class="headerlink" href="https://docs.project.com/configuration.html#confval-config1" title="Permalink to this definition">¶</a></dt>\n<dd><p>Description: This the description for config1</p>\n<p>Default: <code class="docutils literal notranslate"><span class="pre">\'Default</span> <span class="pre">value</span> <span class="pre">for</span> <span class="pre">config\'</span></code></p>\n<p>Type: bool</p>\n</dd></dl>'
157+
content = f'<dl class="std confval">\n<dt id="confval-config1">\n<code class="sig-name descname">config1</code><a class="headerlink" href="https://docs.project.com/configuration.html#confval-config1" title="{title}">¶</a></dt>\n<dd><p>Description: This the description for config1</p>\n<p>Default: <code class="docutils literal notranslate"><span class="pre">\'Default</span> <span class="pre">value</span> <span class="pre">for</span> <span class="pre">config\'</span></code></p>\n<p>Type: bool</p>\n</dd></dl>'
162158
else: # >=4.0
163-
content = '<dl class="std confval">\n<dt class="sig sig-object std" id="confval-config1">\n<span class="sig-name descname"><span class="pre">config1</span></span><a class="headerlink" href="https://docs.project.com/configuration.html#confval-config1" title="Permalink to this definition">¶</a></dt>\n<dd><p>Description: This the description for config1</p>\n<p>Default: <code class="docutils literal notranslate"><span class="pre">\'Default</span> <span class="pre">value</span> <span class="pre">for</span> <span class="pre">config\'</span></code></p>\n<p>Type: bool</p>\n</dd></dl>'
159+
content = f'<dl class="std confval">\n<dt class="sig sig-object std" id="confval-config1">\n<span class="sig-name descname"><span class="pre">config1</span></span><a class="headerlink" href="https://docs.project.com/configuration.html#confval-config1" title="{title}">¶</a></dt>\n<dd><p>Description: This the description for config1</p>\n<p>Default: <code class="docutils literal notranslate"><span class="pre">\'Default</span> <span class="pre">value</span> <span class="pre">for</span> <span class="pre">config\'</span></code></p>\n<p>Type: bool</p>\n</dd></dl>'
164160

165161
assert response.json() == {
166162
"url": "https://docs.project.com/configuration.html#confval-config1",
@@ -232,8 +228,10 @@ def test_glossary_identifier_doctool_sphinx(self, app, client, requests_mock):
232228
response = client.get(self.api_url, params)
233229
assert response.status_code == 200
234230

231+
title = get_anchor_link_title("term")
232+
235233
if sphinx.version_info >= (3, 5, 0):
236-
content = f'<dt id="{fragment}">Read the Docs<a class="headerlink" href="https://docs.project.com/glossary.html#{fragment}" title="Permalink to this term">¶</a></dt>'
234+
content = f'<dt id="{fragment}">Read the Docs<a class="headerlink" href="https://docs.project.com/glossary.html#{fragment}" title="{title}">¶</a></dt>'
237235
else:
238236
content = f'<dt id="{fragment}">Read the Docs</dt>'
239237

@@ -258,7 +256,7 @@ def test_glossary_identifier_doctool_sphinx(self, app, client, requests_mock):
258256
classes = "glossary simple"
259257

260258
if sphinx.version_info >= (3, 5, 0):
261-
content = f'<dl class="{classes}">\n\n<dt id="{fragment}">Read the Docs<a class="headerlink" href="https://docs.project.com/glossary.html#{fragment}" title="Permalink to this term">¶</a></dt><dd><p>Best company ever.</p>\n</dd>\n</dl>'
259+
content = f'<dl class="{classes}">\n\n<dt id="{fragment}">Read the Docs<a class="headerlink" href="https://docs.project.com/glossary.html#{fragment}" title="{title}">¶</a></dt><dd><p>Best company ever.</p>\n</dd>\n</dl>'
262260
else:
263261
content = f'<dl class="{classes}">\n\n<dt id="{fragment}">Read the Docs</dt><dd><p>Best company ever.</p>\n</dd>\n</dl>'
264262

@@ -302,11 +300,7 @@ def test_manual_references(self, app, client, requests_mock):
302300
response = client.get(self.api_url, params)
303301
assert response.status_code == 200
304302

305-
# https://github.com/sphinx-doc/sphinx/commit/bc635627d32b52e8e1381f23cddecf26429db1ae
306-
if sphinx.version_info < (5, 0, 0):
307-
title = "Permalink to this headline"
308-
else:
309-
title = "Permalink to this heading"
303+
title = get_anchor_link_title("heading")
310304

311305
# Note the difference between `<section>` and `<div class="section">`
312306
if Version(docutils.__version__) >= Version("0.17"):

readthedocs/embed/v3/tests/test_internal_pages.py

+13-21
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import django_dynamic_fixture as fixture
55
import docutils
66
import pytest
7-
import sphinx
87
from django.core.cache import cache
98
from django.urls import reverse
109
from packaging.version import Version
@@ -13,28 +12,24 @@
1312
from readthedocs.subscriptions.constants import TYPE_EMBED_API
1413
from readthedocs.subscriptions.products import RTDProductFeature
1514

16-
from .utils import srcdir
15+
from .utils import get_anchor_link_title, srcdir
1716

1817

1918
@pytest.mark.django_db
2019
@pytest.mark.embed_api
2120
class TestEmbedAPIv3InternalPages:
22-
2321
@pytest.fixture(autouse=True)
2422
def setup_method(self, settings):
2523
settings.USE_SUBDOMAIN = True
26-
settings.PUBLIC_DOMAIN = 'readthedocs.io'
24+
settings.PUBLIC_DOMAIN = "readthedocs.io"
2725
settings.RTD_EMBED_API_EXTERNAL_DOMAINS = []
2826
settings.RTD_DEFAULT_FEATURES = dict(
2927
[RTDProductFeature(TYPE_EMBED_API).to_item()]
3028
)
3129

32-
self.api_url = reverse('embed_api_v3')
30+
self.api_url = reverse("embed_api_v3")
3331

34-
self.project = fixture.get(
35-
Project,
36-
slug='project'
37-
)
32+
self.project = fixture.get(Project, slug="project")
3833

3934
yield
4035
cache.clear()
@@ -45,43 +40,40 @@ def f(*args, **kwargs):
4540
read_mock = mock.MagicMock()
4641
read_mock.read.return_value = content
4742
yield read_mock
43+
4844
return f
4945

5046
@pytest.mark.sphinx("html", srcdir=srcdir, freshenv=True)
5147
@mock.patch("readthedocs.embed.v3.views.build_media_storage.open")
5248
@mock.patch("readthedocs.embed.v3.views.build_media_storage.exists")
5349
def test_default_main_section(self, storage_exists, storage_open, app, client):
5450
app.build()
55-
path = app.outdir / 'index.html'
51+
path = app.outdir / "index.html"
5652
assert path.exists() is True
5753
content = open(path).read()
5854

5955
storage_exists.return_value = True
6056
storage_open.side_effect = self._mock_open(content)
6157

6258
params = {
63-
'url': 'https://project.readthedocs.io/en/latest/',
59+
"url": "https://project.readthedocs.io/en/latest/",
6460
}
6561
response = client.get(self.api_url, params)
6662
assert response.status_code == 200
6763

68-
# https://github.com/sphinx-doc/sphinx/commit/bc635627d32b52e8e1381f23cddecf26429db1ae
69-
if sphinx.version_info < (5, 0, 0):
70-
title = "Permalink to this headline"
71-
else:
72-
title = "Permalink to this heading"
64+
title = get_anchor_link_title("heading")
7365

7466
# Note the difference between `<section>` and `<div class="section">`
75-
if Version(docutils.__version__) >= Version('0.17'):
67+
if Version(docutils.__version__) >= Version("0.17"):
7668
content = f'<div class="body" role="main">\n \n <section id="title">\n<h1>Title<a class="headerlink" href="https://project.readthedocs.io/en/latest/#title" title="{title}">¶</a></h1>\n<p>This is an example page used to test EmbedAPI parsing features.</p>\n<section id="sub-title">\n<h2>Sub-title<a class="headerlink" href="https://project.readthedocs.io/en/latest/#sub-title" title="{title}">¶</a></h2>\n<p>This is a reference to <a class="reference internal" href="https://project.readthedocs.io/en/latest/#sub-title"><span class="std std-ref">Sub-title</span></a>.</p>\n</section>\n<section id="manual-reference-section">\n<span id="manual-reference"></span><h2>Manual Reference Section<a class="headerlink" href="https://project.readthedocs.io/en/latest/#manual-reference-section" title="{title}">¶</a></h2>\n<p>This is a reference to a manual reference <a class="reference internal" href="https://project.readthedocs.io/en/latest/#manual-reference"><span class="std std-ref">Manual Reference Section</span></a>.</p>\n</section>\n</section>\n\n\n </div>'
7769
else:
7870
content = f'<div class="body" role="main">\n \n <div class="section" id="title">\n<h1>Title<a class="headerlink" href="https://project.readthedocs.io/en/latest/#title" title="{title}">¶</a></h1>\n<p>This is an example page used to test EmbedAPI parsing features.</p>\n<div class="section" id="sub-title">\n<h2>Sub-title<a class="headerlink" href="https://project.readthedocs.io/en/latest/#sub-title" title="{title}">¶</a></h2>\n<p>This is a reference to <a class="reference internal" href="https://project.readthedocs.io/en/latest/#sub-title"><span class="std std-ref">Sub-title</span></a>.</p>\n</div>\n<div class="section" id="manual-reference-section">\n<span id="manual-reference"></span><h2>Manual Reference Section<a class="headerlink" href="https://project.readthedocs.io/en/latest/#manual-reference-section" title="{title}">¶</a></h2>\n<p>This is a reference to a manual reference <a class="reference internal" href="https://project.readthedocs.io/en/latest/#manual-reference"><span class="std std-ref">Manual Reference Section</span></a>.</p>\n</div>\n</div>\n\n\n </div>'
7971

8072
assert response.json() == {
81-
'url': 'https://project.readthedocs.io/en/latest/',
82-
'fragment': None,
83-
'content': content,
84-
'external': False,
73+
"url": "https://project.readthedocs.io/en/latest/",
74+
"fragment": None,
75+
"content": content,
76+
"external": False,
8577
}
8678

8779
@pytest.mark.sphinx("html", srcdir=srcdir, freshenv=False)

readthedocs/embed/v3/tests/utils.py

+15
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,23 @@
11
import os
22

3+
import sphinx
34

45
srcdir = os.path.join(
56
os.path.dirname(os.path.abspath(__file__)),
67
"examples",
78
"default",
89
)
10+
11+
12+
def get_anchor_link_title(thing):
13+
# https://github.com/sphinx-doc/sphinx/commit/bc635627d32b52e8e1381f23cddecf26429db1ae
14+
if sphinx.version_info < (5, 0, 0):
15+
if thing == "heading":
16+
thing = "headline"
17+
title = f"Permalink to this {thing}"
18+
# https://github.com/sphinx-doc/sphinx/commit/7e9a2066c2f31eda53d075f5a8b20a7430ca0c61
19+
elif sphinx.version_info >= (7, 2, 0):
20+
title = f"Link to this {thing}"
21+
else:
22+
title = f"Permalink to this {thing}"
23+
return title

0 commit comments

Comments
 (0)