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