##// END OF EJS Templates
Add test for alias creation, use and destruction
Thomas Kluyver -
Show More
@@ -0,0 +1,41 b''
1 from IPython.utils.capture import capture_output
2
3 import nose.tools as nt
4
5 def test_alias_lifecycle():
6 name = 'test_alias1'
7 cmd = 'echo "Hello"'
8 am = _ip.alias_manager
9 am.clear_aliases()
10 am.define_alias(name, cmd)
11 assert am.is_alias(name)
12 nt.assert_equal(am.retrieve_alias(name), cmd)
13 nt.assert_in((name, cmd), am.aliases)
14
15 # Test running the alias
16 orig_system = _ip.system
17 result = []
18 _ip.system = result.append
19 try:
20 _ip.run_cell('%{}'.format(name))
21 result = [c.strip() for c in result]
22 nt.assert_equal(result, [cmd])
23 finally:
24 _ip.system = orig_system
25
26 # Test removing the alias
27 am.undefine_alias(name)
28 assert not am.is_alias(name)
29 with nt.assert_raises(ValueError):
30 am.retrieve_alias(name)
31 nt.assert_not_in((name, cmd), am.aliases)
32
33
34 def test_alias_args_error():
35 """Error expanding with wrong number of arguments"""
36 _ip.alias_manager.define_alias('parts', 'echo first %s second %s')
37 # capture stderr:
38 with capture_output() as cap:
39 _ip.run_cell('parts 1')
40
41 nt.assert_equal(cap.stderr.split(':')[0], 'UsageError') No newline at end of file
@@ -1,652 +1,641 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Tests for the key interactiveshell module.
3 3
4 4 Historically the main classes in interactiveshell have been under-tested. This
5 5 module should grow as many single-method tests as possible to trap many of the
6 6 recurring bugs we seem to encounter with high-level interaction.
7 7
8 8 Authors
9 9 -------
10 10 * Fernando Perez
11 11 """
12 12 #-----------------------------------------------------------------------------
13 13 # Copyright (C) 2011 The IPython Development Team
14 14 #
15 15 # Distributed under the terms of the BSD License. The full license is in
16 16 # the file COPYING, distributed as part of this software.
17 17 #-----------------------------------------------------------------------------
18 18
19 19 #-----------------------------------------------------------------------------
20 20 # Imports
21 21 #-----------------------------------------------------------------------------
22 22 # stdlib
23 23 import ast
24 24 import os
25 25 import shutil
26 26 import sys
27 27 import tempfile
28 28 import unittest
29 29 from os.path import join
30 30 from StringIO import StringIO
31 31
32 32 # third-party
33 33 import nose.tools as nt
34 34
35 35 # Our own
36 36 from IPython.testing.decorators import skipif, onlyif_unicode_paths
37 37 from IPython.testing import tools as tt
38 38 from IPython.utils import io
39 39
40 40 #-----------------------------------------------------------------------------
41 41 # Globals
42 42 #-----------------------------------------------------------------------------
43 43 # This is used by every single test, no point repeating it ad nauseam
44 44 ip = get_ipython()
45 45
46 46 #-----------------------------------------------------------------------------
47 47 # Tests
48 48 #-----------------------------------------------------------------------------
49 49
50 50 class InteractiveShellTestCase(unittest.TestCase):
51 51 def test_naked_string_cells(self):
52 52 """Test that cells with only naked strings are fully executed"""
53 53 # First, single-line inputs
54 54 ip.run_cell('"a"\n')
55 55 self.assertEqual(ip.user_ns['_'], 'a')
56 56 # And also multi-line cells
57 57 ip.run_cell('"""a\nb"""\n')
58 58 self.assertEqual(ip.user_ns['_'], 'a\nb')
59 59
60 60 def test_run_empty_cell(self):
61 61 """Just make sure we don't get a horrible error with a blank
62 62 cell of input. Yes, I did overlook that."""
63 63 old_xc = ip.execution_count
64 64 ip.run_cell('')
65 65 self.assertEqual(ip.execution_count, old_xc)
66 66
67 67 def test_run_cell_multiline(self):
68 68 """Multi-block, multi-line cells must execute correctly.
69 69 """
70 70 src = '\n'.join(["x=1",
71 71 "y=2",
72 72 "if 1:",
73 73 " x += 1",
74 74 " y += 1",])
75 75 ip.run_cell(src)
76 76 self.assertEqual(ip.user_ns['x'], 2)
77 77 self.assertEqual(ip.user_ns['y'], 3)
78 78
79 79 def test_multiline_string_cells(self):
80 80 "Code sprinkled with multiline strings should execute (GH-306)"
81 81 ip.run_cell('tmp=0')
82 82 self.assertEqual(ip.user_ns['tmp'], 0)
83 83 ip.run_cell('tmp=1;"""a\nb"""\n')
84 84 self.assertEqual(ip.user_ns['tmp'], 1)
85 85
86 86 def test_dont_cache_with_semicolon(self):
87 87 "Ending a line with semicolon should not cache the returned object (GH-307)"
88 88 oldlen = len(ip.user_ns['Out'])
89 89 a = ip.run_cell('1;', store_history=True)
90 90 newlen = len(ip.user_ns['Out'])
91 91 self.assertEqual(oldlen, newlen)
92 92 #also test the default caching behavior
93 93 ip.run_cell('1', store_history=True)
94 94 newlen = len(ip.user_ns['Out'])
95 95 self.assertEqual(oldlen+1, newlen)
96 96
97 97 def test_In_variable(self):
98 98 "Verify that In variable grows with user input (GH-284)"
99 99 oldlen = len(ip.user_ns['In'])
100 100 ip.run_cell('1;', store_history=True)
101 101 newlen = len(ip.user_ns['In'])
102 102 self.assertEqual(oldlen+1, newlen)
103 103 self.assertEqual(ip.user_ns['In'][-1],'1;')
104 104
105 105 def test_magic_names_in_string(self):
106 106 ip.run_cell('a = """\n%exit\n"""')
107 107 self.assertEqual(ip.user_ns['a'], '\n%exit\n')
108 108
109 def test_alias_crash(self):
110 """Errors in prefilter can't crash IPython"""
111 ip.run_cell('%alias parts echo first %s second %s')
112 # capture stderr:
113 save_err = io.stderr
114 io.stderr = StringIO()
115 ip.run_cell('parts 1')
116 err = io.stderr.getvalue()
117 io.stderr = save_err
118 self.assertEqual(err.split(':')[0], 'ERROR')
119
120 109 def test_trailing_newline(self):
121 110 """test that running !(command) does not raise a SyntaxError"""
122 111 ip.run_cell('!(true)\n', False)
123 112 ip.run_cell('!(true)\n\n\n', False)
124 113
125 114 def test_gh_597(self):
126 115 """Pretty-printing lists of objects with non-ascii reprs may cause
127 116 problems."""
128 117 class Spam(object):
129 118 def __repr__(self):
130 119 return "\xe9"*50
131 120 import IPython.core.formatters
132 121 f = IPython.core.formatters.PlainTextFormatter()
133 122 f([Spam(),Spam()])
134 123
135 124
136 125 def test_future_flags(self):
137 126 """Check that future flags are used for parsing code (gh-777)"""
138 127 ip.run_cell('from __future__ import print_function')
139 128 try:
140 129 ip.run_cell('prfunc_return_val = print(1,2, sep=" ")')
141 130 assert 'prfunc_return_val' in ip.user_ns
142 131 finally:
143 132 # Reset compiler flags so we don't mess up other tests.
144 133 ip.compile.reset_compiler_flags()
145 134
146 135 def test_future_unicode(self):
147 136 """Check that unicode_literals is imported from __future__ (gh #786)"""
148 137 try:
149 138 ip.run_cell(u'byte_str = "a"')
150 139 assert isinstance(ip.user_ns['byte_str'], str) # string literals are byte strings by default
151 140 ip.run_cell('from __future__ import unicode_literals')
152 141 ip.run_cell(u'unicode_str = "a"')
153 142 assert isinstance(ip.user_ns['unicode_str'], unicode) # strings literals are now unicode
154 143 finally:
155 144 # Reset compiler flags so we don't mess up other tests.
156 145 ip.compile.reset_compiler_flags()
157 146
158 147 def test_can_pickle(self):
159 148 "Can we pickle objects defined interactively (GH-29)"
160 149 ip = get_ipython()
161 150 ip.reset()
162 151 ip.run_cell(("class Mylist(list):\n"
163 152 " def __init__(self,x=[]):\n"
164 153 " list.__init__(self,x)"))
165 154 ip.run_cell("w=Mylist([1,2,3])")
166 155
167 156 from cPickle import dumps
168 157
169 158 # We need to swap in our main module - this is only necessary
170 159 # inside the test framework, because IPython puts the interactive module
171 160 # in place (but the test framework undoes this).
172 161 _main = sys.modules['__main__']
173 162 sys.modules['__main__'] = ip.user_module
174 163 try:
175 164 res = dumps(ip.user_ns["w"])
176 165 finally:
177 166 sys.modules['__main__'] = _main
178 167 self.assertTrue(isinstance(res, bytes))
179 168
180 169 def test_global_ns(self):
181 170 "Code in functions must be able to access variables outside them."
182 171 ip = get_ipython()
183 172 ip.run_cell("a = 10")
184 173 ip.run_cell(("def f(x):\n"
185 174 " return x + a"))
186 175 ip.run_cell("b = f(12)")
187 176 self.assertEqual(ip.user_ns["b"], 22)
188 177
189 178 def test_bad_custom_tb(self):
190 179 """Check that InteractiveShell is protected from bad custom exception handlers"""
191 180 from IPython.utils import io
192 181 save_stderr = io.stderr
193 182 try:
194 183 # capture stderr
195 184 io.stderr = StringIO()
196 185 ip.set_custom_exc((IOError,), lambda etype,value,tb: 1/0)
197 186 self.assertEqual(ip.custom_exceptions, (IOError,))
198 187 ip.run_cell(u'raise IOError("foo")')
199 188 self.assertEqual(ip.custom_exceptions, ())
200 189 self.assertTrue("Custom TB Handler failed" in io.stderr.getvalue())
201 190 finally:
202 191 io.stderr = save_stderr
203 192
204 193 def test_bad_custom_tb_return(self):
205 194 """Check that InteractiveShell is protected from bad return types in custom exception handlers"""
206 195 from IPython.utils import io
207 196 save_stderr = io.stderr
208 197 try:
209 198 # capture stderr
210 199 io.stderr = StringIO()
211 200 ip.set_custom_exc((NameError,),lambda etype,value,tb, tb_offset=None: 1)
212 201 self.assertEqual(ip.custom_exceptions, (NameError,))
213 202 ip.run_cell(u'a=abracadabra')
214 203 self.assertEqual(ip.custom_exceptions, ())
215 204 self.assertTrue("Custom TB Handler failed" in io.stderr.getvalue())
216 205 finally:
217 206 io.stderr = save_stderr
218 207
219 208 def test_drop_by_id(self):
220 209 myvars = {"a":object(), "b":object(), "c": object()}
221 210 ip.push(myvars, interactive=False)
222 211 for name in myvars:
223 212 assert name in ip.user_ns, name
224 213 assert name in ip.user_ns_hidden, name
225 214 ip.user_ns['b'] = 12
226 215 ip.drop_by_id(myvars)
227 216 for name in ["a", "c"]:
228 217 assert name not in ip.user_ns, name
229 218 assert name not in ip.user_ns_hidden, name
230 219 assert ip.user_ns['b'] == 12
231 220 ip.reset()
232 221
233 222 def test_var_expand(self):
234 223 ip.user_ns['f'] = u'Ca\xf1o'
235 224 self.assertEqual(ip.var_expand(u'echo $f'), u'echo Ca\xf1o')
236 225 self.assertEqual(ip.var_expand(u'echo {f}'), u'echo Ca\xf1o')
237 226 self.assertEqual(ip.var_expand(u'echo {f[:-1]}'), u'echo Ca\xf1')
238 227 self.assertEqual(ip.var_expand(u'echo {1*2}'), u'echo 2')
239 228
240 229 ip.user_ns['f'] = b'Ca\xc3\xb1o'
241 230 # This should not raise any exception:
242 231 ip.var_expand(u'echo $f')
243 232
244 233 def test_var_expand_local(self):
245 234 """Test local variable expansion in !system and %magic calls"""
246 235 # !system
247 236 ip.run_cell('def test():\n'
248 237 ' lvar = "ttt"\n'
249 238 ' ret = !echo {lvar}\n'
250 239 ' return ret[0]\n')
251 240 res = ip.user_ns['test']()
252 241 nt.assert_in('ttt', res)
253 242
254 243 # %magic
255 244 ip.run_cell('def makemacro():\n'
256 245 ' macroname = "macro_var_expand_locals"\n'
257 246 ' %macro {macroname} codestr\n')
258 247 ip.user_ns['codestr'] = "str(12)"
259 248 ip.run_cell('makemacro()')
260 249 nt.assert_in('macro_var_expand_locals', ip.user_ns)
261 250
262 251 def test_var_expand_self(self):
263 252 """Test variable expansion with the name 'self', which was failing.
264 253
265 254 See https://github.com/ipython/ipython/issues/1878#issuecomment-7698218
266 255 """
267 256 ip.run_cell('class cTest:\n'
268 257 ' classvar="see me"\n'
269 258 ' def test(self):\n'
270 259 ' res = !echo Variable: {self.classvar}\n'
271 260 ' return res[0]\n')
272 261 nt.assert_in('see me', ip.user_ns['cTest']().test())
273 262
274 263 def test_bad_var_expand(self):
275 264 """var_expand on invalid formats shouldn't raise"""
276 265 # SyntaxError
277 266 self.assertEqual(ip.var_expand(u"{'a':5}"), u"{'a':5}")
278 267 # NameError
279 268 self.assertEqual(ip.var_expand(u"{asdf}"), u"{asdf}")
280 269 # ZeroDivisionError
281 270 self.assertEqual(ip.var_expand(u"{1/0}"), u"{1/0}")
282 271
283 272 def test_silent_nopostexec(self):
284 273 """run_cell(silent=True) doesn't invoke post-exec funcs"""
285 274 d = dict(called=False)
286 275 def set_called():
287 276 d['called'] = True
288 277
289 278 ip.register_post_execute(set_called)
290 279 ip.run_cell("1", silent=True)
291 280 self.assertFalse(d['called'])
292 281 # double-check that non-silent exec did what we expected
293 282 # silent to avoid
294 283 ip.run_cell("1")
295 284 self.assertTrue(d['called'])
296 285 # remove post-exec
297 286 ip._post_execute.pop(set_called)
298 287
299 288 def test_silent_noadvance(self):
300 289 """run_cell(silent=True) doesn't advance execution_count"""
301 290 ec = ip.execution_count
302 291 # silent should force store_history=False
303 292 ip.run_cell("1", store_history=True, silent=True)
304 293
305 294 self.assertEqual(ec, ip.execution_count)
306 295 # double-check that non-silent exec did what we expected
307 296 # silent to avoid
308 297 ip.run_cell("1", store_history=True)
309 298 self.assertEqual(ec+1, ip.execution_count)
310 299
311 300 def test_silent_nodisplayhook(self):
312 301 """run_cell(silent=True) doesn't trigger displayhook"""
313 302 d = dict(called=False)
314 303
315 304 trap = ip.display_trap
316 305 save_hook = trap.hook
317 306
318 307 def failing_hook(*args, **kwargs):
319 308 d['called'] = True
320 309
321 310 try:
322 311 trap.hook = failing_hook
323 312 ip.run_cell("1", silent=True)
324 313 self.assertFalse(d['called'])
325 314 # double-check that non-silent exec did what we expected
326 315 # silent to avoid
327 316 ip.run_cell("1")
328 317 self.assertTrue(d['called'])
329 318 finally:
330 319 trap.hook = save_hook
331 320
332 321 @skipif(sys.version_info[0] >= 3, "softspace removed in py3")
333 322 def test_print_softspace(self):
334 323 """Verify that softspace is handled correctly when executing multiple
335 324 statements.
336 325
337 326 In [1]: print 1; print 2
338 327 1
339 328 2
340 329
341 330 In [2]: print 1,; print 2
342 331 1 2
343 332 """
344 333
345 334 def test_ofind_line_magic(self):
346 335 from IPython.core.magic import register_line_magic
347 336
348 337 @register_line_magic
349 338 def lmagic(line):
350 339 "A line magic"
351 340
352 341 # Get info on line magic
353 342 lfind = ip._ofind('lmagic')
354 343 info = dict(found=True, isalias=False, ismagic=True,
355 344 namespace = 'IPython internal', obj= lmagic.__wrapped__,
356 345 parent = None)
357 346 nt.assert_equal(lfind, info)
358 347
359 348 def test_ofind_cell_magic(self):
360 349 from IPython.core.magic import register_cell_magic
361 350
362 351 @register_cell_magic
363 352 def cmagic(line, cell):
364 353 "A cell magic"
365 354
366 355 # Get info on cell magic
367 356 find = ip._ofind('cmagic')
368 357 info = dict(found=True, isalias=False, ismagic=True,
369 358 namespace = 'IPython internal', obj= cmagic.__wrapped__,
370 359 parent = None)
371 360 nt.assert_equal(find, info)
372 361
373 362 def test_custom_exception(self):
374 363 called = []
375 364 def my_handler(shell, etype, value, tb, tb_offset=None):
376 365 called.append(etype)
377 366 shell.showtraceback((etype, value, tb), tb_offset=tb_offset)
378 367
379 368 ip.set_custom_exc((ValueError,), my_handler)
380 369 try:
381 370 ip.run_cell("raise ValueError('test')")
382 371 # Check that this was called, and only once.
383 372 self.assertEqual(called, [ValueError])
384 373 finally:
385 374 # Reset the custom exception hook
386 375 ip.set_custom_exc((), None)
387 376
388 377 @skipif(sys.version_info[0] >= 3, "no differences with __future__ in py3")
389 378 def test_future_environment(self):
390 379 "Can we run code with & without the shell's __future__ imports?"
391 380 ip.run_cell("from __future__ import division")
392 381 ip.run_cell("a = 1/2", shell_futures=True)
393 382 self.assertEqual(ip.user_ns['a'], 0.5)
394 383 ip.run_cell("b = 1/2", shell_futures=False)
395 384 self.assertEqual(ip.user_ns['b'], 0)
396 385
397 386 ip.compile.reset_compiler_flags()
398 387 # This shouldn't leak to the shell's compiler
399 388 ip.run_cell("from __future__ import division \nc=1/2", shell_futures=False)
400 389 self.assertEqual(ip.user_ns['c'], 0.5)
401 390 ip.run_cell("d = 1/2", shell_futures=True)
402 391 self.assertEqual(ip.user_ns['d'], 0)
403 392
404 393
405 394 class TestSafeExecfileNonAsciiPath(unittest.TestCase):
406 395
407 396 @onlyif_unicode_paths
408 397 def setUp(self):
409 398 self.BASETESTDIR = tempfile.mkdtemp()
410 399 self.TESTDIR = join(self.BASETESTDIR, u"Γ₯Àâ")
411 400 os.mkdir(self.TESTDIR)
412 401 with open(join(self.TESTDIR, u"Γ₯Àâtestscript.py"), "w") as sfile:
413 402 sfile.write("pass\n")
414 403 self.oldpath = os.getcwdu()
415 404 os.chdir(self.TESTDIR)
416 405 self.fname = u"Γ₯Àâtestscript.py"
417 406
418 407 def tearDown(self):
419 408 os.chdir(self.oldpath)
420 409 shutil.rmtree(self.BASETESTDIR)
421 410
422 411 @onlyif_unicode_paths
423 412 def test_1(self):
424 413 """Test safe_execfile with non-ascii path
425 414 """
426 415 ip.safe_execfile(self.fname, {}, raise_exceptions=True)
427 416
428 417
429 418 class TestSystemRaw(unittest.TestCase):
430 419 @onlyif_unicode_paths
431 420 def test_1(self):
432 421 """Test system_raw with non-ascii cmd
433 422 """
434 423 cmd = ur'''python -c "'Γ₯Àâ'" '''
435 424 ip.system_raw(cmd)
436 425
437 426 def test_exit_code(self):
438 427 """Test that the exit code is parsed correctly."""
439 428 ip.system_raw('exit 1')
440 429 self.assertEqual(ip.user_ns['_exit_code'], 1)
441 430
442 431 class TestModules(unittest.TestCase, tt.TempFileMixin):
443 432 def test_extraneous_loads(self):
444 433 """Test we're not loading modules on startup that we shouldn't.
445 434 """
446 435 self.mktmp("import sys\n"
447 436 "print('numpy' in sys.modules)\n"
448 437 "print('IPython.parallel' in sys.modules)\n"
449 438 "print('IPython.kernel.zmq' in sys.modules)\n"
450 439 )
451 440 out = "False\nFalse\nFalse\n"
452 441 tt.ipexec_validate(self.fname, out)
453 442
454 443 class Negator(ast.NodeTransformer):
455 444 """Negates all number literals in an AST."""
456 445 def visit_Num(self, node):
457 446 node.n = -node.n
458 447 return node
459 448
460 449 class TestAstTransform(unittest.TestCase):
461 450 def setUp(self):
462 451 self.negator = Negator()
463 452 ip.ast_transformers.append(self.negator)
464 453
465 454 def tearDown(self):
466 455 ip.ast_transformers.remove(self.negator)
467 456
468 457 def test_run_cell(self):
469 458 with tt.AssertPrints('-34'):
470 459 ip.run_cell('print (12 + 22)')
471 460
472 461 # A named reference to a number shouldn't be transformed.
473 462 ip.user_ns['n'] = 55
474 463 with tt.AssertNotPrints('-55'):
475 464 ip.run_cell('print (n)')
476 465
477 466 def test_timeit(self):
478 467 called = set()
479 468 def f(x):
480 469 called.add(x)
481 470 ip.push({'f':f})
482 471
483 472 with tt.AssertPrints("best of "):
484 473 ip.run_line_magic("timeit", "-n1 f(1)")
485 474 self.assertEqual(called, set([-1]))
486 475 called.clear()
487 476
488 477 with tt.AssertPrints("best of "):
489 478 ip.run_cell_magic("timeit", "-n1 f(2)", "f(3)")
490 479 self.assertEqual(called, set([-2, -3]))
491 480
492 481 def test_time(self):
493 482 called = []
494 483 def f(x):
495 484 called.append(x)
496 485 ip.push({'f':f})
497 486
498 487 # Test with an expression
499 488 with tt.AssertPrints("Wall time: "):
500 489 ip.run_line_magic("time", "f(5+9)")
501 490 self.assertEqual(called, [-14])
502 491 called[:] = []
503 492
504 493 # Test with a statement (different code path)
505 494 with tt.AssertPrints("Wall time: "):
506 495 ip.run_line_magic("time", "a = f(-3 + -2)")
507 496 self.assertEqual(called, [5])
508 497
509 498 def test_macro(self):
510 499 ip.push({'a':10})
511 500 # The AST transformation makes this do a+=-1
512 501 ip.define_macro("amacro", "a+=1\nprint(a)")
513 502
514 503 with tt.AssertPrints("9"):
515 504 ip.run_cell("amacro")
516 505 with tt.AssertPrints("8"):
517 506 ip.run_cell("amacro")
518 507
519 508 class IntegerWrapper(ast.NodeTransformer):
520 509 """Wraps all integers in a call to Integer()"""
521 510 def visit_Num(self, node):
522 511 if isinstance(node.n, int):
523 512 return ast.Call(func=ast.Name(id='Integer', ctx=ast.Load()),
524 513 args=[node], keywords=[])
525 514 return node
526 515
527 516 class TestAstTransform2(unittest.TestCase):
528 517 def setUp(self):
529 518 self.intwrapper = IntegerWrapper()
530 519 ip.ast_transformers.append(self.intwrapper)
531 520
532 521 self.calls = []
533 522 def Integer(*args):
534 523 self.calls.append(args)
535 524 return args
536 525 ip.push({"Integer": Integer})
537 526
538 527 def tearDown(self):
539 528 ip.ast_transformers.remove(self.intwrapper)
540 529 del ip.user_ns['Integer']
541 530
542 531 def test_run_cell(self):
543 532 ip.run_cell("n = 2")
544 533 self.assertEqual(self.calls, [(2,)])
545 534
546 535 # This shouldn't throw an error
547 536 ip.run_cell("o = 2.0")
548 537 self.assertEqual(ip.user_ns['o'], 2.0)
549 538
550 539 def test_timeit(self):
551 540 called = set()
552 541 def f(x):
553 542 called.add(x)
554 543 ip.push({'f':f})
555 544
556 545 with tt.AssertPrints("best of "):
557 546 ip.run_line_magic("timeit", "-n1 f(1)")
558 547 self.assertEqual(called, set([(1,)]))
559 548 called.clear()
560 549
561 550 with tt.AssertPrints("best of "):
562 551 ip.run_cell_magic("timeit", "-n1 f(2)", "f(3)")
563 552 self.assertEqual(called, set([(2,), (3,)]))
564 553
565 554 class ErrorTransformer(ast.NodeTransformer):
566 555 """Throws an error when it sees a number."""
567 556 def visit_Num(self):
568 557 raise ValueError("test")
569 558
570 559 class TestAstTransformError(unittest.TestCase):
571 560 def test_unregistering(self):
572 561 err_transformer = ErrorTransformer()
573 562 ip.ast_transformers.append(err_transformer)
574 563
575 564 with tt.AssertPrints("unregister", channel='stderr'):
576 565 ip.run_cell("1 + 2")
577 566
578 567 # This should have been removed.
579 568 nt.assert_not_in(err_transformer, ip.ast_transformers)
580 569
581 570 def test__IPYTHON__():
582 571 # This shouldn't raise a NameError, that's all
583 572 __IPYTHON__
584 573
585 574
586 575 class DummyRepr(object):
587 576 def __repr__(self):
588 577 return "DummyRepr"
589 578
590 579 def _repr_html_(self):
591 580 return "<b>dummy</b>"
592 581
593 582 def _repr_javascript_(self):
594 583 return "console.log('hi');", {'key': 'value'}
595 584
596 585
597 586 def test_user_variables():
598 587 # enable all formatters
599 588 ip.display_formatter.active_types = ip.display_formatter.format_types
600 589
601 590 ip.user_ns['dummy'] = d = DummyRepr()
602 591 keys = set(['dummy', 'doesnotexist'])
603 592 r = ip.user_variables(keys)
604 593
605 594 nt.assert_equal(keys, set(r.keys()))
606 595 dummy = r['dummy']
607 596 nt.assert_equal(set(['status', 'data', 'metadata']), set(dummy.keys()))
608 597 nt.assert_equal(dummy['status'], 'ok')
609 598 data = dummy['data']
610 599 metadata = dummy['metadata']
611 600 nt.assert_equal(data.get('text/html'), d._repr_html_())
612 601 js, jsmd = d._repr_javascript_()
613 602 nt.assert_equal(data.get('application/javascript'), js)
614 603 nt.assert_equal(metadata.get('application/javascript'), jsmd)
615 604
616 605 dne = r['doesnotexist']
617 606 nt.assert_equal(dne['status'], 'error')
618 607 nt.assert_equal(dne['ename'], 'KeyError')
619 608
620 609 # back to text only
621 610 ip.display_formatter.active_types = ['text/plain']
622 611
623 612 def test_user_expression():
624 613 # enable all formatters
625 614 ip.display_formatter.active_types = ip.display_formatter.format_types
626 615 query = {
627 616 'a' : '1 + 2',
628 617 'b' : '1/0',
629 618 }
630 619 r = ip.user_expressions(query)
631 620 import pprint
632 621 pprint.pprint(r)
633 622 nt.assert_equal(r.keys(), query.keys())
634 623 a = r['a']
635 624 nt.assert_equal(set(['status', 'data', 'metadata']), set(a.keys()))
636 625 nt.assert_equal(a['status'], 'ok')
637 626 data = a['data']
638 627 metadata = a['metadata']
639 628 nt.assert_equal(data.get('text/plain'), '3')
640 629
641 630 b = r['b']
642 631 nt.assert_equal(b['status'], 'error')
643 632 nt.assert_equal(b['ename'], 'ZeroDivisionError')
644 633
645 634 # back to text only
646 635 ip.display_formatter.active_types = ['text/plain']
647 636
648 637
649 638
650 639
651 640
652 641
General Comments 0
You need to be logged in to leave comments. Login now