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