test_display.py
459 lines
| 14.8 KiB
| text/x-python
|
PythonLexer
Min RK
|
r19557 | # Copyright (c) IPython Development Team. | ||
# Distributed under the terms of the Modified BSD License. | ||||
import json | ||||
Jerry Fowler
|
r8077 | import os | ||
Min RK
|
r19557 | import warnings | ||
Jerry Fowler
|
r8077 | |||
Min RK
|
r23013 | from unittest import mock | ||
Jerry Fowler
|
r8077 | import nose.tools as nt | ||
Matthias Bussonnier
|
r25632 | from IPython import display | ||
MinRK
|
r15395 | from IPython.core.getipython import get_ipython | ||
Henry Fredrick Schreiner
|
r23962 | from IPython.utils.io import capture_output | ||
Thomas Kluyver
|
r22130 | from IPython.utils.tempdir import NamedFileInTemporaryDirectory | ||
Min RK
|
r21253 | from IPython import paths as ipath | ||
Matthias Bussonnier
|
r25335 | from IPython.testing.tools import AssertNotPrints | ||
Jerry Fowler
|
r8077 | |||
MinRK
|
r15395 | import IPython.testing.decorators as dec | ||
Jerry Fowler
|
r8077 | def test_image_size(): | ||
"""Simple test for display.Image(args, width=x,height=y)""" | ||||
thisurl = 'http://www.google.fr/images/srpr/logo3w.png' | ||||
img = display.Image(url=thisurl, width=200, height=200) | ||||
nt.assert_equal(u'<img src="%s" width="200" height="200"/>' % (thisurl), img._repr_html_()) | ||||
M Pacer
|
r23746 | img = display.Image(url=thisurl, metadata={'width':200, 'height':200}) | ||
nt.assert_equal(u'<img src="%s" width="200" height="200"/>' % (thisurl), img._repr_html_()) | ||||
Jerry Fowler
|
r8077 | img = display.Image(url=thisurl, width=200) | ||
nt.assert_equal(u'<img src="%s" width="200"/>' % (thisurl), img._repr_html_()) | ||||
img = display.Image(url=thisurl) | ||||
nt.assert_equal(u'<img src="%s"/>' % (thisurl), img._repr_html_()) | ||||
Min RK
|
r20986 | img = display.Image(url=thisurl, unconfined=True) | ||
nt.assert_equal(u'<img src="%s" class="unconfined"/>' % (thisurl), img._repr_html_()) | ||||
Jerry Fowler
|
r8077 | |||
Matthias Bussonnier
|
r23406 | |||
Min RK
|
r23849 | def test_image_mimes(): | ||
fmt = get_ipython().display_formatter.format | ||||
for format in display.Image._ACCEPTABLE_EMBEDDINGS: | ||||
mime = display.Image._MIMETYPES[format] | ||||
img = display.Image(b'garbage', format=format) | ||||
data, metadata = fmt(img) | ||||
nt.assert_equal(sorted(data), sorted([mime, 'text/plain'])) | ||||
Matthias Bussonnier
|
r23406 | def test_geojson(): | ||
gj = display.GeoJSON(data={ | ||||
"type": "Feature", | ||||
"geometry": { | ||||
"type": "Point", | ||||
"coordinates": [-81.327, 296.038] | ||||
}, | ||||
"properties": { | ||||
"name": "Inca City" | ||||
} | ||||
}, | ||||
url_template="http://s3-eu-west-1.amazonaws.com/whereonmars.cartodb.net/{basemap_id}/{z}/{x}/{y}.png", | ||||
layer_options={ | ||||
"basemap_id": "celestia_mars-shaded-16k_global", | ||||
"attribution": "Celestia/praesepe", | ||||
"minZoom": 0, | ||||
"maxZoom": 18, | ||||
}) | ||||
Grant Nestor
|
r23410 | nt.assert_equal(u'<IPython.core.display.GeoJSON object>', str(gj)) | ||
Matthias Bussonnier
|
r23406 | |||
MinRK
|
r10804 | def test_retina_png(): | ||
here = os.path.dirname(__file__) | ||||
img = display.Image(os.path.join(here, "2x2.png"), retina=True) | ||||
nt.assert_equal(img.height, 1) | ||||
nt.assert_equal(img.width, 1) | ||||
data, md = img._repr_png_() | ||||
nt.assert_equal(md['width'], 1) | ||||
nt.assert_equal(md['height'], 1) | ||||
Ian Castleden
|
r25616 | def test_embed_svg_url(): | ||
Ian Castleden
|
r25617 | import gzip | ||
from io import BytesIO | ||||
svg_data = b'<svg><circle x="0" y="0" r="1"/></svg>' | ||||
url = 'http://test.com/circle.svg' | ||||
gzip_svg = BytesIO() | ||||
with gzip.open(gzip_svg, 'wb') as fp: | ||||
fp.write(svg_data) | ||||
gzip_svg = gzip_svg.getvalue() | ||||
def mocked_urlopen(*args, **kwargs): | ||||
class MockResponse: | ||||
def __init__(self, svg): | ||||
self._svg_data = svg | ||||
self.headers = {'content-type': 'image/svg+xml'} | ||||
def read(self): | ||||
return self._svg_data | ||||
if args[0] == url: | ||||
return MockResponse(svg_data) | ||||
elif args[0] == url + 'z': | ||||
ret= MockResponse(gzip_svg) | ||||
ret.headers['content-encoding']= 'gzip' | ||||
return ret | ||||
return MockResponse(None) | ||||
with mock.patch('urllib.request.urlopen', side_effect=mocked_urlopen): | ||||
svg = display.SVG(url=url) | ||||
nt.assert_true(svg._repr_svg_().startswith('<svg')) | ||||
svg = display.SVG(url=url + 'z') | ||||
nt.assert_true(svg._repr_svg_().startswith('<svg')) | ||||
MinRK
|
r10804 | def test_retina_jpeg(): | ||
here = os.path.dirname(__file__) | ||||
img = display.Image(os.path.join(here, "2x2.jpg"), retina=True) | ||||
nt.assert_equal(img.height, 1) | ||||
nt.assert_equal(img.width, 1) | ||||
data, md = img._repr_jpeg_() | ||||
nt.assert_equal(md['width'], 1) | ||||
nt.assert_equal(md['height'], 1) | ||||
Matthias Bussonnier
|
r22013 | def test_base64image(): | ||
display.Image("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEUAAACnej3aAAAAAWJLR0QAiAUdSAAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB94BCRQnOqNu0b4AAAAKSURBVAjXY2AAAAACAAHiIbwzAAAAAElFTkSuQmCC") | ||||
Jerry Fowler
|
r8077 | def test_image_filename_defaults(): | ||
'''test format constraint, and validity of jpeg and png''' | ||||
tpath = ipath.get_ipython_package_dir() | ||||
Grant Nestor
|
r23822 | nt.assert_raises(ValueError, display.Image, filename=os.path.join(tpath, 'testing/tests/badformat.zip'), | ||
embed=True) | ||||
Jerry Fowler
|
r8077 | nt.assert_raises(ValueError, display.Image) | ||
nt.assert_raises(ValueError, display.Image, data='this is not an image', format='badformat', embed=True) | ||||
Julian Taylor
|
r14749 | # check boths paths to allow packages to test at build and install time | ||
Min RK
|
r21251 | imgfile = os.path.join(tpath, 'core/tests/2x2.png') | ||
Jerry Fowler
|
r8077 | img = display.Image(filename=imgfile) | ||
nt.assert_equal('png', img.format) | ||||
nt.assert_is_not_none(img._repr_png_()) | ||||
img = display.Image(filename=os.path.join(tpath, 'testing/tests/logo.jpg'), embed=False) | ||||
nt.assert_equal('jpeg', img.format) | ||||
nt.assert_is_none(img._repr_jpeg_()) | ||||
MinRK
|
r15395 | |||
def _get_inline_config(): | ||||
Min RK
|
r21337 | from ipykernel.pylab.config import InlineBackend | ||
MinRK
|
r15395 | return InlineBackend.instance() | ||
Adam Eury
|
r22947 | |||
Matthias Bussonnier
|
r26071 | |||
@dec.skip_without("ipykernel") | ||||
@dec.skip_without("matplotlib") | ||||
MinRK
|
r15395 | def test_set_matplotlib_close(): | ||
cfg = _get_inline_config() | ||||
cfg.close_figures = False | ||||
display.set_matplotlib_close() | ||||
assert cfg.close_figures | ||||
display.set_matplotlib_close(False) | ||||
assert not cfg.close_figures | ||||
_fmt_mime_map = { | ||||
'png': 'image/png', | ||||
'jpeg': 'image/jpeg', | ||||
'pdf': 'application/pdf', | ||||
'retina': 'image/png', | ||||
'svg': 'image/svg+xml', | ||||
} | ||||
@dec.skip_without('matplotlib') | ||||
def test_set_matplotlib_formats(): | ||||
from matplotlib.figure import Figure | ||||
formatters = get_ipython().display_formatter.formatters | ||||
for formats in [ | ||||
('png',), | ||||
('pdf', 'svg'), | ||||
('jpeg', 'retina', 'png'), | ||||
(), | ||||
]: | ||||
active_mimes = {_fmt_mime_map[fmt] for fmt in formats} | ||||
display.set_matplotlib_formats(*formats) | ||||
for mime, f in formatters.items(): | ||||
if mime in active_mimes: | ||||
nt.assert_in(Figure, f) | ||||
else: | ||||
nt.assert_not_in(Figure, f) | ||||
Matthias Bussonnier
|
r26071 | |||
@dec.skip_without("ipykernel") | ||||
@dec.skip_without("matplotlib") | ||||
MinRK
|
r15395 | def test_set_matplotlib_formats_kwargs(): | ||
from matplotlib.figure import Figure | ||||
ip = get_ipython() | ||||
cfg = _get_inline_config() | ||||
cfg.print_figure_kwargs.update(dict(foo='bar')) | ||||
Matthias Bussonnier
|
r26390 | kwargs = dict(dpi=150) | ||
MinRK
|
r15395 | display.set_matplotlib_formats('png', **kwargs) | ||
formatter = ip.display_formatter.formatters['image/png'] | ||||
f = formatter.lookup_by_type(Figure) | ||||
cell = f.__closure__[0].cell_contents | ||||
expected = kwargs | ||||
expected.update(cfg.print_figure_kwargs) | ||||
nt.assert_equal(cell, expected) | ||||
Matthias Bussonnier
|
r23710 | def test_display_available(): | ||
""" | ||||
Test that display is available without import | ||||
We don't really care if it's in builtin or anything else, but it should | ||||
always be available. | ||||
""" | ||||
ip = get_ipython() | ||||
with AssertNotPrints('NameError'): | ||||
ip.run_cell('display') | ||||
try: | ||||
ip.run_cell('del display') | ||||
except NameError: | ||||
pass # it's ok, it might be in builtins | ||||
# even if deleted it should be back | ||||
with AssertNotPrints('NameError'): | ||||
ip.run_cell('display') | ||||
ryan thielke
|
r23729 | def test_textdisplayobj_pretty_repr(): | ||
p = display.Pretty("This is a simple test") | ||||
nt.assert_equal(repr(p), '<IPython.core.display.Pretty object>') | ||||
nt.assert_equal(p.data, 'This is a simple test') | ||||
p._show_mem_addr = True | ||||
nt.assert_equal(repr(p), object.__repr__(p)) | ||||
Matthias Bussonnier
|
r23710 | |||
Jessica B. Hamrick
|
r16397 | def test_displayobject_repr(): | ||
h = display.HTML('<br />') | ||||
nt.assert_equal(repr(h), '<IPython.core.display.HTML object>') | ||||
h._show_mem_addr = True | ||||
Jessica B. Hamrick
|
r16398 | nt.assert_equal(repr(h), object.__repr__(h)) | ||
Jessica B. Hamrick
|
r16397 | h._show_mem_addr = False | ||
nt.assert_equal(repr(h), '<IPython.core.display.HTML object>') | ||||
j = display.Javascript('') | ||||
nt.assert_equal(repr(j), '<IPython.core.display.Javascript object>') | ||||
j._show_mem_addr = True | ||||
Jessica B. Hamrick
|
r16398 | nt.assert_equal(repr(j), object.__repr__(j)) | ||
Jessica B. Hamrick
|
r16397 | j._show_mem_addr = False | ||
nt.assert_equal(repr(j), '<IPython.core.display.Javascript object>') | ||||
Min RK
|
r19557 | |||
Michael Penkov
|
r24619 | @mock.patch('warnings.warn') | ||
def test_encourage_iframe_over_html(m_warn): | ||||
Michael Penkov
|
r24654 | display.HTML() | ||
m_warn.assert_not_called() | ||||
Michael Penkov
|
r24619 | display.HTML('<br />') | ||
m_warn.assert_not_called() | ||||
Michael Penkov
|
r24653 | display.HTML('<html><p>Lots of content here</p><iframe src="http://a.com"></iframe>') | ||
m_warn.assert_not_called() | ||||
Michael Penkov
|
r24619 | display.HTML('<iframe src="http://a.com"></iframe>') | ||
m_warn.assert_called_with('Consider using IPython.display.IFrame instead') | ||||
Michael Penkov
|
r24654 | m_warn.reset_mock() | ||
display.HTML('<IFRAME SRC="http://a.com"></IFRAME>') | ||||
m_warn.assert_called_with('Consider using IPython.display.IFrame instead') | ||||
Marius van Niekerk
|
r23855 | def test_progress(): | ||
p = display.ProgressBar(10) | ||||
Henry Fredrick Schreiner
|
r23943 | nt.assert_in('0/10',repr(p)) | ||
Marius van Niekerk
|
r23861 | p.html_width = '100%' | ||
p.progress = 5 | ||||
nt.assert_equal(p._repr_html_(), "<progress style='width:100%' max='10' value='5'></progress>") | ||||
Marius van Niekerk
|
r23855 | |||
Henry Fredrick Schreiner
|
r23962 | def test_progress_iter(): | ||
with capture_output(display=False) as captured: | ||||
for i in display.ProgressBar(5): | ||||
out = captured.stdout | ||||
nt.assert_in('{0}/5'.format(i), out) | ||||
out = captured.stdout | ||||
Henry Fredrick Schreiner
|
r23943 | nt.assert_in('5/5', out) | ||
Min RK
|
r19557 | def test_json(): | ||
d = {'a': 5} | ||||
lis = [d] | ||||
dhirschf
|
r24413 | metadata = [ | ||
{'expanded': False, 'root': 'root'}, | ||||
{'expanded': True, 'root': 'root'}, | ||||
{'expanded': False, 'root': 'custom'}, | ||||
{'expanded': True, 'root': 'custom'}, | ||||
] | ||||
json_objs = [ | ||||
display.JSON(d), | ||||
display.JSON(d, expanded=True), | ||||
display.JSON(d, root='custom'), | ||||
display.JSON(d, expanded=True, root='custom'), | ||||
] | ||||
for j, md in zip(json_objs, metadata): | ||||
nt.assert_equal(j._repr_json_(), (d, md)) | ||||
Adam Eury
|
r22947 | |||
Min RK
|
r19557 | with warnings.catch_warnings(record=True) as w: | ||
Min RK
|
r19559 | warnings.simplefilter("always") | ||
Min RK
|
r19557 | j = display.JSON(json.dumps(d)) | ||
Bussonnier Matthias
|
r19558 | nt.assert_equal(len(w), 1) | ||
dhirschf
|
r24413 | nt.assert_equal(j._repr_json_(), (d, metadata[0])) | ||
json_objs = [ | ||||
display.JSON(lis), | ||||
display.JSON(lis, expanded=True), | ||||
display.JSON(lis, root='custom'), | ||||
display.JSON(lis, expanded=True, root='custom'), | ||||
] | ||||
for j, md in zip(json_objs, metadata): | ||||
nt.assert_equal(j._repr_json_(), (lis, md)) | ||||
Adam Eury
|
r22947 | |||
Min RK
|
r19557 | with warnings.catch_warnings(record=True) as w: | ||
Min RK
|
r19559 | warnings.simplefilter("always") | ||
Min RK
|
r19557 | j = display.JSON(json.dumps(lis)) | ||
Bussonnier Matthias
|
r19558 | nt.assert_equal(len(w), 1) | ||
dhirschf
|
r24413 | nt.assert_equal(j._repr_json_(), (lis, metadata[0])) | ||
Adam Eury
|
r22947 | |||
sukisuki
|
r21266 | def test_video_embedding(): | ||
"""use a tempfile, with dummy-data, to ensure that video embedding doesn't crash""" | ||||
Min RK
|
r22116 | v = display.Video("http://ignored") | ||
assert not v.embed | ||||
html = v._repr_html_() | ||||
nt.assert_not_in('src="data:', html) | ||||
nt.assert_in('src="http://ignored"', html) | ||||
with nt.assert_raises(ValueError): | ||||
v = display.Video(b'abc') | ||||
Thomas Kluyver
|
r22130 | with NamedFileInTemporaryDirectory('test.mp4') as f: | ||
f.write(b'abc') | ||||
f.close() | ||||
sukisuki
|
r21266 | |||
Min RK
|
r22116 | v = display.Video(f.name) | ||
assert not v.embed | ||||
html = v._repr_html_() | ||||
nt.assert_not_in('src="data:', html) | ||||
Adam Eury
|
r22947 | |||
sukisuki
|
r21266 | v = display.Video(f.name, embed=True) | ||
html = v._repr_html_() | ||||
nt.assert_in('src="data:video/mp4;base64,YWJj"',html) | ||||
Adam Eury
|
r22947 | |||
Min RK
|
r22115 | v = display.Video(f.name, embed=True, mimetype='video/other') | ||
html = v._repr_html_() | ||||
nt.assert_in('src="data:video/other;base64,YWJj"',html) | ||||
Adam Eury
|
r22947 | |||
Min RK
|
r22115 | v = display.Video(b'abc', embed=True, mimetype='video/mp4') | ||
html = v._repr_html_() | ||||
nt.assert_in('src="data:video/mp4;base64,YWJj"',html) | ||||
v = display.Video(u'YWJj', embed=True, mimetype='video/xyz') | ||||
html = v._repr_html_() | ||||
nt.assert_in('src="data:video/xyz;base64,YWJj"',html) | ||||
Min RK
|
r23013 | |||
Thomas Kluyver
|
r24301 | def test_html_metadata(): | ||
s = "<h1>Test</h1>" | ||||
h = display.HTML(s, metadata={"isolated": True}) | ||||
nt.assert_equal(h._repr_html_(), (s, {"isolated": True})) | ||||
Min RK
|
r23013 | |||
def test_display_id(): | ||||
ip = get_ipython() | ||||
with mock.patch.object(ip.display_pub, 'publish') as pub: | ||||
handle = display.display('x') | ||||
nt.assert_is(handle, None) | ||||
handle = display.display('y', display_id='secret') | ||||
nt.assert_is_instance(handle, display.DisplayHandle) | ||||
handle2 = display.display('z', display_id=True) | ||||
nt.assert_is_instance(handle2, display.DisplayHandle) | ||||
nt.assert_not_equal(handle.display_id, handle2.display_id) | ||||
nt.assert_equal(pub.call_count, 3) | ||||
args, kwargs = pub.call_args_list[0] | ||||
nt.assert_equal(args, ()) | ||||
nt.assert_equal(kwargs, { | ||||
'data': { | ||||
'text/plain': repr('x') | ||||
}, | ||||
'metadata': {}, | ||||
}) | ||||
args, kwargs = pub.call_args_list[1] | ||||
nt.assert_equal(args, ()) | ||||
nt.assert_equal(kwargs, { | ||||
'data': { | ||||
'text/plain': repr('y') | ||||
}, | ||||
'metadata': {}, | ||||
'transient': { | ||||
'display_id': handle.display_id, | ||||
}, | ||||
}) | ||||
args, kwargs = pub.call_args_list[2] | ||||
nt.assert_equal(args, ()) | ||||
nt.assert_equal(kwargs, { | ||||
'data': { | ||||
'text/plain': repr('z') | ||||
}, | ||||
'metadata': {}, | ||||
'transient': { | ||||
'display_id': handle2.display_id, | ||||
}, | ||||
}) | ||||
def test_update_display(): | ||||
ip = get_ipython() | ||||
with mock.patch.object(ip.display_pub, 'publish') as pub: | ||||
with nt.assert_raises(TypeError): | ||||
display.update_display('x') | ||||
display.update_display('x', display_id='1') | ||||
display.update_display('y', display_id='2') | ||||
args, kwargs = pub.call_args_list[0] | ||||
nt.assert_equal(args, ()) | ||||
nt.assert_equal(kwargs, { | ||||
'data': { | ||||
'text/plain': repr('x') | ||||
}, | ||||
'metadata': {}, | ||||
'transient': { | ||||
'display_id': '1', | ||||
}, | ||||
'update': True, | ||||
}) | ||||
args, kwargs = pub.call_args_list[1] | ||||
nt.assert_equal(args, ()) | ||||
nt.assert_equal(kwargs, { | ||||
'data': { | ||||
'text/plain': repr('y') | ||||
}, | ||||
'metadata': {}, | ||||
'transient': { | ||||
'display_id': '2', | ||||
}, | ||||
'update': True, | ||||
}) | ||||
def test_display_handle(): | ||||
ip = get_ipython() | ||||
handle = display.DisplayHandle() | ||||
nt.assert_is_instance(handle.display_id, str) | ||||
handle = display.DisplayHandle('my-id') | ||||
nt.assert_equal(handle.display_id, 'my-id') | ||||
with mock.patch.object(ip.display_pub, 'publish') as pub: | ||||
handle.display('x') | ||||
handle.update('y') | ||||
args, kwargs = pub.call_args_list[0] | ||||
nt.assert_equal(args, ()) | ||||
nt.assert_equal(kwargs, { | ||||
'data': { | ||||
'text/plain': repr('x') | ||||
}, | ||||
'metadata': {}, | ||||
'transient': { | ||||
'display_id': handle.display_id, | ||||
} | ||||
}) | ||||
args, kwargs = pub.call_args_list[1] | ||||
nt.assert_equal(args, ()) | ||||
nt.assert_equal(kwargs, { | ||||
'data': { | ||||
'text/plain': repr('y') | ||||
}, | ||||
'metadata': {}, | ||||
'transient': { | ||||
'display_id': handle.display_id, | ||||
}, | ||||
'update': True, | ||||
}) | ||||
Min RK
|
r23849 | |||