1# Copyright (c) IPython Development Team. 2# Distributed under the terms of the Modified BSD License. 3 4import json 5import os 6import sys 7import warnings 8 9import nose.tools as nt 10 11from IPython.core import display 12from IPython.core.getipython import get_ipython 13from IPython.utils.io import capture_output 14from IPython.utils.tempdir import NamedFileInTemporaryDirectory 15from IPython import paths as ipath 16from IPython.testing.tools import AssertPrints, AssertNotPrints 17 18import IPython.testing.decorators as dec 19 20if sys.version_info < (3,): 21 import mock 22else: 23 from unittest import mock 24 25def test_image_size(): 26 """Simple test for display.Image(args, width=x,height=y)""" 27 thisurl = 'http://www.google.fr/images/srpr/logo3w.png' 28 img = display.Image(url=thisurl, width=200, height=200) 29 nt.assert_equal(u'<img src="%s" width="200" height="200"/>' % (thisurl), img._repr_html_()) 30 img = display.Image(url=thisurl, width=200) 31 nt.assert_equal(u'<img src="%s" width="200"/>' % (thisurl), img._repr_html_()) 32 img = display.Image(url=thisurl) 33 nt.assert_equal(u'<img src="%s"/>' % (thisurl), img._repr_html_()) 34 img = display.Image(url=thisurl, unconfined=True) 35 nt.assert_equal(u'<img src="%s" class="unconfined"/>' % (thisurl), img._repr_html_()) 36 37def test_retina_png(): 38 here = os.path.dirname(__file__) 39 img = display.Image(os.path.join(here, "2x2.png"), retina=True) 40 nt.assert_equal(img.height, 1) 41 nt.assert_equal(img.width, 1) 42 data, md = img._repr_png_() 43 nt.assert_equal(md['width'], 1) 44 nt.assert_equal(md['height'], 1) 45 46def test_retina_jpeg(): 47 here = os.path.dirname(__file__) 48 img = display.Image(os.path.join(here, "2x2.jpg"), retina=True) 49 nt.assert_equal(img.height, 1) 50 nt.assert_equal(img.width, 1) 51 data, md = img._repr_jpeg_() 52 nt.assert_equal(md['width'], 1) 53 nt.assert_equal(md['height'], 1) 54 55def test_base64image(): 56 display.Image("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEUAAACnej3aAAAAAWJLR0QAiAUdSAAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB94BCRQnOqNu0b4AAAAKSURBVAjXY2AAAAACAAHiIbwzAAAAAElFTkSuQmCC") 57 58def test_image_filename_defaults(): 59 '''test format constraint, and validity of jpeg and png''' 60 tpath = ipath.get_ipython_package_dir() 61 nt.assert_raises(ValueError, display.Image, filename=os.path.join(tpath, 'testing/tests/badformat.gif'), 62 embed=True) 63 nt.assert_raises(ValueError, display.Image) 64 nt.assert_raises(ValueError, display.Image, data='this is not an image', format='badformat', embed=True) 65 # check boths paths to allow packages to test at build and install time 66 imgfile = os.path.join(tpath, 'core/tests/2x2.png') 67 img = display.Image(filename=imgfile) 68 nt.assert_equal('png', img.format) 69 nt.assert_is_not_none(img._repr_png_()) 70 img = display.Image(filename=os.path.join(tpath, 'testing/tests/logo.jpg'), embed=False) 71 nt.assert_equal('jpeg', img.format) 72 nt.assert_is_none(img._repr_jpeg_()) 73 74def _get_inline_config(): 75 from ipykernel.pylab.config import InlineBackend 76 return InlineBackend.instance() 77 78@dec.skip_without('matplotlib') 79def test_set_matplotlib_close(): 80 cfg = _get_inline_config() 81 cfg.close_figures = False 82 display.set_matplotlib_close() 83 assert cfg.close_figures 84 display.set_matplotlib_close(False) 85 assert not cfg.close_figures 86 87_fmt_mime_map = { 88 'png': 'image/png', 89 'jpeg': 'image/jpeg', 90 'pdf': 'application/pdf', 91 'retina': 'image/png', 92 'svg': 'image/svg+xml', 93} 94 95@dec.skip_without('matplotlib') 96def test_set_matplotlib_formats(): 97 from matplotlib.figure import Figure 98 formatters = get_ipython().display_formatter.formatters 99 for formats in [ 100 ('png',), 101 ('pdf', 'svg'), 102 ('jpeg', 'retina', 'png'), 103 (), 104 ]: 105 active_mimes = {_fmt_mime_map[fmt] for fmt in formats} 106 display.set_matplotlib_formats(*formats) 107 for mime, f in formatters.items(): 108 if mime in active_mimes: 109 nt.assert_in(Figure, f) 110 else: 111 nt.assert_not_in(Figure, f) 112 113@dec.skip_without('matplotlib') 114def test_set_matplotlib_formats_kwargs(): 115 from matplotlib.figure import Figure 116 ip = get_ipython() 117 cfg = _get_inline_config() 118 cfg.print_figure_kwargs.update(dict(foo='bar')) 119 kwargs = dict(quality=10) 120 display.set_matplotlib_formats('png', **kwargs) 121 formatter = ip.display_formatter.formatters['image/png'] 122 f = formatter.lookup_by_type(Figure) 123 cell = f.__closure__[0].cell_contents 124 expected = kwargs 125 expected.update(cfg.print_figure_kwargs) 126 nt.assert_equal(cell, expected) 127 128def test_display_available(): 129 """ 130 Test that display is available without import 131 132 We don't really care if it's in builtin or anything else, but it should 133 always be available. 134 """ 135 ip = get_ipython() 136 with AssertNotPrints('NameError'): 137 ip.run_cell('display') 138 try: 139 ip.run_cell('del display') 140 except NameError: 141 pass # it's ok, it might be in builtins 142 # even if deleted it should be back 143 with AssertNotPrints('NameError'): 144 ip.run_cell('display') 145 146def test_textdisplayobj_pretty_repr(): 147 p = display.Pretty("This is a simple test") 148 nt.assert_equal(repr(p), '<IPython.core.display.Pretty object>') 149 nt.assert_equal(p.data, 'This is a simple test') 150 151 p._show_mem_addr = True 152 nt.assert_equal(repr(p), object.__repr__(p)) 153 154def test_displayobject_repr(): 155 h = display.HTML('<br />') 156 nt.assert_equal(repr(h), '<IPython.core.display.HTML object>') 157 h._show_mem_addr = True 158 nt.assert_equal(repr(h), object.__repr__(h)) 159 h._show_mem_addr = False 160 nt.assert_equal(repr(h), '<IPython.core.display.HTML object>') 161 162 j = display.Javascript('') 163 nt.assert_equal(repr(j), '<IPython.core.display.Javascript object>') 164 j._show_mem_addr = True 165 nt.assert_equal(repr(j), object.__repr__(j)) 166 j._show_mem_addr = False 167 nt.assert_equal(repr(j), '<IPython.core.display.Javascript object>') 168 169def test_progress(): 170 p = display.ProgressBar(10) 171 nt.assert_in('0/10',repr(p)) 172 p.html_width = '100%' 173 p.progress = 5 174 nt.assert_equal(p._repr_html_(), "<progress style='width:100%' max='10' value='5'></progress>") 175 176def test_progress_iter(): 177 with capture_output(display=False) as captured: 178 for i in display.ProgressBar(5): 179 out = captured.stdout 180 nt.assert_in('{0}/5'.format(i), out) 181 out = captured.stdout 182 nt.assert_in('5/5', out) 183 184def test_json(): 185 d = {'a': 5} 186 lis = [d] 187 j = display.JSON(d) 188 nt.assert_equal(j._repr_json_(), d) 189 190 with warnings.catch_warnings(record=True) as w: 191 warnings.simplefilter("always") 192 j = display.JSON(json.dumps(d)) 193 nt.assert_equal(len(w), 1) 194 nt.assert_equal(j._repr_json_(), d) 195 196 j = display.JSON(lis) 197 nt.assert_equal(j._repr_json_(), lis) 198 199 with warnings.catch_warnings(record=True) as w: 200 warnings.simplefilter("always") 201 j = display.JSON(json.dumps(lis)) 202 nt.assert_equal(len(w), 1) 203 nt.assert_equal(j._repr_json_(), lis) 204 205def test_video_embedding(): 206 """use a tempfile, with dummy-data, to ensure that video embedding doesn't crash""" 207 v = display.Video("http://ignored") 208 assert not v.embed 209 html = v._repr_html_() 210 nt.assert_not_in('src="data:', html) 211 nt.assert_in('src="http://ignored"', html) 212 213 with nt.assert_raises(ValueError): 214 v = display.Video(b'abc') 215 216 with NamedFileInTemporaryDirectory('test.mp4') as f: 217 f.write(b'abc') 218 f.close() 219 220 v = display.Video(f.name) 221 assert not v.embed 222 html = v._repr_html_() 223 nt.assert_not_in('src="data:', html) 224 225 v = display.Video(f.name, embed=True) 226 html = v._repr_html_() 227 nt.assert_in('src="data:video/mp4;base64,YWJj"',html) 228 229 v = display.Video(f.name, embed=True, mimetype='video/other') 230 html = v._repr_html_() 231 nt.assert_in('src="data:video/other;base64,YWJj"',html) 232 233 v = display.Video(b'abc', embed=True, mimetype='video/mp4') 234 html = v._repr_html_() 235 nt.assert_in('src="data:video/mp4;base64,YWJj"',html) 236 237 v = display.Video(u'YWJj', embed=True, mimetype='video/xyz') 238 html = v._repr_html_() 239 nt.assert_in('src="data:video/xyz;base64,YWJj"',html) 240 241 242def test_display_id(): 243 ip = get_ipython() 244 with mock.patch.object(ip.display_pub, 'publish') as pub: 245 handle = display.display('x') 246 nt.assert_is(handle, None) 247 handle = display.display('y', display_id='secret') 248 nt.assert_is_instance(handle, display.DisplayHandle) 249 handle2 = display.display('z', display_id=True) 250 nt.assert_is_instance(handle2, display.DisplayHandle) 251 nt.assert_not_equal(handle.display_id, handle2.display_id) 252 253 nt.assert_equal(pub.call_count, 3) 254 args, kwargs = pub.call_args_list[0] 255 nt.assert_equal(args, ()) 256 nt.assert_equal(kwargs, { 257 'data': { 258 'text/plain': repr('x') 259 }, 260 'metadata': {}, 261 }) 262 args, kwargs = pub.call_args_list[1] 263 nt.assert_equal(args, ()) 264 nt.assert_equal(kwargs, { 265 'data': { 266 'text/plain': repr('y') 267 }, 268 'metadata': {}, 269 'transient': { 270 'display_id': handle.display_id, 271 }, 272 }) 273 args, kwargs = pub.call_args_list[2] 274 nt.assert_equal(args, ()) 275 nt.assert_equal(kwargs, { 276 'data': { 277 'text/plain': repr('z') 278 }, 279 'metadata': {}, 280 'transient': { 281 'display_id': handle2.display_id, 282 }, 283 }) 284 285 286def test_update_display(): 287 ip = get_ipython() 288 with mock.patch.object(ip.display_pub, 'publish') as pub: 289 with nt.assert_raises(TypeError): 290 display.update_display('x') 291 display.update_display('x', display_id='1') 292 display.update_display('y', display_id='2') 293 args, kwargs = pub.call_args_list[0] 294 nt.assert_equal(args, ()) 295 nt.assert_equal(kwargs, { 296 'data': { 297 'text/plain': repr('x') 298 }, 299 'metadata': {}, 300 'transient': { 301 'display_id': '1', 302 }, 303 'update': True, 304 }) 305 args, kwargs = pub.call_args_list[1] 306 nt.assert_equal(args, ()) 307 nt.assert_equal(kwargs, { 308 'data': { 309 'text/plain': repr('y') 310 }, 311 'metadata': {}, 312 'transient': { 313 'display_id': '2', 314 }, 315 'update': True, 316 }) 317 318 319def test_display_handle(): 320 ip = get_ipython() 321 handle = display.DisplayHandle() 322 if sys.version_info < (3,): 323 nt.assert_is_instance(handle.display_id, unicode) 324 else: 325 nt.assert_is_instance(handle.display_id, str) 326 handle = display.DisplayHandle('my-id') 327 nt.assert_equal(handle.display_id, 'my-id') 328 with mock.patch.object(ip.display_pub, 'publish') as pub: 329 handle.display('x') 330 handle.update('y') 331 332 args, kwargs = pub.call_args_list[0] 333 nt.assert_equal(args, ()) 334 nt.assert_equal(kwargs, { 335 'data': { 336 'text/plain': repr('x') 337 }, 338 'metadata': {}, 339 'transient': { 340 'display_id': handle.display_id, 341 } 342 }) 343 args, kwargs = pub.call_args_list[1] 344 nt.assert_equal(args, ()) 345 nt.assert_equal(kwargs, { 346 'data': { 347 'text/plain': repr('y') 348 }, 349 'metadata': {}, 350 'transient': { 351 'display_id': handle.display_id, 352 }, 353 'update': True, 354 }) 355