##// END OF EJS Templates
Backport PR #12296: Delete 109-112 for removing external test
Matthias Bussonnier -
Show More
@@ -1,460 +1,455
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.core 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 # do it for real: 6.1kB of data
110 url = "https://upload.wikimedia.org/wikipedia/commons/3/30/Vector-based_example.svg"
111 svg = display.SVG(url=url)
112 nt.assert_true(svg._repr_svg_().startswith('<svg'))
113
114 109 def test_retina_jpeg():
115 110 here = os.path.dirname(__file__)
116 111 img = display.Image(os.path.join(here, "2x2.jpg"), retina=True)
117 112 nt.assert_equal(img.height, 1)
118 113 nt.assert_equal(img.width, 1)
119 114 data, md = img._repr_jpeg_()
120 115 nt.assert_equal(md['width'], 1)
121 116 nt.assert_equal(md['height'], 1)
122 117
123 118 def test_base64image():
124 119 display.Image("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEUAAACnej3aAAAAAWJLR0QAiAUdSAAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB94BCRQnOqNu0b4AAAAKSURBVAjXY2AAAAACAAHiIbwzAAAAAElFTkSuQmCC")
125 120
126 121 def test_image_filename_defaults():
127 122 '''test format constraint, and validity of jpeg and png'''
128 123 tpath = ipath.get_ipython_package_dir()
129 124 nt.assert_raises(ValueError, display.Image, filename=os.path.join(tpath, 'testing/tests/badformat.zip'),
130 125 embed=True)
131 126 nt.assert_raises(ValueError, display.Image)
132 127 nt.assert_raises(ValueError, display.Image, data='this is not an image', format='badformat', embed=True)
133 128 # check boths paths to allow packages to test at build and install time
134 129 imgfile = os.path.join(tpath, 'core/tests/2x2.png')
135 130 img = display.Image(filename=imgfile)
136 131 nt.assert_equal('png', img.format)
137 132 nt.assert_is_not_none(img._repr_png_())
138 133 img = display.Image(filename=os.path.join(tpath, 'testing/tests/logo.jpg'), embed=False)
139 134 nt.assert_equal('jpeg', img.format)
140 135 nt.assert_is_none(img._repr_jpeg_())
141 136
142 137 def _get_inline_config():
143 138 from ipykernel.pylab.config import InlineBackend
144 139 return InlineBackend.instance()
145 140
146 141 @dec.skip_without('matplotlib')
147 142 def test_set_matplotlib_close():
148 143 cfg = _get_inline_config()
149 144 cfg.close_figures = False
150 145 display.set_matplotlib_close()
151 146 assert cfg.close_figures
152 147 display.set_matplotlib_close(False)
153 148 assert not cfg.close_figures
154 149
155 150 _fmt_mime_map = {
156 151 'png': 'image/png',
157 152 'jpeg': 'image/jpeg',
158 153 'pdf': 'application/pdf',
159 154 'retina': 'image/png',
160 155 'svg': 'image/svg+xml',
161 156 }
162 157
163 158 @dec.skip_without('matplotlib')
164 159 def test_set_matplotlib_formats():
165 160 from matplotlib.figure import Figure
166 161 formatters = get_ipython().display_formatter.formatters
167 162 for formats in [
168 163 ('png',),
169 164 ('pdf', 'svg'),
170 165 ('jpeg', 'retina', 'png'),
171 166 (),
172 167 ]:
173 168 active_mimes = {_fmt_mime_map[fmt] for fmt in formats}
174 169 display.set_matplotlib_formats(*formats)
175 170 for mime, f in formatters.items():
176 171 if mime in active_mimes:
177 172 nt.assert_in(Figure, f)
178 173 else:
179 174 nt.assert_not_in(Figure, f)
180 175
181 176 @dec.skip_without('matplotlib')
182 177 def test_set_matplotlib_formats_kwargs():
183 178 from matplotlib.figure import Figure
184 179 ip = get_ipython()
185 180 cfg = _get_inline_config()
186 181 cfg.print_figure_kwargs.update(dict(foo='bar'))
187 182 kwargs = dict(quality=10)
188 183 display.set_matplotlib_formats('png', **kwargs)
189 184 formatter = ip.display_formatter.formatters['image/png']
190 185 f = formatter.lookup_by_type(Figure)
191 186 cell = f.__closure__[0].cell_contents
192 187 expected = kwargs
193 188 expected.update(cfg.print_figure_kwargs)
194 189 nt.assert_equal(cell, expected)
195 190
196 191 def test_display_available():
197 192 """
198 193 Test that display is available without import
199 194
200 195 We don't really care if it's in builtin or anything else, but it should
201 196 always be available.
202 197 """
203 198 ip = get_ipython()
204 199 with AssertNotPrints('NameError'):
205 200 ip.run_cell('display')
206 201 try:
207 202 ip.run_cell('del display')
208 203 except NameError:
209 204 pass # it's ok, it might be in builtins
210 205 # even if deleted it should be back
211 206 with AssertNotPrints('NameError'):
212 207 ip.run_cell('display')
213 208
214 209 def test_textdisplayobj_pretty_repr():
215 210 p = display.Pretty("This is a simple test")
216 211 nt.assert_equal(repr(p), '<IPython.core.display.Pretty object>')
217 212 nt.assert_equal(p.data, 'This is a simple test')
218 213
219 214 p._show_mem_addr = True
220 215 nt.assert_equal(repr(p), object.__repr__(p))
221 216
222 217 def test_displayobject_repr():
223 218 h = display.HTML('<br />')
224 219 nt.assert_equal(repr(h), '<IPython.core.display.HTML object>')
225 220 h._show_mem_addr = True
226 221 nt.assert_equal(repr(h), object.__repr__(h))
227 222 h._show_mem_addr = False
228 223 nt.assert_equal(repr(h), '<IPython.core.display.HTML object>')
229 224
230 225 j = display.Javascript('')
231 226 nt.assert_equal(repr(j), '<IPython.core.display.Javascript object>')
232 227 j._show_mem_addr = True
233 228 nt.assert_equal(repr(j), object.__repr__(j))
234 229 j._show_mem_addr = False
235 230 nt.assert_equal(repr(j), '<IPython.core.display.Javascript object>')
236 231
237 232 @mock.patch('warnings.warn')
238 233 def test_encourage_iframe_over_html(m_warn):
239 234 display.HTML()
240 235 m_warn.assert_not_called()
241 236
242 237 display.HTML('<br />')
243 238 m_warn.assert_not_called()
244 239
245 240 display.HTML('<html><p>Lots of content here</p><iframe src="http://a.com"></iframe>')
246 241 m_warn.assert_not_called()
247 242
248 243 display.HTML('<iframe src="http://a.com"></iframe>')
249 244 m_warn.assert_called_with('Consider using IPython.display.IFrame instead')
250 245
251 246 m_warn.reset_mock()
252 247 display.HTML('<IFRAME SRC="http://a.com"></IFRAME>')
253 248 m_warn.assert_called_with('Consider using IPython.display.IFrame instead')
254 249
255 250 def test_progress():
256 251 p = display.ProgressBar(10)
257 252 nt.assert_in('0/10',repr(p))
258 253 p.html_width = '100%'
259 254 p.progress = 5
260 255 nt.assert_equal(p._repr_html_(), "<progress style='width:100%' max='10' value='5'></progress>")
261 256
262 257 def test_progress_iter():
263 258 with capture_output(display=False) as captured:
264 259 for i in display.ProgressBar(5):
265 260 out = captured.stdout
266 261 nt.assert_in('{0}/5'.format(i), out)
267 262 out = captured.stdout
268 263 nt.assert_in('5/5', out)
269 264
270 265 def test_json():
271 266 d = {'a': 5}
272 267 lis = [d]
273 268 metadata = [
274 269 {'expanded': False, 'root': 'root'},
275 270 {'expanded': True, 'root': 'root'},
276 271 {'expanded': False, 'root': 'custom'},
277 272 {'expanded': True, 'root': 'custom'},
278 273 ]
279 274 json_objs = [
280 275 display.JSON(d),
281 276 display.JSON(d, expanded=True),
282 277 display.JSON(d, root='custom'),
283 278 display.JSON(d, expanded=True, root='custom'),
284 279 ]
285 280 for j, md in zip(json_objs, metadata):
286 281 nt.assert_equal(j._repr_json_(), (d, md))
287 282
288 283 with warnings.catch_warnings(record=True) as w:
289 284 warnings.simplefilter("always")
290 285 j = display.JSON(json.dumps(d))
291 286 nt.assert_equal(len(w), 1)
292 287 nt.assert_equal(j._repr_json_(), (d, metadata[0]))
293 288
294 289 json_objs = [
295 290 display.JSON(lis),
296 291 display.JSON(lis, expanded=True),
297 292 display.JSON(lis, root='custom'),
298 293 display.JSON(lis, expanded=True, root='custom'),
299 294 ]
300 295 for j, md in zip(json_objs, metadata):
301 296 nt.assert_equal(j._repr_json_(), (lis, md))
302 297
303 298 with warnings.catch_warnings(record=True) as w:
304 299 warnings.simplefilter("always")
305 300 j = display.JSON(json.dumps(lis))
306 301 nt.assert_equal(len(w), 1)
307 302 nt.assert_equal(j._repr_json_(), (lis, metadata[0]))
308 303
309 304 def test_video_embedding():
310 305 """use a tempfile, with dummy-data, to ensure that video embedding doesn't crash"""
311 306 v = display.Video("http://ignored")
312 307 assert not v.embed
313 308 html = v._repr_html_()
314 309 nt.assert_not_in('src="data:', html)
315 310 nt.assert_in('src="http://ignored"', html)
316 311
317 312 with nt.assert_raises(ValueError):
318 313 v = display.Video(b'abc')
319 314
320 315 with NamedFileInTemporaryDirectory('test.mp4') as f:
321 316 f.write(b'abc')
322 317 f.close()
323 318
324 319 v = display.Video(f.name)
325 320 assert not v.embed
326 321 html = v._repr_html_()
327 322 nt.assert_not_in('src="data:', html)
328 323
329 324 v = display.Video(f.name, embed=True)
330 325 html = v._repr_html_()
331 326 nt.assert_in('src="data:video/mp4;base64,YWJj"',html)
332 327
333 328 v = display.Video(f.name, embed=True, mimetype='video/other')
334 329 html = v._repr_html_()
335 330 nt.assert_in('src="data:video/other;base64,YWJj"',html)
336 331
337 332 v = display.Video(b'abc', embed=True, mimetype='video/mp4')
338 333 html = v._repr_html_()
339 334 nt.assert_in('src="data:video/mp4;base64,YWJj"',html)
340 335
341 336 v = display.Video(u'YWJj', embed=True, mimetype='video/xyz')
342 337 html = v._repr_html_()
343 338 nt.assert_in('src="data:video/xyz;base64,YWJj"',html)
344 339
345 340 def test_html_metadata():
346 341 s = "<h1>Test</h1>"
347 342 h = display.HTML(s, metadata={"isolated": True})
348 343 nt.assert_equal(h._repr_html_(), (s, {"isolated": True}))
349 344
350 345 def test_display_id():
351 346 ip = get_ipython()
352 347 with mock.patch.object(ip.display_pub, 'publish') as pub:
353 348 handle = display.display('x')
354 349 nt.assert_is(handle, None)
355 350 handle = display.display('y', display_id='secret')
356 351 nt.assert_is_instance(handle, display.DisplayHandle)
357 352 handle2 = display.display('z', display_id=True)
358 353 nt.assert_is_instance(handle2, display.DisplayHandle)
359 354 nt.assert_not_equal(handle.display_id, handle2.display_id)
360 355
361 356 nt.assert_equal(pub.call_count, 3)
362 357 args, kwargs = pub.call_args_list[0]
363 358 nt.assert_equal(args, ())
364 359 nt.assert_equal(kwargs, {
365 360 'data': {
366 361 'text/plain': repr('x')
367 362 },
368 363 'metadata': {},
369 364 })
370 365 args, kwargs = pub.call_args_list[1]
371 366 nt.assert_equal(args, ())
372 367 nt.assert_equal(kwargs, {
373 368 'data': {
374 369 'text/plain': repr('y')
375 370 },
376 371 'metadata': {},
377 372 'transient': {
378 373 'display_id': handle.display_id,
379 374 },
380 375 })
381 376 args, kwargs = pub.call_args_list[2]
382 377 nt.assert_equal(args, ())
383 378 nt.assert_equal(kwargs, {
384 379 'data': {
385 380 'text/plain': repr('z')
386 381 },
387 382 'metadata': {},
388 383 'transient': {
389 384 'display_id': handle2.display_id,
390 385 },
391 386 })
392 387
393 388
394 389 def test_update_display():
395 390 ip = get_ipython()
396 391 with mock.patch.object(ip.display_pub, 'publish') as pub:
397 392 with nt.assert_raises(TypeError):
398 393 display.update_display('x')
399 394 display.update_display('x', display_id='1')
400 395 display.update_display('y', display_id='2')
401 396 args, kwargs = pub.call_args_list[0]
402 397 nt.assert_equal(args, ())
403 398 nt.assert_equal(kwargs, {
404 399 'data': {
405 400 'text/plain': repr('x')
406 401 },
407 402 'metadata': {},
408 403 'transient': {
409 404 'display_id': '1',
410 405 },
411 406 'update': True,
412 407 })
413 408 args, kwargs = pub.call_args_list[1]
414 409 nt.assert_equal(args, ())
415 410 nt.assert_equal(kwargs, {
416 411 'data': {
417 412 'text/plain': repr('y')
418 413 },
419 414 'metadata': {},
420 415 'transient': {
421 416 'display_id': '2',
422 417 },
423 418 'update': True,
424 419 })
425 420
426 421
427 422 def test_display_handle():
428 423 ip = get_ipython()
429 424 handle = display.DisplayHandle()
430 425 nt.assert_is_instance(handle.display_id, str)
431 426 handle = display.DisplayHandle('my-id')
432 427 nt.assert_equal(handle.display_id, 'my-id')
433 428 with mock.patch.object(ip.display_pub, 'publish') as pub:
434 429 handle.display('x')
435 430 handle.update('y')
436 431
437 432 args, kwargs = pub.call_args_list[0]
438 433 nt.assert_equal(args, ())
439 434 nt.assert_equal(kwargs, {
440 435 'data': {
441 436 'text/plain': repr('x')
442 437 },
443 438 'metadata': {},
444 439 'transient': {
445 440 'display_id': handle.display_id,
446 441 }
447 442 })
448 443 args, kwargs = pub.call_args_list[1]
449 444 nt.assert_equal(args, ())
450 445 nt.assert_equal(kwargs, {
451 446 'data': {
452 447 'text/plain': repr('y')
453 448 },
454 449 'metadata': {},
455 450 'transient': {
456 451 'display_id': handle.display_id,
457 452 },
458 453 'update': True,
459 454 })
460 455
General Comments 0
You need to be logged in to leave comments. Login now