##// END OF EJS Templates
Add %time within function to doctest.
Thomas Kluyver -
Show More
@@ -1,417 +1,425 b''
1 """Tests for various magic functions.
1 """Tests for various magic functions.
2
2
3 Needs to be run by nose (to make ipython session available).
3 Needs to be run by nose (to make ipython session available).
4 """
4 """
5 from __future__ import absolute_import
5 from __future__ import absolute_import
6
6
7 #-----------------------------------------------------------------------------
7 #-----------------------------------------------------------------------------
8 # Imports
8 # Imports
9 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
10
10
11 import os
11 import os
12 import sys
12 import sys
13 import tempfile
13 import tempfile
14 import types
14 import types
15 from cStringIO import StringIO
15 from cStringIO import StringIO
16
16
17 import nose.tools as nt
17 import nose.tools as nt
18
18
19 from IPython.utils.path import get_long_path_name
19 from IPython.utils.path import get_long_path_name
20 from IPython.testing import decorators as dec
20 from IPython.testing import decorators as dec
21 from IPython.testing import tools as tt
21 from IPython.testing import tools as tt
22
22
23 #-----------------------------------------------------------------------------
23 #-----------------------------------------------------------------------------
24 # Test functions begin
24 # Test functions begin
25 #-----------------------------------------------------------------------------
25 #-----------------------------------------------------------------------------
26 def test_rehashx():
26 def test_rehashx():
27 # clear up everything
27 # clear up everything
28 _ip = get_ipython()
28 _ip = get_ipython()
29 _ip.alias_manager.alias_table.clear()
29 _ip.alias_manager.alias_table.clear()
30 del _ip.db['syscmdlist']
30 del _ip.db['syscmdlist']
31
31
32 _ip.magic('rehashx')
32 _ip.magic('rehashx')
33 # Practically ALL ipython development systems will have more than 10 aliases
33 # Practically ALL ipython development systems will have more than 10 aliases
34
34
35 yield (nt.assert_true, len(_ip.alias_manager.alias_table) > 10)
35 yield (nt.assert_true, len(_ip.alias_manager.alias_table) > 10)
36 for key, val in _ip.alias_manager.alias_table.iteritems():
36 for key, val in _ip.alias_manager.alias_table.iteritems():
37 # we must strip dots from alias names
37 # we must strip dots from alias names
38 nt.assert_true('.' not in key)
38 nt.assert_true('.' not in key)
39
39
40 # rehashx must fill up syscmdlist
40 # rehashx must fill up syscmdlist
41 scoms = _ip.db['syscmdlist']
41 scoms = _ip.db['syscmdlist']
42 yield (nt.assert_true, len(scoms) > 10)
42 yield (nt.assert_true, len(scoms) > 10)
43
43
44
44
45 def test_magic_parse_options():
45 def test_magic_parse_options():
46 """Test that we don't mangle paths when parsing magic options."""
46 """Test that we don't mangle paths when parsing magic options."""
47 ip = get_ipython()
47 ip = get_ipython()
48 path = 'c:\\x'
48 path = 'c:\\x'
49 opts = ip.parse_options('-f %s' % path,'f:')[0]
49 opts = ip.parse_options('-f %s' % path,'f:')[0]
50 # argv splitting is os-dependent
50 # argv splitting is os-dependent
51 if os.name == 'posix':
51 if os.name == 'posix':
52 expected = 'c:x'
52 expected = 'c:x'
53 else:
53 else:
54 expected = path
54 expected = path
55 nt.assert_equals(opts['f'], expected)
55 nt.assert_equals(opts['f'], expected)
56
56
57
57
58 def doctest_hist_f():
58 def doctest_hist_f():
59 """Test %hist -f with temporary filename.
59 """Test %hist -f with temporary filename.
60
60
61 In [9]: import tempfile
61 In [9]: import tempfile
62
62
63 In [10]: tfile = tempfile.mktemp('.py','tmp-ipython-')
63 In [10]: tfile = tempfile.mktemp('.py','tmp-ipython-')
64
64
65 In [11]: %hist -nl -f $tfile 3
65 In [11]: %hist -nl -f $tfile 3
66
66
67 In [13]: import os; os.unlink(tfile)
67 In [13]: import os; os.unlink(tfile)
68 """
68 """
69
69
70
70
71 def doctest_hist_r():
71 def doctest_hist_r():
72 """Test %hist -r
72 """Test %hist -r
73
73
74 XXX - This test is not recording the output correctly. For some reason, in
74 XXX - This test is not recording the output correctly. For some reason, in
75 testing mode the raw history isn't getting populated. No idea why.
75 testing mode the raw history isn't getting populated. No idea why.
76 Disabling the output checking for now, though at least we do run it.
76 Disabling the output checking for now, though at least we do run it.
77
77
78 In [1]: 'hist' in _ip.lsmagic()
78 In [1]: 'hist' in _ip.lsmagic()
79 Out[1]: True
79 Out[1]: True
80
80
81 In [2]: x=1
81 In [2]: x=1
82
82
83 In [3]: %hist -rl 2
83 In [3]: %hist -rl 2
84 x=1 # random
84 x=1 # random
85 %hist -r 2
85 %hist -r 2
86 """
86 """
87
87
88 def doctest_hist_op():
88 def doctest_hist_op():
89 """Test %hist -op
89 """Test %hist -op
90
90
91 In [1]: class b:
91 In [1]: class b:
92 ...: pass
92 ...: pass
93 ...:
93 ...:
94
94
95 In [2]: class s(b):
95 In [2]: class s(b):
96 ...: def __str__(self):
96 ...: def __str__(self):
97 ...: return 's'
97 ...: return 's'
98 ...:
98 ...:
99
99
100 In [3]:
100 In [3]:
101
101
102 In [4]: class r(b):
102 In [4]: class r(b):
103 ...: def __repr__(self):
103 ...: def __repr__(self):
104 ...: return 'r'
104 ...: return 'r'
105 ...:
105 ...:
106
106
107 In [5]: class sr(s,r): pass
107 In [5]: class sr(s,r): pass
108 ...:
108 ...:
109
109
110 In [6]:
110 In [6]:
111
111
112 In [7]: bb=b()
112 In [7]: bb=b()
113
113
114 In [8]: ss=s()
114 In [8]: ss=s()
115
115
116 In [9]: rr=r()
116 In [9]: rr=r()
117
117
118 In [10]: ssrr=sr()
118 In [10]: ssrr=sr()
119
119
120 In [11]: bb
120 In [11]: bb
121 Out[11]: <...b instance at ...>
121 Out[11]: <...b instance at ...>
122
122
123 In [12]: ss
123 In [12]: ss
124 Out[12]: <...s instance at ...>
124 Out[12]: <...s instance at ...>
125
125
126 In [13]:
126 In [13]:
127
127
128 In [14]: %hist -op
128 In [14]: %hist -op
129 >>> class b:
129 >>> class b:
130 ... pass
130 ... pass
131 ...
131 ...
132 >>> class s(b):
132 >>> class s(b):
133 ... def __str__(self):
133 ... def __str__(self):
134 ... return 's'
134 ... return 's'
135 ...
135 ...
136 >>>
136 >>>
137 >>> class r(b):
137 >>> class r(b):
138 ... def __repr__(self):
138 ... def __repr__(self):
139 ... return 'r'
139 ... return 'r'
140 ...
140 ...
141 >>> class sr(s,r): pass
141 >>> class sr(s,r): pass
142 >>>
142 >>>
143 >>> bb=b()
143 >>> bb=b()
144 >>> ss=s()
144 >>> ss=s()
145 >>> rr=r()
145 >>> rr=r()
146 >>> ssrr=sr()
146 >>> ssrr=sr()
147 >>> bb
147 >>> bb
148 <...b instance at ...>
148 <...b instance at ...>
149 >>> ss
149 >>> ss
150 <...s instance at ...>
150 <...s instance at ...>
151 >>>
151 >>>
152 """
152 """
153
153
154 def test_macro():
154 def test_macro():
155 ip = get_ipython()
155 ip = get_ipython()
156 ip.history_manager.reset() # Clear any existing history.
156 ip.history_manager.reset() # Clear any existing history.
157 cmds = ["a=1", "def b():\n return a**2", "print(a,b())"]
157 cmds = ["a=1", "def b():\n return a**2", "print(a,b())"]
158 for i, cmd in enumerate(cmds, start=1):
158 for i, cmd in enumerate(cmds, start=1):
159 ip.history_manager.store_inputs(i, cmd)
159 ip.history_manager.store_inputs(i, cmd)
160 ip.magic("macro test 1-3")
160 ip.magic("macro test 1-3")
161 nt.assert_equal(ip.user_ns["test"].value, "\n".join(cmds)+"\n")
161 nt.assert_equal(ip.user_ns["test"].value, "\n".join(cmds)+"\n")
162
162
163 # List macros.
163 # List macros.
164 assert "test" in ip.magic("macro")
164 assert "test" in ip.magic("macro")
165
165
166 def test_macro_run():
166 def test_macro_run():
167 """Test that we can run a multi-line macro successfully."""
167 """Test that we can run a multi-line macro successfully."""
168 ip = get_ipython()
168 ip = get_ipython()
169 ip.history_manager.reset()
169 ip.history_manager.reset()
170 cmds = ["a=10", "a+=1", "print a", "%macro test 2-3"]
170 cmds = ["a=10", "a+=1", "print a", "%macro test 2-3"]
171 for cmd in cmds:
171 for cmd in cmds:
172 ip.run_cell(cmd)
172 ip.run_cell(cmd)
173 nt.assert_equal(ip.user_ns["test"].value, "a+=1\nprint a\n")
173 nt.assert_equal(ip.user_ns["test"].value, "a+=1\nprint a\n")
174 original_stdout = sys.stdout
174 original_stdout = sys.stdout
175 new_stdout = StringIO()
175 new_stdout = StringIO()
176 sys.stdout = new_stdout
176 sys.stdout = new_stdout
177 try:
177 try:
178 ip.run_cell("test")
178 ip.run_cell("test")
179 nt.assert_true("12" in new_stdout.getvalue())
179 nt.assert_true("12" in new_stdout.getvalue())
180 ip.run_cell("test")
180 ip.run_cell("test")
181 nt.assert_true("13" in new_stdout.getvalue())
181 nt.assert_true("13" in new_stdout.getvalue())
182 finally:
182 finally:
183 sys.stdout = original_stdout
183 sys.stdout = original_stdout
184 new_stdout.close()
184 new_stdout.close()
185
185
186
186
187 # XXX failing for now, until we get clearcmd out of quarantine. But we should
187 # XXX failing for now, until we get clearcmd out of quarantine. But we should
188 # fix this and revert the skip to happen only if numpy is not around.
188 # fix this and revert the skip to happen only if numpy is not around.
189 #@dec.skipif_not_numpy
189 #@dec.skipif_not_numpy
190 @dec.skip_known_failure
190 @dec.skip_known_failure
191 def test_numpy_clear_array_undec():
191 def test_numpy_clear_array_undec():
192 from IPython.extensions import clearcmd
192 from IPython.extensions import clearcmd
193
193
194 _ip.ex('import numpy as np')
194 _ip.ex('import numpy as np')
195 _ip.ex('a = np.empty(2)')
195 _ip.ex('a = np.empty(2)')
196 yield (nt.assert_true, 'a' in _ip.user_ns)
196 yield (nt.assert_true, 'a' in _ip.user_ns)
197 _ip.magic('clear array')
197 _ip.magic('clear array')
198 yield (nt.assert_false, 'a' in _ip.user_ns)
198 yield (nt.assert_false, 'a' in _ip.user_ns)
199
199
200
200
201 # Multiple tests for clipboard pasting
201 # Multiple tests for clipboard pasting
202 @dec.parametric
202 @dec.parametric
203 def test_paste():
203 def test_paste():
204 _ip = get_ipython()
204 _ip = get_ipython()
205 def paste(txt, flags='-q'):
205 def paste(txt, flags='-q'):
206 """Paste input text, by default in quiet mode"""
206 """Paste input text, by default in quiet mode"""
207 hooks.clipboard_get = lambda : txt
207 hooks.clipboard_get = lambda : txt
208 _ip.magic('paste '+flags)
208 _ip.magic('paste '+flags)
209
209
210 # Inject fake clipboard hook but save original so we can restore it later
210 # Inject fake clipboard hook but save original so we can restore it later
211 hooks = _ip.hooks
211 hooks = _ip.hooks
212 user_ns = _ip.user_ns
212 user_ns = _ip.user_ns
213 original_clip = hooks.clipboard_get
213 original_clip = hooks.clipboard_get
214
214
215 try:
215 try:
216 # This try/except with an emtpy except clause is here only because
216 # This try/except with an emtpy except clause is here only because
217 # try/yield/finally is invalid syntax in Python 2.4. This will be
217 # try/yield/finally is invalid syntax in Python 2.4. This will be
218 # removed when we drop 2.4-compatibility, and the emtpy except below
218 # removed when we drop 2.4-compatibility, and the emtpy except below
219 # will be changed to a finally.
219 # will be changed to a finally.
220
220
221 # Run tests with fake clipboard function
221 # Run tests with fake clipboard function
222 user_ns.pop('x', None)
222 user_ns.pop('x', None)
223 paste('x=1')
223 paste('x=1')
224 yield nt.assert_equal(user_ns['x'], 1)
224 yield nt.assert_equal(user_ns['x'], 1)
225
225
226 user_ns.pop('x', None)
226 user_ns.pop('x', None)
227 paste('>>> x=2')
227 paste('>>> x=2')
228 yield nt.assert_equal(user_ns['x'], 2)
228 yield nt.assert_equal(user_ns['x'], 2)
229
229
230 paste("""
230 paste("""
231 >>> x = [1,2,3]
231 >>> x = [1,2,3]
232 >>> y = []
232 >>> y = []
233 >>> for i in x:
233 >>> for i in x:
234 ... y.append(i**2)
234 ... y.append(i**2)
235 ...
235 ...
236 """)
236 """)
237 yield nt.assert_equal(user_ns['x'], [1,2,3])
237 yield nt.assert_equal(user_ns['x'], [1,2,3])
238 yield nt.assert_equal(user_ns['y'], [1,4,9])
238 yield nt.assert_equal(user_ns['y'], [1,4,9])
239
239
240 # Now, test that paste -r works
240 # Now, test that paste -r works
241 user_ns.pop('x', None)
241 user_ns.pop('x', None)
242 yield nt.assert_false('x' in user_ns)
242 yield nt.assert_false('x' in user_ns)
243 _ip.magic('paste -r')
243 _ip.magic('paste -r')
244 yield nt.assert_equal(user_ns['x'], [1,2,3])
244 yield nt.assert_equal(user_ns['x'], [1,2,3])
245
245
246 # Also test paste echoing, by temporarily faking the writer
246 # Also test paste echoing, by temporarily faking the writer
247 w = StringIO()
247 w = StringIO()
248 writer = _ip.write
248 writer = _ip.write
249 _ip.write = w.write
249 _ip.write = w.write
250 code = """
250 code = """
251 a = 100
251 a = 100
252 b = 200"""
252 b = 200"""
253 try:
253 try:
254 paste(code,'')
254 paste(code,'')
255 out = w.getvalue()
255 out = w.getvalue()
256 finally:
256 finally:
257 _ip.write = writer
257 _ip.write = writer
258 yield nt.assert_equal(user_ns['a'], 100)
258 yield nt.assert_equal(user_ns['a'], 100)
259 yield nt.assert_equal(user_ns['b'], 200)
259 yield nt.assert_equal(user_ns['b'], 200)
260 yield nt.assert_equal(out, code+"\n## -- End pasted text --\n")
260 yield nt.assert_equal(out, code+"\n## -- End pasted text --\n")
261
261
262 finally:
262 finally:
263 # This should be in a finally clause, instead of the bare except above.
263 # This should be in a finally clause, instead of the bare except above.
264 # Restore original hook
264 # Restore original hook
265 hooks.clipboard_get = original_clip
265 hooks.clipboard_get = original_clip
266
266
267
267
268 def test_time():
268 def test_time():
269 _ip.magic('time None')
269 _ip.magic('time None')
270
270
271
271
272 def doctest_time():
272 def doctest_time():
273 """
273 """
274 In [10]: %time None
274 In [10]: %time None
275 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
275 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
276 Wall time: 0.00 s
276 Wall time: 0.00 s
277
278 In [11]: def f(kmjy):
279 ....: %time print 2*kmjy
280
281 In [12]: f(3)
282 6
283 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
284 Wall time: 0.00 s
277 """
285 """
278
286
279
287
280 def test_doctest_mode():
288 def test_doctest_mode():
281 "Toggle doctest_mode twice, it should be a no-op and run without error"
289 "Toggle doctest_mode twice, it should be a no-op and run without error"
282 _ip.magic('doctest_mode')
290 _ip.magic('doctest_mode')
283 _ip.magic('doctest_mode')
291 _ip.magic('doctest_mode')
284
292
285
293
286 def test_parse_options():
294 def test_parse_options():
287 """Tests for basic options parsing in magics."""
295 """Tests for basic options parsing in magics."""
288 # These are only the most minimal of tests, more should be added later. At
296 # These are only the most minimal of tests, more should be added later. At
289 # the very least we check that basic text/unicode calls work OK.
297 # the very least we check that basic text/unicode calls work OK.
290 nt.assert_equal(_ip.parse_options('foo', '')[1], 'foo')
298 nt.assert_equal(_ip.parse_options('foo', '')[1], 'foo')
291 nt.assert_equal(_ip.parse_options(u'foo', '')[1], u'foo')
299 nt.assert_equal(_ip.parse_options(u'foo', '')[1], u'foo')
292
300
293
301
294 def test_dirops():
302 def test_dirops():
295 """Test various directory handling operations."""
303 """Test various directory handling operations."""
296 curpath = lambda :os.path.splitdrive(os.getcwdu())[1].replace('\\','/')
304 curpath = lambda :os.path.splitdrive(os.getcwdu())[1].replace('\\','/')
297
305
298 startdir = os.getcwdu()
306 startdir = os.getcwdu()
299 ipdir = _ip.ipython_dir
307 ipdir = _ip.ipython_dir
300 try:
308 try:
301 _ip.magic('cd "%s"' % ipdir)
309 _ip.magic('cd "%s"' % ipdir)
302 nt.assert_equal(curpath(), ipdir)
310 nt.assert_equal(curpath(), ipdir)
303 _ip.magic('cd -')
311 _ip.magic('cd -')
304 nt.assert_equal(curpath(), startdir)
312 nt.assert_equal(curpath(), startdir)
305 _ip.magic('pushd "%s"' % ipdir)
313 _ip.magic('pushd "%s"' % ipdir)
306 nt.assert_equal(curpath(), ipdir)
314 nt.assert_equal(curpath(), ipdir)
307 _ip.magic('popd')
315 _ip.magic('popd')
308 nt.assert_equal(curpath(), startdir)
316 nt.assert_equal(curpath(), startdir)
309 finally:
317 finally:
310 os.chdir(startdir)
318 os.chdir(startdir)
311
319
312
320
313 def check_cpaste(code, should_fail=False):
321 def check_cpaste(code, should_fail=False):
314 """Execute code via 'cpaste' and ensure it was executed, unless
322 """Execute code via 'cpaste' and ensure it was executed, unless
315 should_fail is set.
323 should_fail is set.
316 """
324 """
317 _ip.user_ns['code_ran'] = False
325 _ip.user_ns['code_ran'] = False
318
326
319 src = StringIO()
327 src = StringIO()
320 src.write('\n')
328 src.write('\n')
321 src.write(code)
329 src.write(code)
322 src.write('\n--\n')
330 src.write('\n--\n')
323 src.seek(0)
331 src.seek(0)
324
332
325 stdin_save = sys.stdin
333 stdin_save = sys.stdin
326 sys.stdin = src
334 sys.stdin = src
327
335
328 try:
336 try:
329 _ip.magic('cpaste')
337 _ip.magic('cpaste')
330 except:
338 except:
331 if not should_fail:
339 if not should_fail:
332 raise AssertionError("Failure not expected : '%s'" %
340 raise AssertionError("Failure not expected : '%s'" %
333 code)
341 code)
334 else:
342 else:
335 assert _ip.user_ns['code_ran']
343 assert _ip.user_ns['code_ran']
336 if should_fail:
344 if should_fail:
337 raise AssertionError("Failure expected : '%s'" % code)
345 raise AssertionError("Failure expected : '%s'" % code)
338 finally:
346 finally:
339 sys.stdin = stdin_save
347 sys.stdin = stdin_save
340
348
341
349
342 def test_cpaste():
350 def test_cpaste():
343 """Test cpaste magic"""
351 """Test cpaste magic"""
344
352
345 def run():
353 def run():
346 """Marker function: sets a flag when executed.
354 """Marker function: sets a flag when executed.
347 """
355 """
348 _ip.user_ns['code_ran'] = True
356 _ip.user_ns['code_ran'] = True
349 return 'run' # return string so '+ run()' doesn't result in success
357 return 'run' # return string so '+ run()' doesn't result in success
350
358
351 tests = {'pass': ["> > > run()",
359 tests = {'pass': ["> > > run()",
352 ">>> > run()",
360 ">>> > run()",
353 "+++ run()",
361 "+++ run()",
354 "++ run()",
362 "++ run()",
355 " >>> run()"],
363 " >>> run()"],
356
364
357 'fail': ["+ + run()",
365 'fail': ["+ + run()",
358 " ++ run()"]}
366 " ++ run()"]}
359
367
360 _ip.user_ns['run'] = run
368 _ip.user_ns['run'] = run
361
369
362 for code in tests['pass']:
370 for code in tests['pass']:
363 check_cpaste(code)
371 check_cpaste(code)
364
372
365 for code in tests['fail']:
373 for code in tests['fail']:
366 check_cpaste(code, should_fail=True)
374 check_cpaste(code, should_fail=True)
367
375
368 def test_xmode():
376 def test_xmode():
369 # Calling xmode three times should be a no-op
377 # Calling xmode three times should be a no-op
370 xmode = _ip.InteractiveTB.mode
378 xmode = _ip.InteractiveTB.mode
371 for i in range(3):
379 for i in range(3):
372 _ip.magic("xmode")
380 _ip.magic("xmode")
373 nt.assert_equal(_ip.InteractiveTB.mode, xmode)
381 nt.assert_equal(_ip.InteractiveTB.mode, xmode)
374
382
375 def doctest_who():
383 def doctest_who():
376 """doctest for %who
384 """doctest for %who
377
385
378 In [1]: %reset -f
386 In [1]: %reset -f
379
387
380 In [2]: alpha = 123
388 In [2]: alpha = 123
381
389
382 In [3]: beta = 'beta'
390 In [3]: beta = 'beta'
383
391
384 In [4]: %who int
392 In [4]: %who int
385 alpha
393 alpha
386
394
387 In [5]: %who str
395 In [5]: %who str
388 beta
396 beta
389
397
390 In [6]: %whos
398 In [6]: %whos
391 Variable Type Data/Info
399 Variable Type Data/Info
392 ----------------------------
400 ----------------------------
393 alpha int 123
401 alpha int 123
394 beta str beta
402 beta str beta
395
403
396 In [7]: %who_ls
404 In [7]: %who_ls
397 Out[7]: ['alpha', 'beta']
405 Out[7]: ['alpha', 'beta']
398 """
406 """
399
407
400 def doctest_precision():
408 def doctest_precision():
401 """doctest for %precision
409 """doctest for %precision
402
410
403 In [1]: f = get_ipython().shell.display_formatter.formatters['text/plain']
411 In [1]: f = get_ipython().shell.display_formatter.formatters['text/plain']
404
412
405 In [2]: %precision 5
413 In [2]: %precision 5
406 Out[2]: '%.5f'
414 Out[2]: '%.5f'
407
415
408 In [3]: f.float_format
416 In [3]: f.float_format
409 Out[3]: '%.5f'
417 Out[3]: '%.5f'
410
418
411 In [4]: %precision %e
419 In [4]: %precision %e
412 Out[4]: '%e'
420 Out[4]: '%e'
413
421
414 In [5]: f(3.1415927)
422 In [5]: f(3.1415927)
415 Out[5]: '3.141593e+00'
423 Out[5]: '3.141593e+00'
416 """
424 """
417
425
General Comments 0
You need to be logged in to leave comments. Login now