Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit ef8df26

Browse files
committed
Add some animation tests.
1 parent d610a5d commit ef8df26

File tree

7 files changed

+84
-40
lines changed

7 files changed

+84
-40
lines changed

.appveyor.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ install:
6363
- activate test-environment
6464
- echo %PYTHON_VERSION% %TARGET_ARCH%
6565
# pytest-cov>=2.3.1 due to https://github.com/pytest-dev/pytest-cov/issues/124
66-
- pip install -q "pytest!=3.3.0,>=3.2.0" "pytest-cov>=2.3.1" pytest-rerunfailures pytest-timeout pytest-xdist
66+
- pip install -q "pytest>=3.3.1" "pytest-cov>=2.3.1" pytest-rerunfailures pytest-timeout pytest-xdist
6767

6868
# Apply patch to `subprocess` on Python versions > 2 and < 3.6.3
6969
# https://github.com/matplotlib/matplotlib/issues/9176

.travis.yml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,16 @@ addons:
1818
paths:
1919
- result_images.tar.bz2
2020
apt:
21+
sources:
22+
- ppa:jonathonf/ffmpeg-3
2123
packages:
2224
- cm-super
2325
- dvipng
26+
- ffmpeg
2427
- gdb
2528
- gir1.2-gtk-3.0
2629
- graphviz
2730
- inkscape
28-
- libav-tools
2931
- libcairo2
3032
- libgeos-dev
3133
- libgirepository-1.0.1
@@ -52,7 +54,7 @@ env:
5254
- NUMPY=numpy
5355
- PANDAS=
5456
- PYPARSING=pyparsing
55-
- PYTEST='pytest!=3.3.0,>=3.2.0'
57+
- PYTEST='pytest>=3.3.1'
5658
- PYTEST_COV=pytest-cov
5759
- PYTEST_PEP8=
5860
- SPHINX=sphinx
@@ -74,7 +76,7 @@ matrix:
7476
- NUMPY=numpy==1.10.0
7577
- PANDAS='pandas<0.21.0'
7678
- PYPARSING=pyparsing==2.0.1
77-
- PYTEST=pytest==3.1.0
79+
- PYTEST=pytest==3.3.1
7880
- PYTEST_COV=pytest-cov==2.3.1
7981
- SPHINX=sphinx==1.3
8082
- python: 3.5

doc/devel/contributing.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ environment is set up properly::
151151

152152
.. note::
153153

154-
**Additional dependencies for testing**: pytest_ (version 3.1 or later),
154+
**Additional dependencies for testing**: pytest_ (version 3.3.1 or later),
155155
Ghostscript_, Inkscape_
156156

157157
.. seealso::

doc/devel/testing.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ local FreeType build
2525

2626
The following software is required to run the tests:
2727

28-
- pytest_ (>=3.1)
28+
- pytest_ (>=3.3.1)
2929
- Ghostscript_ (to render PDF files)
3030
- Inkscape_ (to render SVG files)
3131

lib/matplotlib/animation.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -687,8 +687,7 @@ def _args(self):
687687
'-vframes', str(self._frame_counter)] + self.output_args
688688

689689

