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