Skip to content

Commit c0a8dfa

Browse files
weiji14seisman
andauthored
Make IPython partially optional on CI to increase test coverage of figure.py (#1496)
Makes IPython an optional dependency in Continuous Integration for the minimum dependency stream (Python 3.7/NumPy 1.18), so that uncovered if-branches in `figure.py` are covered. Tests which require IPython have a pytest.importorskip line added so that the test suite doesn't break. * Install IPython as an optional dependency only for Python 3.9 CI tests * Add pytest.importorskip ipython to test_figure_show * Add pytest.importorskip ipython and sphinx_gallery to test_pygmtscrapper * Skip running the fig.inset doctest's fig.show line * Add test for fig.show using notebook method when IPython isn't installed * Add tests for figure's PNG and HTML printable representations * Provide reason for skipping test_figure_show and test_pygmtscrapper * Silence pylint protected-access warning on accessing PNG and HTML repr * Try test figure display external method * Move pytest.importorskip IPython outside of test_pygmtscrapper Co-authored-by: Dongdong Tian <[email protected]>
1 parent 8414b7e commit c0a8dfa

File tree

4 files changed

+52
-8
lines changed

4 files changed

+52
-8
lines changed

.github/workflows/ci_tests.yaml

+3-4
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ jobs:
5252
optional-packages: ''
5353
- python-version: 3.9
5454
numpy-version: '1.21'
55-
optional-packages: 'geopandas'
55+
optional-packages: 'geopandas ipython'
5656
defaults:
5757
run:
5858
shell: bash -l {0}
@@ -96,9 +96,8 @@ jobs:
9696
mamba install gmt=6.2.0 numpy=${{ matrix.numpy-version }} \
9797
pandas xarray netCDF4 packaging \
9898
${{ matrix.optional-packages }} \
99-
coverage[toml] dvc ipython make \
100-
pytest-cov pytest-mpl pytest>=6.0 \
101-
sphinx-gallery
99+
coverage[toml] dvc make pytest>=6.0 \
100+
pytest-cov pytest-mpl sphinx-gallery
102101
103102
# Show installed pkg information for postmortem diagnostic
104103
- name: List installed packages

pygmt/src/inset.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ def inset(self, **kwargs):
119119
...
120120
>>> # Map elements outside the "with" block are plotted in the main figure
121121
>>> fig.logo(position="jBR+o0.2c+w3c")
122-
>>> fig.show()
122+
>>> fig.show() # doctest: +SKIP
123123
<IPython.core.display.Image object>
124124
"""
125125
kwargs = self._preprocess(**kwargs) # pylint: disable=protected-access

pygmt/tests/test_figure.py

+46-1
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,17 @@
55
"""
66
import os
77

8+
try:
9+
import IPython
10+
except ModuleNotFoundError:
11+
IPython = None # pylint: disable=invalid-name
12+
13+
814
import numpy as np
915
import numpy.testing as npt
1016
import pytest
1117
from pygmt import Figure, set_display
12-
from pygmt.exceptions import GMTInvalidInput
18+
from pygmt.exceptions import GMTError, GMTInvalidInput
1319
from pygmt.helpers import GMTTempFile
1420

1521

@@ -52,6 +58,23 @@ def test_figure_region_country_codes():
5258
npt.assert_allclose(fig.region, np.array([0.0, 360.0, -90.0, 90.0]))
5359

5460

61+
def test_figure_repr():
62+
"""
63+
Make sure that figure output's PNG and HTML printable representations look
64+
ok.
65+
"""
66+
fig = Figure()
67+
fig.basemap(region=[0, 1, 2, 3], frame=True)
68+
# Check that correct PNG 8-byte file header is produced
69+
# https://en.wikipedia.org/wiki/Portable_Network_Graphics#File_header
70+
repr_png = fig._repr_png_() # pylint: disable=protected-access
71+
assert repr_png.hex().startswith("89504e470d0a1a0a")
72+
# Check that correct HTML image tags are produced
73+
repr_html = fig._repr_html_() # pylint: disable=protected-access
74+
assert repr_html.startswith('<img src="data:image/png;base64,')
75+
assert repr_html.endswith('" width="500px">')
76+
77+
5578
def test_figure_savefig_exists():
5679
"""
5780
Make sure the saved figure has the right name.
@@ -159,6 +182,7 @@ def mock_psconvert(*args, **kwargs): # pylint: disable=unused-argument
159182
)
160183

161184

185+
@pytest.mark.skipif(IPython is None, reason="run when IPython is installed")
162186
def test_figure_show():
163187
"""
164188
Test that show creates the correct file name and deletes the temp dir.
@@ -199,6 +223,27 @@ def test_figure_show_invalid_method():
199223
fig.show(method="test")
200224

201225

226+
@pytest.mark.skipif(IPython is not None, reason="run without IPython installed")
227+
def test_figure_show_notebook_error_without_ipython():
228+
"""
229+
Test to check if an error is raised when display method is 'notebook', but
230+
IPython is not installed.
231+
"""
232+
fig = Figure()
233+
fig.basemap(region=[0, 1, 2, 3], frame=True)
234+
with pytest.raises(GMTError):
235+
fig.show(method="notebook")
236+
237+
238+
def test_figure_display_external():
239+
"""
240+
Test to check that a figure can be displayed in an external window.
241+
"""
242+
fig = Figure()
243+
fig.basemap(region=[0, 3, 6, 9], projection="X1c", frame=True)
244+
fig.show(method="external")
245+
246+
202247
def test_figure_set_display_invalid():
203248
"""
204249
Test to check if an error is raised when an invalid method is passed to

pygmt/tests/test_sphinx_gallery.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@
88
from pygmt.figure import SHOWED_FIGURES, Figure
99

1010
pygmt_sphinx_gallery = pytest.importorskip(
11-
"pygmt.sphinx_gallery", reason="requires sphinx-gallery to be installed"
11+
"pygmt.sphinx_gallery", reason="Requires sphinx-gallery to be installed"
1212
)
13+
pytest.importorskip("IPython", reason="Requires IPython to be installed")
1314

1415

1516
def test_pygmtscraper():
1617
"""
1718
Make sure the scraper finds the figures and removes them from the pool.
1819
"""
19-
2020
showed = SHOWED_FIGURES.copy()
2121
for _ in range(len(SHOWED_FIGURES)):
2222
SHOWED_FIGURES.pop()

0 commit comments

Comments
 (0)