1
- from __future__ import absolute_import , division , print_function
2
-
3
- import six
4
-
1
+ import os
2
+ from pathlib import Path
5
3
import sys
6
4
import tempfile
7
5
@@ -42,29 +40,35 @@ def finish(self):
42
40
pass
43
41
44
42
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 ([])
49
46
50
47
def init ():
51
48
pass
52
49
53
50
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.
55
59
56
60
num_frames = 5
61
+ anim = make_animation (frames = num_frames )
62
+
57
63
filename = "unused.null"
58
64
dpi = 50
59
65
savefig_kwargs = dict (foo = 0 )
60
-
61
- anim = animation .FuncAnimation (fig , animate , init_func = init ,
62
- frames = num_frames )
63
66
writer = NullMovieWriter ()
67
+
64
68
anim .save (filename , dpi = dpi , writer = writer ,
65
69
savefig_kwargs = savefig_kwargs )
66
70
67
- assert writer .fig == fig
71
+ assert writer .fig == plt . figure ( 1 ) # The figure used by make_animation.
68
72
assert writer .outfile == filename
69
73
assert writer .dpi == dpi
70
74
assert writer .args == ()
@@ -178,23 +182,8 @@ def animate(i):
178
182
179
183
180
184
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 ()))
198
187
199
188
200
189
def test_movie_writer_registry ():
@@ -212,10 +201,64 @@ def test_movie_writer_registry():
212
201
assert not animation .writers .is_available ("ffmpeg" )
213
202
# something which is guaranteed to be available in path
214
203
# and exits immediately
215
- bin = u "true" if sys .platform != 'win32' else u "where"
204
+ bin = "true" if sys .platform != 'win32' else "where"
216
205
mpl .rcParams ['animation.ffmpeg_path' ] = bin
217
206
assert animation .writers ._dirty
218
207
animation .writers .list () # resets
219
208
assert not animation .writers ._dirty
220
209
assert animation .writers .is_available ("ffmpeg" )
221
210
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 ()
0 commit comments