##// END OF EJS Templates
Add a testcase for Image raising on bad filename
Blazej Michalik -
Show More
@@ -1,459 +1,463 b''
1 1 # Copyright (c) IPython Development Team.
2 2 # Distributed under the terms of the Modified BSD License.
3 3
4 4 import json
5 5 import os
6 6 import warnings
7 7
8 8 from unittest import mock
9 9
10 10 import nose.tools as nt
11 11
12 12 from IPython import display
13 13 from IPython.core.getipython import get_ipython
14 14 from IPython.utils.io import capture_output
15 15 from IPython.utils.tempdir import NamedFileInTemporaryDirectory
16 16 from IPython import paths as ipath
17 17 from IPython.testing.tools import AssertNotPrints
18 18
19 19 import IPython.testing.decorators as dec
20 20
21 21 def test_image_size():
22 22 """Simple test for display.Image(args, width=x,height=y)"""
23 23 thisurl = 'http://www.google.fr/images/srpr/logo3w.png'
24 24 img = display.Image(url=thisurl, width=200, height=200)
25 25 nt.assert_equal(u'<img src="%s" width="200" height="200"/>' % (thisurl), img._repr_html_())
26 26 img = display.Image(url=thisurl, metadata={'width':200, 'height':200})
27 27 nt.assert_equal(u'<img src="%s" width="200" height="200"/>' % (thisurl), img._repr_html_())
28 28 img = display.Image(url=thisurl, width=200)
29 29 nt.assert_equal(u'<img src="%s" width="200"/>' % (thisurl), img._repr_html_())
30 30 img = display.Image(url=thisurl)
31 31 nt.assert_equal(u'<img src="%s"/>' % (thisurl), img._repr_html_())
32 32 img = display.Image(url=thisurl, unconfined=True)
33 33 nt.assert_equal(u'<img src="%s" class="unconfined"/>' % (thisurl), img._repr_html_())
34 34
35 35
36 36 def test_image_mimes():
37 37 fmt = get_ipython().display_formatter.format
38 38 for format in display.Image._ACCEPTABLE_EMBEDDINGS:
39 39 mime = display.Image._MIMETYPES[format]
40 40 img = display.Image(b'garbage', format=format)
41 41 data, metadata = fmt(img)
42 42 nt.assert_equal(sorted(data), sorted([mime, 'text/plain']))
43 43
44 44
45 45 def test_geojson():
46 46
47 47 gj = display.GeoJSON(data={
48 48 "type": "Feature",
49 49 "geometry": {
50 50 "type": "Point",
51 51 "coordinates": [-81.327, 296.038]
52 52 },
53 53 "properties": {
54 54 "name": "Inca City"
55 55 }
56 56 },
57 57 url_template="http://s3-eu-west-1.amazonaws.com/whereonmars.cartodb.net/{basemap_id}/{z}/{x}/{y}.png",
58 58 layer_options={
59 59 "basemap_id": "celestia_mars-shaded-16k_global",
60 60 "attribution": "Celestia/praesepe",
61 61 "minZoom": 0,
62 62 "maxZoom": 18,
63 63 })
64 64 nt.assert_equal(u'<IPython.core.display.GeoJSON object>', str(gj))
65 65
66 66 def test_retina_png():
67 67 here = os.path.dirname(__file__)
68 68 img = display.Image(os.path.join(here, "2x2.png"), retina=True)
69 69 nt.assert_equal(img.height, 1)
70 70 nt.assert_equal(img.width, 1)
71 71 data, md = img._repr_png_()
72 72 nt.assert_equal(md['width'], 1)
73 73 nt.assert_equal(md['height'], 1)
74 74
75 75 def test_embed_svg_url():
76 76 import gzip
77 77 from io import BytesIO
78 78 svg_data = b'<svg><circle x="0" y="0" r="1"/></svg>'
79 79 url = 'http://test.com/circle.svg'
80 80
81 81 gzip_svg = BytesIO()
82 82 with gzip.open(gzip_svg, 'wb') as fp:
83 83 fp.write(svg_data)
84 84 gzip_svg = gzip_svg.getvalue()
85 85
86 86 def mocked_urlopen(*args, **kwargs):
87 87 class MockResponse:
88 88 def __init__(self, svg):
89 89 self._svg_data = svg
90 90 self.headers = {'content-type': 'image/svg+xml'}
91 91
92 92 def read(self):
93 93 return self._svg_data
94 94
95 95 if args[0] == url:
96 96 return MockResponse(svg_data)
97 97 elif args[0] == url + 'z':
98 98 ret= MockResponse(gzip_svg)
99 99 ret.headers['content-encoding']= 'gzip'
100 100 return ret
101 101 return MockResponse(None)
102 102
103 103 with mock.patch('urllib.request.urlopen', side_effect=mocked_urlopen):
104 104 svg = display.SVG(url=url)
105 105 nt.assert_true(svg._repr_svg_().startswith('<svg'))
106 106 svg = display.SVG(url=url + 'z')
107 107 nt.assert_true(svg._repr_svg_().startswith('<svg'))
108 108
109 109 def test_retina_jpeg():
110 110 here = os.path.dirname(__file__)
111 111 img = display.Image(os.path.join(here, "2x2.jpg"), retina=True)
112 112 nt.assert_equal(img.height, 1)
113 113 nt.assert_equal(img.width, 1)
114 114 data, md = img._repr_jpeg_()
115 115 nt.assert_equal(md['width'], 1)
116 116 nt.assert_equal(md['height'], 1)
117 117
118 118 def test_base64image():
119 119 display.Image("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEUAAACnej3aAAAAAWJLR0QAiAUdSAAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB94BCRQnOqNu0b4AAAAKSURBVAjXY2AAAAACAAHiIbwzAAAAAElFTkSuQmCC")
120 120
121 121 def test_image_filename_defaults():
122 122 '''test format constraint, and validity of jpeg and png'''
123 123 tpath = ipath.get_ipython_package_dir()
124 124 nt.assert_raises(ValueError, display.Image, filename=os.path.join(tpath, 'testing/tests/badformat.zip'),
125 125 embed=True)
126 126 nt.assert_raises(ValueError, display.Image)
127 127 nt.assert_raises(ValueError, display.Image, data='this is not an image', format='badformat', embed=True)
128 128 # check boths paths to allow packages to test at build and install time
129 129 imgfile = os.path.join(tpath, 'core/tests/2x2.png')
130 130 img = display.Image(filename=imgfile)
131 131 nt.assert_equal('png', img.format)
132 132 nt.assert_is_not_none(img._repr_png_())
133 133 img = display.Image(filename=os.path.join(tpath, 'testing/tests/logo.jpg'), embed=False)
134 134 nt.assert_equal('jpeg', img.format)
135 135 nt.assert_is_none(img._repr_jpeg_())
136 136
137 137 def _get_inline_config():
138 138 from ipykernel.pylab.config import InlineBackend
139 139 return InlineBackend.instance()
140 140
141 141
142 142 @dec.skip_without("ipykernel")
143 143 @dec.skip_without("matplotlib")
144 144 def test_set_matplotlib_close():
145 145 cfg = _get_inline_config()
146 146 cfg.close_figures = False
147 147 display.set_matplotlib_close()
148 148 assert cfg.close_figures
149 149 display.set_matplotlib_close(False)
150 150 assert not cfg.close_figures
151 151
152 152 _fmt_mime_map = {
153 153 'png': 'image/png',
154 154 'jpeg': 'image/jpeg',
155 155 'pdf': 'application/pdf',
156 156 'retina': 'image/png',
157 157 'svg': 'image/svg+xml',
158 158 }
159 159
160 160 @dec.skip_without('matplotlib')
161 161 def test_set_matplotlib_formats():
162 162 from matplotlib.figure import Figure
163 163 formatters = get_ipython().display_formatter.formatters
164 164 for formats in [
165 165 ('png',),
166 166 ('pdf', 'svg'),
167 167 ('jpeg', 'retina', 'png'),
168 168 (),
169 169 ]:
170 170 active_mimes = {_fmt_mime_map[fmt] for fmt in formats}
171 171 display.set_matplotlib_formats(*formats)
172 172 for mime, f in formatters.items():
173 173 if mime in active_mimes:
174 174 nt.assert_in(Figure, f)
175 175 else:
176 176 nt.assert_not_in(Figure, f)
177 177
178 178
179 179 @dec.skip_without("ipykernel")
180 180 @dec.skip_without("matplotlib")
181 181 def test_set_matplotlib_formats_kwargs():
182 182 from matplotlib.figure import Figure
183 183 ip = get_ipython()
184 184 cfg = _get_inline_config()
185 185 cfg.print_figure_kwargs.update(dict(foo='bar'))
186 186 kwargs = dict(dpi=150)
187 187 display.set_matplotlib_formats('png', **kwargs)
188 188 formatter = ip.display_formatter.formatters['image/png']
189 189 f = formatter.lookup_by_type(Figure)
190 190 cell = f.__closure__[0].cell_contents
191 191 expected = kwargs
192 192 expected.update(cfg.print_figure_kwargs)
193 193 nt.assert_equal(cell, expected)
194 194
195 195 def test_display_available():
196 196 """
197 197 Test that display is available without import
198 198
199 199 We don't really care if it's in builtin or anything else, but it should
200 200 always be available.
201 201 """
202 202 ip = get_ipython()
203 203 with AssertNotPrints('NameError'):
204 204 ip.run_cell('display')
205 205 try:
206 206 ip.run_cell('del display')
207 207 except NameError:
208 208 pass # it's ok, it might be in builtins
209 209 # even if deleted it should be back
210 210 with AssertNotPrints('NameError'):
211 211 ip.run_cell('display')
212 212
213 213 def test_textdisplayobj_pretty_repr():
214 214 p = display.Pretty("This is a simple test")
215 215 nt.assert_equal(repr(p), '<IPython.core.display.Pretty object>')
216 216 nt.assert_equal(p.data, 'This is a simple test')
217 217
218 218 p._show_mem_addr = True
219 219 nt.assert_equal(repr(p), object.__repr__(p))
220 220
221 221 def test_displayobject_repr():
222 222 h = display.HTML('<br />')
223 223 nt.assert_equal(repr(h), '<IPython.core.display.HTML object>')
224 224 h._show_mem_addr = True
225 225 nt.assert_equal(repr(h), object.__repr__(h))
226 226 h._show_mem_addr = False
227 227 nt.assert_equal(repr(h), '<IPython.core.display.HTML object>')
228 228
229 229 j = display.Javascript('')
230 230 nt.assert_equal(repr(j), '<IPython.core.display.Javascript object>')
231 231 j._show_mem_addr = True
232 232 nt.assert_equal(repr(j), object.__repr__(j))
233 233 j._show_mem_addr = False
234 234 nt.assert_equal(repr(j), '<IPython.core.display.Javascript object>')
235 235
236 236 @mock.patch('warnings.warn')
237 237 def test_encourage_iframe_over_html(m_warn):
238 238 display.HTML()
239 239 m_warn.assert_not_called()
240 240
241 241 display.HTML('<br />')
242 242 m_warn.assert_not_called()
243 243
244 244 display.HTML('<html><p>Lots of content here</p><iframe src="http://a.com"></iframe>')
245 245 m_warn.assert_not_called()
246 246
247 247 display.HTML('<iframe src="http://a.com"></iframe>')
248 248 m_warn.assert_called_with('Consider using IPython.display.IFrame instead')
249 249
250 250 m_warn.reset_mock()
251 251 display.HTML('<IFRAME SRC="http://a.com"></IFRAME>')
252 252 m_warn.assert_called_with('Consider using IPython.display.IFrame instead')
253 253
254 254 def test_progress():
255 255 p = display.ProgressBar(10)
256 256 nt.assert_in('0/10',repr(p))
257 257 p.html_width = '100%'
258 258 p.progress = 5
259 259 nt.assert_equal(p._repr_html_(), "<progress style='width:100%' max='10' value='5'></progress>")
260 260
261 261 def test_progress_iter():
262 262 with capture_output(display=False) as captured:
263 263 for i in display.ProgressBar(5):
264 264 out = captured.stdout
265 265 nt.assert_in('{0}/5'.format(i), out)
266 266 out = captured.stdout
267 267 nt.assert_in('5/5', out)
268 268
269 269 def test_json():
270 270 d = {'a': 5}
271 271 lis = [d]
272 272 metadata = [
273 273 {'expanded': False, 'root': 'root'},
274 274 {'expanded': True, 'root': 'root'},
275 275 {'expanded': False, 'root': 'custom'},
276 276 {'expanded': True, 'root': 'custom'},
277 277 ]
278 278 json_objs = [
279 279 display.JSON(d),
280 280 display.JSON(d, expanded=True),
281 281 display.JSON(d, root='custom'),
282 282 display.JSON(d, expanded=True, root='custom'),
283 283 ]
284 284 for j, md in zip(json_objs, metadata):
285 285 nt.assert_equal(j._repr_json_(), (d, md))
286 286
287 287 with warnings.catch_warnings(record=True) as w:
288 288 warnings.simplefilter("always")
289 289 j = display.JSON(json.dumps(d))
290 290 nt.assert_equal(len(w), 1)
291 291 nt.assert_equal(j._repr_json_(), (d, metadata[0]))
292 292
293 293 json_objs = [
294 294 display.JSON(lis),
295 295 display.JSON(lis, expanded=True),
296 296 display.JSON(lis, root='custom'),
297 297 display.JSON(lis, expanded=True, root='custom'),
298 298 ]
299 299 for j, md in zip(json_objs, metadata):
300 300 nt.assert_equal(j._repr_json_(), (lis, md))
301 301
302 302 with warnings.catch_warnings(record=True) as w:
303 303 warnings.simplefilter("always")
304 304 j = display.JSON(json.dumps(lis))
305 305 nt.assert_equal(len(w), 1)
306 306 nt.assert_equal(j._repr_json_(), (lis, metadata[0]))
307 307
308 308 def test_video_embedding():
309 309 """use a tempfile, with dummy-data, to ensure that video embedding doesn't crash"""
310 310 v = display.Video("http://ignored")
311 311 assert not v.embed
312 312 html = v._repr_html_()
313 313 nt.assert_not_in('src="data:', html)
314 314 nt.assert_in('src="http://ignored"', html)
315 315
316 316 with nt.assert_raises(ValueError):
317 317 v = display.Video(b'abc')
318 318
319 319 with NamedFileInTemporaryDirectory('test.mp4') as f:
320 320 f.write(b'abc')
321 321 f.close()
322 322
323 323 v = display.Video(f.name)
324 324 assert not v.embed
325 325 html = v._repr_html_()
326 326 nt.assert_not_in('src="data:', html)
327 327
328 328 v = display.Video(f.name, embed=True)
329 329 html = v._repr_html_()
330 330 nt.assert_in('src="data:video/mp4;base64,YWJj"',html)
331 331
332 332 v = display.Video(f.name, embed=True, mimetype='video/other')
333 333 html = v._repr_html_()
334 334 nt.assert_in('src="data:video/other;base64,YWJj"',html)
335 335
336 336 v = display.Video(b'abc', embed=True, mimetype='video/mp4')
337 337 html = v._repr_html_()
338 338 nt.assert_in('src="data:video/mp4;base64,YWJj"',html)
339 339
340 340 v = display.Video(u'YWJj', embed=True, mimetype='video/xyz')
341 341 html = v._repr_html_()
342 342 nt.assert_in('src="data:video/xyz;base64,YWJj"',html)
343 343
344 344 def test_html_metadata():
345 345 s = "<h1>Test</h1>"
346 346 h = display.HTML(s, metadata={"isolated": True})
347 347 nt.assert_equal(h._repr_html_(), (s, {"isolated": True}))
348 348
349 349 def test_display_id():
350 350 ip = get_ipython()
351 351 with mock.patch.object(ip.display_pub, 'publish') as pub:
352 352 handle = display.display('x')
353 353 nt.assert_is(handle, None)
354 354 handle = display.display('y', display_id='secret')
355 355 nt.assert_is_instance(handle, display.DisplayHandle)
356 356 handle2 = display.display('z', display_id=True)
357 357 nt.assert_is_instance(handle2, display.DisplayHandle)
358 358 nt.assert_not_equal(handle.display_id, handle2.display_id)
359 359
360 360 nt.assert_equal(pub.call_count, 3)
361 361 args, kwargs = pub.call_args_list[0]
362 362 nt.assert_equal(args, ())
363 363 nt.assert_equal(kwargs, {
364 364 'data': {
365 365 'text/plain': repr('x')
366 366 },
367 367 'metadata': {},
368 368 })
369 369 args, kwargs = pub.call_args_list[1]
370 370 nt.assert_equal(args, ())
371 371 nt.assert_equal(kwargs, {
372 372 'data': {
373 373 'text/plain': repr('y')
374 374 },
375 375 'metadata': {},
376 376 'transient': {
377 377 'display_id': handle.display_id,
378 378 },
379 379 })
380 380 args, kwargs = pub.call_args_list[2]
381 381 nt.assert_equal(args, ())
382 382 nt.assert_equal(kwargs, {
383 383 'data': {
384 384 'text/plain': repr('z')
385 385 },
386 386 'metadata': {},
387 387 'transient': {
388 388 'display_id': handle2.display_id,
389 389 },
390 390 })
391 391
392 392
393 393 def test_update_display():
394 394 ip = get_ipython()
395 395 with mock.patch.object(ip.display_pub, 'publish') as pub:
396 396 with nt.assert_raises(TypeError):
397 397 display.update_display('x')
398 398 display.update_display('x', display_id='1')
399 399 display.update_display('y', display_id='2')
400 400 args, kwargs = pub.call_args_list[0]
401 401 nt.assert_equal(args, ())
402 402 nt.assert_equal(kwargs, {
403 403 'data': {
404 404 'text/plain': repr('x')
405 405 },
406 406 'metadata': {},
407 407 'transient': {
408 408 'display_id': '1',
409 409 },
410 410 'update': True,
411 411 })
412 412 args, kwargs = pub.call_args_list[1]
413 413 nt.assert_equal(args, ())
414 414 nt.assert_equal(kwargs, {
415 415 'data': {
416 416 'text/plain': repr('y')
417 417 },
418 418 'metadata': {},
419 419 'transient': {
420 420 'display_id': '2',
421 421 },
422 422 'update': True,
423 423 })
424 424
425 425
426 426 def test_display_handle():
427 427 ip = get_ipython()
428 428 handle = display.DisplayHandle()
429 429 nt.assert_is_instance(handle.display_id, str)
430 430 handle = display.DisplayHandle('my-id')
431 431 nt.assert_equal(handle.display_id, 'my-id')
432 432 with mock.patch.object(ip.display_pub, 'publish') as pub:
433 433 handle.display('x')
434 434 handle.update('y')
435 435
436 436 args, kwargs = pub.call_args_list[0]
437 437 nt.assert_equal(args, ())
438 438 nt.assert_equal(kwargs, {
439 439 'data': {
440 440 'text/plain': repr('x')
441 441 },
442 442 'metadata': {},
443 443 'transient': {
444 444 'display_id': handle.display_id,
445 445 }
446 446 })
447 447 args, kwargs = pub.call_args_list[1]
448 448 nt.assert_equal(args, ())
449 449 nt.assert_equal(kwargs, {
450 450 'data': {
451 451 'text/plain': repr('y')
452 452 },
453 453 'metadata': {},
454 454 'transient': {
455 455 'display_id': handle.display_id,
456 456 },
457 457 'update': True,
458 458 })
459 459
460
461 @nt.raises(FileNotFoundError)
462 def test_image_bad_filename_raises_proper_exception():
463 display.Image('/this/file/does/not/exist/')
General Comments 0
You need to be logged in to leave comments. Login now