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