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