##// END OF EJS Templates
Fix test I'd broken with change of reporting in %who.
Fernando Perez -
Show More
@@ -1,269 +1,269 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 Test process execution and IO redirection.
3 Test process execution and IO redirection.
4 """
4 """
5
5
6 __docformat__ = "restructuredtext en"
6 __docformat__ = "restructuredtext en"
7
7
8 #-------------------------------------------------------------------------------
8 #-------------------------------------------------------------------------------
9 # Copyright (C) 2008 The IPython Development Team
9 # Copyright (C) 2008 The IPython Development Team
10 #
10 #
11 # Distributed under the terms of the BSD License. The full license is
11 # Distributed under the terms of the BSD License. The full license is
12 # in the file COPYING, distributed as part of this software.
12 # in the file COPYING, distributed as part of this software.
13 #-------------------------------------------------------------------------------
13 #-------------------------------------------------------------------------------
14
14
15 from copy import copy, deepcopy
15 from copy import copy, deepcopy
16 from cStringIO import StringIO
16 from cStringIO import StringIO
17 import string
17 import string
18 import sys
18 import sys
19
19
20 from nose.tools import assert_equal
20 from nose.tools import assert_equal
21
21
22 from IPython.frontend.prefilterfrontend import PrefilterFrontEnd
22 from IPython.frontend.prefilterfrontend import PrefilterFrontEnd
23 from IPython.core.ipapi import get as get_ipython0
23 from IPython.core.ipapi import get as get_ipython0
24 from IPython.testing.tools import default_argv
24 from IPython.testing.tools import default_argv
25
25
26 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
27 # Support utilities
27 # Support utilities
28 #-----------------------------------------------------------------------------
28 #-----------------------------------------------------------------------------
29
29
30 class TestPrefilterFrontEnd(PrefilterFrontEnd):
30 class TestPrefilterFrontEnd(PrefilterFrontEnd):
31
31
32 input_prompt_template = string.Template('')
32 input_prompt_template = string.Template('')
33 output_prompt_template = string.Template('')
33 output_prompt_template = string.Template('')
34 banner = ''
34 banner = ''
35
35
36 def __init__(self):
36 def __init__(self):
37 self.out = StringIO()
37 self.out = StringIO()
38 PrefilterFrontEnd.__init__(self,argv=default_argv())
38 PrefilterFrontEnd.__init__(self,argv=default_argv())
39 # Some more code for isolation (yeah, crazy)
39 # Some more code for isolation (yeah, crazy)
40 self._on_enter()
40 self._on_enter()
41 self.out.flush()
41 self.out.flush()
42 self.out.reset()
42 self.out.reset()
43 self.out.truncate()
43 self.out.truncate()
44
44
45 def write(self, string, *args, **kwargs):
45 def write(self, string, *args, **kwargs):
46 self.out.write(string)
46 self.out.write(string)
47
47
48 def _on_enter(self):
48 def _on_enter(self):
49 self.input_buffer += '\n'
49 self.input_buffer += '\n'
50 PrefilterFrontEnd._on_enter(self)
50 PrefilterFrontEnd._on_enter(self)
51
51
52
52
53 def isolate_ipython0(func):
53 def isolate_ipython0(func):
54 """ Decorator to isolate execution that involves an iptyhon0.
54 """ Decorator to isolate execution that involves an iptyhon0.
55
55
56 Notes
56 Notes
57 -----
57 -----
58
58
59 Apply only to functions with no arguments. Nose skips functions
59 Apply only to functions with no arguments. Nose skips functions
60 with arguments.
60 with arguments.
61 """
61 """
62 def my_func():
62 def my_func():
63 ip0 = get_ipython0()
63 ip0 = get_ipython0()
64 if ip0 is None:
64 if ip0 is None:
65 return func()
65 return func()
66 # We have a real ipython running...
66 # We have a real ipython running...
67 user_ns = ip0.user_ns
67 user_ns = ip0.user_ns
68 user_global_ns = ip0.user_global_ns
68 user_global_ns = ip0.user_global_ns
69
69
70 # Previously the isolation was attempted with a deep copy of the user
70 # Previously the isolation was attempted with a deep copy of the user
71 # dicts, but we found cases where this didn't work correctly. I'm not
71 # dicts, but we found cases where this didn't work correctly. I'm not
72 # quite sure why, but basically it did damage the user namespace, such
72 # quite sure why, but basically it did damage the user namespace, such
73 # that later tests stopped working correctly. Instead we use a simpler
73 # that later tests stopped working correctly. Instead we use a simpler
74 # approach, just computing the list of added keys to the namespace and
74 # approach, just computing the list of added keys to the namespace and
75 # eliminating those afterwards. Existing keys that may have been
75 # eliminating those afterwards. Existing keys that may have been
76 # modified remain modified. So far this has proven to be robust.
76 # modified remain modified. So far this has proven to be robust.
77
77
78 # Compute set of old local/global keys
78 # Compute set of old local/global keys
79 old_locals = set(user_ns.keys())
79 old_locals = set(user_ns.keys())
80 old_globals = set(user_global_ns.keys())
80 old_globals = set(user_global_ns.keys())
81 try:
81 try:
82 out = func()
82 out = func()
83 finally:
83 finally:
84 # Find new keys, and if any, remove them
84 # Find new keys, and if any, remove them
85 new_locals = set(user_ns.keys()) - old_locals
85 new_locals = set(user_ns.keys()) - old_locals
86 new_globals = set(user_global_ns.keys()) - old_globals
86 new_globals = set(user_global_ns.keys()) - old_globals
87 for k in new_locals:
87 for k in new_locals:
88 del user_ns[k]
88 del user_ns[k]
89 for k in new_globals:
89 for k in new_globals:
90 del user_global_ns[k]
90 del user_global_ns[k]
91 return out
91 return out
92
92
93 my_func.__name__ = func.__name__
93 my_func.__name__ = func.__name__
94 return my_func
94 return my_func
95
95
96 #-----------------------------------------------------------------------------
96 #-----------------------------------------------------------------------------
97 # Tests
97 # Tests
98 #-----------------------------------------------------------------------------
98 #-----------------------------------------------------------------------------
99
99
100 @isolate_ipython0
100 @isolate_ipython0
101 def test_execution():
101 def test_execution():
102 """ Test execution of a command.
102 """ Test execution of a command.
103 """
103 """
104 f = TestPrefilterFrontEnd()
104 f = TestPrefilterFrontEnd()
105 f.input_buffer = 'print(1)'
105 f.input_buffer = 'print(1)'
106 f._on_enter()
106 f._on_enter()
107 out_value = f.out.getvalue()
107 out_value = f.out.getvalue()
108 assert_equal(out_value, '1\n')
108 assert_equal(out_value, '1\n')
109
109
110
110
111 @isolate_ipython0
111 @isolate_ipython0
112 def test_multiline():
112 def test_multiline():
113 """ Test execution of a multiline command.
113 """ Test execution of a multiline command.
114 """
114 """
115 f = TestPrefilterFrontEnd()
115 f = TestPrefilterFrontEnd()
116 f.input_buffer = 'if True:'
116 f.input_buffer = 'if True:'
117 f._on_enter()
117 f._on_enter()
118 f.input_buffer += 'print 1'
118 f.input_buffer += 'print 1'
119 f._on_enter()
119 f._on_enter()
120 out_value = f.out.getvalue()
120 out_value = f.out.getvalue()
121 yield assert_equal, out_value, ''
121 yield assert_equal, out_value, ''
122 f._on_enter()
122 f._on_enter()
123 out_value = f.out.getvalue()
123 out_value = f.out.getvalue()
124 yield assert_equal, out_value, '1\n'
124 yield assert_equal, out_value, '1\n'
125 f = TestPrefilterFrontEnd()
125 f = TestPrefilterFrontEnd()
126 f.input_buffer='(1 +'
126 f.input_buffer='(1 +'
127 f._on_enter()
127 f._on_enter()
128 f.input_buffer += '0)'
128 f.input_buffer += '0)'
129 f._on_enter()
129 f._on_enter()
130 out_value = f.out.getvalue()
130 out_value = f.out.getvalue()
131 yield assert_equal, out_value, ''
131 yield assert_equal, out_value, ''
132 f._on_enter()
132 f._on_enter()
133 out_value = f.out.getvalue()
133 out_value = f.out.getvalue()
134 yield assert_equal, out_value, '1\n'
134 yield assert_equal, out_value, '1\n'
135
135
136
136
137 @isolate_ipython0
137 @isolate_ipython0
138 def test_capture():
138 def test_capture():
139 """ Test the capture of output in different channels.
139 """ Test the capture of output in different channels.
140 """
140 """
141 # Test on the OS-level stdout, stderr.
141 # Test on the OS-level stdout, stderr.
142 f = TestPrefilterFrontEnd()
142 f = TestPrefilterFrontEnd()
143 f.input_buffer = \
143 f.input_buffer = \
144 'import os; out=os.fdopen(1, "w"); out.write("1") ; out.flush()'
144 'import os; out=os.fdopen(1, "w"); out.write("1") ; out.flush()'
145 f._on_enter()
145 f._on_enter()
146 out_value = f.out.getvalue()
146 out_value = f.out.getvalue()
147 yield assert_equal, out_value, '1'
147 yield assert_equal, out_value, '1'
148 f = TestPrefilterFrontEnd()
148 f = TestPrefilterFrontEnd()
149 f.input_buffer = \
149 f.input_buffer = \
150 'import os; out=os.fdopen(2, "w"); out.write("1") ; out.flush()'
150 'import os; out=os.fdopen(2, "w"); out.write("1") ; out.flush()'
151 f._on_enter()
151 f._on_enter()
152 out_value = f.out.getvalue()
152 out_value = f.out.getvalue()
153 yield assert_equal, out_value, '1'
153 yield assert_equal, out_value, '1'
154
154
155
155
156 @isolate_ipython0
156 @isolate_ipython0
157 def test_magic():
157 def test_magic():
158 """ Test the magic expansion and history.
158 """ Test the magic expansion and history.
159
159
160 This test is fairly fragile and will break when magics change.
160 This test is fairly fragile and will break when magics change.
161 """
161 """
162 f = TestPrefilterFrontEnd()
162 f = TestPrefilterFrontEnd()
163 # Before checking the interactive namespace, make sure it's clear (it can
163 # Before checking the interactive namespace, make sure it's clear (it can
164 # otherwise pick up things stored in the user's local db)
164 # otherwise pick up things stored in the user's local db)
165 f.input_buffer += '%reset -f'
165 f.input_buffer += '%reset -f'
166 f._on_enter()
166 f._on_enter()
167 f.complete_current_input()
167 f.complete_current_input()
168 # Now, run the %who magic and check output
168 # Now, run the %who magic and check output
169 f.input_buffer += '%who'
169 f.input_buffer += '%who'
170 f._on_enter()
170 f._on_enter()
171 out_value = f.out.getvalue()
171 out_value = f.out.getvalue()
172 assert_equal(out_value, 'In\tOut\tget_ipython\t\n')
172 assert_equal(out_value, 'Interactive namespace is empty.\n')
173
173
174
174
175 @isolate_ipython0
175 @isolate_ipython0
176 def test_help():
176 def test_help():
177 """ Test object inspection.
177 """ Test object inspection.
178 """
178 """
179 f = TestPrefilterFrontEnd()
179 f = TestPrefilterFrontEnd()
180 f.input_buffer += "def f():"
180 f.input_buffer += "def f():"
181 f._on_enter()
181 f._on_enter()
182 f.input_buffer += "'foobar'"
182 f.input_buffer += "'foobar'"
183 f._on_enter()
183 f._on_enter()
184 f.input_buffer += "pass"
184 f.input_buffer += "pass"
185 f._on_enter()
185 f._on_enter()
186 f._on_enter()
186 f._on_enter()
187 f.input_buffer += "f?"
187 f.input_buffer += "f?"
188 f._on_enter()
188 f._on_enter()
189 assert 'traceback' not in f.last_result
189 assert 'traceback' not in f.last_result
190 ## XXX: ipython doctest magic breaks this. I have no clue why
190 ## XXX: ipython doctest magic breaks this. I have no clue why
191 #out_value = f.out.getvalue()
191 #out_value = f.out.getvalue()
192 #assert out_value.split()[-1] == 'foobar'
192 #assert out_value.split()[-1] == 'foobar'
193
193
194
194
195 @isolate_ipython0
195 @isolate_ipython0
196 def test_completion_simple():
196 def test_completion_simple():
197 """ Test command-line completion on trivial examples.
197 """ Test command-line completion on trivial examples.
198 """
198 """
199 f = TestPrefilterFrontEnd()
199 f = TestPrefilterFrontEnd()
200 f.input_buffer = 'zzza = 1'
200 f.input_buffer = 'zzza = 1'
201 f._on_enter()
201 f._on_enter()
202 f.input_buffer = 'zzzb = 2'
202 f.input_buffer = 'zzzb = 2'
203 f._on_enter()
203 f._on_enter()
204 f.input_buffer = 'zz'
204 f.input_buffer = 'zz'
205 f.complete_current_input()
205 f.complete_current_input()
206 out_value = f.out.getvalue()
206 out_value = f.out.getvalue()
207 yield assert_equal, out_value, '\nzzza zzzb '
207 yield assert_equal, out_value, '\nzzza zzzb '
208 yield assert_equal, f.input_buffer, 'zzz'
208 yield assert_equal, f.input_buffer, 'zzz'
209
209
210
210
211 @isolate_ipython0
211 @isolate_ipython0
212 def test_completion_parenthesis():
212 def test_completion_parenthesis():
213 """ Test command-line completion when a parenthesis is open.
213 """ Test command-line completion when a parenthesis is open.
214 """
214 """
215 f = TestPrefilterFrontEnd()
215 f = TestPrefilterFrontEnd()
216 f.input_buffer = 'zzza = 1'
216 f.input_buffer = 'zzza = 1'
217 f._on_enter()
217 f._on_enter()
218 f.input_buffer = 'zzzb = 2'
218 f.input_buffer = 'zzzb = 2'
219 f._on_enter()
219 f._on_enter()
220 f.input_buffer = 'map(zz'
220 f.input_buffer = 'map(zz'
221 f.complete_current_input()
221 f.complete_current_input()
222 out_value = f.out.getvalue()
222 out_value = f.out.getvalue()
223 yield assert_equal, out_value, '\nzzza zzzb '
223 yield assert_equal, out_value, '\nzzza zzzb '
224 yield assert_equal, f.input_buffer, 'map(zzz'
224 yield assert_equal, f.input_buffer, 'map(zzz'
225
225
226
226
227 @isolate_ipython0
227 @isolate_ipython0
228 def test_completion_indexing():
228 def test_completion_indexing():
229 """ Test command-line completion when indexing on objects.
229 """ Test command-line completion when indexing on objects.
230 """
230 """
231 f = TestPrefilterFrontEnd()
231 f = TestPrefilterFrontEnd()
232 f.input_buffer = 'a = [0]'
232 f.input_buffer = 'a = [0]'
233 f._on_enter()
233 f._on_enter()
234 f.input_buffer = 'a[0].'
234 f.input_buffer = 'a[0].'
235 f.complete_current_input()
235 f.complete_current_input()
236
236
237 if sys.version_info[:2] >= (2,6):
237 if sys.version_info[:2] >= (2,6):
238 # In Python 2.6, ints picked up a few non __ methods, so now there are
238 # In Python 2.6, ints picked up a few non __ methods, so now there are
239 # no completions.
239 # no completions.
240 assert_equal(f.input_buffer, 'a[0].')
240 assert_equal(f.input_buffer, 'a[0].')
241 else:
241 else:
242 # Right answer for 2.4/2.5
242 # Right answer for 2.4/2.5
243 assert_equal(f.input_buffer, 'a[0].__')
243 assert_equal(f.input_buffer, 'a[0].__')
244
244
245
245
246 @isolate_ipython0
246 @isolate_ipython0
247 def test_completion_equal():
247 def test_completion_equal():
248 """ Test command-line completion when the delimiter is "=", not " ".
248 """ Test command-line completion when the delimiter is "=", not " ".
249 """
249 """
250 f = TestPrefilterFrontEnd()
250 f = TestPrefilterFrontEnd()
251 f.input_buffer = 'a=1.'
251 f.input_buffer = 'a=1.'
252 f.complete_current_input()
252 f.complete_current_input()
253 if sys.version_info[:2] >= (2,6):
253 if sys.version_info[:2] >= (2,6):
254 # In Python 2.6, ints picked up a few non __ methods, so now there are
254 # In Python 2.6, ints picked up a few non __ methods, so now there are
255 # no completions.
255 # no completions.
256 assert_equal(f.input_buffer, 'a=1.')
256 assert_equal(f.input_buffer, 'a=1.')
257 else:
257 else:
258 # Right answer for 2.4/2.5
258 # Right answer for 2.4/2.5
259 assert_equal(f.input_buffer, 'a=1.__')
259 assert_equal(f.input_buffer, 'a=1.__')
260
260
261
261
262 if __name__ == '__main__':
262 if __name__ == '__main__':
263 test_magic()
263 test_magic()
264 test_help()
264 test_help()
265 test_execution()
265 test_execution()
266 test_multiline()
266 test_multiline()
267 test_capture()
267 test_capture()
268 test_completion_simple()
268 test_completion_simple()
269 test_completion_complex()
269 test_completion_complex()
General Comments 0
You need to be logged in to leave comments. Login now