##// END OF EJS Templates
Update tests for info changes
Thomas Kluyver -
Show More
@@ -1,373 +1,374
1 """Tests for the object inspection functionality.
1 """Tests for the object inspection functionality.
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.
6 # Distributed under the terms of the BSD License.
7 #
7 #
8 # The full license is in the file COPYING.txt, distributed with this software.
8 # The full license is in the file COPYING.txt, distributed with this software.
9 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
10
10
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12 # Imports
12 # Imports
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 from __future__ import print_function
14 from __future__ import print_function
15
15
16 # Stdlib imports
16 # Stdlib imports
17 import os
17 import os
18 import re
18 import re
19
19
20 # Third-party imports
20 # Third-party imports
21 import nose.tools as nt
21 import nose.tools as nt
22
22
23 # Our own imports
23 # Our own imports
24 from .. import oinspect
24 from .. import oinspect
25 from IPython.core.magic import (Magics, magics_class, line_magic,
25 from IPython.core.magic import (Magics, magics_class, line_magic,
26 cell_magic, line_cell_magic,
26 cell_magic, line_cell_magic,
27 register_line_magic, register_cell_magic,
27 register_line_magic, register_cell_magic,
28 register_line_cell_magic)
28 register_line_cell_magic)
29 from IPython.external.decorator import decorator
29 from IPython.external.decorator import decorator
30 from IPython.testing.decorators import skipif
30 from IPython.testing.decorators import skipif
31 from IPython.utils.path import compress_user
31 from IPython.utils import py3compat
32 from IPython.utils import py3compat
32
33
33
34
34 #-----------------------------------------------------------------------------
35 #-----------------------------------------------------------------------------
35 # Globals and constants
36 # Globals and constants
36 #-----------------------------------------------------------------------------
37 #-----------------------------------------------------------------------------
37
38
38 inspector = oinspect.Inspector()
39 inspector = oinspect.Inspector()
39 ip = get_ipython()
40 ip = get_ipython()
40
41
41 #-----------------------------------------------------------------------------
42 #-----------------------------------------------------------------------------
42 # Local utilities
43 # Local utilities
43 #-----------------------------------------------------------------------------
44 #-----------------------------------------------------------------------------
44
45
45 # WARNING: since this test checks the line number where a function is
46 # WARNING: since this test checks the line number where a function is
46 # defined, if any code is inserted above, the following line will need to be
47 # defined, if any code is inserted above, the following line will need to be
47 # updated. Do NOT insert any whitespace between the next line and the function
48 # updated. Do NOT insert any whitespace between the next line and the function
48 # definition below.
49 # definition below.
49 THIS_LINE_NUMBER = 49 # Put here the actual number of this line
50 THIS_LINE_NUMBER = 49 # Put here the actual number of this line
50 def test_find_source_lines():
51 def test_find_source_lines():
51 nt.assert_equal(oinspect.find_source_lines(test_find_source_lines),
52 nt.assert_equal(oinspect.find_source_lines(test_find_source_lines),
52 THIS_LINE_NUMBER+1)
53 THIS_LINE_NUMBER+1)
53
54
54
55
55 # A couple of utilities to ensure these tests work the same from a source or a
56 # A couple of utilities to ensure these tests work the same from a source or a
56 # binary install
57 # binary install
57 def pyfile(fname):
58 def pyfile(fname):
58 return os.path.normcase(re.sub('.py[co]$', '.py', fname))
59 return os.path.normcase(re.sub('.py[co]$', '.py', fname))
59
60
60
61
61 def match_pyfiles(f1, f2):
62 def match_pyfiles(f1, f2):
62 nt.assert_equal(pyfile(f1), pyfile(f2))
63 nt.assert_equal(pyfile(f1), pyfile(f2))
63
64
64
65
65 def test_find_file():
66 def test_find_file():
66 match_pyfiles(oinspect.find_file(test_find_file), os.path.abspath(__file__))
67 match_pyfiles(oinspect.find_file(test_find_file), os.path.abspath(__file__))
67
68
68
69
69 def test_find_file_decorated1():
70 def test_find_file_decorated1():
70
71
71 @decorator
72 @decorator
72 def noop1(f):
73 def noop1(f):
73 def wrapper():
74 def wrapper():
74 return f(*a, **kw)
75 return f(*a, **kw)
75 return wrapper
76 return wrapper
76
77
77 @noop1
78 @noop1
78 def f(x):
79 def f(x):
79 "My docstring"
80 "My docstring"
80
81
81 match_pyfiles(oinspect.find_file(f), os.path.abspath(__file__))
82 match_pyfiles(oinspect.find_file(f), os.path.abspath(__file__))
82 nt.assert_equal(f.__doc__, "My docstring")
83 nt.assert_equal(f.__doc__, "My docstring")
83
84
84
85
85 def test_find_file_decorated2():
86 def test_find_file_decorated2():
86
87
87 @decorator
88 @decorator
88 def noop2(f, *a, **kw):
89 def noop2(f, *a, **kw):
89 return f(*a, **kw)
90 return f(*a, **kw)
90
91
91 @noop2
92 @noop2
92 def f(x):
93 def f(x):
93 "My docstring 2"
94 "My docstring 2"
94
95
95 match_pyfiles(oinspect.find_file(f), os.path.abspath(__file__))
96 match_pyfiles(oinspect.find_file(f), os.path.abspath(__file__))
96 nt.assert_equal(f.__doc__, "My docstring 2")
97 nt.assert_equal(f.__doc__, "My docstring 2")
97
98
98
99
99 def test_find_file_magic():
100 def test_find_file_magic():
100 run = ip.find_line_magic('run')
101 run = ip.find_line_magic('run')
101 nt.assert_not_equal(oinspect.find_file(run), None)
102 nt.assert_not_equal(oinspect.find_file(run), None)
102
103
103
104
104 # A few generic objects we can then inspect in the tests below
105 # A few generic objects we can then inspect in the tests below
105
106
106 class Call(object):
107 class Call(object):
107 """This is the class docstring."""
108 """This is the class docstring."""
108
109
109 def __init__(self, x, y=1):
110 def __init__(self, x, y=1):
110 """This is the constructor docstring."""
111 """This is the constructor docstring."""
111
112
112 def __call__(self, *a, **kw):
113 def __call__(self, *a, **kw):
113 """This is the call docstring."""
114 """This is the call docstring."""
114
115
115 def method(self, x, z=2):
116 def method(self, x, z=2):
116 """Some method's docstring"""
117 """Some method's docstring"""
117
118
118 class SimpleClass(object):
119 class SimpleClass(object):
119 def method(self, x, z=2):
120 def method(self, x, z=2):
120 """Some method's docstring"""
121 """Some method's docstring"""
121
122
122
123
123 class OldStyle:
124 class OldStyle:
124 """An old-style class for testing."""
125 """An old-style class for testing."""
125 pass
126 pass
126
127
127
128
128 def f(x, y=2, *a, **kw):
129 def f(x, y=2, *a, **kw):
129 """A simple function."""
130 """A simple function."""
130
131
131
132
132 def g(y, z=3, *a, **kw):
133 def g(y, z=3, *a, **kw):
133 pass # no docstring
134 pass # no docstring
134
135
135
136
136 @register_line_magic
137 @register_line_magic
137 def lmagic(line):
138 def lmagic(line):
138 "A line magic"
139 "A line magic"
139
140
140
141
141 @register_cell_magic
142 @register_cell_magic
142 def cmagic(line, cell):
143 def cmagic(line, cell):
143 "A cell magic"
144 "A cell magic"
144
145
145
146
146 @register_line_cell_magic
147 @register_line_cell_magic
147 def lcmagic(line, cell=None):
148 def lcmagic(line, cell=None):
148 "A line/cell magic"
149 "A line/cell magic"
149
150
150
151
151 @magics_class
152 @magics_class
152 class SimpleMagics(Magics):
153 class SimpleMagics(Magics):
153 @line_magic
154 @line_magic
154 def Clmagic(self, cline):
155 def Clmagic(self, cline):
155 "A class-based line magic"
156 "A class-based line magic"
156
157
157 @cell_magic
158 @cell_magic
158 def Ccmagic(self, cline, ccell):
159 def Ccmagic(self, cline, ccell):
159 "A class-based cell magic"
160 "A class-based cell magic"
160
161
161 @line_cell_magic
162 @line_cell_magic
162 def Clcmagic(self, cline, ccell=None):
163 def Clcmagic(self, cline, ccell=None):
163 "A class-based line/cell magic"
164 "A class-based line/cell magic"
164
165
165
166
166 class Awkward(object):
167 class Awkward(object):
167 def __getattr__(self, name):
168 def __getattr__(self, name):
168 raise Exception(name)
169 raise Exception(name)
169
170
170
171
171 def check_calltip(obj, name, call, docstring):
172 def check_calltip(obj, name, call, docstring):
172 """Generic check pattern all calltip tests will use"""
173 """Generic check pattern all calltip tests will use"""
173 info = inspector.info(obj, name)
174 info = inspector.info(obj, name)
174 call_line, ds = oinspect.call_tip(info)
175 call_line, ds = oinspect.call_tip(info)
175 nt.assert_equal(call_line, call)
176 nt.assert_equal(call_line, call)
176 nt.assert_equal(ds, docstring)
177 nt.assert_equal(ds, docstring)
177
178
178 #-----------------------------------------------------------------------------
179 #-----------------------------------------------------------------------------
179 # Tests
180 # Tests
180 #-----------------------------------------------------------------------------
181 #-----------------------------------------------------------------------------
181
182
182 def test_calltip_class():
183 def test_calltip_class():
183 check_calltip(Call, 'Call', 'Call(x, y=1)', Call.__init__.__doc__)
184 check_calltip(Call, 'Call', 'Call(x, y=1)', Call.__init__.__doc__)
184
185
185
186
186 def test_calltip_instance():
187 def test_calltip_instance():
187 c = Call(1)
188 c = Call(1)
188 check_calltip(c, 'c', 'c(*a, **kw)', c.__call__.__doc__)
189 check_calltip(c, 'c', 'c(*a, **kw)', c.__call__.__doc__)
189
190
190
191
191 def test_calltip_method():
192 def test_calltip_method():
192 c = Call(1)
193 c = Call(1)
193 check_calltip(c.method, 'c.method', 'c.method(x, z=2)', c.method.__doc__)
194 check_calltip(c.method, 'c.method', 'c.method(x, z=2)', c.method.__doc__)
194
195
195
196
196 def test_calltip_function():
197 def test_calltip_function():
197 check_calltip(f, 'f', 'f(x, y=2, *a, **kw)', f.__doc__)
198 check_calltip(f, 'f', 'f(x, y=2, *a, **kw)', f.__doc__)
198
199
199
200
200 def test_calltip_function2():
201 def test_calltip_function2():
201 check_calltip(g, 'g', 'g(y, z=3, *a, **kw)', '<no docstring>')
202 check_calltip(g, 'g', 'g(y, z=3, *a, **kw)', '<no docstring>')
202
203
203
204
204 def test_calltip_builtin():
205 def test_calltip_builtin():
205 check_calltip(sum, 'sum', None, sum.__doc__)
206 check_calltip(sum, 'sum', None, sum.__doc__)
206
207
207
208
208 def test_calltip_line_magic():
209 def test_calltip_line_magic():
209 check_calltip(lmagic, 'lmagic', 'lmagic(line)', "A line magic")
210 check_calltip(lmagic, 'lmagic', 'lmagic(line)', "A line magic")
210
211
211
212
212 def test_calltip_cell_magic():
213 def test_calltip_cell_magic():
213 check_calltip(cmagic, 'cmagic', 'cmagic(line, cell)', "A cell magic")
214 check_calltip(cmagic, 'cmagic', 'cmagic(line, cell)', "A cell magic")
214
215
215
216
216 def test_calltip_line_cell_magic():
217 def test_calltip_line_cell_magic():
217 check_calltip(lcmagic, 'lcmagic', 'lcmagic(line, cell=None)',
218 check_calltip(lcmagic, 'lcmagic', 'lcmagic(line, cell=None)',
218 "A line/cell magic")
219 "A line/cell magic")
219
220
220
221
221 def test_class_magics():
222 def test_class_magics():
222 cm = SimpleMagics(ip)
223 cm = SimpleMagics(ip)
223 ip.register_magics(cm)
224 ip.register_magics(cm)
224 check_calltip(cm.Clmagic, 'Clmagic', 'Clmagic(cline)',
225 check_calltip(cm.Clmagic, 'Clmagic', 'Clmagic(cline)',
225 "A class-based line magic")
226 "A class-based line magic")
226 check_calltip(cm.Ccmagic, 'Ccmagic', 'Ccmagic(cline, ccell)',
227 check_calltip(cm.Ccmagic, 'Ccmagic', 'Ccmagic(cline, ccell)',
227 "A class-based cell magic")
228 "A class-based cell magic")
228 check_calltip(cm.Clcmagic, 'Clcmagic', 'Clcmagic(cline, ccell=None)',
229 check_calltip(cm.Clcmagic, 'Clcmagic', 'Clcmagic(cline, ccell=None)',
229 "A class-based line/cell magic")
230 "A class-based line/cell magic")
230
231
231
232
232 def test_info():
233 def test_info():
233 "Check that Inspector.info fills out various fields as expected."
234 "Check that Inspector.info fills out various fields as expected."
234 i = inspector.info(Call, oname='Call')
235 i = inspector.info(Call, oname='Call')
235 nt.assert_equal(i['type_name'], 'type')
236 nt.assert_equal(i['type_name'], 'type')
236 expted_class = str(type(type)) # <class 'type'> (Python 3) or <type 'type'>
237 expted_class = str(type(type)) # <class 'type'> (Python 3) or <type 'type'>
237 nt.assert_equal(i['base_class'], expted_class)
238 nt.assert_equal(i['base_class'], expted_class)
238 nt.assert_equal(i['string_form'], "<class 'IPython.core.tests.test_oinspect.Call'>")
239 nt.assert_equal(i['string_form'], "<class 'IPython.core.tests.test_oinspect.Call'>")
239 fname = __file__
240 fname = __file__
240 if fname.endswith(".pyc"):
241 if fname.endswith(".pyc"):
241 fname = fname[:-1]
242 fname = fname[:-1]
242 # case-insensitive comparison needed on some filesystems
243 # case-insensitive comparison needed on some filesystems
243 # e.g. Windows:
244 # e.g. Windows:
244 nt.assert_equal(i['file'].lower(), fname.lower())
245 nt.assert_equal(i['file'].lower(), compress_user(fname.lower()))
245 nt.assert_equal(i['definition'], None)
246 nt.assert_equal(i['definition'], None)
246 nt.assert_equal(i['docstring'], Call.__doc__)
247 nt.assert_equal(i['docstring'], Call.__doc__)
247 nt.assert_equal(i['source'], None)
248 nt.assert_equal(i['source'], None)
248 nt.assert_true(i['isclass'])
249 nt.assert_true(i['isclass'])
249 nt.assert_equal(i['init_definition'], "Call(self, x, y=1)\n")
250 nt.assert_equal(i['init_definition'], "Call(self, x, y=1)\n")
250 nt.assert_equal(i['init_docstring'], Call.__init__.__doc__)
251 nt.assert_equal(i['init_docstring'], Call.__init__.__doc__)
251
252
252 i = inspector.info(Call, detail_level=1)
253 i = inspector.info(Call, detail_level=1)
253 nt.assert_not_equal(i['source'], None)
254 nt.assert_not_equal(i['source'], None)
254 nt.assert_equal(i['docstring'], None)
255 nt.assert_equal(i['docstring'], None)
255
256
256 c = Call(1)
257 c = Call(1)
257 c.__doc__ = "Modified instance docstring"
258 c.__doc__ = "Modified instance docstring"
258 i = inspector.info(c)
259 i = inspector.info(c)
259 nt.assert_equal(i['type_name'], 'Call')
260 nt.assert_equal(i['type_name'], 'Call')
260 nt.assert_equal(i['docstring'], "Modified instance docstring")
261 nt.assert_equal(i['docstring'], "Modified instance docstring")
261 nt.assert_equal(i['class_docstring'], Call.__doc__)
262 nt.assert_equal(i['class_docstring'], Call.__doc__)
262 nt.assert_equal(i['init_docstring'], Call.__init__.__doc__)
263 nt.assert_equal(i['init_docstring'], Call.__init__.__doc__)
263 nt.assert_equal(i['call_docstring'], Call.__call__.__doc__)
264 nt.assert_equal(i['call_docstring'], Call.__call__.__doc__)
264
265
265 # Test old-style classes, which for example may not have an __init__ method.
266 # Test old-style classes, which for example may not have an __init__ method.
266 if not py3compat.PY3:
267 if not py3compat.PY3:
267 i = inspector.info(OldStyle)
268 i = inspector.info(OldStyle)
268 nt.assert_equal(i['type_name'], 'classobj')
269 nt.assert_equal(i['type_name'], 'classobj')
269
270
270 i = inspector.info(OldStyle())
271 i = inspector.info(OldStyle())
271 nt.assert_equal(i['type_name'], 'instance')
272 nt.assert_equal(i['type_name'], 'instance')
272 nt.assert_equal(i['docstring'], OldStyle.__doc__)
273 nt.assert_equal(i['docstring'], OldStyle.__doc__)
273
274
274 def test_info_awkward():
275 def test_info_awkward():
275 # Just test that this doesn't throw an error.
276 # Just test that this doesn't throw an error.
276 i = inspector.info(Awkward())
277 i = inspector.info(Awkward())
277
278
278 def test_calldef_none():
279 def test_calldef_none():
279 # We should ignore __call__ for all of these.
280 # We should ignore __call__ for all of these.
280 for obj in [f, SimpleClass().method, any, str.upper]:
281 for obj in [f, SimpleClass().method, any, str.upper]:
281 print(obj)
282 print(obj)
282 i = inspector.info(obj)
283 i = inspector.info(obj)
283 nt.assert_is(i['call_def'], None)
284 nt.assert_is(i['call_def'], None)
284
285
285 if py3compat.PY3:
286 if py3compat.PY3:
286 exec("def f_kwarg(pos, *, kwonly): pass")
287 exec("def f_kwarg(pos, *, kwonly): pass")
287
288
288 @skipif(not py3compat.PY3)
289 @skipif(not py3compat.PY3)
289 def test_definition_kwonlyargs():
290 def test_definition_kwonlyargs():
290 i = inspector.info(f_kwarg, oname='f_kwarg') # analysis:ignore
291 i = inspector.info(f_kwarg, oname='f_kwarg') # analysis:ignore
291 nt.assert_equal(i['definition'], "f_kwarg(pos, *, kwonly)\n")
292 nt.assert_equal(i['definition'], "f_kwarg(pos, *, kwonly)\n")
292
293
293 def test_getdoc():
294 def test_getdoc():
294 class A(object):
295 class A(object):
295 """standard docstring"""
296 """standard docstring"""
296 pass
297 pass
297
298
298 class B(object):
299 class B(object):
299 """standard docstring"""
300 """standard docstring"""
300 def getdoc(self):
301 def getdoc(self):
301 return "custom docstring"
302 return "custom docstring"
302
303
303 class C(object):
304 class C(object):
304 """standard docstring"""
305 """standard docstring"""
305 def getdoc(self):
306 def getdoc(self):
306 return None
307 return None
307
308
308 a = A()
309 a = A()
309 b = B()
310 b = B()
310 c = C()
311 c = C()
311
312
312 nt.assert_equal(oinspect.getdoc(a), "standard docstring")
313 nt.assert_equal(oinspect.getdoc(a), "standard docstring")
313 nt.assert_equal(oinspect.getdoc(b), "custom docstring")
314 nt.assert_equal(oinspect.getdoc(b), "custom docstring")
314 nt.assert_equal(oinspect.getdoc(c), "standard docstring")
315 nt.assert_equal(oinspect.getdoc(c), "standard docstring")
315
316
316
317
317 def test_empty_property_has_no_source():
318 def test_empty_property_has_no_source():
318 i = inspector.info(property(), detail_level=1)
319 i = inspector.info(property(), detail_level=1)
319 nt.assert_is(i['source'], None)
320 nt.assert_is(i['source'], None)
320
321
321
322
322 def test_property_sources():
323 def test_property_sources():
323 import zlib
324 import zlib
324
325
325 class A(object):
326 class A(object):
326 @property
327 @property
327 def foo(self):
328 def foo(self):
328 return 'bar'
329 return 'bar'
329
330
330 foo = foo.setter(lambda self, v: setattr(self, 'bar', v))
331 foo = foo.setter(lambda self, v: setattr(self, 'bar', v))
331
332
332 id = property(id)
333 id = property(id)
333 compress = property(zlib.compress)
334 compress = property(zlib.compress)
334
335
335 i = inspector.info(A.foo, detail_level=1)
336 i = inspector.info(A.foo, detail_level=1)
336 nt.assert_in('def foo(self):', i['source'])
337 nt.assert_in('def foo(self):', i['source'])
337 nt.assert_in('lambda self, v:', i['source'])
338 nt.assert_in('lambda self, v:', i['source'])
338
339
339 i = inspector.info(A.id, detail_level=1)
340 i = inspector.info(A.id, detail_level=1)
340 nt.assert_in('fget = <function id>', i['source'])
341 nt.assert_in('fget = <function id>', i['source'])
341
342
342 i = inspector.info(A.compress, detail_level=1)
343 i = inspector.info(A.compress, detail_level=1)
343 nt.assert_in('fget = <function zlib.compress>', i['source'])
344 nt.assert_in('fget = <function zlib.compress>', i['source'])
344
345
345
346
346 def test_property_docstring_is_in_info_for_detail_level_0():
347 def test_property_docstring_is_in_info_for_detail_level_0():
347 class A(object):
348 class A(object):
348 @property
349 @property
349 def foobar():
350 def foobar():
350 """This is `foobar` property."""
351 """This is `foobar` property."""
351 pass
352 pass
352
353
353 ip.user_ns['a_obj'] = A()
354 ip.user_ns['a_obj'] = A()
354 nt.assert_equals(
355 nt.assert_equals(
355 'This is `foobar` property.',
356 'This is `foobar` property.',
356 ip.object_inspect('a_obj.foobar', detail_level=0)['docstring'])
357 ip.object_inspect('a_obj.foobar', detail_level=0)['docstring'])
357
358
358 ip.user_ns['a_cls'] = A
359 ip.user_ns['a_cls'] = A
359 nt.assert_equals(
360 nt.assert_equals(
360 'This is `foobar` property.',
361 'This is `foobar` property.',
361 ip.object_inspect('a_cls.foobar', detail_level=0)['docstring'])
362 ip.object_inspect('a_cls.foobar', detail_level=0)['docstring'])
362
363
363
364
364 def test_pdef():
365 def test_pdef():
365 # See gh-1914
366 # See gh-1914
366 def foo(): pass
367 def foo(): pass
367 inspector.pdef(foo, 'foo')
368 inspector.pdef(foo, 'foo')
368
369
369 def test_pinfo_nonascii():
370 def test_pinfo_nonascii():
370 # See gh-1177
371 # See gh-1177
371 from . import nonascii2
372 from . import nonascii2
372 ip.user_ns['nonascii2'] = nonascii2
373 ip.user_ns['nonascii2'] = nonascii2
373 ip._inspect('pinfo', 'nonascii2', detail_level=1)
374 ip._inspect('pinfo', 'nonascii2', detail_level=1)
@@ -1,496 +1,496
1 """Test suite for our zeromq-based message specification."""
1 """Test suite for our zeromq-based message specification."""
2
2
3 # Copyright (c) IPython Development Team.
3 # Copyright (c) IPython Development Team.
4 # Distributed under the terms of the Modified BSD License.
4 # Distributed under the terms of the Modified BSD License.
5
5
6 import re
6 import re
7 import sys
7 import sys
8 from distutils.version import LooseVersion as V
8 from distutils.version import LooseVersion as V
9 try:
9 try:
10 from queue import Empty # Py 3
10 from queue import Empty # Py 3
11 except ImportError:
11 except ImportError:
12 from Queue import Empty # Py 2
12 from Queue import Empty # Py 2
13
13
14 import nose.tools as nt
14 import nose.tools as nt
15
15
16 from IPython.utils.traitlets import (
16 from IPython.utils.traitlets import (
17 HasTraits, TraitError, Bool, Unicode, Dict, Integer, List, Enum,
17 HasTraits, TraitError, Bool, Unicode, Dict, Integer, List, Enum,
18 )
18 )
19 from IPython.utils.py3compat import string_types, iteritems
19 from IPython.utils.py3compat import string_types, iteritems
20
20
21 from .utils import TIMEOUT, start_global_kernel, flush_channels, execute
21 from .utils import TIMEOUT, start_global_kernel, flush_channels, execute
22
22
23 #-----------------------------------------------------------------------------
23 #-----------------------------------------------------------------------------
24 # Globals
24 # Globals
25 #-----------------------------------------------------------------------------
25 #-----------------------------------------------------------------------------
26 KC = None
26 KC = None
27
27
28 def setup():
28 def setup():
29 global KC
29 global KC
30 KC = start_global_kernel()
30 KC = start_global_kernel()
31
31
32 #-----------------------------------------------------------------------------
32 #-----------------------------------------------------------------------------
33 # Message Spec References
33 # Message Spec References
34 #-----------------------------------------------------------------------------
34 #-----------------------------------------------------------------------------
35
35
36 class Reference(HasTraits):
36 class Reference(HasTraits):
37
37
38 """
38 """
39 Base class for message spec specification testing.
39 Base class for message spec specification testing.
40
40
41 This class is the core of the message specification test. The
41 This class is the core of the message specification test. The
42 idea is that child classes implement trait attributes for each
42 idea is that child classes implement trait attributes for each
43 message keys, so that message keys can be tested against these
43 message keys, so that message keys can be tested against these
44 traits using :meth:`check` method.
44 traits using :meth:`check` method.
45
45
46 """
46 """
47
47
48 def check(self, d):
48 def check(self, d):
49 """validate a dict against our traits"""
49 """validate a dict against our traits"""
50 for key in self.trait_names():
50 for key in self.trait_names():
51 nt.assert_in(key, d)
51 nt.assert_in(key, d)
52 # FIXME: always allow None, probably not a good idea
52 # FIXME: always allow None, probably not a good idea
53 if d[key] is None:
53 if d[key] is None:
54 continue
54 continue
55 try:
55 try:
56 setattr(self, key, d[key])
56 setattr(self, key, d[key])
57 except TraitError as e:
57 except TraitError as e:
58 assert False, str(e)
58 assert False, str(e)
59
59
60
60
61 class Version(Unicode):
61 class Version(Unicode):
62 def __init__(self, *args, **kwargs):
62 def __init__(self, *args, **kwargs):
63 self.min = kwargs.pop('min', None)
63 self.min = kwargs.pop('min', None)
64 self.max = kwargs.pop('max', None)
64 self.max = kwargs.pop('max', None)
65 kwargs['default_value'] = self.min
65 kwargs['default_value'] = self.min
66 super(Version, self).__init__(*args, **kwargs)
66 super(Version, self).__init__(*args, **kwargs)
67
67
68 def validate(self, obj, value):
68 def validate(self, obj, value):
69 if self.min and V(value) < V(self.min):
69 if self.min and V(value) < V(self.min):
70 raise TraitError("bad version: %s < %s" % (value, self.min))
70 raise TraitError("bad version: %s < %s" % (value, self.min))
71 if self.max and (V(value) > V(self.max)):
71 if self.max and (V(value) > V(self.max)):
72 raise TraitError("bad version: %s > %s" % (value, self.max))
72 raise TraitError("bad version: %s > %s" % (value, self.max))
73
73
74
74
75 class RMessage(Reference):
75 class RMessage(Reference):
76 msg_id = Unicode()
76 msg_id = Unicode()
77 msg_type = Unicode()
77 msg_type = Unicode()
78 header = Dict()
78 header = Dict()
79 parent_header = Dict()
79 parent_header = Dict()
80 content = Dict()
80 content = Dict()
81
81
82 def check(self, d):
82 def check(self, d):
83 super(RMessage, self).check(d)
83 super(RMessage, self).check(d)
84 RHeader().check(self.header)
84 RHeader().check(self.header)
85 if self.parent_header:
85 if self.parent_header:
86 RHeader().check(self.parent_header)
86 RHeader().check(self.parent_header)
87
87
88 class RHeader(Reference):
88 class RHeader(Reference):
89 msg_id = Unicode()
89 msg_id = Unicode()
90 msg_type = Unicode()
90 msg_type = Unicode()
91 session = Unicode()
91 session = Unicode()
92 username = Unicode()
92 username = Unicode()
93 version = Version(min='5.0')
93 version = Version(min='5.0')
94
94
95 mime_pat = re.compile(r'^[\w\-\+\.]+/[\w\-\+\.]+$')
95 mime_pat = re.compile(r'^[\w\-\+\.]+/[\w\-\+\.]+$')
96
96
97 class MimeBundle(Reference):
97 class MimeBundle(Reference):
98 metadata = Dict()
98 metadata = Dict()
99 data = Dict()
99 data = Dict()
100 def _data_changed(self, name, old, new):
100 def _data_changed(self, name, old, new):
101 for k,v in iteritems(new):
101 for k,v in iteritems(new):
102 assert mime_pat.match(k)
102 assert mime_pat.match(k)
103 nt.assert_is_instance(v, string_types)
103 nt.assert_is_instance(v, string_types)
104
104
105 # shell replies
105 # shell replies
106
106
107 class ExecuteReply(Reference):
107 class ExecuteReply(Reference):
108 execution_count = Integer()
108 execution_count = Integer()
109 status = Enum((u'ok', u'error'))
109 status = Enum((u'ok', u'error'))
110
110
111 def check(self, d):
111 def check(self, d):
112 Reference.check(self, d)
112 Reference.check(self, d)
113 if d['status'] == 'ok':
113 if d['status'] == 'ok':
114 ExecuteReplyOkay().check(d)
114 ExecuteReplyOkay().check(d)
115 elif d['status'] == 'error':
115 elif d['status'] == 'error':
116 ExecuteReplyError().check(d)
116 ExecuteReplyError().check(d)
117
117
118
118
119 class ExecuteReplyOkay(Reference):
119 class ExecuteReplyOkay(Reference):
120 payload = List(Dict)
120 payload = List(Dict)
121 user_expressions = Dict()
121 user_expressions = Dict()
122
122
123
123
124 class ExecuteReplyError(Reference):
124 class ExecuteReplyError(Reference):
125 ename = Unicode()
125 ename = Unicode()
126 evalue = Unicode()
126 evalue = Unicode()
127 traceback = List(Unicode)
127 traceback = List(Unicode)
128
128
129
129
130 class InspectReply(MimeBundle):
130 class InspectReply(MimeBundle):
131 found = Bool()
131 found = Bool()
132
132
133
133
134 class ArgSpec(Reference):
134 class ArgSpec(Reference):
135 args = List(Unicode)
135 args = List(Unicode)
136 varargs = Unicode()
136 varargs = Unicode()
137 varkw = Unicode()
137 varkw = Unicode()
138 defaults = List()
138 defaults = List()
139
139
140
140
141 class Status(Reference):
141 class Status(Reference):
142 execution_state = Enum((u'busy', u'idle', u'starting'))
142 execution_state = Enum((u'busy', u'idle', u'starting'))
143
143
144
144
145 class CompleteReply(Reference):
145 class CompleteReply(Reference):
146 matches = List(Unicode)
146 matches = List(Unicode)
147 cursor_start = Integer()
147 cursor_start = Integer()
148 cursor_end = Integer()
148 cursor_end = Integer()
149 status = Unicode()
149 status = Unicode()
150
150
151 class LanguageInfo(Reference):
151 class LanguageInfo(Reference):
152 name = Unicode('python')
152 name = Unicode('python')
153 version = Unicode(sys.version.split()[0])
153 version = Unicode(sys.version.split()[0])
154
154
155 class KernelInfoReply(Reference):
155 class KernelInfoReply(Reference):
156 protocol_version = Version(min='5.0')
156 protocol_version = Version(min='5.0')
157 implementation = Unicode('ipython')
157 implementation = Unicode('ipython')
158 implementation_version = Version(min='2.1')
158 implementation_version = Version(min='2.1')
159 language_info = Dict()
159 language_info = Dict()
160 banner = Unicode()
160 banner = Unicode()
161
161
162 def check(self, d):
162 def check(self, d):
163 Reference.check(self, d)
163 Reference.check(self, d)
164 LanguageInfo().check(d['language_info'])
164 LanguageInfo().check(d['language_info'])
165
165
166
166
167 class IsCompleteReply(Reference):
167 class IsCompleteReply(Reference):
168 status = Enum((u'complete', u'incomplete', u'invalid', u'unknown'))
168 status = Enum((u'complete', u'incomplete', u'invalid', u'unknown'))
169
169
170 def check(self, d):
170 def check(self, d):
171 Reference.check(self, d)
171 Reference.check(self, d)
172 if d['status'] == 'incomplete':
172 if d['status'] == 'incomplete':
173 IsCompleteReplyIncomplete().check(d)
173 IsCompleteReplyIncomplete().check(d)
174
174
175 class IsCompleteReplyIncomplete(Reference):
175 class IsCompleteReplyIncomplete(Reference):
176 indent = Unicode()
176 indent = Unicode()
177
177
178
178
179 # IOPub messages
179 # IOPub messages
180
180
181 class ExecuteInput(Reference):
181 class ExecuteInput(Reference):
182 code = Unicode()
182 code = Unicode()
183 execution_count = Integer()
183 execution_count = Integer()
184
184
185
185
186 Error = ExecuteReplyError
186 Error = ExecuteReplyError
187
187
188
188
189 class Stream(Reference):
189 class Stream(Reference):
190 name = Enum((u'stdout', u'stderr'))
190 name = Enum((u'stdout', u'stderr'))
191 text = Unicode()
191 text = Unicode()
192
192
193
193
194 class DisplayData(MimeBundle):
194 class DisplayData(MimeBundle):
195 pass
195 pass
196
196
197
197
198 class ExecuteResult(MimeBundle):
198 class ExecuteResult(MimeBundle):
199 execution_count = Integer()
199 execution_count = Integer()
200
200
201 class HistoryReply(Reference):
201 class HistoryReply(Reference):
202 history = List(List())
202 history = List(List())
203
203
204
204
205 references = {
205 references = {
206 'execute_reply' : ExecuteReply(),
206 'execute_reply' : ExecuteReply(),
207 'inspect_reply' : InspectReply(),
207 'inspect_reply' : InspectReply(),
208 'status' : Status(),
208 'status' : Status(),
209 'complete_reply' : CompleteReply(),
209 'complete_reply' : CompleteReply(),
210 'kernel_info_reply': KernelInfoReply(),
210 'kernel_info_reply': KernelInfoReply(),
211 'is_complete_reply': IsCompleteReply(),
211 'is_complete_reply': IsCompleteReply(),
212 'execute_input' : ExecuteInput(),
212 'execute_input' : ExecuteInput(),
213 'execute_result' : ExecuteResult(),
213 'execute_result' : ExecuteResult(),
214 'history_reply' : HistoryReply(),
214 'history_reply' : HistoryReply(),
215 'error' : Error(),
215 'error' : Error(),
216 'stream' : Stream(),
216 'stream' : Stream(),
217 'display_data' : DisplayData(),
217 'display_data' : DisplayData(),
218 'header' : RHeader(),
218 'header' : RHeader(),
219 }
219 }
220 """
220 """
221 Specifications of `content` part of the reply messages.
221 Specifications of `content` part of the reply messages.
222 """
222 """
223
223
224
224
225 def validate_message(msg, msg_type=None, parent=None):
225 def validate_message(msg, msg_type=None, parent=None):
226 """validate a message
226 """validate a message
227
227
228 This is a generator, and must be iterated through to actually
228 This is a generator, and must be iterated through to actually
229 trigger each test.
229 trigger each test.
230
230
231 If msg_type and/or parent are given, the msg_type and/or parent msg_id
231 If msg_type and/or parent are given, the msg_type and/or parent msg_id
232 are compared with the given values.
232 are compared with the given values.
233 """
233 """
234 RMessage().check(msg)
234 RMessage().check(msg)
235 if msg_type:
235 if msg_type:
236 nt.assert_equal(msg['msg_type'], msg_type)
236 nt.assert_equal(msg['msg_type'], msg_type)
237 if parent:
237 if parent:
238 nt.assert_equal(msg['parent_header']['msg_id'], parent)
238 nt.assert_equal(msg['parent_header']['msg_id'], parent)
239 content = msg['content']
239 content = msg['content']
240 ref = references[msg['msg_type']]
240 ref = references[msg['msg_type']]
241 ref.check(content)
241 ref.check(content)
242
242
243
243
244 #-----------------------------------------------------------------------------
244 #-----------------------------------------------------------------------------
245 # Tests
245 # Tests
246 #-----------------------------------------------------------------------------
246 #-----------------------------------------------------------------------------
247
247
248 # Shell channel
248 # Shell channel
249
249
250 def test_execute():
250 def test_execute():
251 flush_channels()
251 flush_channels()
252
252
253 msg_id = KC.execute(code='x=1')
253 msg_id = KC.execute(code='x=1')
254 reply = KC.get_shell_msg(timeout=TIMEOUT)
254 reply = KC.get_shell_msg(timeout=TIMEOUT)
255 validate_message(reply, 'execute_reply', msg_id)
255 validate_message(reply, 'execute_reply', msg_id)
256
256
257
257
258 def test_execute_silent():
258 def test_execute_silent():
259 flush_channels()
259 flush_channels()
260 msg_id, reply = execute(code='x=1', silent=True)
260 msg_id, reply = execute(code='x=1', silent=True)
261
261
262 # flush status=idle
262 # flush status=idle
263 status = KC.iopub_channel.get_msg(timeout=TIMEOUT)
263 status = KC.iopub_channel.get_msg(timeout=TIMEOUT)
264 validate_message(status, 'status', msg_id)
264 validate_message(status, 'status', msg_id)
265 nt.assert_equal(status['content']['execution_state'], 'idle')
265 nt.assert_equal(status['content']['execution_state'], 'idle')
266
266
267 nt.assert_raises(Empty, KC.iopub_channel.get_msg, timeout=0.1)
267 nt.assert_raises(Empty, KC.iopub_channel.get_msg, timeout=0.1)
268 count = reply['execution_count']
268 count = reply['execution_count']
269
269
270 msg_id, reply = execute(code='x=2', silent=True)
270 msg_id, reply = execute(code='x=2', silent=True)
271
271
272 # flush status=idle
272 # flush status=idle
273 status = KC.iopub_channel.get_msg(timeout=TIMEOUT)
273 status = KC.iopub_channel.get_msg(timeout=TIMEOUT)
274 validate_message(status, 'status', msg_id)
274 validate_message(status, 'status', msg_id)
275 nt.assert_equal(status['content']['execution_state'], 'idle')
275 nt.assert_equal(status['content']['execution_state'], 'idle')
276
276
277 nt.assert_raises(Empty, KC.iopub_channel.get_msg, timeout=0.1)
277 nt.assert_raises(Empty, KC.iopub_channel.get_msg, timeout=0.1)
278 count_2 = reply['execution_count']
278 count_2 = reply['execution_count']
279 nt.assert_equal(count_2, count)
279 nt.assert_equal(count_2, count)
280
280
281
281
282 def test_execute_error():
282 def test_execute_error():
283 flush_channels()
283 flush_channels()
284
284
285 msg_id, reply = execute(code='1/0')
285 msg_id, reply = execute(code='1/0')
286 nt.assert_equal(reply['status'], 'error')
286 nt.assert_equal(reply['status'], 'error')
287 nt.assert_equal(reply['ename'], 'ZeroDivisionError')
287 nt.assert_equal(reply['ename'], 'ZeroDivisionError')
288
288
289 error = KC.iopub_channel.get_msg(timeout=TIMEOUT)
289 error = KC.iopub_channel.get_msg(timeout=TIMEOUT)
290 validate_message(error, 'error', msg_id)
290 validate_message(error, 'error', msg_id)
291
291
292
292
293 def test_execute_inc():
293 def test_execute_inc():
294 """execute request should increment execution_count"""
294 """execute request should increment execution_count"""
295 flush_channels()
295 flush_channels()
296
296
297 msg_id, reply = execute(code='x=1')
297 msg_id, reply = execute(code='x=1')
298 count = reply['execution_count']
298 count = reply['execution_count']
299
299
300 flush_channels()
300 flush_channels()
301
301
302 msg_id, reply = execute(code='x=2')
302 msg_id, reply = execute(code='x=2')
303 count_2 = reply['execution_count']
303 count_2 = reply['execution_count']
304 nt.assert_equal(count_2, count+1)
304 nt.assert_equal(count_2, count+1)
305
305
306 def test_execute_stop_on_error():
306 def test_execute_stop_on_error():
307 """execute request should not abort execution queue with stop_on_error False"""
307 """execute request should not abort execution queue with stop_on_error False"""
308 flush_channels()
308 flush_channels()
309
309
310 fail = '\n'.join([
310 fail = '\n'.join([
311 # sleep to ensure subsequent message is waiting in the queue to be aborted
311 # sleep to ensure subsequent message is waiting in the queue to be aborted
312 'import time',
312 'import time',
313 'time.sleep(0.5)',
313 'time.sleep(0.5)',
314 'raise ValueError',
314 'raise ValueError',
315 ])
315 ])
316 KC.execute(code=fail)
316 KC.execute(code=fail)
317 msg_id = KC.execute(code='print("Hello")')
317 msg_id = KC.execute(code='print("Hello")')
318 KC.get_shell_msg(timeout=TIMEOUT)
318 KC.get_shell_msg(timeout=TIMEOUT)
319 reply = KC.get_shell_msg(timeout=TIMEOUT)
319 reply = KC.get_shell_msg(timeout=TIMEOUT)
320 nt.assert_equal(reply['content']['status'], 'aborted')
320 nt.assert_equal(reply['content']['status'], 'aborted')
321
321
322 flush_channels()
322 flush_channels()
323
323
324 KC.execute(code=fail, stop_on_error=False)
324 KC.execute(code=fail, stop_on_error=False)
325 msg_id = KC.execute(code='print("Hello")')
325 msg_id = KC.execute(code='print("Hello")')
326 KC.get_shell_msg(timeout=TIMEOUT)
326 KC.get_shell_msg(timeout=TIMEOUT)
327 reply = KC.get_shell_msg(timeout=TIMEOUT)
327 reply = KC.get_shell_msg(timeout=TIMEOUT)
328 nt.assert_equal(reply['content']['status'], 'ok')
328 nt.assert_equal(reply['content']['status'], 'ok')
329
329
330
330
331 def test_user_expressions():
331 def test_user_expressions():
332 flush_channels()
332 flush_channels()
333
333
334 msg_id, reply = execute(code='x=1', user_expressions=dict(foo='x+1'))
334 msg_id, reply = execute(code='x=1', user_expressions=dict(foo='x+1'))
335 user_expressions = reply['user_expressions']
335 user_expressions = reply['user_expressions']
336 nt.assert_equal(user_expressions, {u'foo': {
336 nt.assert_equal(user_expressions, {u'foo': {
337 u'status': u'ok',
337 u'status': u'ok',
338 u'data': {u'text/plain': u'2'},
338 u'data': {u'text/plain': u'2'},
339 u'metadata': {},
339 u'metadata': {},
340 }})
340 }})
341
341
342
342
343 def test_user_expressions_fail():
343 def test_user_expressions_fail():
344 flush_channels()
344 flush_channels()
345
345
346 msg_id, reply = execute(code='x=0', user_expressions=dict(foo='nosuchname'))
346 msg_id, reply = execute(code='x=0', user_expressions=dict(foo='nosuchname'))
347 user_expressions = reply['user_expressions']
347 user_expressions = reply['user_expressions']
348 foo = user_expressions['foo']
348 foo = user_expressions['foo']
349 nt.assert_equal(foo['status'], 'error')
349 nt.assert_equal(foo['status'], 'error')
350 nt.assert_equal(foo['ename'], 'NameError')
350 nt.assert_equal(foo['ename'], 'NameError')
351
351
352
352
353 def test_oinfo():
353 def test_oinfo():
354 flush_channels()
354 flush_channels()
355
355
356 msg_id = KC.inspect('a')
356 msg_id = KC.inspect('a')
357 reply = KC.get_shell_msg(timeout=TIMEOUT)
357 reply = KC.get_shell_msg(timeout=TIMEOUT)
358 validate_message(reply, 'inspect_reply', msg_id)
358 validate_message(reply, 'inspect_reply', msg_id)
359
359
360
360
361 def test_oinfo_found():
361 def test_oinfo_found():
362 flush_channels()
362 flush_channels()
363
363
364 msg_id, reply = execute(code='a=5')
364 msg_id, reply = execute(code='a=5')
365
365
366 msg_id = KC.inspect('a')
366 msg_id = KC.inspect('a')
367 reply = KC.get_shell_msg(timeout=TIMEOUT)
367 reply = KC.get_shell_msg(timeout=TIMEOUT)
368 validate_message(reply, 'inspect_reply', msg_id)
368 validate_message(reply, 'inspect_reply', msg_id)
369 content = reply['content']
369 content = reply['content']
370 assert content['found']
370 assert content['found']
371 text = content['data']['text/plain']
371 text = content['data']['text/plain']
372 nt.assert_in('Type:', text)
372 nt.assert_in('Type:', text)
373 nt.assert_in('Docstring:', text)
373 nt.assert_in('Docstring:', text)
374
374
375
375
376 def test_oinfo_detail():
376 def test_oinfo_detail():
377 flush_channels()
377 flush_channels()
378
378
379 msg_id, reply = execute(code='ip=get_ipython()')
379 msg_id, reply = execute(code='ip=get_ipython()')
380
380
381 msg_id = KC.inspect('ip.object_inspect', cursor_pos=10, detail_level=1)
381 msg_id = KC.inspect('ip.object_inspect', cursor_pos=10, detail_level=1)
382 reply = KC.get_shell_msg(timeout=TIMEOUT)
382 reply = KC.get_shell_msg(timeout=TIMEOUT)
383 validate_message(reply, 'inspect_reply', msg_id)
383 validate_message(reply, 'inspect_reply', msg_id)
384 content = reply['content']
384 content = reply['content']
385 assert content['found']
385 assert content['found']
386 text = content['data']['text/plain']
386 text = content['data']['text/plain']
387 nt.assert_in('Definition:', text)
387 nt.assert_in('Signature:', text)
388 nt.assert_in('Source:', text)
388 nt.assert_in('Source:', text)
389
389
390
390
391 def test_oinfo_not_found():
391 def test_oinfo_not_found():
392 flush_channels()
392 flush_channels()
393
393
394 msg_id = KC.inspect('dne')
394 msg_id = KC.inspect('dne')
395 reply = KC.get_shell_msg(timeout=TIMEOUT)
395 reply = KC.get_shell_msg(timeout=TIMEOUT)
396 validate_message(reply, 'inspect_reply', msg_id)
396 validate_message(reply, 'inspect_reply', msg_id)
397 content = reply['content']
397 content = reply['content']
398 nt.assert_false(content['found'])
398 nt.assert_false(content['found'])
399
399
400
400
401 def test_complete():
401 def test_complete():
402 flush_channels()
402 flush_channels()
403
403
404 msg_id, reply = execute(code="alpha = albert = 5")
404 msg_id, reply = execute(code="alpha = albert = 5")
405
405
406 msg_id = KC.complete('al', 2)
406 msg_id = KC.complete('al', 2)
407 reply = KC.get_shell_msg(timeout=TIMEOUT)
407 reply = KC.get_shell_msg(timeout=TIMEOUT)
408 validate_message(reply, 'complete_reply', msg_id)
408 validate_message(reply, 'complete_reply', msg_id)
409 matches = reply['content']['matches']
409 matches = reply['content']['matches']
410 for name in ('alpha', 'albert'):
410 for name in ('alpha', 'albert'):
411 nt.assert_in(name, matches)
411 nt.assert_in(name, matches)
412
412
413
413
414 def test_kernel_info_request():
414 def test_kernel_info_request():
415 flush_channels()
415 flush_channels()
416
416
417 msg_id = KC.kernel_info()
417 msg_id = KC.kernel_info()
418 reply = KC.get_shell_msg(timeout=TIMEOUT)
418 reply = KC.get_shell_msg(timeout=TIMEOUT)
419 validate_message(reply, 'kernel_info_reply', msg_id)
419 validate_message(reply, 'kernel_info_reply', msg_id)
420
420
421
421
422 def test_single_payload():
422 def test_single_payload():
423 flush_channels()
423 flush_channels()
424 msg_id, reply = execute(code="for i in range(3):\n"+
424 msg_id, reply = execute(code="for i in range(3):\n"+
425 " x=range?\n")
425 " x=range?\n")
426 payload = reply['payload']
426 payload = reply['payload']
427 next_input_pls = [pl for pl in payload if pl["source"] == "set_next_input"]
427 next_input_pls = [pl for pl in payload if pl["source"] == "set_next_input"]
428 nt.assert_equal(len(next_input_pls), 1)
428 nt.assert_equal(len(next_input_pls), 1)
429
429
430 def test_is_complete():
430 def test_is_complete():
431 flush_channels()
431 flush_channels()
432
432
433 msg_id = KC.is_complete("a = 1")
433 msg_id = KC.is_complete("a = 1")
434 reply = KC.get_shell_msg(timeout=TIMEOUT)
434 reply = KC.get_shell_msg(timeout=TIMEOUT)
435 validate_message(reply, 'is_complete_reply', msg_id)
435 validate_message(reply, 'is_complete_reply', msg_id)
436
436
437 def test_history_range():
437 def test_history_range():
438 flush_channels()
438 flush_channels()
439
439
440 msg_id_exec = KC.execute(code='x=1', store_history = True)
440 msg_id_exec = KC.execute(code='x=1', store_history = True)
441 reply_exec = KC.get_shell_msg(timeout=TIMEOUT)
441 reply_exec = KC.get_shell_msg(timeout=TIMEOUT)
442
442
443 msg_id = KC.history(hist_access_type = 'range', raw = True, output = True, start = 1, stop = 2, session = 0)
443 msg_id = KC.history(hist_access_type = 'range', raw = True, output = True, start = 1, stop = 2, session = 0)
444 reply = KC.get_shell_msg(timeout=TIMEOUT)
444 reply = KC.get_shell_msg(timeout=TIMEOUT)
445 validate_message(reply, 'history_reply', msg_id)
445 validate_message(reply, 'history_reply', msg_id)
446 content = reply['content']
446 content = reply['content']
447 nt.assert_equal(len(content['history']), 1)
447 nt.assert_equal(len(content['history']), 1)
448
448
449 def test_history_tail():
449 def test_history_tail():
450 flush_channels()
450 flush_channels()
451
451
452 msg_id_exec = KC.execute(code='x=1', store_history = True)
452 msg_id_exec = KC.execute(code='x=1', store_history = True)
453 reply_exec = KC.get_shell_msg(timeout=TIMEOUT)
453 reply_exec = KC.get_shell_msg(timeout=TIMEOUT)
454
454
455 msg_id = KC.history(hist_access_type = 'tail', raw = True, output = True, n = 1, session = 0)
455 msg_id = KC.history(hist_access_type = 'tail', raw = True, output = True, n = 1, session = 0)
456 reply = KC.get_shell_msg(timeout=TIMEOUT)
456 reply = KC.get_shell_msg(timeout=TIMEOUT)
457 validate_message(reply, 'history_reply', msg_id)
457 validate_message(reply, 'history_reply', msg_id)
458 content = reply['content']
458 content = reply['content']
459 nt.assert_equal(len(content['history']), 1)
459 nt.assert_equal(len(content['history']), 1)
460
460
461 def test_history_search():
461 def test_history_search():
462 flush_channels()
462 flush_channels()
463
463
464 msg_id_exec = KC.execute(code='x=1', store_history = True)
464 msg_id_exec = KC.execute(code='x=1', store_history = True)
465 reply_exec = KC.get_shell_msg(timeout=TIMEOUT)
465 reply_exec = KC.get_shell_msg(timeout=TIMEOUT)
466
466
467 msg_id = KC.history(hist_access_type = 'search', raw = True, output = True, n = 1, pattern = '*', session = 0)
467 msg_id = KC.history(hist_access_type = 'search', raw = True, output = True, n = 1, pattern = '*', session = 0)
468 reply = KC.get_shell_msg(timeout=TIMEOUT)
468 reply = KC.get_shell_msg(timeout=TIMEOUT)
469 validate_message(reply, 'history_reply', msg_id)
469 validate_message(reply, 'history_reply', msg_id)
470 content = reply['content']
470 content = reply['content']
471 nt.assert_equal(len(content['history']), 1)
471 nt.assert_equal(len(content['history']), 1)
472
472
473 # IOPub channel
473 # IOPub channel
474
474
475
475
476 def test_stream():
476 def test_stream():
477 flush_channels()
477 flush_channels()
478
478
479 msg_id, reply = execute("print('hi')")
479 msg_id, reply = execute("print('hi')")
480
480
481 stdout = KC.iopub_channel.get_msg(timeout=TIMEOUT)
481 stdout = KC.iopub_channel.get_msg(timeout=TIMEOUT)
482 validate_message(stdout, 'stream', msg_id)
482 validate_message(stdout, 'stream', msg_id)
483 content = stdout['content']
483 content = stdout['content']
484 nt.assert_equal(content['text'], u'hi\n')
484 nt.assert_equal(content['text'], u'hi\n')
485
485
486
486
487 def test_display_data():
487 def test_display_data():
488 flush_channels()
488 flush_channels()
489
489
490 msg_id, reply = execute("from IPython.core.display import display; display(1)")
490 msg_id, reply = execute("from IPython.core.display import display; display(1)")
491
491
492 display = KC.iopub_channel.get_msg(timeout=TIMEOUT)
492 display = KC.iopub_channel.get_msg(timeout=TIMEOUT)
493 validate_message(display, 'display_data', parent=msg_id)
493 validate_message(display, 'display_data', parent=msg_id)
494 data = display['content']['data']
494 data = display['content']['data']
495 nt.assert_equal(data['text/plain'], u'1')
495 nt.assert_equal(data['text/plain'], u'1')
496
496
General Comments 0
You need to be logged in to leave comments. Login now