1
1
import sys
2
+ from unittest import TestCase
3
+ from contextlib import contextmanager
2
4
3
5
from IPython .display import Markdown , Image
4
- from ipywidgets import Output
6
+ from ipywidgets import widget_output
7
+
8
+
9
+ class TestOutputWidget (TestCase ):
10
+
11
+ @contextmanager
12
+ def _mocked_ipython (self , get_ipython , clear_output ):
13
+ """ Context manager that monkeypatches get_ipython and clear_output """
14
+ original_clear_output = widget_output .clear_output
15
+ original_get_ipython = widget_output .get_ipython
16
+ widget_output .get_ipython = get_ipython
17
+ widget_output .clear_output = clear_output
18
+ try :
19
+ yield
20
+ finally :
21
+ widget_output .clear_output = original_clear_output
22
+ widget_output .get_ipython = original_get_ipython
23
+
24
+ def _mock_get_ipython (self , msg_id ):
25
+ """ Returns a mock IPython application with a mocked kernel """
26
+ kernel = type (
27
+ 'mock_kernel' ,
28
+ (object , ),
29
+ {'_parent_header' : {'header' : {'msg_id' : msg_id }}}
30
+ )
31
+
32
+ # Specifically override this so the traceback
33
+ # is still printed to screen
34
+ def showtraceback (self_ , exc_tuple , * args , ** kwargs ):
35
+ etype , evalue , tb = exc_tuple
36
+ raise etype (evalue )
37
+
38
+ ipython = type (
39
+ 'mock_ipython' ,
40
+ (object , ),
41
+ {'kernel' : kernel , 'showtraceback' : showtraceback }
42
+ )
43
+ return ipython
44
+
45
+ def _mock_clear_output (self ):
46
+ """ Mock function that records calls to it """
47
+ calls = []
48
+
49
+ def clear_output (* args , ** kwargs ):
50
+ calls .append ((args , kwargs ))
51
+ clear_output .calls = calls
52
+
53
+ return clear_output
54
+
55
+ def test_set_msg_id_when_capturing (self ):
56
+ msg_id = 'msg-id'
57
+ get_ipython = self ._mock_get_ipython (msg_id )
58
+ clear_output = self ._mock_clear_output ()
59
+
60
+ with self ._mocked_ipython (get_ipython , clear_output ):
61
+ widget = widget_output .Output ()
62
+ assert widget .msg_id == ''
63
+ with widget :
64
+ assert widget .msg_id == msg_id
65
+ assert widget .msg_id == ''
66
+
67
+ def test_clear_output (self ):
68
+ msg_id = 'msg-id'
69
+ get_ipython = self ._mock_get_ipython (msg_id )
70
+ clear_output = self ._mock_clear_output ()
71
+
72
+ with self ._mocked_ipython (get_ipython , clear_output ):
73
+ widget = widget_output .Output ()
74
+ widget .clear_output (wait = True )
75
+
76
+ assert len (clear_output .calls ) == 1
77
+ assert clear_output .calls [0 ] == ((), {'wait' : True })
78
+
79
+ def test_capture_decorator (self ):
80
+ msg_id = 'msg-id'
81
+ get_ipython = self ._mock_get_ipython (msg_id )
82
+ clear_output = self ._mock_clear_output ()
83
+ expected_argument = 'arg'
84
+ expected_keyword_argument = True
85
+ captee_calls = []
86
+
87
+ with self ._mocked_ipython (get_ipython , clear_output ):
88
+ widget = widget_output .Output ()
89
+ assert widget .msg_id == ''
90
+
91
+ @widget .capture ()
92
+ def captee (* args , ** kwargs ):
93
+ # Check that we are capturing output
94
+ assert widget .msg_id == msg_id
95
+
96
+ # Check that arguments are passed correctly
97
+ captee_calls .append ((args , kwargs ))
98
+
99
+ captee (
100
+ expected_argument , keyword_argument = expected_keyword_argument )
101
+ assert widget .msg_id == ''
102
+ captee ()
103
+
104
+ assert len (captee_calls ) == 2
105
+ assert captee_calls [0 ] == (
106
+ (expected_argument , ),
107
+ {'keyword_argument' : expected_keyword_argument }
108
+ )
109
+ assert captee_calls [1 ] == ((), {})
110
+
111
+ def test_capture_decorator_clear_output (self ):
112
+ msg_id = 'msg-id'
113
+ get_ipython = self ._mock_get_ipython (msg_id )
114
+ clear_output = self ._mock_clear_output ()
115
+
116
+ with self ._mocked_ipython (get_ipython , clear_output ):
117
+ widget = widget_output .Output ()
118
+
119
+ @widget .capture (clear_output = True , wait = True )
120
+ def captee (* args , ** kwargs ):
121
+ # Check that we are capturing output
122
+ assert widget .msg_id == msg_id
123
+
124
+ captee ()
125
+ captee ()
126
+
127
+ assert len (clear_output .calls ) == 2
128
+ assert clear_output .calls [0 ] == clear_output .calls [1 ] == \
129
+ ((), {'wait' : True })
130
+
131
+ def test_capture_decorator_no_clear_output (self ):
132
+ msg_id = 'msg-id'
133
+ get_ipython = self ._mock_get_ipython (msg_id )
134
+ clear_output = self ._mock_clear_output ()
135
+
136
+ with self ._mocked_ipython (get_ipython , clear_output ):
137
+ widget = widget_output .Output ()
138
+
139
+ @widget .capture (clear_output = False )
140
+ def captee (* args , ** kwargs ):
141
+ # Check that we are capturing output
142
+ assert widget .msg_id == msg_id
143
+
144
+ captee ()
145
+ captee ()
146
+
147
+ assert len (clear_output .calls ) == 0
5
148
6
149
7
150
def _make_stream_output (text , name ):
@@ -13,38 +156,38 @@ def _make_stream_output(text, name):
13
156
14
157
15
158
def test_append_stdout ():
16
- output = Output ()
159
+ widget = widget_output . Output ()
17
160
18
161
# Try appending a message to stdout.
19
- output .append_stdout ("snakes!" )
162
+ widget .append_stdout ("snakes!" )
20
163
expected = (_make_stream_output ("snakes!" , "stdout" ),)
21
- assert output .outputs == expected , repr (output .outputs )
164
+ assert widget .outputs == expected , repr (widget .outputs )
22
165
23
166
# Try appending a second message.
24
- output .append_stdout ("more snakes!" )
167
+ widget .append_stdout ("more snakes!" )
25
168
expected += (_make_stream_output ("more snakes!" , "stdout" ),)
26
- assert output .outputs == expected , repr (output .outputs )
169
+ assert widget .outputs == expected , repr (widget .outputs )
27
170
28
171
29
172
def test_append_stderr ():
30
- output = Output ()
173
+ widget = widget_output . Output ()
31
174
32
175
# Try appending a message to stderr.
33
- output .append_stderr ("snakes!" )
176
+ widget .append_stderr ("snakes!" )
34
177
expected = (_make_stream_output ("snakes!" , "stderr" ),)
35
- assert output .outputs == expected , repr (output .outputs )
178
+ assert widget .outputs == expected , repr (widget .outputs )
36
179
37
180
# Try appending a second message.
38
- output .append_stderr ("more snakes!" )
181
+ widget .append_stderr ("more snakes!" )
39
182
expected += (_make_stream_output ("more snakes!" , "stderr" ),)
40
- assert output .outputs == expected , repr (output .outputs )
183
+ assert widget .outputs == expected , repr (widget .outputs )
41
184
42
185
43
186
def test_append_display_data ():
44
- output = Output ()
187
+ widget = widget_output . Output ()
45
188
46
189
# Try appending a Markdown object.
47
- output .append_display_data (Markdown ("# snakes!" ))
190
+ widget .append_display_data (Markdown ("# snakes!" ))
48
191
expected = (
49
192
{
50
193
'output_type' : 'display_data' ,
@@ -55,13 +198,13 @@ def test_append_display_data():
55
198
'metadata' : {}
56
199
},
57
200
)
58
- assert output .outputs == expected , repr (output .outputs )
201
+ assert widget .outputs == expected , repr (widget .outputs )
59
202
60
203
# Now try appending an Image.
61
204
image_data = b"foobar"
62
205
image_data_b64 = image_data if sys .version_info [0 ] < 3 else 'Zm9vYmFy\n '
63
206
64
- output .append_display_data (Image (image_data , width = 123 , height = 456 ))
207
+ widget .append_display_data (Image (image_data , width = 123 , height = 456 ))
65
208
expected += (
66
209
{
67
210
'output_type' : 'display_data' ,
@@ -77,4 +220,4 @@ def test_append_display_data():
77
220
}
78
221
},
79
222
)
80
- assert output .outputs == expected , repr (output .outputs )
223
+ assert widget .outputs == expected , repr (widget .outputs )
0 commit comments