##// END OF EJS Templates
Improvements and bugfixes to %paste....
Fernando Perez -
Show More

The requested changes are too big and content was truncated. Show full diff

1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
@@ -1,302 +1,325 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
5
6 import os
6 import os
7 import sys
7 import sys
8 import tempfile
8 import tempfile
9 import types
9 import types
10 from cStringIO import StringIO
10
11
11 import nose.tools as nt
12 import nose.tools as nt
12
13
13 from IPython.platutils import find_cmd, get_long_path_name
14 from IPython.platutils import find_cmd, get_long_path_name
14 from IPython.testing import decorators as dec
15 from IPython.testing import decorators as dec
15 from IPython.testing import tools as tt
16 from IPython.testing import tools as tt
16
17
17 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
18 # Test functions begin
19 # Test functions begin
19
20
20 def test_rehashx():
21 def test_rehashx():
21 # clear up everything
22 # clear up everything
22 _ip.IP.alias_table.clear()
23 _ip.IP.alias_table.clear()
23 del _ip.db['syscmdlist']
24 del _ip.db['syscmdlist']
24
25
25 _ip.magic('rehashx')
26 _ip.magic('rehashx')
26 # Practically ALL ipython development systems will have more than 10 aliases
27 # Practically ALL ipython development systems will have more than 10 aliases
27
28
28 yield (nt.assert_true, len(_ip.IP.alias_table) > 10)
29 yield (nt.assert_true, len(_ip.IP.alias_table) > 10)
29 for key, val in _ip.IP.alias_table.items():
30 for key, val in _ip.IP.alias_table.items():
30 # we must strip dots from alias names
31 # we must strip dots from alias names
31 nt.assert_true('.' not in key)
32 nt.assert_true('.' not in key)
32
33
33 # rehashx must fill up syscmdlist
34 # rehashx must fill up syscmdlist
34 scoms = _ip.db['syscmdlist']
35 scoms = _ip.db['syscmdlist']
35 yield (nt.assert_true, len(scoms) > 10)
36 yield (nt.assert_true, len(scoms) > 10)
36
37
37
38
38 def doctest_hist_f():
39 def doctest_hist_f():
39 """Test %hist -f with temporary filename.
40 """Test %hist -f with temporary filename.
40
41
41 In [9]: import tempfile
42 In [9]: import tempfile
42
43
43 In [10]: tfile = tempfile.mktemp('.py','tmp-ipython-')
44 In [10]: tfile = tempfile.mktemp('.py','tmp-ipython-')
44
45
45 In [11]: %hist -n -f $tfile 3
46 In [11]: %hist -n -f $tfile 3
46 """
47 """
47
48
48
49
49 def doctest_hist_r():
50 def doctest_hist_r():
50 """Test %hist -r
51 """Test %hist -r
51
52
52 XXX - This test is not recording the output correctly. Not sure why...
53 XXX - This test is not recording the output correctly. Not sure why...
53
54
54 In [20]: 'hist' in _ip.IP.lsmagic()
55 In [20]: 'hist' in _ip.IP.lsmagic()
55 Out[20]: True
56 Out[20]: True
56
57
57 In [6]: x=1
58 In [6]: x=1
58
59
59 In [7]: %hist -n -r 2
60 In [7]: %hist -n -r 2
60 x=1 # random
61 x=1 # random
61 hist -n -r 2 # random
62 hist -n -r 2 # random
62 """
63 """
63
64
64 # This test is known to fail on win32.
65 # This test is known to fail on win32.
65 # See ticket https://bugs.launchpad.net/bugs/366334
66 # See ticket https://bugs.launchpad.net/bugs/366334
66 def test_obj_del():
67 def test_obj_del():
67 """Test that object's __del__ methods are called on exit."""
68 """Test that object's __del__ methods are called on exit."""
68 test_dir = os.path.dirname(__file__)
69 test_dir = os.path.dirname(__file__)
69 del_file = os.path.join(test_dir,'obj_del.py')
70 del_file = os.path.join(test_dir,'obj_del.py')
70 ipython_cmd = find_cmd('ipython')
71 ipython_cmd = find_cmd('ipython')
71 out = _ip.IP.getoutput('%s %s' % (ipython_cmd, del_file))
72 out = _ip.IP.getoutput('%s %s' % (ipython_cmd, del_file))
72 nt.assert_equals(out,'obj_del.py: object A deleted')
73 nt.assert_equals(out,'obj_del.py: object A deleted')
73
74
74
75
75 def test_shist():
76 def test_shist():
76 # Simple tests of ShadowHist class - test generator.
77 # Simple tests of ShadowHist class - test generator.
77 import os, shutil, tempfile
78 import os, shutil, tempfile
78
79
79 from IPython.Extensions import pickleshare
80 from IPython.Extensions import pickleshare
80 from IPython.history import ShadowHist
81 from IPython.history import ShadowHist
81
82
82 tfile = tempfile.mktemp('','tmp-ipython-')
83 tfile = tempfile.mktemp('','tmp-ipython-')
83
84
84 db = pickleshare.PickleShareDB(tfile)
85 db = pickleshare.PickleShareDB(tfile)
85 s = ShadowHist(db)
86 s = ShadowHist(db)
86 s.add('hello')
87 s.add('hello')
87 s.add('world')
88 s.add('world')
88 s.add('hello')
89 s.add('hello')
89 s.add('hello')
90 s.add('hello')
90 s.add('karhu')
91 s.add('karhu')
91
92
92 yield nt.assert_equals,s.all(),[(1, 'hello'), (2, 'world'), (3, 'karhu')]
93 yield nt.assert_equals,s.all(),[(1, 'hello'), (2, 'world'), (3, 'karhu')]
93
94
94 yield nt.assert_equal,s.get(2),'world'
95 yield nt.assert_equal,s.get(2),'world'
95
96
96 shutil.rmtree(tfile)
97 shutil.rmtree(tfile)
97
98
98 @dec.skipif_not_numpy
99 @dec.skipif_not_numpy
99 def test_numpy_clear_array_undec():
100 def test_numpy_clear_array_undec():
100 from IPython.Extensions import clearcmd
101 from IPython.Extensions import clearcmd
101
102
102 _ip.ex('import numpy as np')
103 _ip.ex('import numpy as np')
103 _ip.ex('a = np.empty(2)')
104 _ip.ex('a = np.empty(2)')
104 yield (nt.assert_true, 'a' in _ip.user_ns)
105 yield (nt.assert_true, 'a' in _ip.user_ns)
105 _ip.magic('clear array')
106 _ip.magic('clear array')
106 yield (nt.assert_false, 'a' in _ip.user_ns)
107 yield (nt.assert_false, 'a' in _ip.user_ns)
107
108
108
109
109 @dec.skip()
110 @dec.skip()
110 def test_fail_dec(*a,**k):
111 def test_fail_dec(*a,**k):
111 yield nt.assert_true, False
112 yield nt.assert_true, False
112
113
113 @dec.skip('This one shouldn not run')
114 @dec.skip('This one shouldn not run')
114 def test_fail_dec2(*a,**k):
115 def test_fail_dec2(*a,**k):
115 yield nt.assert_true, False
116 yield nt.assert_true, False
116
117
117 @dec.skipknownfailure
118 @dec.skipknownfailure
118 def test_fail_dec3(*a,**k):
119 def test_fail_dec3(*a,**k):
119 yield nt.assert_true, False
120 yield nt.assert_true, False
120
121
121
122
122 def doctest_refbug():
123 def doctest_refbug():
123 """Very nasty problem with references held by multiple runs of a script.
124 """Very nasty problem with references held by multiple runs of a script.
124 See: https://bugs.launchpad.net/ipython/+bug/269966
125 See: https://bugs.launchpad.net/ipython/+bug/269966
125
126
126 In [1]: _ip.IP.clear_main_mod_cache()
127 In [1]: _ip.IP.clear_main_mod_cache()
127
128
128 In [2]: run refbug
129 In [2]: run refbug
129
130
130 In [3]: call_f()
131 In [3]: call_f()
131 lowercased: hello
132 lowercased: hello
132
133
133 In [4]: run refbug
134 In [4]: run refbug
134
135
135 In [5]: call_f()
136 In [5]: call_f()
136 lowercased: hello
137 lowercased: hello
137 lowercased: hello
138 lowercased: hello
138 """
139 """
139
140
140 #-----------------------------------------------------------------------------
141 #-----------------------------------------------------------------------------
141 # Tests for %run
142 # Tests for %run
142 #-----------------------------------------------------------------------------
143 #-----------------------------------------------------------------------------
143
144
144 # %run is critical enough that it's a good idea to have a solid collection of
145 # %run is critical enough that it's a good idea to have a solid collection of
145 # tests for it, some as doctests and some as normal tests.
146 # tests for it, some as doctests and some as normal tests.
146
147
147 def doctest_run_ns():
148 def doctest_run_ns():
148 """Classes declared %run scripts must be instantiable afterwards.
149 """Classes declared %run scripts must be instantiable afterwards.
149
150
150 In [11]: run tclass foo
151 In [11]: run tclass foo
151
152
152 In [12]: isinstance(f(),foo)
153 In [12]: isinstance(f(),foo)
153 Out[12]: True
154 Out[12]: True
154 """
155 """
155
156
156
157
157 def doctest_run_ns2():
158 def doctest_run_ns2():
158 """Classes declared %run scripts must be instantiable afterwards.
159 """Classes declared %run scripts must be instantiable afterwards.
159
160
160 In [4]: run tclass C-first_pass
161 In [4]: run tclass C-first_pass
161
162
162 In [5]: run tclass C-second_pass
163 In [5]: run tclass C-second_pass
163 tclass.py: deleting object: C-first_pass
164 tclass.py: deleting object: C-first_pass
164 """
165 """
165
166
166 def doctest_run_builtins():
167 def doctest_run_builtins():
167 """Check that %run doesn't damage __builtins__ via a doctest.
168 """Check that %run doesn't damage __builtins__ via a doctest.
168
169
169 This is similar to the test_run_builtins, but I want *both* forms of the
170 This is similar to the test_run_builtins, but I want *both* forms of the
170 test to catch any possible glitches in our testing machinery, since that
171 test to catch any possible glitches in our testing machinery, since that
171 modifies %run somewhat. So for this, we have both a normal test (below)
172 modifies %run somewhat. So for this, we have both a normal test (below)
172 and a doctest (this one).
173 and a doctest (this one).
173
174
174 In [1]: import tempfile
175 In [1]: import tempfile
175
176
176 In [2]: bid1 = id(__builtins__)
177 In [2]: bid1 = id(__builtins__)
177
178
178 In [3]: fname = tempfile.mkstemp()[1]
179 In [3]: fname = tempfile.mkstemp()[1]
179
180
180 In [3]: f = open(fname,'w')
181 In [3]: f = open(fname,'w')
181
182
182 In [4]: f.write('pass\\n')
183 In [4]: f.write('pass\\n')
183
184
184 In [5]: f.flush()
185 In [5]: f.flush()
185
186
186 In [6]: print type(__builtins__)
187 In [6]: print type(__builtins__)
187 <type 'module'>
188 <type 'module'>
188
189
189 In [7]: %run "$fname"
190 In [7]: %run "$fname"
190
191
191 In [7]: f.close()
192 In [7]: f.close()
192
193
193 In [8]: bid2 = id(__builtins__)
194 In [8]: bid2 = id(__builtins__)
194
195
195 In [9]: print type(__builtins__)
196 In [9]: print type(__builtins__)
196 <type 'module'>
197 <type 'module'>
197
198
198 In [10]: bid1 == bid2
199 In [10]: bid1 == bid2
199 Out[10]: True
200 Out[10]: True
200
201
201 In [12]: try:
202 In [12]: try:
202 ....: os.unlink(fname)
203 ....: os.unlink(fname)
203 ....: except:
204 ....: except:
204 ....: pass
205 ....: pass
205 ....:
206 ....:
206 """
207 """
207
208
208 # For some tests, it will be handy to organize them in a class with a common
209 # For some tests, it will be handy to organize them in a class with a common
209 # setup that makes a temp file
210 # setup that makes a temp file
210
211
211 class TestMagicRun(object):
212 class TestMagicRun(object):
212
213
213 def setup(self):
214 def setup(self):
214 """Make a valid python temp file."""
215 """Make a valid python temp file."""
215 fname = tempfile.mkstemp()[1]
216 fname = tempfile.mkstemp()[1]
216 f = open(fname,'w')
217 f = open(fname,'w')
217 f.write('pass\n')
218 f.write('pass\n')
218 f.flush()
219 f.flush()
219 self.tmpfile = f
220 self.tmpfile = f
220 self.fname = fname
221 self.fname = fname
221
222
222 def run_tmpfile(self):
223 def run_tmpfile(self):
223 # This fails on Windows if self.tmpfile.name has spaces or "~" in it.
224 # This fails on Windows if self.tmpfile.name has spaces or "~" in it.
224 # See below and ticket https://bugs.launchpad.net/bugs/366353
225 # See below and ticket https://bugs.launchpad.net/bugs/366353
225 _ip.magic('run "%s"' % self.fname)
226 _ip.magic('run "%s"' % self.fname)
226
227
227 def test_builtins_id(self):
228 def test_builtins_id(self):
228 """Check that %run doesn't damage __builtins__ """
229 """Check that %run doesn't damage __builtins__ """
229
230
230 # Test that the id of __builtins__ is not modified by %run
231 # Test that the id of __builtins__ is not modified by %run
231 bid1 = id(_ip.user_ns['__builtins__'])
232 bid1 = id(_ip.user_ns['__builtins__'])
232 self.run_tmpfile()
233 self.run_tmpfile()
233 bid2 = id(_ip.user_ns['__builtins__'])
234 bid2 = id(_ip.user_ns['__builtins__'])
234 tt.assert_equals(bid1, bid2)
235 tt.assert_equals(bid1, bid2)
235
236
236 def test_builtins_type(self):
237 def test_builtins_type(self):
237 """Check that the type of __builtins__ doesn't change with %run.
238 """Check that the type of __builtins__ doesn't change with %run.
238
239
239 However, the above could pass if __builtins__ was already modified to
240 However, the above could pass if __builtins__ was already modified to
240 be a dict (it should be a module) by a previous use of %run. So we
241 be a dict (it should be a module) by a previous use of %run. So we
241 also check explicitly that it really is a module:
242 also check explicitly that it really is a module:
242 """
243 """
243 self.run_tmpfile()
244 self.run_tmpfile()
244 tt.assert_equals(type(_ip.user_ns['__builtins__']),type(sys))
245 tt.assert_equals(type(_ip.user_ns['__builtins__']),type(sys))
245
246
246 def test_prompts(self):
247 def test_prompts(self):
247 """Test that prompts correctly generate after %run"""
248 """Test that prompts correctly generate after %run"""
248 self.run_tmpfile()
249 self.run_tmpfile()
249 p2 = str(_ip.IP.outputcache.prompt2).strip()
250 p2 = str(_ip.IP.outputcache.prompt2).strip()
250 nt.assert_equals(p2[:3], '...')
251 nt.assert_equals(p2[:3], '...')
251
252
252 def teardown(self):
253 def teardown(self):
253 self.tmpfile.close()
254 self.tmpfile.close()
254 try:
255 try:
255 os.unlink(self.fname)
256 os.unlink(self.fname)
256 except:
257 except:
257 # On Windows, even though we close the file, we still can't delete
258 # On Windows, even though we close the file, we still can't delete
258 # it. I have no clue why
259 # it. I have no clue why
259 pass
260 pass
260
261
261 # Multiple tests for clipboard pasting
262 # Multiple tests for clipboard pasting
262 def test_paste():
263 def test_paste():
263
264
264 def paste(txt):
265 def paste(txt, flags=''):
265 hooks.clipboard_get = lambda : txt
266 hooks.clipboard_get = lambda : txt
266 _ip.magic('paste')
267 _ip.magic('paste '+flags)
267
268
268 # Inject fake clipboard hook but save original so we can restore it later
269 # Inject fake clipboard hook but save original so we can restore it later
269 hooks = _ip.IP.hooks
270 hooks = _ip.IP.hooks
270 user_ns = _ip.user_ns
271 user_ns = _ip.user_ns
271 original_clip = hooks.clipboard_get
272 original_clip = hooks.clipboard_get
272
273
273 try:
274 try:
274 # This try/except with an emtpy except clause is here only because
275 # This try/except with an emtpy except clause is here only because
275 # try/yield/finally is invalid syntax in Python 2.4. This will be
276 # try/yield/finally is invalid syntax in Python 2.4. This will be
276 # removed when we drop 2.4-compatibility, and the emtpy except below
277 # removed when we drop 2.4-compatibility, and the emtpy except below
277 # will be changed to a finally.
278 # will be changed to a finally.
278
279
279 # Run tests with fake clipboard function
280 # Run tests with fake clipboard function
280 user_ns.pop('x', None)
281 user_ns.pop('x', None)
281 paste('x=1')
282 paste('x=1')
282 yield (nt.assert_equal, user_ns['x'], 1)
283 yield (nt.assert_equal, user_ns['x'], 1)
283
284
284 user_ns.pop('x', None)
285 user_ns.pop('x', None)
285 paste('>>> x=2')
286 paste('>>> x=2')
286 yield (nt.assert_equal, user_ns['x'], 2)
287 yield (nt.assert_equal, user_ns['x'], 2)
287
288
288 paste("""
289 paste("""
289 >>> x = [1,2,3]
290 >>> x = [1,2,3]
290 >>> y = []
291 >>> y = []
291 >>> for i in x:
292 >>> for i in x:
292 ... y.append(i**2)
293 ... y.append(i**2)
293 ...
294 ...
294 """)
295 """)
295 yield (nt.assert_equal, user_ns['x'], [1,2,3])
296 yield (nt.assert_equal, user_ns['x'], [1,2,3])
296 yield (nt.assert_equal, user_ns['y'], [1,4,9])
297 yield (nt.assert_equal, user_ns['y'], [1,4,9])
297 except:
298 pass
299
298
300 # This should be in a finally clause, instead of the bare except above.
299 # Now, test that paste -r works
301 # Restore original hook
300 user_ns.pop('x', None)
302 hooks.clipboard_get = original_clip
301 yield (nt.assert_false, 'x' in user_ns)
302 _ip.magic('paste -r')
303 yield (nt.assert_equal, user_ns['x'], [1,2,3])
304
305 # Also test paste -e, by temporarily faking the writer
306 w = StringIO()
307 writer = _ip.IP.write
308 _ip.IP.write = w.write
309 code = """
310 a = 100
311 b = 200"""
312 try:
313 paste(code,'-e')
314 out = w.getvalue()
315 finally:
316 _ip.IP.write = writer
317 yield (nt.assert_equal, user_ns['a'], 100)
318 yield (nt.assert_equal, user_ns['b'], 200)
319 yield (nt.assert_equal, out, code+"\n## -- End pasted text --\n")
320
321 finally:
322 # This should be in a finally clause, instead of the bare except above.
323 # Restore original hook
324 hooks.clipboard_get = original_clip
325
General Comments 0
You need to be logged in to leave comments. Login now