##// END OF EJS Templates
start removing nose from IPython/lib/tests/test_display.py
Matthias Bussonnier -
Show More
@@ -1,266 +1,272 b''
1 """Tests for IPython.lib.display.
1 """Tests for IPython.lib.display.
2
2
3 """
3 """
4 #-----------------------------------------------------------------------------
4 #-----------------------------------------------------------------------------
5 # Copyright (c) 2012, the IPython Development Team.
5 # Copyright (c) 2012, the IPython Development Team.
6 #
6 #
7 # Distributed under the terms of the Modified BSD License.
7 # Distributed under the terms of the Modified BSD License.
8 #
8 #
9 # The full license is in the file COPYING.txt, distributed with this software.
9 # The full license is in the file COPYING.txt, distributed with this software.
10 #-----------------------------------------------------------------------------
10 #-----------------------------------------------------------------------------
11
11
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13 # Imports
13 # Imports
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15 from tempfile import NamedTemporaryFile, mkdtemp
15 from tempfile import NamedTemporaryFile, mkdtemp
16 from os.path import split, join as pjoin, dirname
16 from os.path import split, join as pjoin, dirname
17 import pathlib
17 import pathlib
18 from unittest import TestCase, mock
18 from unittest import TestCase, mock
19 import struct
19 import struct
20 import wave
20 import wave
21 from io import BytesIO
21 from io import BytesIO
22
22
23 # Third-party imports
23 # Third-party imports
24 import nose.tools as nt
24 import nose.tools as nt
25
25
26 try:
26 try:
27 import numpy
27 import numpy
28 except ImportError:
28 except ImportError:
29 pass
29 pass
30
30
31 # Our own imports
31 # Our own imports
32 from IPython.lib import display
32 from IPython.lib import display
33
33
34 from IPython.testing.decorators import skipif_not_numpy
34 from IPython.testing.decorators import skipif_not_numpy
35
35
36 #-----------------------------------------------------------------------------
36 #-----------------------------------------------------------------------------
37 # Classes and functions
37 # Classes and functions
38 #-----------------------------------------------------------------------------
38 #-----------------------------------------------------------------------------
39
39
40 #--------------------------
40 #--------------------------
41 # FileLink tests
41 # FileLink tests
42 #--------------------------
42 #--------------------------
43
43
44 def test_instantiation_FileLink():
44 def test_instantiation_FileLink():
45 """FileLink: Test class can be instantiated"""
45 """FileLink: Test class can be instantiated"""
46 fl = display.FileLink('example.txt')
46 fl = display.FileLink('example.txt')
47 # TODO: remove if when only Python >= 3.6 is supported
47 # TODO: remove if when only Python >= 3.6 is supported
48 fl = display.FileLink(pathlib.PurePath('example.txt'))
48 fl = display.FileLink(pathlib.PurePath('example.txt'))
49
49
50 def test_warning_on_non_existent_path_FileLink():
50 def test_warning_on_non_existent_path_FileLink():
51 """FileLink: Calling _repr_html_ on non-existent files returns a warning
51 """FileLink: Calling _repr_html_ on non-existent files returns a warning
52 """
52 """
53 fl = display.FileLink('example.txt')
53 fl = display.FileLink('example.txt')
54 nt.assert_true(fl._repr_html_().startswith('Path (<tt>example.txt</tt>)'))
54 nt.assert_true(fl._repr_html_().startswith('Path (<tt>example.txt</tt>)'))
55
55
56 def test_existing_path_FileLink():
56 def test_existing_path_FileLink():
57 """FileLink: Calling _repr_html_ functions as expected on existing filepath
57 """FileLink: Calling _repr_html_ functions as expected on existing filepath
58 """
58 """
59 tf = NamedTemporaryFile()
59 tf = NamedTemporaryFile()
60 fl = display.FileLink(tf.name)
60 fl = display.FileLink(tf.name)
61 actual = fl._repr_html_()
61 actual = fl._repr_html_()
62 expected = "<a href='%s' target='_blank'>%s</a><br>" % (tf.name,tf.name)
62 expected = "<a href='%s' target='_blank'>%s</a><br>" % (tf.name, tf.name)
63 nt.assert_equal(actual,expected)
63 assert actual == expected
64
64
65
65 def test_existing_path_FileLink_repr():
66 def test_existing_path_FileLink_repr():
66 """FileLink: Calling repr() functions as expected on existing filepath
67 """FileLink: Calling repr() functions as expected on existing filepath
67 """
68 """
68 tf = NamedTemporaryFile()
69 tf = NamedTemporaryFile()
69 fl = display.FileLink(tf.name)
70 fl = display.FileLink(tf.name)
70 actual = repr(fl)
71 actual = repr(fl)
71 expected = tf.name
72 expected = tf.name
72 nt.assert_equal(actual,expected)
73 assert actual == expected
74
73
75
74 def test_error_on_directory_to_FileLink():
76 def test_error_on_directory_to_FileLink():
75 """FileLink: Raises error when passed directory
77 """FileLink: Raises error when passed directory
76 """
78 """
77 td = mkdtemp()
79 td = mkdtemp()
78 nt.assert_raises(ValueError,display.FileLink,td)
80 nt.assert_raises(ValueError,display.FileLink,td)
79
81
80 #--------------------------
82 #--------------------------
81 # FileLinks tests
83 # FileLinks tests
82 #--------------------------
84 #--------------------------
83
85
84 def test_instantiation_FileLinks():
86 def test_instantiation_FileLinks():
85 """FileLinks: Test class can be instantiated
87 """FileLinks: Test class can be instantiated
86 """
88 """
87 fls = display.FileLinks('example')
89 fls = display.FileLinks('example')
88
90
89 def test_warning_on_non_existent_path_FileLinks():
91 def test_warning_on_non_existent_path_FileLinks():
90 """FileLinks: Calling _repr_html_ on non-existent files returns a warning
92 """FileLinks: Calling _repr_html_ on non-existent files returns a warning
91 """
93 """
92 fls = display.FileLinks('example')
94 fls = display.FileLinks('example')
93 nt.assert_true(fls._repr_html_().startswith('Path (<tt>example</tt>)'))
95 nt.assert_true(fls._repr_html_().startswith('Path (<tt>example</tt>)'))
94
96
95 def test_existing_path_FileLinks():
97 def test_existing_path_FileLinks():
96 """FileLinks: Calling _repr_html_ functions as expected on existing dir
98 """FileLinks: Calling _repr_html_ functions as expected on existing dir
97 """
99 """
98 td = mkdtemp()
100 td = mkdtemp()
99 tf1 = NamedTemporaryFile(dir=td)
101 tf1 = NamedTemporaryFile(dir=td)
100 tf2 = NamedTemporaryFile(dir=td)
102 tf2 = NamedTemporaryFile(dir=td)
101 fl = display.FileLinks(td)
103 fl = display.FileLinks(td)
102 actual = fl._repr_html_()
104 actual = fl._repr_html_()
103 actual = actual.split('\n')
105 actual = actual.split('\n')
104 actual.sort()
106 actual.sort()
105 # the links should always have forward slashes, even on windows, so replace
107 # the links should always have forward slashes, even on windows, so replace
106 # backslashes with forward slashes here
108 # backslashes with forward slashes here
107 expected = ["%s/<br>" % td,
109 expected = ["%s/<br>" % td,
108 "&nbsp;&nbsp;<a href='%s' target='_blank'>%s</a><br>" %\
110 "&nbsp;&nbsp;<a href='%s' target='_blank'>%s</a><br>" %\
109 (tf2.name.replace("\\","/"),split(tf2.name)[1]),
111 (tf2.name.replace("\\","/"),split(tf2.name)[1]),
110 "&nbsp;&nbsp;<a href='%s' target='_blank'>%s</a><br>" %\
112 "&nbsp;&nbsp;<a href='%s' target='_blank'>%s</a><br>" %\
111 (tf1.name.replace("\\","/"),split(tf1.name)[1])]
113 (tf1.name.replace("\\","/"),split(tf1.name)[1])]
112 expected.sort()
114 expected.sort()
113 # We compare the sorted list of links here as that's more reliable
115 # We compare the sorted list of links here as that's more reliable
114 nt.assert_equal(actual,expected)
116 assert actual == expected
117
115
118
116 def test_existing_path_FileLinks_alt_formatter():
119 def test_existing_path_FileLinks_alt_formatter():
117 """FileLinks: Calling _repr_html_ functions as expected w/ an alt formatter
120 """FileLinks: Calling _repr_html_ functions as expected w/ an alt formatter
118 """
121 """
119 td = mkdtemp()
122 td = mkdtemp()
120 tf1 = NamedTemporaryFile(dir=td)
123 tf1 = NamedTemporaryFile(dir=td)
121 tf2 = NamedTemporaryFile(dir=td)
124 tf2 = NamedTemporaryFile(dir=td)
122 def fake_formatter(dirname,fnames,included_suffixes):
125 def fake_formatter(dirname,fnames,included_suffixes):
123 return ["hello","world"]
126 return ["hello","world"]
124 fl = display.FileLinks(td,notebook_display_formatter=fake_formatter)
127 fl = display.FileLinks(td,notebook_display_formatter=fake_formatter)
125 actual = fl._repr_html_()
128 actual = fl._repr_html_()
126 actual = actual.split('\n')
129 actual = actual.split('\n')
127 actual.sort()
130 actual.sort()
128 expected = ["hello","world"]
131 expected = ["hello","world"]
129 expected.sort()
132 expected.sort()
130 # We compare the sorted list of links here as that's more reliable
133 # We compare the sorted list of links here as that's more reliable
131 nt.assert_equal(actual,expected)
134 assert actual == expected
135
132
136
133 def test_existing_path_FileLinks_repr():
137 def test_existing_path_FileLinks_repr():
134 """FileLinks: Calling repr() functions as expected on existing directory """
138 """FileLinks: Calling repr() functions as expected on existing directory """
135 td = mkdtemp()
139 td = mkdtemp()
136 tf1 = NamedTemporaryFile(dir=td)
140 tf1 = NamedTemporaryFile(dir=td)
137 tf2 = NamedTemporaryFile(dir=td)
141 tf2 = NamedTemporaryFile(dir=td)
138 fl = display.FileLinks(td)
142 fl = display.FileLinks(td)
139 actual = repr(fl)
143 actual = repr(fl)
140 actual = actual.split('\n')
144 actual = actual.split('\n')
141 actual.sort()
145 actual.sort()
142 expected = ['%s/' % td, ' %s' % split(tf1.name)[1],' %s' % split(tf2.name)[1]]
146 expected = ['%s/' % td, ' %s' % split(tf1.name)[1],' %s' % split(tf2.name)[1]]
143 expected.sort()
147 expected.sort()
144 # We compare the sorted list of links here as that's more reliable
148 # We compare the sorted list of links here as that's more reliable
145 nt.assert_equal(actual,expected)
149 assert actual == expected
150
146
151
147 def test_existing_path_FileLinks_repr_alt_formatter():
152 def test_existing_path_FileLinks_repr_alt_formatter():
148 """FileLinks: Calling repr() functions as expected w/ alt formatter
153 """FileLinks: Calling repr() functions as expected w/ alt formatter
149 """
154 """
150 td = mkdtemp()
155 td = mkdtemp()
151 tf1 = NamedTemporaryFile(dir=td)
156 tf1 = NamedTemporaryFile(dir=td)
152 tf2 = NamedTemporaryFile(dir=td)
157 tf2 = NamedTemporaryFile(dir=td)
153 def fake_formatter(dirname,fnames,included_suffixes):
158 def fake_formatter(dirname,fnames,included_suffixes):
154 return ["hello","world"]
159 return ["hello","world"]
155 fl = display.FileLinks(td,terminal_display_formatter=fake_formatter)
160 fl = display.FileLinks(td,terminal_display_formatter=fake_formatter)
156 actual = repr(fl)
161 actual = repr(fl)
157 actual = actual.split('\n')
162 actual = actual.split('\n')
158 actual.sort()
163 actual.sort()
159 expected = ["hello","world"]
164 expected = ["hello","world"]
160 expected.sort()
165 expected.sort()
161 # We compare the sorted list of links here as that's more reliable
166 # We compare the sorted list of links here as that's more reliable
162 nt.assert_equal(actual,expected)
167 assert actual == expected
168
163
169
164 def test_error_on_file_to_FileLinks():
170 def test_error_on_file_to_FileLinks():
165 """FileLinks: Raises error when passed file
171 """FileLinks: Raises error when passed file
166 """
172 """
167 td = mkdtemp()
173 td = mkdtemp()
168 tf1 = NamedTemporaryFile(dir=td)
174 tf1 = NamedTemporaryFile(dir=td)
169 nt.assert_raises(ValueError,display.FileLinks,tf1.name)
175 nt.assert_raises(ValueError,display.FileLinks,tf1.name)
170
176
171 def test_recursive_FileLinks():
177 def test_recursive_FileLinks():
172 """FileLinks: Does not recurse when recursive=False
178 """FileLinks: Does not recurse when recursive=False
173 """
179 """
174 td = mkdtemp()
180 td = mkdtemp()
175 tf = NamedTemporaryFile(dir=td)
181 tf = NamedTemporaryFile(dir=td)
176 subtd = mkdtemp(dir=td)
182 subtd = mkdtemp(dir=td)
177 subtf = NamedTemporaryFile(dir=subtd)
183 subtf = NamedTemporaryFile(dir=subtd)
178 fl = display.FileLinks(td)
184 fl = display.FileLinks(td)
179 actual = str(fl)
185 actual = str(fl)
180 actual = actual.split('\n')
186 actual = actual.split('\n')
181 nt.assert_equal(len(actual), 4, actual)
187 assert len(actual) == 4, actual
182 fl = display.FileLinks(td, recursive=False)
188 fl = display.FileLinks(td, recursive=False)
183 actual = str(fl)
189 actual = str(fl)
184 actual = actual.split('\n')
190 actual = actual.split('\n')
185 nt.assert_equal(len(actual), 2, actual)
191 assert len(actual) == 2, actual
186
192
187 def test_audio_from_file():
193 def test_audio_from_file():
188 path = pjoin(dirname(__file__), 'test.wav')
194 path = pjoin(dirname(__file__), 'test.wav')
189 display.Audio(filename=path)
195 display.Audio(filename=path)
190
196
191 class TestAudioDataWithNumpy(TestCase):
197 class TestAudioDataWithNumpy(TestCase):
192
198
193 @skipif_not_numpy
199 @skipif_not_numpy
194 def test_audio_from_numpy_array(self):
200 def test_audio_from_numpy_array(self):
195 test_tone = get_test_tone()
201 test_tone = get_test_tone()
196 audio = display.Audio(test_tone, rate=44100)
202 audio = display.Audio(test_tone, rate=44100)
197 nt.assert_equal(len(read_wav(audio.data)), len(test_tone))
203 assert len(read_wav(audio.data)) == len(test_tone)
198
204
199 @skipif_not_numpy
205 @skipif_not_numpy
200 def test_audio_from_list(self):
206 def test_audio_from_list(self):
201 test_tone = get_test_tone()
207 test_tone = get_test_tone()
202 audio = display.Audio(list(test_tone), rate=44100)
208 audio = display.Audio(list(test_tone), rate=44100)
203 nt.assert_equal(len(read_wav(audio.data)), len(test_tone))
209 assert len(read_wav(audio.data)) == len(test_tone)
204
210
205 @skipif_not_numpy
211 @skipif_not_numpy
206 def test_audio_from_numpy_array_without_rate_raises(self):
212 def test_audio_from_numpy_array_without_rate_raises(self):
207 nt.assert_raises(ValueError, display.Audio, get_test_tone())
213 nt.assert_raises(ValueError, display.Audio, get_test_tone())
208
214
209 @skipif_not_numpy
215 @skipif_not_numpy
210 def test_audio_data_normalization(self):
216 def test_audio_data_normalization(self):
211 expected_max_value = numpy.iinfo(numpy.int16).max
217 expected_max_value = numpy.iinfo(numpy.int16).max
212 for scale in [1, 0.5, 2]:
218 for scale in [1, 0.5, 2]:
213 audio = display.Audio(get_test_tone(scale), rate=44100)
219 audio = display.Audio(get_test_tone(scale), rate=44100)
214 actual_max_value = numpy.max(numpy.abs(read_wav(audio.data)))
220 actual_max_value = numpy.max(numpy.abs(read_wav(audio.data)))
215 nt.assert_equal(actual_max_value, expected_max_value)
221 assert actual_max_value == expected_max_value
216
222
217 @skipif_not_numpy
223 @skipif_not_numpy
218 def test_audio_data_without_normalization(self):
224 def test_audio_data_without_normalization(self):
219 max_int16 = numpy.iinfo(numpy.int16).max
225 max_int16 = numpy.iinfo(numpy.int16).max
220 for scale in [1, 0.5, 0.2]:
226 for scale in [1, 0.5, 0.2]:
221 test_tone = get_test_tone(scale)
227 test_tone = get_test_tone(scale)
222 test_tone_max_abs = numpy.max(numpy.abs(test_tone))
228 test_tone_max_abs = numpy.max(numpy.abs(test_tone))
223 expected_max_value = int(max_int16 * test_tone_max_abs)
229 expected_max_value = int(max_int16 * test_tone_max_abs)
224 audio = display.Audio(test_tone, rate=44100, normalize=False)
230 audio = display.Audio(test_tone, rate=44100, normalize=False)
225 actual_max_value = numpy.max(numpy.abs(read_wav(audio.data)))
231 actual_max_value = numpy.max(numpy.abs(read_wav(audio.data)))
226 nt.assert_equal(actual_max_value, expected_max_value)
232 assert actual_max_value == expected_max_value
227
233
228 def test_audio_data_without_normalization_raises_for_invalid_data(self):
234 def test_audio_data_without_normalization_raises_for_invalid_data(self):
229 nt.assert_raises(
235 nt.assert_raises(
230 ValueError,
236 ValueError,
231 lambda: display.Audio([1.001], rate=44100, normalize=False))
237 lambda: display.Audio([1.001], rate=44100, normalize=False))
232 nt.assert_raises(
238 nt.assert_raises(
233 ValueError,
239 ValueError,
234 lambda: display.Audio([-1.001], rate=44100, normalize=False))
240 lambda: display.Audio([-1.001], rate=44100, normalize=False))
235
241
236 def simulate_numpy_not_installed():
242 def simulate_numpy_not_installed():
237 try:
243 try:
238 import numpy
244 import numpy
239 return mock.patch('numpy.array', mock.MagicMock(side_effect=ImportError))
245 return mock.patch('numpy.array', mock.MagicMock(side_effect=ImportError))
240 except ModuleNotFoundError:
246 except ModuleNotFoundError:
241 return lambda x:x
247 return lambda x:x
242
248
243 @simulate_numpy_not_installed()
249 @simulate_numpy_not_installed()
244 class TestAudioDataWithoutNumpy(TestAudioDataWithNumpy):
250 class TestAudioDataWithoutNumpy(TestAudioDataWithNumpy):
245 # All tests from `TestAudioDataWithNumpy` are inherited.
251 # All tests from `TestAudioDataWithNumpy` are inherited.
246
252
247 @skipif_not_numpy
253 @skipif_not_numpy
248 def test_audio_raises_for_nested_list(self):
254 def test_audio_raises_for_nested_list(self):
249 stereo_signal = [list(get_test_tone())] * 2
255 stereo_signal = [list(get_test_tone())] * 2
250 nt.assert_raises(
256 nt.assert_raises(
251 TypeError,
257 TypeError,
252 lambda: display.Audio(stereo_signal, rate=44100))
258 lambda: display.Audio(stereo_signal, rate=44100))
253
259
254 @skipif_not_numpy
260 @skipif_not_numpy
255 def get_test_tone(scale=1):
261 def get_test_tone(scale=1):
256 return numpy.sin(2 * numpy.pi * 440 * numpy.linspace(0, 1, 44100)) * scale
262 return numpy.sin(2 * numpy.pi * 440 * numpy.linspace(0, 1, 44100)) * scale
257
263
258 def read_wav(data):
264 def read_wav(data):
259 with wave.open(BytesIO(data)) as wave_file:
265 with wave.open(BytesIO(data)) as wave_file:
260 wave_data = wave_file.readframes(wave_file.getnframes())
266 wave_data = wave_file.readframes(wave_file.getnframes())
261 num_samples = wave_file.getnframes() * wave_file.getnchannels()
267 num_samples = wave_file.getnframes() * wave_file.getnchannels()
262 return struct.unpack('<%sh' % num_samples, wave_data)
268 return struct.unpack('<%sh' % num_samples, wave_data)
263
269
264 def test_code_from_file():
270 def test_code_from_file():
265 c = display.Code(filename=__file__)
271 c = display.Code(filename=__file__)
266 assert c._repr_html_().startswith('<style>')
272 assert c._repr_html_().startswith('<style>')
General Comments 0
You need to be logged in to leave comments. Login now