##// END OF EJS Templates
Add test for magic macro command.
Thomas Kluyver -
Show More
@@ -1,408 +1,420 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 -n -f $tfile 3
65 In [11]: %hist -n -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 -r 2
83 In [3]: %hist -r 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_shist():
154 def test_shist():
155 # Simple tests of ShadowHist class - test generator.
155 # Simple tests of ShadowHist class - test generator.
156 import os, shutil, tempfile
156 import os, shutil, tempfile
157
157
158 from IPython.utils import pickleshare
158 from IPython.utils import pickleshare
159 from IPython.core.history import ShadowHist
159 from IPython.core.history import ShadowHist
160
160
161 tfile = tempfile.mktemp('','tmp-ipython-')
161 tfile = tempfile.mktemp('','tmp-ipython-')
162
162
163 db = pickleshare.PickleShareDB(tfile)
163 db = pickleshare.PickleShareDB(tfile)
164 s = ShadowHist(db, get_ipython())
164 s = ShadowHist(db, get_ipython())
165 s.add('hello')
165 s.add('hello')
166 s.add('world')
166 s.add('world')
167 s.add('hello')
167 s.add('hello')
168 s.add('hello')
168 s.add('hello')
169 s.add('karhu')
169 s.add('karhu')
170
170
171 yield nt.assert_equals,s.all(),[(1, 'hello'), (2, 'world'), (3, 'karhu')]
171 yield nt.assert_equals,s.all(),[(1, 'hello'), (2, 'world'), (3, 'karhu')]
172
172
173 yield nt.assert_equal,s.get(2),'world'
173 yield nt.assert_equal,s.get(2),'world'
174
174
175 shutil.rmtree(tfile)
175 shutil.rmtree(tfile)
176
177 def test_macro():
178 ip = get_ipython()
179 ip.history_manager.reset() # Clear any existing history.
180 cmds = ["a=1", "def b():\n return a**2", "print(a,b())"]
181 for cmd in cmds:
182 ip.history_manager.store_inputs(cmd)
183 ip.magic("macro test 1-3")
184 nt.assert_equal(ip.user_ns["test"].value, "\n".join(cmds)+"\n")
185
186 # List macros. This goes to stdout, so just check it doesn't crash.
187 ip.magic("macro")
176
188
177
189
178 # XXX failing for now, until we get clearcmd out of quarantine. But we should
190 # XXX failing for now, until we get clearcmd out of quarantine. But we should
179 # fix this and revert the skip to happen only if numpy is not around.
191 # fix this and revert the skip to happen only if numpy is not around.
180 #@dec.skipif_not_numpy
192 #@dec.skipif_not_numpy
181 @dec.skip_known_failure
193 @dec.skip_known_failure
182 def test_numpy_clear_array_undec():
194 def test_numpy_clear_array_undec():
183 from IPython.extensions import clearcmd
195 from IPython.extensions import clearcmd
184
196
185 _ip.ex('import numpy as np')
197 _ip.ex('import numpy as np')
186 _ip.ex('a = np.empty(2)')
198 _ip.ex('a = np.empty(2)')
187 yield (nt.assert_true, 'a' in _ip.user_ns)
199 yield (nt.assert_true, 'a' in _ip.user_ns)
188 _ip.magic('clear array')
200 _ip.magic('clear array')
189 yield (nt.assert_false, 'a' in _ip.user_ns)
201 yield (nt.assert_false, 'a' in _ip.user_ns)
190
202
191
203
192 # Multiple tests for clipboard pasting
204 # Multiple tests for clipboard pasting
193 @dec.parametric
205 @dec.parametric
194 def test_paste():
206 def test_paste():
195 _ip = get_ipython()
207 _ip = get_ipython()
196 def paste(txt, flags='-q'):
208 def paste(txt, flags='-q'):
197 """Paste input text, by default in quiet mode"""
209 """Paste input text, by default in quiet mode"""
198 hooks.clipboard_get = lambda : txt
210 hooks.clipboard_get = lambda : txt
199 _ip.magic('paste '+flags)
211 _ip.magic('paste '+flags)
200
212
201 # Inject fake clipboard hook but save original so we can restore it later
213 # Inject fake clipboard hook but save original so we can restore it later
202 hooks = _ip.hooks
214 hooks = _ip.hooks
203 user_ns = _ip.user_ns
215 user_ns = _ip.user_ns
204 original_clip = hooks.clipboard_get
216 original_clip = hooks.clipboard_get
205
217
206 try:
218 try:
207 # This try/except with an emtpy except clause is here only because
219 # This try/except with an emtpy except clause is here only because
208 # try/yield/finally is invalid syntax in Python 2.4. This will be
220 # try/yield/finally is invalid syntax in Python 2.4. This will be
209 # removed when we drop 2.4-compatibility, and the emtpy except below
221 # removed when we drop 2.4-compatibility, and the emtpy except below
210 # will be changed to a finally.
222 # will be changed to a finally.
211
223
212 # Run tests with fake clipboard function
224 # Run tests with fake clipboard function
213 user_ns.pop('x', None)
225 user_ns.pop('x', None)
214 paste('x=1')
226 paste('x=1')
215 yield nt.assert_equal(user_ns['x'], 1)
227 yield nt.assert_equal(user_ns['x'], 1)
216
228
217 user_ns.pop('x', None)
229 user_ns.pop('x', None)
218 paste('>>> x=2')
230 paste('>>> x=2')
219 yield nt.assert_equal(user_ns['x'], 2)
231 yield nt.assert_equal(user_ns['x'], 2)
220
232
221 paste("""
233 paste("""
222 >>> x = [1,2,3]
234 >>> x = [1,2,3]
223 >>> y = []
235 >>> y = []
224 >>> for i in x:
236 >>> for i in x:
225 ... y.append(i**2)
237 ... y.append(i**2)
226 ...
238 ...
227 """)
239 """)
228 yield nt.assert_equal(user_ns['x'], [1,2,3])
240 yield nt.assert_equal(user_ns['x'], [1,2,3])
229 yield nt.assert_equal(user_ns['y'], [1,4,9])
241 yield nt.assert_equal(user_ns['y'], [1,4,9])
230
242
231 # Now, test that paste -r works
243 # Now, test that paste -r works
232 user_ns.pop('x', None)
244 user_ns.pop('x', None)
233 yield nt.assert_false('x' in user_ns)
245 yield nt.assert_false('x' in user_ns)
234 _ip.magic('paste -r')
246 _ip.magic('paste -r')
235 yield nt.assert_equal(user_ns['x'], [1,2,3])
247 yield nt.assert_equal(user_ns['x'], [1,2,3])
236
248
237 # Also test paste echoing, by temporarily faking the writer
249 # Also test paste echoing, by temporarily faking the writer
238 w = StringIO()
250 w = StringIO()
239 writer = _ip.write
251 writer = _ip.write
240 _ip.write = w.write
252 _ip.write = w.write
241 code = """
253 code = """
242 a = 100
254 a = 100
243 b = 200"""
255 b = 200"""
244 try:
256 try:
245 paste(code,'')
257 paste(code,'')
246 out = w.getvalue()
258 out = w.getvalue()
247 finally:
259 finally:
248 _ip.write = writer
260 _ip.write = writer
249 yield nt.assert_equal(user_ns['a'], 100)
261 yield nt.assert_equal(user_ns['a'], 100)
250 yield nt.assert_equal(user_ns['b'], 200)
262 yield nt.assert_equal(user_ns['b'], 200)
251 yield nt.assert_equal(out, code+"\n## -- End pasted text --\n")
263 yield nt.assert_equal(out, code+"\n## -- End pasted text --\n")
252
264
253 finally:
265 finally:
254 # This should be in a finally clause, instead of the bare except above.
266 # This should be in a finally clause, instead of the bare except above.
255 # Restore original hook
267 # Restore original hook
256 hooks.clipboard_get = original_clip
268 hooks.clipboard_get = original_clip
257
269
258
270
259 def test_time():
271 def test_time():
260 _ip.magic('time None')
272 _ip.magic('time None')
261
273
262
274
263 def doctest_time():
275 def doctest_time():
264 """
276 """
265 In [10]: %time None
277 In [10]: %time None
266 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
278 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
267 Wall time: 0.00 s
279 Wall time: 0.00 s
268 """
280 """
269
281
270
282
271 def test_doctest_mode():
283 def test_doctest_mode():
272 "Toggle doctest_mode twice, it should be a no-op and run without error"
284 "Toggle doctest_mode twice, it should be a no-op and run without error"
273 _ip.magic('doctest_mode')
285 _ip.magic('doctest_mode')
274 _ip.magic('doctest_mode')
286 _ip.magic('doctest_mode')
275
287
276
288
277 def test_parse_options():
289 def test_parse_options():
278 """Tests for basic options parsing in magics."""
290 """Tests for basic options parsing in magics."""
279 # These are only the most minimal of tests, more should be added later. At
291 # These are only the most minimal of tests, more should be added later. At
280 # the very least we check that basic text/unicode calls work OK.
292 # the very least we check that basic text/unicode calls work OK.
281 nt.assert_equal(_ip.parse_options('foo', '')[1], 'foo')
293 nt.assert_equal(_ip.parse_options('foo', '')[1], 'foo')
282 nt.assert_equal(_ip.parse_options(u'foo', '')[1], u'foo')
294 nt.assert_equal(_ip.parse_options(u'foo', '')[1], u'foo')
283
295
284
296
285 def test_dirops():
297 def test_dirops():
286 """Test various directory handling operations."""
298 """Test various directory handling operations."""
287 curpath = lambda :os.path.splitdrive(os.getcwd())[1].replace('\\','/')
299 curpath = lambda :os.path.splitdrive(os.getcwd())[1].replace('\\','/')
288
300
289 startdir = os.getcwd()
301 startdir = os.getcwd()
290 ipdir = _ip.ipython_dir
302 ipdir = _ip.ipython_dir
291 try:
303 try:
292 _ip.magic('cd "%s"' % ipdir)
304 _ip.magic('cd "%s"' % ipdir)
293 nt.assert_equal(curpath(), ipdir)
305 nt.assert_equal(curpath(), ipdir)
294 _ip.magic('cd -')
306 _ip.magic('cd -')
295 nt.assert_equal(curpath(), startdir)
307 nt.assert_equal(curpath(), startdir)
296 _ip.magic('pushd "%s"' % ipdir)
308 _ip.magic('pushd "%s"' % ipdir)
297 nt.assert_equal(curpath(), ipdir)
309 nt.assert_equal(curpath(), ipdir)
298 _ip.magic('popd')
310 _ip.magic('popd')
299 nt.assert_equal(curpath(), startdir)
311 nt.assert_equal(curpath(), startdir)
300 finally:
312 finally:
301 os.chdir(startdir)
313 os.chdir(startdir)
302
314
303
315
304 def check_cpaste(code, should_fail=False):
316 def check_cpaste(code, should_fail=False):
305 """Execute code via 'cpaste' and ensure it was executed, unless
317 """Execute code via 'cpaste' and ensure it was executed, unless
306 should_fail is set.
318 should_fail is set.
307 """
319 """
308 _ip.user_ns['code_ran'] = False
320 _ip.user_ns['code_ran'] = False
309
321
310 src = StringIO()
322 src = StringIO()
311 src.write('\n')
323 src.write('\n')
312 src.write(code)
324 src.write(code)
313 src.write('\n--\n')
325 src.write('\n--\n')
314 src.seek(0)
326 src.seek(0)
315
327
316 stdin_save = sys.stdin
328 stdin_save = sys.stdin
317 sys.stdin = src
329 sys.stdin = src
318
330
319 try:
331 try:
320 _ip.magic('cpaste')
332 _ip.magic('cpaste')
321 except:
333 except:
322 if not should_fail:
334 if not should_fail:
323 raise AssertionError("Failure not expected : '%s'" %
335 raise AssertionError("Failure not expected : '%s'" %
324 code)
336 code)
325 else:
337 else:
326 assert _ip.user_ns['code_ran']
338 assert _ip.user_ns['code_ran']
327 if should_fail:
339 if should_fail:
328 raise AssertionError("Failure expected : '%s'" % code)
340 raise AssertionError("Failure expected : '%s'" % code)
329 finally:
341 finally:
330 sys.stdin = stdin_save
342 sys.stdin = stdin_save
331
343
332
344
333 def test_cpaste():
345 def test_cpaste():
334 """Test cpaste magic"""
346 """Test cpaste magic"""
335
347
336 def run():
348 def run():
337 """Marker function: sets a flag when executed.
349 """Marker function: sets a flag when executed.
338 """
350 """
339 _ip.user_ns['code_ran'] = True
351 _ip.user_ns['code_ran'] = True
340 return 'run' # return string so '+ run()' doesn't result in success
352 return 'run' # return string so '+ run()' doesn't result in success
341
353
342 tests = {'pass': ["> > > run()",
354 tests = {'pass': ["> > > run()",
343 ">>> > run()",
355 ">>> > run()",
344 "+++ run()",
356 "+++ run()",
345 "++ run()",
357 "++ run()",
346 " >>> run()"],
358 " >>> run()"],
347
359
348 'fail': ["+ + run()",
360 'fail': ["+ + run()",
349 " ++ run()"]}
361 " ++ run()"]}
350
362
351 _ip.user_ns['run'] = run
363 _ip.user_ns['run'] = run
352
364
353 for code in tests['pass']:
365 for code in tests['pass']:
354 check_cpaste(code)
366 check_cpaste(code)
355
367
356 for code in tests['fail']:
368 for code in tests['fail']:
357 check_cpaste(code, should_fail=True)
369 check_cpaste(code, should_fail=True)
358
370
359 def test_xmode():
371 def test_xmode():
360 # Calling xmode three times should be a no-op
372 # Calling xmode three times should be a no-op
361 xmode = _ip.InteractiveTB.mode
373 xmode = _ip.InteractiveTB.mode
362 for i in range(3):
374 for i in range(3):
363 _ip.magic("xmode")
375 _ip.magic("xmode")
364 nt.assert_equal(_ip.InteractiveTB.mode, xmode)
376 nt.assert_equal(_ip.InteractiveTB.mode, xmode)
365
377
366 def doctest_who():
378 def doctest_who():
367 """doctest for %who
379 """doctest for %who
368
380
369 In [1]: %reset -f
381 In [1]: %reset -f
370
382
371 In [2]: alpha = 123
383 In [2]: alpha = 123
372
384
373 In [3]: beta = 'beta'
385 In [3]: beta = 'beta'
374
386
375 In [4]: %who int
387 In [4]: %who int
376 alpha
388 alpha
377
389
378 In [5]: %who str
390 In [5]: %who str
379 beta
391 beta
380
392
381 In [6]: %whos
393 In [6]: %whos
382 Variable Type Data/Info
394 Variable Type Data/Info
383 ----------------------------
395 ----------------------------
384 alpha int 123
396 alpha int 123
385 beta str beta
397 beta str beta
386
398
387 In [7]: %who_ls
399 In [7]: %who_ls
388 Out[7]: ['alpha', 'beta']
400 Out[7]: ['alpha', 'beta']
389 """
401 """
390
402
391 def doctest_precision():
403 def doctest_precision():
392 """doctest for %precision
404 """doctest for %precision
393
405
394 In [1]: f = get_ipython().shell.display_formatter.formatters['text/plain']
406 In [1]: f = get_ipython().shell.display_formatter.formatters['text/plain']
395
407
396 In [2]: %precision 5
408 In [2]: %precision 5
397 Out[2]: '%.5f'
409 Out[2]: '%.5f'
398
410
399 In [3]: f.float_format
411 In [3]: f.float_format
400 Out[3]: '%.5f'
412 Out[3]: '%.5f'
401
413
402 In [4]: %precision %e
414 In [4]: %precision %e
403 Out[4]: '%e'
415 Out[4]: '%e'
404
416
405 In [5]: f(3.1415927)
417 In [5]: f(3.1415927)
406 Out[5]: '3.141593e+00'
418 Out[5]: '3.141593e+00'
407 """
419 """
408
420
General Comments 0
You need to be logged in to leave comments. Login now