Skip to content

Commit 31ffe4b

Browse files
committed
Add rebuild tests for plot_directive
The new tests: - make sure that unchanged plots are not recreated upon a second invocation of sphinx-build - make sure that plots with `:context:` are recreated (matplotlib#20523) - make sure that plots included via `.. include:` are updated when modified (matplotlib#17860)
1 parent 608a868 commit 31ffe4b

File tree

3 files changed

+67
-16
lines changed

3 files changed

+67
-16
lines changed

lib/matplotlib/tests/test_sphinxext.py

Lines changed: 56 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from pathlib import Path
66
from subprocess import Popen, PIPE
77
import sys
8+
import shutil
89

910
import pytest
1011

@@ -13,27 +14,21 @@
1314

1415

1516
def test_tinypages(tmpdir):
16-
tmp_path = Path(tmpdir)
17-
html_dir = tmp_path / 'html'
18-
doctree_dir = tmp_path / 'doctrees'
19-
# Build the pages with warnings turned into errors
20-
cmd = [sys.executable, '-msphinx', '-W', '-b', 'html',
21-
'-d', str(doctree_dir),
22-
str(Path(__file__).parent / 'tinypages'), str(html_dir)]
23-
proc = Popen(cmd, stdout=PIPE, stderr=PIPE, universal_newlines=True,
24-
env={**os.environ, "MPLBACKEND": ""})
25-
out, err = proc.communicate()
17+
source_dir = Path(tmpdir) / 'src'
18+
shutil.copytree(str(Path(__file__).parent / 'tinypages'), str(source_dir))
19+
html_dir = source_dir / '_build' / 'html'
20+
doctree_dir = source_dir / 'doctrees'
2621

27-
assert proc.returncode == 0, \
28-
f"sphinx build failed with stdout:\n{out}\nstderr:\n{err}\n"
29-
if err:
30-
pytest.fail(f"sphinx build emitted the following warnings:\n{err}")
31-
32-
assert html_dir.is_dir()
22+
# Build the pages with warnings turned into errors
23+
build_sphinx_html(source_dir, doctree_dir, html_dir)
3324

3425
def plot_file(num):
3526
return html_dir / f'some_plots-{num}.png'
3627

28+
def plot_directive_file(num):
29+
# This is always next to the doctree dir.
30+
return doctree_dir.parent / 'plot_directive' / f'some_plots-{num}.png'
31+
3732
range_10, range_6, range_4 = [plot_file(i) for i in range(1, 4)]
3833
# Plot 5 is range(6) plot
3934
assert filecmp.cmp(range_6, plot_file(5))
@@ -48,6 +43,7 @@ def plot_file(num):
4843
assert filecmp.cmp(range_4, plot_file(13))
4944
# Plot 14 has included source
5045
html_contents = (html_dir / 'some_plots.html').read_bytes()
46+
5147
assert b'# Only a comment' in html_contents
5248
# check plot defined in external file.
5349
assert filecmp.cmp(range_4, html_dir / 'range4.png')
@@ -62,3 +58,47 @@ def plot_file(num):
6258
assert b'plot-directive my-class my-other-class' in html_contents
6359
# check that the multi-image caption is applied twice
6460
assert html_contents.count(b'This caption applies to both plots.') == 2
61+
# Plot 21 is range(6) plot via an include directive. But because some of
62+
# the previous plots are repeated, the argument to plot_file() is only 17.
63+
assert filecmp.cmp(range_6, plot_file(17))
64+
65+
# Modify the included plot
66+
with open(str(source_dir / 'included_plot_21.rst'), 'r') as file:
67+
contents = file.read()
68+
contents = contents.replace('plt.plot(range(6))', 'plt.plot(range(4))')
69+
with open(str(source_dir / 'included_plot_21.rst'), 'w') as file:
70+
file.write(contents)
71+
# Build the pages again and check that the modified file was updated
72+
modification_times = [plot_directive_file(i).stat().st_mtime
73+
for i in (1, 2, 3, 5)]
74+
build_sphinx_html(source_dir, doctree_dir, html_dir)
75+
assert filecmp.cmp(range_4, plot_file(17))
76+
# Check that the plots in the plot_directive folder weren't changed.
77+
# (plot_directive_file(1) won't be modified, but it will be copied to html/
78+
# upon compilation, so plot_file(1) will be modified)
79+
assert plot_directive_file(1).stat().st_mtime == modification_times[0]
80+
assert plot_directive_file(2).stat().st_mtime == modification_times[1]
81+
assert plot_directive_file(3).stat().st_mtime == modification_times[2]
82+
assert filecmp.cmp(range_10, plot_file(1))
83+
assert filecmp.cmp(range_6, plot_file(2))
84+
assert filecmp.cmp(range_4, plot_file(3))
85+
# Make sure that figures marked with context are re-created (but that the
86+
# contents are the same)
87+
assert plot_directive_file(5).stat().st_mtime > modification_times[3]
88+
assert filecmp.cmp(range_6, plot_file(5))
89+
90+
91+
def build_sphinx_html(source_dir, doctree_dir, html_dir):
92+
# Build the pages with warnings turned into errors
93+
cmd = [sys.executable, '-msphinx', '-W', '-b', 'html',
94+
'-d', str(doctree_dir), str(source_dir), str(html_dir)]
95+
proc = Popen(cmd, stdout=PIPE, stderr=PIPE, universal_newlines=True,
96+
env={**os.environ, "MPLBACKEND": ""})
97+
out, err = proc.communicate()
98+
99+
assert proc.returncode == 0, \
100+
f"sphinx build failed with stdout:\n{out}\nstderr:\n{err}\n"
101+
if err:
102+
pytest.fail(f"sphinx build emitted the following warnings:\n{err}")
103+
104+
assert html_dir.is_dir()
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Plot 21 has length 6
2+
3+
.. plot::
4+
5+
plt.plot(range(6))
6+

lib/matplotlib/tests/tinypages/some_plots.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,3 +166,8 @@ scenario:
166166

167167
plt.figure()
168168
plt.plot(range(4))
169+
170+
Plot 21 is generated via an include directive:
171+
172+
.. include:: included_plot_21.rst
173+

0 commit comments

Comments
 (0)