##// END OF EJS Templates
Skip some more tests that require unicode paths
Thomas Kluyver -
Show More
@@ -1,79 +1,120 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Tests for completerlib.
3 3
4 4 """
5 5 from __future__ import absolute_import
6 6
7 7 #-----------------------------------------------------------------------------
8 8 # Imports
9 9 #-----------------------------------------------------------------------------
10 10
11 11 import os
12 12 import shutil
13 13 import sys
14 14 import tempfile
15 15 import unittest
16 16 from os.path import join
17 17
18 18 from IPython.core.completerlib import magic_run_completer, module_completion
19 19 from IPython.utils.tempdir import TemporaryDirectory
20 from IPython.testing.decorators import onlyif_unicode_paths
20 21
21 22
22 23 class MockEvent(object):
23 24 def __init__(self, line):
24 25 self.line = line
25 26
26 27 #-----------------------------------------------------------------------------
27 28 # Test functions begin
28 29 #-----------------------------------------------------------------------------
29 30 class Test_magic_run_completer(unittest.TestCase):
30 31 def setUp(self):
31 32 self.BASETESTDIR = tempfile.mkdtemp()
32 for fil in [u"aaø.py", u"a.py", u"b.py"]:
33 for fil in [u"aao.py", u"a.py", u"b.py"]:
33 34 with open(join(self.BASETESTDIR, fil), "w") as sfile:
34 35 sfile.write("pass\n")
35 36 self.oldpath = os.getcwdu()
36 37 os.chdir(self.BASETESTDIR)
37 38
38 39 def tearDown(self):
39 40 os.chdir(self.oldpath)
40 41 shutil.rmtree(self.BASETESTDIR)
41 42
42 43 def test_1(self):
43 44 """Test magic_run_completer, should match two alterntives
44 45 """
45 46 event = MockEvent(u"%run a")
46 47 mockself = None
47 48 match = set(magic_run_completer(mockself, event))
48 self.assertEqual(match, set([u"a.py", u"aaø.py"]))
49 self.assertEqual(match, set([u"a.py", u"aao.py"]))
49 50
50 51 def test_2(self):
51 52 """Test magic_run_completer, should match one alterntive
52 53 """
53 54 event = MockEvent(u"%run aa")
54 55 mockself = None
55 56 match = set(magic_run_completer(mockself, event))
56 self.assertEqual(match, set([u"aaø.py"]))
57 self.assertEqual(match, set([u"aao.py"]))
57 58
58 59 def test_3(self):
59 60 """Test magic_run_completer with unterminated " """
60 61 event = MockEvent(u'%run "a')
61 62 mockself = None
62 63 match = set(magic_run_completer(mockself, event))
63 self.assertEqual(match, set([u"a.py", u"aaø.py"]))
64 self.assertEqual(match, set([u"a.py", u"aao.py"]))
64 65
65 66 def test_import_invalid_module(self):
66 67 """Testing of issue https://github.com/ipython/ipython/issues/1107"""
67 68 invalid_module_names = set(['foo-bar', 'foo:bar', '10foo'])
68 69 valid_module_names = set(['foobar'])
69 70 with TemporaryDirectory() as tmpdir:
70 71 sys.path.insert( 0, tmpdir )
71 72 for name in invalid_module_names | valid_module_names:
72 73 filename = os.path.join(tmpdir, name + '.py')
73 74 open(filename, 'w').close()
74 75
75 76 s = set( module_completion('import foo') )
76 77 intersection = s.intersection(invalid_module_names)
77 78 self.assertFalse(intersection, intersection)
78 79
79 80 assert valid_module_names.issubset(s), valid_module_names.intersection(s)
81
82 class Test_magic_run_completer_nonascii(unittest.TestCase):
83 @onlyif_unicode_paths
84 def setUp(self):
85 self.BASETESTDIR = tempfile.mkdtemp()
86 for fil in [u"aaø.py", u"a.py", u"b.py"]:
87 with open(join(self.BASETESTDIR, fil), "w") as sfile:
88 sfile.write("pass\n")
89 self.oldpath = os.getcwdu()
90 os.chdir(self.BASETESTDIR)
91
92 def tearDown(self):
93 os.chdir(self.oldpath)
94 shutil.rmtree(self.BASETESTDIR)
95
96 @onlyif_unicode_paths
97 def test_1(self):
98 """Test magic_run_completer, should match two alterntives
99 """
100 event = MockEvent(u"%run a")
101 mockself = None
102 match = set(magic_run_completer(mockself, event))
103 self.assertEqual(match, set([u"a.py", u"aaø.py"]))
104
105 @onlyif_unicode_paths
106 def test_2(self):
107 """Test magic_run_completer, should match one alterntive
108 """
109 event = MockEvent(u"%run aa")
110 mockself = None
111 match = set(magic_run_completer(mockself, event))
112 self.assertEqual(match, set([u"aaø.py"]))
113
114 @onlyif_unicode_paths
115 def test_3(self):
116 """Test magic_run_completer with unterminated " """
117 event = MockEvent(u'%run "a')
118 mockself = None
119 match = set(magic_run_completer(mockself, event))
120 self.assertEqual(match, set([u"a.py", u"aaø.py"]))
@@ -1,649 +1,652 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 from IPython.testing.decorators import skipif
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 109 def test_alias_crash(self):
110 110 """Errors in prefilter can't crash IPython"""
111 111 ip.run_cell('%alias parts echo first %s second %s')
112 112 # capture stderr:
113 113 save_err = io.stderr
114 114 io.stderr = StringIO()
115 115 ip.run_cell('parts 1')
116 116 err = io.stderr.getvalue()
117 117 io.stderr = save_err
118 118 self.assertEqual(err.split(':')[0], 'ERROR')
119 119
120 120 def test_trailing_newline(self):
121 121 """test that running !(command) does not raise a SyntaxError"""
122 122 ip.run_cell('!(true)\n', False)
123 123 ip.run_cell('!(true)\n\n\n', False)
124 124
125 125 def test_gh_597(self):
126 126 """Pretty-printing lists of objects with non-ascii reprs may cause
127 127 problems."""
128 128 class Spam(object):
129 129 def __repr__(self):
130 130 return "\xe9"*50
131 131 import IPython.core.formatters
132 132 f = IPython.core.formatters.PlainTextFormatter()
133 133 f([Spam(),Spam()])
134 134
135 135
136 136 def test_future_flags(self):
137 137 """Check that future flags are used for parsing code (gh-777)"""
138 138 ip.run_cell('from __future__ import print_function')
139 139 try:
140 140 ip.run_cell('prfunc_return_val = print(1,2, sep=" ")')
141 141 assert 'prfunc_return_val' in ip.user_ns
142 142 finally:
143 143 # Reset compiler flags so we don't mess up other tests.
144 144 ip.compile.reset_compiler_flags()
145 145
146 146 def test_future_unicode(self):
147 147 """Check that unicode_literals is imported from __future__ (gh #786)"""
148 148 try:
149 149 ip.run_cell(u'byte_str = "a"')
150 150 assert isinstance(ip.user_ns['byte_str'], str) # string literals are byte strings by default
151 151 ip.run_cell('from __future__ import unicode_literals')
152 152 ip.run_cell(u'unicode_str = "a"')
153 153 assert isinstance(ip.user_ns['unicode_str'], unicode) # strings literals are now unicode
154 154 finally:
155 155 # Reset compiler flags so we don't mess up other tests.
156 156 ip.compile.reset_compiler_flags()
157 157
158 158 def test_can_pickle(self):
159 159 "Can we pickle objects defined interactively (GH-29)"
160 160 ip = get_ipython()
161 161 ip.reset()
162 162 ip.run_cell(("class Mylist(list):\n"
163 163 " def __init__(self,x=[]):\n"
164 164 " list.__init__(self,x)"))
165 165 ip.run_cell("w=Mylist([1,2,3])")
166 166
167 167 from cPickle import dumps
168 168
169 169 # We need to swap in our main module - this is only necessary
170 170 # inside the test framework, because IPython puts the interactive module
171 171 # in place (but the test framework undoes this).
172 172 _main = sys.modules['__main__']
173 173 sys.modules['__main__'] = ip.user_module
174 174 try:
175 175 res = dumps(ip.user_ns["w"])
176 176 finally:
177 177 sys.modules['__main__'] = _main
178 178 self.assertTrue(isinstance(res, bytes))
179 179
180 180 def test_global_ns(self):
181 181 "Code in functions must be able to access variables outside them."
182 182 ip = get_ipython()
183 183 ip.run_cell("a = 10")
184 184 ip.run_cell(("def f(x):\n"
185 185 " return x + a"))
186 186 ip.run_cell("b = f(12)")
187 187 self.assertEqual(ip.user_ns["b"], 22)
188 188
189 189 def test_bad_custom_tb(self):
190 190 """Check that InteractiveShell is protected from bad custom exception handlers"""
191 191 from IPython.utils import io
192 192 save_stderr = io.stderr
193 193 try:
194 194 # capture stderr
195 195 io.stderr = StringIO()
196 196 ip.set_custom_exc((IOError,), lambda etype,value,tb: 1/0)
197 197 self.assertEqual(ip.custom_exceptions, (IOError,))
198 198 ip.run_cell(u'raise IOError("foo")')
199 199 self.assertEqual(ip.custom_exceptions, ())
200 200 self.assertTrue("Custom TB Handler failed" in io.stderr.getvalue())
201 201 finally:
202 202 io.stderr = save_stderr
203 203
204 204 def test_bad_custom_tb_return(self):
205 205 """Check that InteractiveShell is protected from bad return types in custom exception handlers"""
206 206 from IPython.utils import io
207 207 save_stderr = io.stderr
208 208 try:
209 209 # capture stderr
210 210 io.stderr = StringIO()
211 211 ip.set_custom_exc((NameError,),lambda etype,value,tb, tb_offset=None: 1)
212 212 self.assertEqual(ip.custom_exceptions, (NameError,))
213 213 ip.run_cell(u'a=abracadabra')
214 214 self.assertEqual(ip.custom_exceptions, ())
215 215 self.assertTrue("Custom TB Handler failed" in io.stderr.getvalue())
216 216 finally:
217 217 io.stderr = save_stderr
218 218
219 219 def test_drop_by_id(self):
220 220 myvars = {"a":object(), "b":object(), "c": object()}
221 221 ip.push(myvars, interactive=False)
222 222 for name in myvars:
223 223 assert name in ip.user_ns, name
224 224 assert name in ip.user_ns_hidden, name
225 225 ip.user_ns['b'] = 12
226 226 ip.drop_by_id(myvars)
227 227 for name in ["a", "c"]:
228 228 assert name not in ip.user_ns, name
229 229 assert name not in ip.user_ns_hidden, name
230 230 assert ip.user_ns['b'] == 12
231 231 ip.reset()
232 232
233 233 def test_var_expand(self):
234 234 ip.user_ns['f'] = u'Ca\xf1o'
235 235 self.assertEqual(ip.var_expand(u'echo $f'), u'echo Ca\xf1o')
236 236 self.assertEqual(ip.var_expand(u'echo {f}'), u'echo Ca\xf1o')
237 237 self.assertEqual(ip.var_expand(u'echo {f[:-1]}'), u'echo Ca\xf1')
238 238 self.assertEqual(ip.var_expand(u'echo {1*2}'), u'echo 2')
239 239
240 240 ip.user_ns['f'] = b'Ca\xc3\xb1o'
241 241 # This should not raise any exception:
242 242 ip.var_expand(u'echo $f')
243 243
244 244 def test_var_expand_local(self):
245 245 """Test local variable expansion in !system and %magic calls"""
246 246 # !system
247 247 ip.run_cell('def test():\n'
248 248 ' lvar = "ttt"\n'
249 249 ' ret = !echo {lvar}\n'
250 250 ' return ret[0]\n')
251 251 res = ip.user_ns['test']()
252 252 nt.assert_in('ttt', res)
253 253
254 254 # %magic
255 255 ip.run_cell('def makemacro():\n'
256 256 ' macroname = "macro_var_expand_locals"\n'
257 257 ' %macro {macroname} codestr\n')
258 258 ip.user_ns['codestr'] = "str(12)"
259 259 ip.run_cell('makemacro()')
260 260 nt.assert_in('macro_var_expand_locals', ip.user_ns)
261 261
262 262 def test_var_expand_self(self):
263 263 """Test variable expansion with the name 'self', which was failing.
264 264
265 265 See https://github.com/ipython/ipython/issues/1878#issuecomment-7698218
266 266 """
267 267 ip.run_cell('class cTest:\n'
268 268 ' classvar="see me"\n'
269 269 ' def test(self):\n'
270 270 ' res = !echo Variable: {self.classvar}\n'
271 271 ' return res[0]\n')
272 272 nt.assert_in('see me', ip.user_ns['cTest']().test())
273 273
274 274 def test_bad_var_expand(self):
275 275 """var_expand on invalid formats shouldn't raise"""
276 276 # SyntaxError
277 277 self.assertEqual(ip.var_expand(u"{'a':5}"), u"{'a':5}")
278 278 # NameError
279 279 self.assertEqual(ip.var_expand(u"{asdf}"), u"{asdf}")
280 280 # ZeroDivisionError
281 281 self.assertEqual(ip.var_expand(u"{1/0}"), u"{1/0}")
282 282
283 283 def test_silent_nopostexec(self):
284 284 """run_cell(silent=True) doesn't invoke post-exec funcs"""
285 285 d = dict(called=False)
286 286 def set_called():
287 287 d['called'] = True
288 288
289 289 ip.register_post_execute(set_called)
290 290 ip.run_cell("1", silent=True)
291 291 self.assertFalse(d['called'])
292 292 # double-check that non-silent exec did what we expected
293 293 # silent to avoid
294 294 ip.run_cell("1")
295 295 self.assertTrue(d['called'])
296 296 # remove post-exec
297 297 ip._post_execute.pop(set_called)
298 298
299 299 def test_silent_noadvance(self):
300 300 """run_cell(silent=True) doesn't advance execution_count"""
301 301 ec = ip.execution_count
302 302 # silent should force store_history=False
303 303 ip.run_cell("1", store_history=True, silent=True)
304 304
305 305 self.assertEqual(ec, ip.execution_count)
306 306 # double-check that non-silent exec did what we expected
307 307 # silent to avoid
308 308 ip.run_cell("1", store_history=True)
309 309 self.assertEqual(ec+1, ip.execution_count)
310 310
311 311 def test_silent_nodisplayhook(self):
312 312 """run_cell(silent=True) doesn't trigger displayhook"""
313 313 d = dict(called=False)
314 314
315 315 trap = ip.display_trap
316 316 save_hook = trap.hook
317 317
318 318 def failing_hook(*args, **kwargs):
319 319 d['called'] = True
320 320
321 321 try:
322 322 trap.hook = failing_hook
323 323 ip.run_cell("1", silent=True)
324 324 self.assertFalse(d['called'])
325 325 # double-check that non-silent exec did what we expected
326 326 # silent to avoid
327 327 ip.run_cell("1")
328 328 self.assertTrue(d['called'])
329 329 finally:
330 330 trap.hook = save_hook
331 331
332 332 @skipif(sys.version_info[0] >= 3, "softspace removed in py3")
333 333 def test_print_softspace(self):
334 334 """Verify that softspace is handled correctly when executing multiple
335 335 statements.
336 336
337 337 In [1]: print 1; print 2
338 338 1
339 339 2
340 340
341 341 In [2]: print 1,; print 2
342 342 1 2
343 343 """
344 344
345 345 def test_ofind_line_magic(self):
346 346 from IPython.core.magic import register_line_magic
347 347
348 348 @register_line_magic
349 349 def lmagic(line):
350 350 "A line magic"
351 351
352 352 # Get info on line magic
353 353 lfind = ip._ofind('lmagic')
354 354 info = dict(found=True, isalias=False, ismagic=True,
355 355 namespace = 'IPython internal', obj= lmagic.__wrapped__,
356 356 parent = None)
357 357 nt.assert_equal(lfind, info)
358 358
359 359 def test_ofind_cell_magic(self):
360 360 from IPython.core.magic import register_cell_magic
361 361
362 362 @register_cell_magic
363 363 def cmagic(line, cell):
364 364 "A cell magic"
365 365
366 366 # Get info on cell magic
367 367 find = ip._ofind('cmagic')
368 368 info = dict(found=True, isalias=False, ismagic=True,
369 369 namespace = 'IPython internal', obj= cmagic.__wrapped__,
370 370 parent = None)
371 371 nt.assert_equal(find, info)
372 372
373 373 def test_custom_exception(self):
374 374 called = []
375 375 def my_handler(shell, etype, value, tb, tb_offset=None):
376 376 called.append(etype)
377 377 shell.showtraceback((etype, value, tb), tb_offset=tb_offset)
378 378
379 379 ip.set_custom_exc((ValueError,), my_handler)
380 380 try:
381 381 ip.run_cell("raise ValueError('test')")
382 382 # Check that this was called, and only once.
383 383 self.assertEqual(called, [ValueError])
384 384 finally:
385 385 # Reset the custom exception hook
386 386 ip.set_custom_exc((), None)
387 387
388 388 @skipif(sys.version_info[0] >= 3, "no differences with __future__ in py3")
389 389 def test_future_environment(self):
390 390 "Can we run code with & without the shell's __future__ imports?"
391 391 ip.run_cell("from __future__ import division")
392 392 ip.run_cell("a = 1/2", shell_futures=True)
393 393 self.assertEqual(ip.user_ns['a'], 0.5)
394 394 ip.run_cell("b = 1/2", shell_futures=False)
395 395 self.assertEqual(ip.user_ns['b'], 0)
396 396
397 397 ip.compile.reset_compiler_flags()
398 398 # This shouldn't leak to the shell's compiler
399 399 ip.run_cell("from __future__ import division \nc=1/2", shell_futures=False)
400 400 self.assertEqual(ip.user_ns['c'], 0.5)
401 401 ip.run_cell("d = 1/2", shell_futures=True)
402 402 self.assertEqual(ip.user_ns['d'], 0)
403 403
404 404
405 405 class TestSafeExecfileNonAsciiPath(unittest.TestCase):
406 406
407 @onlyif_unicode_paths
407 408 def setUp(self):
408 409 self.BASETESTDIR = tempfile.mkdtemp()
409 410 self.TESTDIR = join(self.BASETESTDIR, u"åäö")
410 411 os.mkdir(self.TESTDIR)
411 412 with open(join(self.TESTDIR, u"åäötestscript.py"), "w") as sfile:
412 413 sfile.write("pass\n")
413 414 self.oldpath = os.getcwdu()
414 415 os.chdir(self.TESTDIR)
415 416 self.fname = u"åäötestscript.py"
416 417
417 418 def tearDown(self):
418 419 os.chdir(self.oldpath)
419 420 shutil.rmtree(self.BASETESTDIR)
420 421
422 @onlyif_unicode_paths
421 423 def test_1(self):
422 424 """Test safe_execfile with non-ascii path
423 425 """
424 426 ip.safe_execfile(self.fname, {}, raise_exceptions=True)
425 427
426 428
427 429 class TestSystemRaw(unittest.TestCase):
430 @onlyif_unicode_paths
428 431 def test_1(self):
429 432 """Test system_raw with non-ascii cmd
430 433 """
431 434 cmd = ur'''python -c "'åäö'" '''
432 435 ip.system_raw(cmd)
433 436
434 437 def test_exit_code(self):
435 438 """Test that the exit code is parsed correctly."""
436 439 ip.system_raw('exit 1')
437 440 self.assertEqual(ip.user_ns['_exit_code'], 1)
438 441
439 442 class TestModules(unittest.TestCase, tt.TempFileMixin):
440 443 def test_extraneous_loads(self):
441 444 """Test we're not loading modules on startup that we shouldn't.
442 445 """
443 446 self.mktmp("import sys\n"
444 447 "print('numpy' in sys.modules)\n"
445 448 "print('IPython.parallel' in sys.modules)\n"
446 449 "print('IPython.kernel.zmq' in sys.modules)\n"
447 450 )
448 451 out = "False\nFalse\nFalse\n"
449 452 tt.ipexec_validate(self.fname, out)
450 453
451 454 class Negator(ast.NodeTransformer):
452 455 """Negates all number literals in an AST."""
453 456 def visit_Num(self, node):
454 457 node.n = -node.n
455 458 return node
456 459
457 460 class TestAstTransform(unittest.TestCase):
458 461 def setUp(self):
459 462 self.negator = Negator()
460 463 ip.ast_transformers.append(self.negator)
461 464
462 465 def tearDown(self):
463 466 ip.ast_transformers.remove(self.negator)
464 467
465 468 def test_run_cell(self):
466 469 with tt.AssertPrints('-34'):
467 470 ip.run_cell('print (12 + 22)')
468 471
469 472 # A named reference to a number shouldn't be transformed.
470 473 ip.user_ns['n'] = 55
471 474 with tt.AssertNotPrints('-55'):
472 475 ip.run_cell('print (n)')
473 476
474 477 def test_timeit(self):
475 478 called = set()
476 479 def f(x):
477 480 called.add(x)
478 481 ip.push({'f':f})
479 482
480 483 with tt.AssertPrints("best of "):
481 484 ip.run_line_magic("timeit", "-n1 f(1)")
482 485 self.assertEqual(called, set([-1]))
483 486 called.clear()
484 487
485 488 with tt.AssertPrints("best of "):
486 489 ip.run_cell_magic("timeit", "-n1 f(2)", "f(3)")
487 490 self.assertEqual(called, set([-2, -3]))
488 491
489 492 def test_time(self):
490 493 called = []
491 494 def f(x):
492 495 called.append(x)
493 496 ip.push({'f':f})
494 497
495 498 # Test with an expression
496 499 with tt.AssertPrints("Wall time: "):
497 500 ip.run_line_magic("time", "f(5+9)")
498 501 self.assertEqual(called, [-14])
499 502 called[:] = []
500 503
501 504 # Test with a statement (different code path)
502 505 with tt.AssertPrints("Wall time: "):
503 506 ip.run_line_magic("time", "a = f(-3 + -2)")
504 507 self.assertEqual(called, [5])
505 508
506 509 def test_macro(self):
507 510 ip.push({'a':10})
508 511 # The AST transformation makes this do a+=-1
509 512 ip.define_macro("amacro", "a+=1\nprint(a)")
510 513
511 514 with tt.AssertPrints("9"):
512 515 ip.run_cell("amacro")
513 516 with tt.AssertPrints("8"):
514 517 ip.run_cell("amacro")
515 518
516 519 class IntegerWrapper(ast.NodeTransformer):
517 520 """Wraps all integers in a call to Integer()"""
518 521 def visit_Num(self, node):
519 522 if isinstance(node.n, int):
520 523 return ast.Call(func=ast.Name(id='Integer', ctx=ast.Load()),
521 524 args=[node], keywords=[])
522 525 return node
523 526
524 527 class TestAstTransform2(unittest.TestCase):
525 528 def setUp(self):
526 529 self.intwrapper = IntegerWrapper()
527 530 ip.ast_transformers.append(self.intwrapper)
528 531
529 532 self.calls = []
530 533 def Integer(*args):
531 534 self.calls.append(args)
532 535 return args
533 536 ip.push({"Integer": Integer})
534 537
535 538 def tearDown(self):
536 539 ip.ast_transformers.remove(self.intwrapper)
537 540 del ip.user_ns['Integer']
538 541
539 542 def test_run_cell(self):
540 543 ip.run_cell("n = 2")
541 544 self.assertEqual(self.calls, [(2,)])
542 545
543 546 # This shouldn't throw an error
544 547 ip.run_cell("o = 2.0")
545 548 self.assertEqual(ip.user_ns['o'], 2.0)
546 549
547 550 def test_timeit(self):
548 551 called = set()
549 552 def f(x):
550 553 called.add(x)
551 554 ip.push({'f':f})
552 555
553 556 with tt.AssertPrints("best of "):
554 557 ip.run_line_magic("timeit", "-n1 f(1)")
555 558 self.assertEqual(called, set([(1,)]))
556 559 called.clear()
557 560
558 561 with tt.AssertPrints("best of "):
559 562 ip.run_cell_magic("timeit", "-n1 f(2)", "f(3)")
560 563 self.assertEqual(called, set([(2,), (3,)]))
561 564
562 565 class ErrorTransformer(ast.NodeTransformer):
563 566 """Throws an error when it sees a number."""
564 567 def visit_Num(self):
565 568 raise ValueError("test")
566 569
567 570 class TestAstTransformError(unittest.TestCase):
568 571 def test_unregistering(self):
569 572 err_transformer = ErrorTransformer()
570 573 ip.ast_transformers.append(err_transformer)
571 574
572 575 with tt.AssertPrints("unregister", channel='stderr'):
573 576 ip.run_cell("1 + 2")
574 577
575 578 # This should have been removed.
576 579 nt.assert_not_in(err_transformer, ip.ast_transformers)
577 580
578 581 def test__IPYTHON__():
579 582 # This shouldn't raise a NameError, that's all
580 583 __IPYTHON__
581 584
582 585
583 586 class DummyRepr(object):
584 587 def __repr__(self):
585 588 return "DummyRepr"
586 589
587 590 def _repr_html_(self):
588 591 return "<b>dummy</b>"
589 592
590 593 def _repr_javascript_(self):
591 594 return "console.log('hi');", {'key': 'value'}
592 595
593 596
594 597 def test_user_variables():
595 598 # enable all formatters
596 599 ip.display_formatter.active_types = ip.display_formatter.format_types
597 600
598 601 ip.user_ns['dummy'] = d = DummyRepr()
599 602 keys = set(['dummy', 'doesnotexist'])
600 603 r = ip.user_variables(keys)
601 604
602 605 nt.assert_equal(keys, set(r.keys()))
603 606 dummy = r['dummy']
604 607 nt.assert_equal(set(['status', 'data', 'metadata']), set(dummy.keys()))
605 608 nt.assert_equal(dummy['status'], 'ok')
606 609 data = dummy['data']
607 610 metadata = dummy['metadata']
608 611 nt.assert_equal(data.get('text/html'), d._repr_html_())
609 612 js, jsmd = d._repr_javascript_()
610 613 nt.assert_equal(data.get('application/javascript'), js)
611 614 nt.assert_equal(metadata.get('application/javascript'), jsmd)
612 615
613 616 dne = r['doesnotexist']
614 617 nt.assert_equal(dne['status'], 'error')
615 618 nt.assert_equal(dne['ename'], 'KeyError')
616 619
617 620 # back to text only
618 621 ip.display_formatter.active_types = ['text/plain']
619 622
620 623 def test_user_expression():
621 624 # enable all formatters
622 625 ip.display_formatter.active_types = ip.display_formatter.format_types
623 626 query = {
624 627 'a' : '1 + 2',
625 628 'b' : '1/0',
626 629 }
627 630 r = ip.user_expressions(query)
628 631 import pprint
629 632 pprint.pprint(r)
630 633 nt.assert_equal(r.keys(), query.keys())
631 634 a = r['a']
632 635 nt.assert_equal(set(['status', 'data', 'metadata']), set(a.keys()))
633 636 nt.assert_equal(a['status'], 'ok')
634 637 data = a['data']
635 638 metadata = a['metadata']
636 639 nt.assert_equal(data.get('text/plain'), '3')
637 640
638 641 b = r['b']
639 642 nt.assert_equal(b['status'], 'error')
640 643 nt.assert_equal(b['ename'], 'ZeroDivisionError')
641 644
642 645 # back to text only
643 646 ip.display_formatter.active_types = ['text/plain']
644 647
645 648
646 649
647 650
648 651
649 652
@@ -1,150 +1,153 b''
1 1 # coding: utf-8
2 2 """Tests for profile-related functions.
3 3
4 4 Currently only the startup-dir functionality is tested, but more tests should
5 5 be added for:
6 6
7 7 * ipython profile create
8 8 * ipython profile list
9 9 * ipython profile create --parallel
10 10 * security dir permissions
11 11
12 12 Authors
13 13 -------
14 14
15 15 * MinRK
16 16
17 17 """
18 18 from __future__ import absolute_import
19 19
20 20 #-----------------------------------------------------------------------------
21 21 # Imports
22 22 #-----------------------------------------------------------------------------
23 23
24 24 import os
25 25 import shutil
26 26 import sys
27 27 import tempfile
28 28
29 29 from unittest import TestCase
30 30
31 31 import nose.tools as nt
32 32
33 33 from IPython.core.profileapp import list_profiles_in, list_bundled_profiles
34 34 from IPython.core.profiledir import ProfileDir
35 35
36 36 from IPython.testing import decorators as dec
37 37 from IPython.testing import tools as tt
38 38 from IPython.utils import py3compat
39 39
40 40
41 41 #-----------------------------------------------------------------------------
42 42 # Globals
43 43 #-----------------------------------------------------------------------------
44 44 TMP_TEST_DIR = tempfile.mkdtemp()
45 45 HOME_TEST_DIR = os.path.join(TMP_TEST_DIR, "home_test_dir")
46 46 IP_TEST_DIR = os.path.join(HOME_TEST_DIR,'.ipython')
47 47
48 48 #
49 49 # Setup/teardown functions/decorators
50 50 #
51 51
52 52 def setup():
53 53 """Setup test environment for the module:
54 54
55 55 - Adds dummy home dir tree
56 56 """
57 57 # Do not mask exceptions here. In particular, catching WindowsError is a
58 58 # problem because that exception is only defined on Windows...
59 59 os.makedirs(IP_TEST_DIR)
60 60
61 61
62 62 def teardown():
63 63 """Teardown test environment for the module:
64 64
65 65 - Remove dummy home dir tree
66 66 """
67 67 # Note: we remove the parent test dir, which is the root of all test
68 68 # subdirs we may have created. Use shutil instead of os.removedirs, so
69 69 # that non-empty directories are all recursively removed.
70 70 shutil.rmtree(TMP_TEST_DIR)
71 71
72 72
73 73 #-----------------------------------------------------------------------------
74 74 # Test functions
75 75 #-----------------------------------------------------------------------------
76 76 def win32_without_pywin32():
77 77 if sys.platform == 'win32':
78 78 try:
79 79 import pywin32
80 80 except ImportError:
81 81 return True
82 82 return False
83 83
84 84
85 85 class ProfileStartupTest(TestCase):
86 86 def setUp(self):
87 87 # create profile dir
88 88 self.pd = ProfileDir.create_profile_dir_by_name(IP_TEST_DIR, 'test')
89 89 self.options = ['--ipython-dir', IP_TEST_DIR, '--profile', 'test']
90 90 self.fname = os.path.join(TMP_TEST_DIR, 'test.py')
91 91
92 92 def tearDown(self):
93 93 # We must remove this profile right away so its presence doesn't
94 94 # confuse other tests.
95 95 shutil.rmtree(self.pd.location)
96 96
97 97 def init(self, startup_file, startup, test):
98 98 # write startup python file
99 99 with open(os.path.join(self.pd.startup_dir, startup_file), 'w') as f:
100 100 f.write(startup)
101 101 # write simple test file, to check that the startup file was run
102 102 with open(self.fname, 'w') as f:
103 103 f.write(py3compat.doctest_refactor_print(test))
104 104
105 105 def validate(self, output):
106 106 tt.ipexec_validate(self.fname, output, '', options=self.options)
107 107
108 108 @dec.skipif(win32_without_pywin32(), "Test requires pywin32 on Windows")
109 109 def test_startup_py(self):
110 110 self.init('00-start.py', 'zzz=123\n',
111 111 py3compat.doctest_refactor_print('print zzz\n'))
112 112 self.validate('123')
113 113
114 114 @dec.skipif(win32_without_pywin32(), "Test requires pywin32 on Windows")
115 115 def test_startup_ipy(self):
116 116 self.init('00-start.ipy', '%profile\n', '')
117 117 self.validate('test')
118 118
119 119
120 120 def test_list_profiles_in():
121 121 # No need to remove these directories and files, as they will get nuked in
122 122 # the module-level teardown.
123 123 td = tempfile.mkdtemp(dir=TMP_TEST_DIR)
124 124 td = py3compat.str_to_unicode(td)
125 for name in ('profile_foo', u'profile_ünicode', 'profile_hello',
126 'not_a_profile'):
125 for name in ('profile_foo', 'profile_hello', 'not_a_profile'):
127 126 os.mkdir(os.path.join(td, name))
127 if dec.unicode_paths:
128 os.mkdir(os.path.join(td, u'profile_ünicode'))
129
128 130 with open(os.path.join(td, 'profile_file'), 'w') as f:
129 131 f.write("I am not a profile directory")
130 132 profiles = list_profiles_in(td)
131 133
132 134 # unicode normalization can turn u'ünicode' into u'u\0308nicode',
133 135 # so only check for *nicode, and that creating a ProfileDir from the
134 136 # name remains valid
135 137 found_unicode = False
136 138 for p in list(profiles):
137 139 if p.endswith('nicode'):
138 140 pd = ProfileDir.find_profile_dir_by_name(td, p)
139 141 profiles.remove(p)
140 142 found_unicode = True
141 143 break
144 if dec.unicode_paths:
142 145 nt.assert_true(found_unicode)
143 146 nt.assert_equal(set(profiles), set(['foo', 'hello']))
144 147
145 148
146 149 def test_list_bundled_profiles():
147 150 # This variable will need to be updated when a new profile gets bundled
148 151 bundled_true = [u'cluster', u'math', u'pysh', u'sympy']
149 152 bundled = sorted(list_bundled_profiles())
150 153 nt.assert_equal(bundled, bundled_true)
@@ -1,109 +1,110 b''
1 1 # -*- coding: utf-8
2 2 """Tests for prompt generation."""
3 3
4 4 import unittest
5 5
6 6 import os
7 7
8 8 from IPython.testing import tools as tt, decorators as dec
9 9 from IPython.core.prompts import PromptManager, LazyEvaluate
10 10 from IPython.testing.globalipapp import get_ipython
11 11 from IPython.utils.tempdir import TemporaryDirectory
12 12
13 13 ip = get_ipython()
14 14
15 15
16 16 class PromptTests(unittest.TestCase):
17 17 def setUp(self):
18 18 self.pm = PromptManager(shell=ip, config=ip.config)
19 19
20 20 def test_multiline_prompt(self):
21 21 self.pm.in_template = "[In]\n>>>"
22 22 self.pm.render('in')
23 23 self.assertEqual(self.pm.width, 3)
24 24 self.assertEqual(self.pm.txtwidth, 3)
25 25
26 26 self.pm.in_template = '[In]\n'
27 27 self.pm.render('in')
28 28 self.assertEqual(self.pm.width, 0)
29 29 self.assertEqual(self.pm.txtwidth, 0)
30 30
31 31 def test_translate_abbreviations(self):
32 32 def do_translate(template):
33 33 self.pm.in_template = template
34 34 return self.pm.templates['in']
35 35
36 36 pairs = [(r'%n>', '{color.number}{count}{color.prompt}>'),
37 37 (r'\T', '{time}'),
38 38 (r'\n', '\n')
39 39 ]
40 40
41 41 tt.check_pairs(do_translate, pairs)
42 42
43 43 def test_user_ns(self):
44 44 self.pm.color_scheme = 'NoColor'
45 45 ip.ex("foo='bar'")
46 46 self.pm.in_template = "In [{foo}]"
47 47 prompt = self.pm.render('in')
48 48 self.assertEqual(prompt, u'In [bar]')
49 49
50 50 def test_builtins(self):
51 51 self.pm.color_scheme = 'NoColor'
52 52 self.pm.in_template = "In [{int}]"
53 53 prompt = self.pm.render('in')
54 54 self.assertEqual(prompt, u"In [%r]" % int)
55 55
56 56 def test_undefined(self):
57 57 self.pm.color_scheme = 'NoColor'
58 58 self.pm.in_template = "In [{foo_dne}]"
59 59 prompt = self.pm.render('in')
60 60 self.assertEqual(prompt, u"In [<ERROR: 'foo_dne' not found>]")
61 61
62 62 def test_render(self):
63 63 self.pm.in_template = r'\#>'
64 64 self.assertEqual(self.pm.render('in',color=False), '%d>' % ip.execution_count)
65 65
66 @dec.onlyif_unicode_paths
66 67 def test_render_unicode_cwd(self):
67 68 save = os.getcwdu()
68 69 with TemporaryDirectory(u'ünicødé') as td:
69 70 os.chdir(td)
70 71 self.pm.in_template = r'\w [\#]'
71 72 p = self.pm.render('in', color=False)
72 73 self.assertEqual(p, u"%s [%i]" % (os.getcwdu(), ip.execution_count))
73 74 os.chdir(save)
74 75
75 76 def test_lazy_eval_unicode(self):
76 77 u = u'ünicødé'
77 78 lz = LazyEvaluate(lambda : u)
78 79 # str(lz) would fail
79 80 self.assertEqual(unicode(lz), u)
80 81 self.assertEqual(format(lz), u)
81 82
82 83 def test_lazy_eval_nonascii_bytes(self):
83 84 u = u'ünicødé'
84 85 b = u.encode('utf8')
85 86 lz = LazyEvaluate(lambda : b)
86 87 # unicode(lz) would fail
87 88 self.assertEqual(str(lz), str(b))
88 89 self.assertEqual(format(lz), str(b))
89 90
90 91 def test_lazy_eval_float(self):
91 92 f = 0.503
92 93 lz = LazyEvaluate(lambda : f)
93 94
94 95 self.assertEqual(str(lz), str(f))
95 96 self.assertEqual(unicode(lz), unicode(f))
96 97 self.assertEqual(format(lz), str(f))
97 98 self.assertEqual(format(lz, '.1'), '0.5')
98 99
99 100 @dec.skip_win32
100 101 def test_cwd_x(self):
101 102 self.pm.in_template = r"\X0"
102 103 save = os.getcwdu()
103 104 os.chdir(os.path.expanduser('~'))
104 105 p = self.pm.render('in', color=False)
105 106 try:
106 107 self.assertEqual(p, '~')
107 108 finally:
108 109 os.chdir(save)
109 110
General Comments 0
You need to be logged in to leave comments. Login now