690-
# Base class of avconv information. AVConv has identical arguments to
691-
# FFMpeg
690+
# Base class of avconv information. AVConv has identical arguments to FFMpeg.
692691
class AVConvBase(FFMpegBase):
693692
'''Mixin class for avconv output.
694693

lib/matplotlib/tests/test_animation.py

Lines changed: 74 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
from __future__ import absolute_import, division, print_function
2-
3-
import six
4-
1+
import os
2+
from pathlib import Path
53
import sys
64
import tempfile
75

@@ -42,29 +40,35 @@ def finish(self):
4240
pass
4341

4442

45-
def test_null_movie_writer():
46-
# Test running an animation with NullMovieWriter.
47-
48-
fig = plt.figure()
43+
def make_animation(**kwargs):
44+
fig, ax = plt.subplots()
45+
line, = ax.plot([])
4946

5047
def init():
5148
pass
5249

5350
def animate(i):
54-
pass
51+
line.set_data([0, 1], [0, i])
52+
return line,
53+
54+
return animation.FuncAnimation(fig, animate, **kwargs)
55+
56+
57+
def test_null_movie_writer():
58+
# Test running an animation with NullMovieWriter.
5559

5660
num_frames = 5
61+
anim = make_animation(frames=num_frames)
62+
5763
filename = "unused.null"
5864
dpi = 50
5965
savefig_kwargs = dict(foo=0)
60-
61-
anim = animation.FuncAnimation(fig, animate, init_func=init,
62-
frames=num_frames)
6366
writer = NullMovieWriter()
67+
6468
anim.save(filename, dpi=dpi, writer=writer,
6569
savefig_kwargs=savefig_kwargs)
6670

67-
assert writer.fig == fig
71+
assert writer.fig == plt.figure(1) # The figure used by make_animation.
6872
assert writer.outfile == filename
6973
assert writer.dpi == dpi
7074
assert writer.args == ()
@@ -178,23 +182,8 @@ def animate(i):
178182

179183

180184
def test_no_length_frames():
181-
fig, ax = plt.subplots()
182-
line, = ax.plot([], [])
183-
184-
def init():
185-
line.set_data([], [])
186-
return line,
187-
188-
def animate(i):
189-
x = np.linspace(0, 10, 100)
190-
y = np.sin(x + i)
191-
line.set_data(x, y)
192-
return line,
193-
194-
anim = animation.FuncAnimation(fig, animate, init_func=init,
195-
frames=iter(range(5)))
196-
writer = NullMovieWriter()
197-
anim.save('unused.null', writer=writer)
185+
(make_animation(frames=iter(range(5)))
186+
.save('unused.null', writer=NullMovieWriter()))
198187

199188

200189
def test_movie_writer_registry():
@@ -212,10 +201,64 @@ def test_movie_writer_registry():
212201
assert not animation.writers.is_available("ffmpeg")
213202
# something which is guaranteed to be available in path
214203
# and exits immediately
215-
bin = u"true" if sys.platform != 'win32' else u"where"
204+
bin = "true" if sys.platform != 'win32' else "where"
216205
mpl.rcParams['animation.ffmpeg_path'] = bin
217206
assert animation.writers._dirty
218207
animation.writers.list() # resets
219208
assert not animation.writers._dirty
220209
assert animation.writers.is_available("ffmpeg")
221210
mpl.rcParams['animation.ffmpeg_path'] = ffmpeg_path
211+
212+
213+
@pytest.mark.skipif(
214+
not animation.writers.is_available(mpl.rcParams["animation.writer"]),
215+
reason="animation writer not installed")
216+
@pytest.mark.parametrize("method_name", ["to_html5_video", "to_jshtml"])
217+
def test_embed_limit(method_name, caplog):
218+
with mpl.rc_context({"animation.embed_limit": 1e-6}): # ~1 byte.
219+
getattr(make_animation(frames=1), method_name)()
220+
assert len(caplog.records) == 1
221+
record, = caplog.records
222+
assert (record.name == "matplotlib.animation"
223+
and record.levelname == "WARNING")
224+
225+
226+
@pytest.mark.skipif(
227+
not animation.writers.is_available(mpl.rcParams["animation.writer"]),
228+
reason="animation writer not installed")
229+
@pytest.mark.parametrize(
230+
"method_name",
231+
["to_html5_video",
232+
pytest.mark.xfail("to_jshtml")]) # Needs to be fixed.
233+
def test_cleanup_temporaries(method_name, tmpdir):
234+
with tmpdir.as_cwd():
235+
getattr(make_animation(frames=1), method_name)()
236+
assert list(Path(tmpdir).iterdir()) == []
237+
238+
239+
# Currently, this fails with a ValueError after we try to communicate() twice
240+
# with the Popen.
241+
@pytest.mark.xfail
242+
@pytest.mark.skipif(os.name != "posix", reason="requires a POSIX OS")
243+
def test_failing_ffmpeg(tmpdir, monkeypatch):
244+
"""
245+
Test that we correctly raise an OSError when ffmpeg fails.
246+
247+
To do so, mock ffmpeg using a simple executable shell script that
248+
succeeds when called with no arguments (so that it gets registered by
249+
`isAvailable`), but fails otherwise, and add it to the $PATH.
250+
"""
251+
try:
252+
with tmpdir.as_cwd():
253+
monkeypatch.setenv("PATH", ".:" + os.environ["PATH"])
254+
exe_path = Path(tmpdir, "ffmpeg")
255+
exe_path.write_text("""\
256+
#!/bin/sh
257+
[[ "$@" -gt 0 ]] && exit 1 || exit 0
258+
""")
259+
os.chmod(str(exe_path), 0o755)
260+
animation.writers.reset_available_writers()
261+
with pytest.raises(OSError):
262+
make_animation().save("test.mpeg")
263+
finally:
264+
animation.writers.reset_available_writers()

setupext.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -739,7 +739,7 @@ def get_namespace_packages(self):
739739

740740
class Tests(OptionalPackage):
741741
name = "tests"
742-
pytest_min_version = '3.1'
742+
pytest_min_version = '3.3.1'
743743
default_config = False
744744

745745
def check(self):

0 commit comments

Comments
 (0)