##// END OF EJS Templates
Document how test_message_spec works
Takafumi Arakaki -
Show More
@@ -1,452 +1,465 b''
1 """Test suite for our zeromq-based messaging specification.
1 """Test suite for our zeromq-based messaging specification.
2 """
2 """
3 #-----------------------------------------------------------------------------
3 #-----------------------------------------------------------------------------
4 # Copyright (C) 2010-2011 The IPython Development Team
4 # Copyright (C) 2010-2011 The IPython Development Team
5 #
5 #
6 # Distributed under the terms of the BSD License. The full license is in
6 # Distributed under the terms of the BSD License. The full license is in
7 # the file COPYING.txt, distributed as part of this software.
7 # the file COPYING.txt, distributed as part of this software.
8 #-----------------------------------------------------------------------------
8 #-----------------------------------------------------------------------------
9
9
10 import re
10 import re
11 import sys
11 import sys
12 import time
12 import time
13 from subprocess import PIPE
13 from subprocess import PIPE
14 from Queue import Empty
14 from Queue import Empty
15
15
16 import nose.tools as nt
16 import nose.tools as nt
17
17
18 from ..blockingkernelmanager import BlockingKernelManager
18 from ..blockingkernelmanager import BlockingKernelManager
19
19
20
20
21 from IPython.testing import decorators as dec
21 from IPython.testing import decorators as dec
22 from IPython.utils import io
22 from IPython.utils import io
23 from IPython.utils.traitlets import (
23 from IPython.utils.traitlets import (
24 HasTraits, TraitError, Bool, Unicode, Dict, Integer, List, Enum,
24 HasTraits, TraitError, Bool, Unicode, Dict, Integer, List, Enum,
25 )
25 )
26
26
27 #-----------------------------------------------------------------------------
27 #-----------------------------------------------------------------------------
28 # Global setup and utilities
28 # Global setup and utilities
29 #-----------------------------------------------------------------------------
29 #-----------------------------------------------------------------------------
30
30
31 def setup():
31 def setup():
32 global KM
32 global KM
33 KM = BlockingKernelManager()
33 KM = BlockingKernelManager()
34
34
35 KM.start_kernel(stdout=PIPE, stderr=PIPE)
35 KM.start_kernel(stdout=PIPE, stderr=PIPE)
36 KM.start_channels()
36 KM.start_channels()
37
37
38 # wait for kernel to be ready
38 # wait for kernel to be ready
39 KM.shell_channel.execute("pass")
39 KM.shell_channel.execute("pass")
40 KM.shell_channel.get_msg(block=True, timeout=5)
40 KM.shell_channel.get_msg(block=True, timeout=5)
41 flush_channels()
41 flush_channels()
42
42
43
43
44 def teardown():
44 def teardown():
45 KM.stop_channels()
45 KM.stop_channels()
46 KM.shutdown_kernel()
46 KM.shutdown_kernel()
47
47
48
48
49 def flush_channels():
49 def flush_channels():
50 """flush any messages waiting on the queue"""
50 """flush any messages waiting on the queue"""
51 for channel in (KM.shell_channel, KM.sub_channel):
51 for channel in (KM.shell_channel, KM.sub_channel):
52 while True:
52 while True:
53 try:
53 try:
54 msg = channel.get_msg(block=True, timeout=0.1)
54 msg = channel.get_msg(block=True, timeout=0.1)
55 except Empty:
55 except Empty:
56 break
56 break
57 else:
57 else:
58 list(validate_message(msg))
58 list(validate_message(msg))
59
59
60
60
61 def execute(code='', **kwargs):
61 def execute(code='', **kwargs):
62 """wrapper for doing common steps for validating an execution request"""
62 """wrapper for doing common steps for validating an execution request"""
63 shell = KM.shell_channel
63 shell = KM.shell_channel
64 sub = KM.sub_channel
64 sub = KM.sub_channel
65
65
66 msg_id = shell.execute(code=code, **kwargs)
66 msg_id = shell.execute(code=code, **kwargs)
67 reply = shell.get_msg(timeout=2)
67 reply = shell.get_msg(timeout=2)
68 list(validate_message(reply, 'execute_reply', msg_id))
68 list(validate_message(reply, 'execute_reply', msg_id))
69 busy = sub.get_msg(timeout=2)
69 busy = sub.get_msg(timeout=2)
70 list(validate_message(busy, 'status', msg_id))
70 list(validate_message(busy, 'status', msg_id))
71 nt.assert_equal(busy['content']['execution_state'], 'busy')
71 nt.assert_equal(busy['content']['execution_state'], 'busy')
72
72
73 if not kwargs.get('silent'):
73 if not kwargs.get('silent'):
74 pyin = sub.get_msg(timeout=2)
74 pyin = sub.get_msg(timeout=2)
75 list(validate_message(pyin, 'pyin', msg_id))
75 list(validate_message(pyin, 'pyin', msg_id))
76 nt.assert_equal(pyin['content']['code'], code)
76 nt.assert_equal(pyin['content']['code'], code)
77
77
78 return msg_id, reply['content']
78 return msg_id, reply['content']
79
79
80 #-----------------------------------------------------------------------------
80 #-----------------------------------------------------------------------------
81 # MSG Spec References
81 # MSG Spec References
82 #-----------------------------------------------------------------------------
82 #-----------------------------------------------------------------------------
83
83
84
84
85 class Reference(HasTraits):
85 class Reference(HasTraits):
86
86
87 """
88 Base class for message spec specification testing.
89
90 This class is the core of the message specification test. The
91 idea is that child classes implement trait attributes for each
92 message keys, so that message keys can be tested against these
93 traits using :meth:`check` method.
94
95 """
96
87 def check(self, d):
97 def check(self, d):
88 """validate a dict against our traits"""
98 """validate a dict against our traits"""
89 for key in self.trait_names():
99 for key in self.trait_names():
90 yield nt.assert_true(key in d, "Missing key: %r, should be found in %s" % (key, d))
100 yield nt.assert_true(key in d, "Missing key: %r, should be found in %s" % (key, d))
91 # FIXME: always allow None, probably not a good idea
101 # FIXME: always allow None, probably not a good idea
92 if d[key] is None:
102 if d[key] is None:
93 continue
103 continue
94 try:
104 try:
95 setattr(self, key, d[key])
105 setattr(self, key, d[key])
96 except TraitError as e:
106 except TraitError as e:
97 yield nt.assert_true(False, str(e))
107 yield nt.assert_true(False, str(e))
98
108
99
109
100 class RMessage(Reference):
110 class RMessage(Reference):
101 msg_id = Unicode()
111 msg_id = Unicode()
102 msg_type = Unicode()
112 msg_type = Unicode()
103 header = Dict()
113 header = Dict()
104 parent_header = Dict()
114 parent_header = Dict()
105 content = Dict()
115 content = Dict()
106
116
107 class RHeader(Reference):
117 class RHeader(Reference):
108 msg_id = Unicode()
118 msg_id = Unicode()
109 msg_type = Unicode()
119 msg_type = Unicode()
110 session = Unicode()
120 session = Unicode()
111 username = Unicode()
121 username = Unicode()
112
122
113 class RContent(Reference):
123 class RContent(Reference):
114 status = Enum((u'ok', u'error'))
124 status = Enum((u'ok', u'error'))
115
125
116
126
117 class ExecuteReply(Reference):
127 class ExecuteReply(Reference):
118 execution_count = Integer()
128 execution_count = Integer()
119 status = Enum((u'ok', u'error'))
129 status = Enum((u'ok', u'error'))
120
130
121 def check(self, d):
131 def check(self, d):
122 for tst in Reference.check(self, d):
132 for tst in Reference.check(self, d):
123 yield tst
133 yield tst
124 if d['status'] == 'ok':
134 if d['status'] == 'ok':
125 for tst in ExecuteReplyOkay().check(d):
135 for tst in ExecuteReplyOkay().check(d):
126 yield tst
136 yield tst
127 elif d['status'] == 'error':
137 elif d['status'] == 'error':
128 for tst in ExecuteReplyError().check(d):
138 for tst in ExecuteReplyError().check(d):
129 yield tst
139 yield tst
130
140
131
141
132 class ExecuteReplyOkay(Reference):
142 class ExecuteReplyOkay(Reference):
133 payload = List(Dict)
143 payload = List(Dict)
134 user_variables = Dict()
144 user_variables = Dict()
135 user_expressions = Dict()
145 user_expressions = Dict()
136
146
137
147
138 class ExecuteReplyError(Reference):
148 class ExecuteReplyError(Reference):
139 ename = Unicode()
149 ename = Unicode()
140 evalue = Unicode()
150 evalue = Unicode()
141 traceback = List(Unicode)
151 traceback = List(Unicode)
142
152
143
153
144 class OInfoReply(Reference):
154 class OInfoReply(Reference):
145 name = Unicode()
155 name = Unicode()
146 found = Bool()
156 found = Bool()
147 ismagic = Bool()
157 ismagic = Bool()
148 isalias = Bool()
158 isalias = Bool()
149 namespace = Enum((u'builtin', u'magics', u'alias', u'Interactive'))
159 namespace = Enum((u'builtin', u'magics', u'alias', u'Interactive'))
150 type_name = Unicode()
160 type_name = Unicode()
151 string_form = Unicode()
161 string_form = Unicode()
152 base_class = Unicode()
162 base_class = Unicode()
153 length = Integer()
163 length = Integer()
154 file = Unicode()
164 file = Unicode()
155 definition = Unicode()
165 definition = Unicode()
156 argspec = Dict()
166 argspec = Dict()
157 init_definition = Unicode()
167 init_definition = Unicode()
158 docstring = Unicode()
168 docstring = Unicode()
159 init_docstring = Unicode()
169 init_docstring = Unicode()
160 class_docstring = Unicode()
170 class_docstring = Unicode()
161 call_def = Unicode()
171 call_def = Unicode()
162 call_docstring = Unicode()
172 call_docstring = Unicode()
163 source = Unicode()
173 source = Unicode()
164
174
165 def check(self, d):
175 def check(self, d):
166 for tst in Reference.check(self, d):
176 for tst in Reference.check(self, d):
167 yield tst
177 yield tst
168 if d['argspec'] is not None:
178 if d['argspec'] is not None:
169 for tst in ArgSpec().check(d['argspec']):
179 for tst in ArgSpec().check(d['argspec']):
170 yield tst
180 yield tst
171
181
172
182
173 class ArgSpec(Reference):
183 class ArgSpec(Reference):
174 args = List(Unicode)
184 args = List(Unicode)
175 varargs = Unicode()
185 varargs = Unicode()
176 varkw = Unicode()
186 varkw = Unicode()
177 defaults = List()
187 defaults = List()
178
188
179
189
180 class Status(Reference):
190 class Status(Reference):
181 execution_state = Enum((u'busy', u'idle'))
191 execution_state = Enum((u'busy', u'idle'))
182
192
183
193
184 class CompleteReply(Reference):
194 class CompleteReply(Reference):
185 matches = List(Unicode)
195 matches = List(Unicode)
186
196
187
197
188 # IOPub messages
198 # IOPub messages
189
199
190 class PyIn(Reference):
200 class PyIn(Reference):
191 code = Unicode()
201 code = Unicode()
192 execution_count = Integer()
202 execution_count = Integer()
193
203
194
204
195 PyErr = ExecuteReplyError
205 PyErr = ExecuteReplyError
196
206
197
207
198 class Stream(Reference):
208 class Stream(Reference):
199 name = Enum((u'stdout', u'stderr'))
209 name = Enum((u'stdout', u'stderr'))
200 data = Unicode()
210 data = Unicode()
201
211
202
212
203 mime_pat = re.compile(r'\w+/\w+')
213 mime_pat = re.compile(r'\w+/\w+')
204
214
205 class DisplayData(Reference):
215 class DisplayData(Reference):
206 source = Unicode()
216 source = Unicode()
207 metadata = Dict()
217 metadata = Dict()
208 data = Dict()
218 data = Dict()
209 def _data_changed(self, name, old, new):
219 def _data_changed(self, name, old, new):
210 for k,v in new.iteritems():
220 for k,v in new.iteritems():
211 nt.assert_true(mime_pat.match(k))
221 nt.assert_true(mime_pat.match(k))
212 nt.assert_true(isinstance(v, basestring), "expected string data, got %r" % v)
222 nt.assert_true(isinstance(v, basestring), "expected string data, got %r" % v)
213
223
214
224
215 class PyOut(Reference):
225 class PyOut(Reference):
216 execution_count = Integer()
226 execution_count = Integer()
217 data = Dict()
227 data = Dict()
218 def _data_changed(self, name, old, new):
228 def _data_changed(self, name, old, new):
219 for k,v in new.iteritems():
229 for k,v in new.iteritems():
220 nt.assert_true(mime_pat.match(k))
230 nt.assert_true(mime_pat.match(k))
221 nt.assert_true(isinstance(v, basestring), "expected string data, got %r" % v)
231 nt.assert_true(isinstance(v, basestring), "expected string data, got %r" % v)
222
232
223
233
224 references = {
234 references = {
225 'execute_reply' : ExecuteReply(),
235 'execute_reply' : ExecuteReply(),
226 'object_info_reply' : OInfoReply(),
236 'object_info_reply' : OInfoReply(),
227 'status' : Status(),
237 'status' : Status(),
228 'complete_reply' : CompleteReply(),
238 'complete_reply' : CompleteReply(),
229 'pyin' : PyIn(),
239 'pyin' : PyIn(),
230 'pyout' : PyOut(),
240 'pyout' : PyOut(),
231 'pyerr' : PyErr(),
241 'pyerr' : PyErr(),
232 'stream' : Stream(),
242 'stream' : Stream(),
233 'display_data' : DisplayData(),
243 'display_data' : DisplayData(),
234 }
244 }
245 """
246 Specifications of `content` part of the reply messages.
247 """
235
248
236
249
237 def validate_message(msg, msg_type=None, parent=None):
250 def validate_message(msg, msg_type=None, parent=None):
238 """validate a message
251 """validate a message
239
252
240 This is a generator, and must be iterated through to actually
253 This is a generator, and must be iterated through to actually
241 trigger each test.
254 trigger each test.
242
255
243 If msg_type and/or parent are given, the msg_type and/or parent msg_id
256 If msg_type and/or parent are given, the msg_type and/or parent msg_id
244 are compared with the given values.
257 are compared with the given values.
245 """
258 """
246 RMessage().check(msg)
259 RMessage().check(msg)
247 if msg_type:
260 if msg_type:
248 yield nt.assert_equal(msg['msg_type'], msg_type)
261 yield nt.assert_equal(msg['msg_type'], msg_type)
249 if parent:
262 if parent:
250 yield nt.assert_equal(msg['parent_header']['msg_id'], parent)
263 yield nt.assert_equal(msg['parent_header']['msg_id'], parent)
251 content = msg['content']
264 content = msg['content']
252 ref = references[msg['msg_type']]
265 ref = references[msg['msg_type']]
253 for tst in ref.check(content):
266 for tst in ref.check(content):
254 yield tst
267 yield tst
255
268
256
269
257 #-----------------------------------------------------------------------------
270 #-----------------------------------------------------------------------------
258 # Tests
271 # Tests
259 #-----------------------------------------------------------------------------
272 #-----------------------------------------------------------------------------
260
273
261 # Shell channel
274 # Shell channel
262
275
263 @dec.parametric
276 @dec.parametric
264 def test_execute():
277 def test_execute():
265 flush_channels()
278 flush_channels()
266
279
267 shell = KM.shell_channel
280 shell = KM.shell_channel
268 msg_id = shell.execute(code='x=1')
281 msg_id = shell.execute(code='x=1')
269 reply = shell.get_msg(timeout=2)
282 reply = shell.get_msg(timeout=2)
270 for tst in validate_message(reply, 'execute_reply', msg_id):
283 for tst in validate_message(reply, 'execute_reply', msg_id):
271 yield tst
284 yield tst
272
285
273
286
274 @dec.parametric
287 @dec.parametric
275 def test_execute_silent():
288 def test_execute_silent():
276 flush_channels()
289 flush_channels()
277 msg_id, reply = execute(code='x=1', silent=True)
290 msg_id, reply = execute(code='x=1', silent=True)
278
291
279 # flush status=idle
292 # flush status=idle
280 status = KM.sub_channel.get_msg(timeout=2)
293 status = KM.sub_channel.get_msg(timeout=2)
281 for tst in validate_message(status, 'status', msg_id):
294 for tst in validate_message(status, 'status', msg_id):
282 yield tst
295 yield tst
283 nt.assert_equal(status['content']['execution_state'], 'idle')
296 nt.assert_equal(status['content']['execution_state'], 'idle')
284
297
285 yield nt.assert_raises(Empty, KM.sub_channel.get_msg, timeout=0.1)
298 yield nt.assert_raises(Empty, KM.sub_channel.get_msg, timeout=0.1)
286 count = reply['execution_count']
299 count = reply['execution_count']
287
300
288 msg_id, reply = execute(code='x=2', silent=True)
301 msg_id, reply = execute(code='x=2', silent=True)
289
302
290 # flush status=idle
303 # flush status=idle
291 status = KM.sub_channel.get_msg(timeout=2)
304 status = KM.sub_channel.get_msg(timeout=2)
292 for tst in validate_message(status, 'status', msg_id):
305 for tst in validate_message(status, 'status', msg_id):
293 yield tst
306 yield tst
294 yield nt.assert_equal(status['content']['execution_state'], 'idle')
307 yield nt.assert_equal(status['content']['execution_state'], 'idle')
295
308
296 yield nt.assert_raises(Empty, KM.sub_channel.get_msg, timeout=0.1)
309 yield nt.assert_raises(Empty, KM.sub_channel.get_msg, timeout=0.1)
297 count_2 = reply['execution_count']
310 count_2 = reply['execution_count']
298 yield nt.assert_equal(count_2, count)
311 yield nt.assert_equal(count_2, count)
299
312
300
313
301 @dec.parametric
314 @dec.parametric
302 def test_execute_error():
315 def test_execute_error():
303 flush_channels()
316 flush_channels()
304
317
305 msg_id, reply = execute(code='1/0')
318 msg_id, reply = execute(code='1/0')
306 yield nt.assert_equal(reply['status'], 'error')
319 yield nt.assert_equal(reply['status'], 'error')
307 yield nt.assert_equal(reply['ename'], 'ZeroDivisionError')
320 yield nt.assert_equal(reply['ename'], 'ZeroDivisionError')
308
321
309 pyerr = KM.sub_channel.get_msg(timeout=2)
322 pyerr = KM.sub_channel.get_msg(timeout=2)
310 for tst in validate_message(pyerr, 'pyerr', msg_id):
323 for tst in validate_message(pyerr, 'pyerr', msg_id):
311 yield tst
324 yield tst
312
325
313
326
314 def test_execute_inc():
327 def test_execute_inc():
315 """execute request should increment execution_count"""
328 """execute request should increment execution_count"""
316 flush_channels()
329 flush_channels()
317
330
318 msg_id, reply = execute(code='x=1')
331 msg_id, reply = execute(code='x=1')
319 count = reply['execution_count']
332 count = reply['execution_count']
320
333
321 flush_channels()
334 flush_channels()
322
335
323 msg_id, reply = execute(code='x=2')
336 msg_id, reply = execute(code='x=2')
324 count_2 = reply['execution_count']
337 count_2 = reply['execution_count']
325 nt.assert_equal(count_2, count+1)
338 nt.assert_equal(count_2, count+1)
326
339
327
340
328 def test_user_variables():
341 def test_user_variables():
329 flush_channels()
342 flush_channels()
330
343
331 msg_id, reply = execute(code='x=1', user_variables=['x'])
344 msg_id, reply = execute(code='x=1', user_variables=['x'])
332 user_variables = reply['user_variables']
345 user_variables = reply['user_variables']
333 nt.assert_equal(user_variables, {u'x' : u'1'})
346 nt.assert_equal(user_variables, {u'x' : u'1'})
334
347
335
348
336 def test_user_expressions():
349 def test_user_expressions():
337 flush_channels()
350 flush_channels()
338
351
339 msg_id, reply = execute(code='x=1', user_expressions=dict(foo='x+1'))
352 msg_id, reply = execute(code='x=1', user_expressions=dict(foo='x+1'))
340 user_expressions = reply['user_expressions']
353 user_expressions = reply['user_expressions']
341 nt.assert_equal(user_expressions, {u'foo' : u'2'})
354 nt.assert_equal(user_expressions, {u'foo' : u'2'})
342
355
343
356
344 @dec.parametric
357 @dec.parametric
345 def test_oinfo():
358 def test_oinfo():
346 flush_channels()
359 flush_channels()
347
360
348 shell = KM.shell_channel
361 shell = KM.shell_channel
349
362
350 msg_id = shell.object_info('a')
363 msg_id = shell.object_info('a')
351 reply = shell.get_msg(timeout=2)
364 reply = shell.get_msg(timeout=2)
352 for tst in validate_message(reply, 'object_info_reply', msg_id):
365 for tst in validate_message(reply, 'object_info_reply', msg_id):
353 yield tst
366 yield tst
354
367
355
368
356 @dec.parametric
369 @dec.parametric
357 def test_oinfo_found():
370 def test_oinfo_found():
358 flush_channels()
371 flush_channels()
359
372
360 shell = KM.shell_channel
373 shell = KM.shell_channel
361
374
362 msg_id, reply = execute(code='a=5')
375 msg_id, reply = execute(code='a=5')
363
376
364 msg_id = shell.object_info('a')
377 msg_id = shell.object_info('a')
365 reply = shell.get_msg(timeout=2)
378 reply = shell.get_msg(timeout=2)
366 for tst in validate_message(reply, 'object_info_reply', msg_id):
379 for tst in validate_message(reply, 'object_info_reply', msg_id):
367 yield tst
380 yield tst
368 content = reply['content']
381 content = reply['content']
369 yield nt.assert_true(content['found'])
382 yield nt.assert_true(content['found'])
370 argspec = content['argspec']
383 argspec = content['argspec']
371 yield nt.assert_true(argspec is None, "didn't expect argspec dict, got %r" % argspec)
384 yield nt.assert_true(argspec is None, "didn't expect argspec dict, got %r" % argspec)
372
385
373
386
374 @dec.parametric
387 @dec.parametric
375 def test_oinfo_detail():
388 def test_oinfo_detail():
376 flush_channels()
389 flush_channels()
377
390
378 shell = KM.shell_channel
391 shell = KM.shell_channel
379
392
380 msg_id, reply = execute(code='ip=get_ipython()')
393 msg_id, reply = execute(code='ip=get_ipython()')
381
394
382 msg_id = shell.object_info('ip.object_inspect', detail_level=2)
395 msg_id = shell.object_info('ip.object_inspect', detail_level=2)
383 reply = shell.get_msg(timeout=2)
396 reply = shell.get_msg(timeout=2)
384 for tst in validate_message(reply, 'object_info_reply', msg_id):
397 for tst in validate_message(reply, 'object_info_reply', msg_id):
385 yield tst
398 yield tst
386 content = reply['content']
399 content = reply['content']
387 yield nt.assert_true(content['found'])
400 yield nt.assert_true(content['found'])
388 argspec = content['argspec']
401 argspec = content['argspec']
389 yield nt.assert_true(isinstance(argspec, dict), "expected non-empty argspec dict, got %r" % argspec)
402 yield nt.assert_true(isinstance(argspec, dict), "expected non-empty argspec dict, got %r" % argspec)
390 yield nt.assert_equal(argspec['defaults'], [0])
403 yield nt.assert_equal(argspec['defaults'], [0])
391
404
392
405
393 @dec.parametric
406 @dec.parametric
394 def test_oinfo_not_found():
407 def test_oinfo_not_found():
395 flush_channels()
408 flush_channels()
396
409
397 shell = KM.shell_channel
410 shell = KM.shell_channel
398
411
399 msg_id = shell.object_info('dne')
412 msg_id = shell.object_info('dne')
400 reply = shell.get_msg(timeout=2)
413 reply = shell.get_msg(timeout=2)
401 for tst in validate_message(reply, 'object_info_reply', msg_id):
414 for tst in validate_message(reply, 'object_info_reply', msg_id):
402 yield tst
415 yield tst
403 content = reply['content']
416 content = reply['content']
404 yield nt.assert_false(content['found'])
417 yield nt.assert_false(content['found'])
405
418
406
419
407 @dec.parametric
420 @dec.parametric
408 def test_complete():
421 def test_complete():
409 flush_channels()
422 flush_channels()
410
423
411 shell = KM.shell_channel
424 shell = KM.shell_channel
412
425
413 msg_id, reply = execute(code="alpha = albert = 5")
426 msg_id, reply = execute(code="alpha = albert = 5")
414
427
415 msg_id = shell.complete('al', 'al', 2)
428 msg_id = shell.complete('al', 'al', 2)
416 reply = shell.get_msg(timeout=2)
429 reply = shell.get_msg(timeout=2)
417 for tst in validate_message(reply, 'complete_reply', msg_id):
430 for tst in validate_message(reply, 'complete_reply', msg_id):
418 yield tst
431 yield tst
419 matches = reply['content']['matches']
432 matches = reply['content']['matches']
420 for name in ('alpha', 'albert'):
433 for name in ('alpha', 'albert'):
421 yield nt.assert_true(name in matches, "Missing match: %r" % name)
434 yield nt.assert_true(name in matches, "Missing match: %r" % name)
422
435
423
436
424 # IOPub channel
437 # IOPub channel
425
438
426
439
427 @dec.parametric
440 @dec.parametric
428 def test_stream():
441 def test_stream():
429 flush_channels()
442 flush_channels()
430
443
431 msg_id, reply = execute("print('hi')")
444 msg_id, reply = execute("print('hi')")
432
445
433 stdout = KM.sub_channel.get_msg(timeout=2)
446 stdout = KM.sub_channel.get_msg(timeout=2)
434 for tst in validate_message(stdout, 'stream', msg_id):
447 for tst in validate_message(stdout, 'stream', msg_id):
435 yield tst
448 yield tst
436 content = stdout['content']
449 content = stdout['content']
437 yield nt.assert_equal(content['name'], u'stdout')
450 yield nt.assert_equal(content['name'], u'stdout')
438 yield nt.assert_equal(content['data'], u'hi\n')
451 yield nt.assert_equal(content['data'], u'hi\n')
439
452
440
453
441 @dec.parametric
454 @dec.parametric
442 def test_display_data():
455 def test_display_data():
443 flush_channels()
456 flush_channels()
444
457
445 msg_id, reply = execute("from IPython.core.display import display; display(1)")
458 msg_id, reply = execute("from IPython.core.display import display; display(1)")
446
459
447 display = KM.sub_channel.get_msg(timeout=2)
460 display = KM.sub_channel.get_msg(timeout=2)
448 for tst in validate_message(display, 'display_data', parent=msg_id):
461 for tst in validate_message(display, 'display_data', parent=msg_id):
449 yield tst
462 yield tst
450 data = display['content']['data']
463 data = display['content']['data']
451 yield nt.assert_equal(data['text/plain'], u'1')
464 yield nt.assert_equal(data['text/plain'], u'1')
452
465
General Comments 0
You need to be logged in to leave comments. Login now