##// END OF EJS Templates
Fixes to frontend tests....
Fernando Perez -
Show More
@@ -1,280 +1,285 b''
1 """
1 """
2 Frontend class that uses IPython0 to prefilter the inputs.
2 Frontend class that uses IPython0 to prefilter the inputs.
3
3
4 Using the IPython0 mechanism gives us access to the magics.
4 Using the IPython0 mechanism gives us access to the magics.
5
5
6 This is a transitory class, used here to do the transition between
6 This is a transitory class, used here to do the transition between
7 ipython0 and ipython1. This class is meant to be short-lived as more
7 ipython0 and ipython1. This class is meant to be short-lived as more
8 functionnality is abstracted out of ipython0 in reusable functions and
8 functionnality is abstracted out of ipython0 in reusable functions and
9 is added on the interpreter. This class can be a used to guide this
9 is added on the interpreter. This class can be a used to guide this
10 refactoring.
10 refactoring.
11 """
11 """
12 __docformat__ = "restructuredtext en"
12 __docformat__ = "restructuredtext en"
13
13
14 #-------------------------------------------------------------------------------
14 #-------------------------------------------------------------------------------
15 # Copyright (C) 2008 The IPython Development Team
15 # Copyright (C) 2008 The IPython Development Team
16 #
16 #
17 # Distributed under the terms of the BSD License. The full license is in
17 # Distributed under the terms of the BSD License. The full license is in
18 # the file COPYING, distributed as part of this software.
18 # the file COPYING, distributed as part of this software.
19 #-------------------------------------------------------------------------------
19 #-------------------------------------------------------------------------------
20
20
21 #-------------------------------------------------------------------------------
21 #-------------------------------------------------------------------------------
22 # Imports
22 # Imports
23 #-------------------------------------------------------------------------------
23 #-------------------------------------------------------------------------------
24 import sys
24 import sys
25 import pydoc
25 import pydoc
26 import os
26 import os
27 import re
27 import re
28 import __builtin__
28 import __builtin__
29
29
30 from IPython.ipmaker import make_IPython
30 from IPython.ipmaker import make_IPython
31 from IPython.ipapi import IPApi
31 from IPython.ipapi import IPApi
32 from IPython.kernel.core.redirector_output_trap import RedirectorOutputTrap
32 from IPython.kernel.core.redirector_output_trap import RedirectorOutputTrap
33
33
34 from IPython.kernel.core.sync_traceback_trap import SyncTracebackTrap
34 from IPython.kernel.core.sync_traceback_trap import SyncTracebackTrap
35
35
36 from IPython.genutils import Term
36 from IPython.genutils import Term
37
37
38 from linefrontendbase import LineFrontEndBase, common_prefix
38 from linefrontendbase import LineFrontEndBase, common_prefix
39
39
40
40
41 def mk_system_call(system_call_function, command):
41 def mk_system_call(system_call_function, command):
42 """ given a os.system replacement, and a leading string command,
42 """ given a os.system replacement, and a leading string command,
43 returns a function that will execute the command with the given
43 returns a function that will execute the command with the given
44 argument string.
44 argument string.
45 """
45 """
46 def my_system_call(args):
46 def my_system_call(args):
47 system_call_function("%s %s" % (command, args))
47 system_call_function("%s %s" % (command, args))
48
48
49 my_system_call.__doc__ = "Calls %s" % command
49 my_system_call.__doc__ = "Calls %s" % command
50 return my_system_call
50 return my_system_call
51
51
52 #-------------------------------------------------------------------------------
52 #-------------------------------------------------------------------------------
53 # Frontend class using ipython0 to do the prefiltering.
53 # Frontend class using ipython0 to do the prefiltering.
54 #-------------------------------------------------------------------------------
54 #-------------------------------------------------------------------------------
55 class PrefilterFrontEnd(LineFrontEndBase):
55 class PrefilterFrontEnd(LineFrontEndBase):
56 """ Class that uses ipython0 to do prefilter the input, do the
56 """ Class that uses ipython0 to do prefilter the input, do the
57 completion and the magics.
57 completion and the magics.
58
58
59 The core trick is to use an ipython0 instance to prefilter the
59 The core trick is to use an ipython0 instance to prefilter the
60 input, and share the namespace between the interpreter instance used
60 input, and share the namespace between the interpreter instance used
61 to execute the statements and the ipython0 used for code
61 to execute the statements and the ipython0 used for code
62 completion...
62 completion...
63 """
63 """
64
64
65 debug = False
65 debug = False
66
66
67 def __init__(self, ipython0=None, *args, **kwargs):
67 def __init__(self, ipython0=None, argv=None, *args, **kwargs):
68 """ Parameters:
68 """ Parameters:
69 -----------
69 -----------
70
70
71 ipython0: an optional ipython0 instance to use for command
71 ipython0: an optional ipython0 instance to use for command
72 prefiltering and completion.
72 prefiltering and completion.
73
74 argv : list, optional
75 Used as the instance's argv value. If not given, [] is used.
73 """
76 """
77 if argv is None:
78 argv = []
74 # This is a hack to avoid the IPython exception hook to trigger
79 # This is a hack to avoid the IPython exception hook to trigger
75 # on exceptions (https://bugs.launchpad.net/bugs/337105)
80 # on exceptions (https://bugs.launchpad.net/bugs/337105)
76 # XXX: This is horrible: module-leve monkey patching -> side
81 # XXX: This is horrible: module-leve monkey patching -> side
77 # effects.
82 # effects.
78 from IPython import iplib
83 from IPython import iplib
79 iplib.InteractiveShell.isthreaded = True
84 iplib.InteractiveShell.isthreaded = True
80
85
81 LineFrontEndBase.__init__(self, *args, **kwargs)
86 LineFrontEndBase.__init__(self, *args, **kwargs)
82 self.shell.output_trap = RedirectorOutputTrap(
87 self.shell.output_trap = RedirectorOutputTrap(
83 out_callback=self.write,
88 out_callback=self.write,
84 err_callback=self.write,
89 err_callback=self.write,
85 )
90 )
86 self.shell.traceback_trap = SyncTracebackTrap(
91 self.shell.traceback_trap = SyncTracebackTrap(
87 formatters=self.shell.traceback_trap.formatters,
92 formatters=self.shell.traceback_trap.formatters,
88 )
93 )
89
94
90 # Start the ipython0 instance:
95 # Start the ipython0 instance:
91 self.save_output_hooks()
96 self.save_output_hooks()
92 if ipython0 is None:
97 if ipython0 is None:
93 # Instanciate an IPython0 interpreter to be able to use the
98 # Instanciate an IPython0 interpreter to be able to use the
94 # prefiltering.
99 # prefiltering.
95 # Suppress all key input, to avoid waiting
100 # Suppress all key input, to avoid waiting
96 def my_rawinput(x=None):
101 def my_rawinput(x=None):
97 return '\n'
102 return '\n'
98 old_rawinput = __builtin__.raw_input
103 old_rawinput = __builtin__.raw_input
99 __builtin__.raw_input = my_rawinput
104 __builtin__.raw_input = my_rawinput
100 # XXX: argv=[] is a bit bold.
105 # XXX: argv=[] is a bit bold.
101 ipython0 = make_IPython(argv=[],
106 ipython0 = make_IPython(argv=argv,
102 user_ns=self.shell.user_ns,
107 user_ns=self.shell.user_ns,
103 user_global_ns=self.shell.user_global_ns)
108 user_global_ns=self.shell.user_global_ns)
104 __builtin__.raw_input = old_rawinput
109 __builtin__.raw_input = old_rawinput
105 self.ipython0 = ipython0
110 self.ipython0 = ipython0
106 # Set the pager:
111 # Set the pager:
107 self.ipython0.set_hook('show_in_pager',
112 self.ipython0.set_hook('show_in_pager',
108 lambda s, string: self.write("\n" + string))
113 lambda s, string: self.write("\n" + string))
109 self.ipython0.write = self.write
114 self.ipython0.write = self.write
110 self._ip = _ip = IPApi(self.ipython0)
115 self._ip = _ip = IPApi(self.ipython0)
111 # Make sure the raw system call doesn't get called, as we don't
116 # Make sure the raw system call doesn't get called, as we don't
112 # have a stdin accessible.
117 # have a stdin accessible.
113 self._ip.system = self.system_call
118 self._ip.system = self.system_call
114 # XXX: Muck around with magics so that they work better
119 # XXX: Muck around with magics so that they work better
115 # in our environment
120 # in our environment
116 if not sys.platform.startswith('win'):
121 if not sys.platform.startswith('win'):
117 self.ipython0.magic_ls = mk_system_call(self.system_call,
122 self.ipython0.magic_ls = mk_system_call(self.system_call,
118 'ls -CF')
123 'ls -CF')
119 # And now clean up the mess created by ipython0
124 # And now clean up the mess created by ipython0
120 self.release_output()
125 self.release_output()
121
126
122
127
123 if not 'banner' in kwargs and self.banner is None:
128 if not 'banner' in kwargs and self.banner is None:
124 self.banner = self.ipython0.BANNER
129 self.banner = self.ipython0.BANNER
125
130
126 # FIXME: __init__ and start should be two different steps
131 # FIXME: __init__ and start should be two different steps
127 self.start()
132 self.start()
128
133
129 #--------------------------------------------------------------------------
134 #--------------------------------------------------------------------------
130 # FrontEndBase interface
135 # FrontEndBase interface
131 #--------------------------------------------------------------------------
136 #--------------------------------------------------------------------------
132
137
133 def show_traceback(self):
138 def show_traceback(self):
134 """ Use ipython0 to capture the last traceback and display it.
139 """ Use ipython0 to capture the last traceback and display it.
135 """
140 """
136 # Don't do the capture; the except_hook has already done some
141 # Don't do the capture; the except_hook has already done some
137 # modifications to the IO streams, if we store them, we'll be
142 # modifications to the IO streams, if we store them, we'll be
138 # storing the wrong ones.
143 # storing the wrong ones.
139 #self.capture_output()
144 #self.capture_output()
140 self.ipython0.showtraceback(tb_offset=-1)
145 self.ipython0.showtraceback(tb_offset=-1)
141 self.release_output()
146 self.release_output()
142
147
143
148
144 def execute(self, python_string, raw_string=None):
149 def execute(self, python_string, raw_string=None):
145 if self.debug:
150 if self.debug:
146 print 'Executing Python code:', repr(python_string)
151 print 'Executing Python code:', repr(python_string)
147 self.capture_output()
152 self.capture_output()
148 LineFrontEndBase.execute(self, python_string,
153 LineFrontEndBase.execute(self, python_string,
149 raw_string=raw_string)
154 raw_string=raw_string)
150 self.release_output()
155 self.release_output()
151
156
152
157
153 def save_output_hooks(self):
158 def save_output_hooks(self):
154 """ Store all the output hooks we can think of, to be able to
159 """ Store all the output hooks we can think of, to be able to
155 restore them.
160 restore them.
156
161
157 We need to do this early, as starting the ipython0 instance will
162 We need to do this early, as starting the ipython0 instance will
158 screw ouput hooks.
163 screw ouput hooks.
159 """
164 """
160 self.__old_cout_write = Term.cout.write
165 self.__old_cout_write = Term.cout.write
161 self.__old_cerr_write = Term.cerr.write
166 self.__old_cerr_write = Term.cerr.write
162 self.__old_stdout = sys.stdout
167 self.__old_stdout = sys.stdout
163 self.__old_stderr= sys.stderr
168 self.__old_stderr= sys.stderr
164 self.__old_help_output = pydoc.help.output
169 self.__old_help_output = pydoc.help.output
165 self.__old_display_hook = sys.displayhook
170 self.__old_display_hook = sys.displayhook
166
171
167
172
168 def capture_output(self):
173 def capture_output(self):
169 """ Capture all the output mechanisms we can think of.
174 """ Capture all the output mechanisms we can think of.
170 """
175 """
171 self.save_output_hooks()
176 self.save_output_hooks()
172 Term.cout.write = self.write
177 Term.cout.write = self.write
173 Term.cerr.write = self.write
178 Term.cerr.write = self.write
174 sys.stdout = Term.cout
179 sys.stdout = Term.cout
175 sys.stderr = Term.cerr
180 sys.stderr = Term.cerr
176 pydoc.help.output = self.shell.output_trap.out
181 pydoc.help.output = self.shell.output_trap.out
177
182
178
183
179 def release_output(self):
184 def release_output(self):
180 """ Release all the different captures we have made.
185 """ Release all the different captures we have made.
181 """
186 """
182 Term.cout.write = self.__old_cout_write
187 Term.cout.write = self.__old_cout_write
183 Term.cerr.write = self.__old_cerr_write
188 Term.cerr.write = self.__old_cerr_write
184 sys.stdout = self.__old_stdout
189 sys.stdout = self.__old_stdout
185 sys.stderr = self.__old_stderr
190 sys.stderr = self.__old_stderr
186 pydoc.help.output = self.__old_help_output
191 pydoc.help.output = self.__old_help_output
187 sys.displayhook = self.__old_display_hook
192 sys.displayhook = self.__old_display_hook
188
193
189
194
190 def complete(self, line):
195 def complete(self, line):
191 # FIXME: This should be factored out in the linefrontendbase
196 # FIXME: This should be factored out in the linefrontendbase
192 # method.
197 # method.
193 word = self._get_completion_text(line)
198 word = self._get_completion_text(line)
194 completions = self.ipython0.complete(word)
199 completions = self.ipython0.complete(word)
195 # FIXME: The proper sort should be done in the complete method.
200 # FIXME: The proper sort should be done in the complete method.
196 key = lambda x: x.replace('_', '')
201 key = lambda x: x.replace('_', '')
197 completions.sort(key=key)
202 completions.sort(key=key)
198 if completions:
203 if completions:
199 prefix = common_prefix(completions)
204 prefix = common_prefix(completions)
200 line = line[:-len(word)] + prefix
205 line = line[:-len(word)] + prefix
201 return line, completions
206 return line, completions
202
207
203
208
204 #--------------------------------------------------------------------------
209 #--------------------------------------------------------------------------
205 # LineFrontEndBase interface
210 # LineFrontEndBase interface
206 #--------------------------------------------------------------------------
211 #--------------------------------------------------------------------------
207
212
208 def prefilter_input(self, input_string):
213 def prefilter_input(self, input_string):
209 """ Using IPython0 to prefilter the commands to turn them
214 """ Using IPython0 to prefilter the commands to turn them
210 in executable statements that are valid Python strings.
215 in executable statements that are valid Python strings.
211 """
216 """
212 input_string = LineFrontEndBase.prefilter_input(self, input_string)
217 input_string = LineFrontEndBase.prefilter_input(self, input_string)
213 filtered_lines = []
218 filtered_lines = []
214 # The IPython0 prefilters sometime produce output. We need to
219 # The IPython0 prefilters sometime produce output. We need to
215 # capture it.
220 # capture it.
216 self.capture_output()
221 self.capture_output()
217 self.last_result = dict(number=self.prompt_number)
222 self.last_result = dict(number=self.prompt_number)
218
223
219 ## try:
224 ## try:
220 ## for line in input_string.split('\n'):
225 ## for line in input_string.split('\n'):
221 ## filtered_lines.append(
226 ## filtered_lines.append(
222 ## self.ipython0.prefilter(line, False).rstrip())
227 ## self.ipython0.prefilter(line, False).rstrip())
223 ## except:
228 ## except:
224 ## # XXX: probably not the right thing to do.
229 ## # XXX: probably not the right thing to do.
225 ## self.ipython0.showsyntaxerror()
230 ## self.ipython0.showsyntaxerror()
226 ## self.after_execute()
231 ## self.after_execute()
227 ## finally:
232 ## finally:
228 ## self.release_output()
233 ## self.release_output()
229
234
230
235
231 try:
236 try:
232 try:
237 try:
233 for line in input_string.split('\n'):
238 for line in input_string.split('\n'):
234 filtered_lines.append(
239 filtered_lines.append(
235 self.ipython0.prefilter(line, False).rstrip())
240 self.ipython0.prefilter(line, False).rstrip())
236 except:
241 except:
237 # XXX: probably not the right thing to do.
242 # XXX: probably not the right thing to do.
238 self.ipython0.showsyntaxerror()
243 self.ipython0.showsyntaxerror()
239 self.after_execute()
244 self.after_execute()
240 finally:
245 finally:
241 self.release_output()
246 self.release_output()
242
247
243
248
244
249
245 # Clean up the trailing whitespace, to avoid indentation errors
250 # Clean up the trailing whitespace, to avoid indentation errors
246 filtered_string = '\n'.join(filtered_lines)
251 filtered_string = '\n'.join(filtered_lines)
247 return filtered_string
252 return filtered_string
248
253
249
254
250 #--------------------------------------------------------------------------
255 #--------------------------------------------------------------------------
251 # PrefilterFrontEnd interface
256 # PrefilterFrontEnd interface
252 #--------------------------------------------------------------------------
257 #--------------------------------------------------------------------------
253
258
254 def system_call(self, command_string):
259 def system_call(self, command_string):
255 """ Allows for frontend to define their own system call, to be
260 """ Allows for frontend to define their own system call, to be
256 able capture output and redirect input.
261 able capture output and redirect input.
257 """
262 """
258 return os.system(command_string)
263 return os.system(command_string)
259
264
260
265
261 def do_exit(self):
266 def do_exit(self):
262 """ Exit the shell, cleanup and save the history.
267 """ Exit the shell, cleanup and save the history.
263 """
268 """
264 self.ipython0.atexit_operations()
269 self.ipython0.atexit_operations()
265
270
266
271
267 def _get_completion_text(self, line):
272 def _get_completion_text(self, line):
268 """ Returns the text to be completed by breaking the line at specified
273 """ Returns the text to be completed by breaking the line at specified
269 delimiters.
274 delimiters.
270 """
275 """
271 # Break at: spaces, '=', all parentheses (except if balanced).
276 # Break at: spaces, '=', all parentheses (except if balanced).
272 # FIXME2: In the future, we need to make the implementation similar to
277 # FIXME2: In the future, we need to make the implementation similar to
273 # that in the 'pyreadline' module (modes/basemode.py) where we break at
278 # that in the 'pyreadline' module (modes/basemode.py) where we break at
274 # each delimiter and try to complete the residual line, until we get a
279 # each delimiter and try to complete the residual line, until we get a
275 # successful list of completions.
280 # successful list of completions.
276 expression = '\s|=|,|:|\((?!.*\))|\[(?!.*\])|\{(?!.*\})'
281 expression = '\s|=|,|:|\((?!.*\))|\[(?!.*\])|\{(?!.*\})'
277 complete_sep = re.compile(expression)
282 complete_sep = re.compile(expression)
278 text = complete_sep.split(line)[-1]
283 text = complete_sep.split(line)[-1]
279 return text
284 return text
280
285
@@ -1,244 +1,252 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 cStringIO import StringIO
16 from cStringIO import StringIO
16 import string
17 import string
17
18
18 from nose.tools import assert_equal
19 from nose.tools import assert_equal
19
20
20 from IPython.ipapi import get as get_ipython0
21 from IPython.frontend.prefilterfrontend import PrefilterFrontEnd
21 from IPython.frontend.prefilterfrontend import PrefilterFrontEnd
22 from copy import copy, deepcopy
22 from IPython.ipapi import get as get_ipython0
23 from IPython.testing.plugin.ipdoctest import default_argv
24
23
25
24 def safe_deepcopy(d):
26 def safe_deepcopy(d):
25 """ Deep copy every key of the given dict, when possible. Elsewhere
27 """ Deep copy every key of the given dict, when possible. Elsewhere
26 do a copy.
28 do a copy.
27 """
29 """
28 copied_d = dict()
30 copied_d = dict()
29 for key, value in d.iteritems():
31 for key, value in d.iteritems():
30 try:
32 try:
31 copied_d[key] = deepcopy(value)
33 copied_d[key] = deepcopy(value)
32 except:
34 except:
33 try:
35 try:
34 copied_d[key] = copy(value)
36 copied_d[key] = copy(value)
35 except:
37 except:
36 copied_d[key] = value
38 copied_d[key] = value
37 return copied_d
39 return copied_d
38
40
39
41
40 class TestPrefilterFrontEnd(PrefilterFrontEnd):
42 class TestPrefilterFrontEnd(PrefilterFrontEnd):
41
43
42 input_prompt_template = string.Template('')
44 input_prompt_template = string.Template('')
43 output_prompt_template = string.Template('')
45 output_prompt_template = string.Template('')
44 banner = ''
46 banner = ''
45
47
46 def __init__(self):
48 def __init__(self):
47 self.out = StringIO()
49 self.out = StringIO()
48 PrefilterFrontEnd.__init__(self)
50 PrefilterFrontEnd.__init__(self,argv=default_argv())
49 # Some more code for isolation (yeah, crazy)
51 # Some more code for isolation (yeah, crazy)
50 self._on_enter()
52 self._on_enter()
51 self.out.flush()
53 self.out.flush()
52 self.out.reset()
54 self.out.reset()
53 self.out.truncate()
55 self.out.truncate()
54
56
55 def write(self, string, *args, **kwargs):
57 def write(self, string, *args, **kwargs):
56 self.out.write(string)
58 self.out.write(string)
57
59
58 def _on_enter(self):
60 def _on_enter(self):
59 self.input_buffer += '\n'
61 self.input_buffer += '\n'
60 PrefilterFrontEnd._on_enter(self)
62 PrefilterFrontEnd._on_enter(self)
61
63
62
64
63 def isolate_ipython0(func):
65 def isolate_ipython0(func):
64 """ Decorator to isolate execution that involves an iptyhon0.
66 """ Decorator to isolate execution that involves an iptyhon0.
65
67
66 Notes
68 Notes
67 ------
69 -----
68
70
69 Apply only to functions with no arguments. Nose skips functions
71 Apply only to functions with no arguments. Nose skips functions
70 with arguments.
72 with arguments.
71 """
73 """
72 def my_func():
74 def my_func():
73 iplib = get_ipython0()
75 iplib = get_ipython0()
74 if iplib is None:
76 if iplib is None:
75 return func()
77 return func()
76 ipython0 = iplib.IP
78 ipython0 = iplib.IP
77 global_ns = safe_deepcopy(ipython0.user_global_ns)
79 global_ns = safe_deepcopy(ipython0.user_global_ns)
78 user_ns = safe_deepcopy(ipython0.user_ns)
80 user_ns = safe_deepcopy(ipython0.user_ns)
79 try:
81 try:
80 out = func()
82 out = func()
81 finally:
83 finally:
82 ipython0.user_ns = user_ns
84 ipython0.user_ns = user_ns
83 ipython0.user_global_ns = global_ns
85 ipython0.user_global_ns = global_ns
84 # Undo the hack at creation of PrefilterFrontEnd
86 # Undo the hack at creation of PrefilterFrontEnd
85 from IPython import iplib
87 from IPython import iplib
86 iplib.InteractiveShell.isthreaded = False
88 iplib.InteractiveShell.isthreaded = False
87 return out
89 return out
88
90
89 my_func.__name__ = func.__name__
91 my_func.__name__ = func.__name__
90 return my_func
92 return my_func
91
93
92
94
93 @isolate_ipython0
95 @isolate_ipython0
94 def test_execution():
96 def test_execution():
95 """ Test execution of a command.
97 """ Test execution of a command.
96 """
98 """
97 f = TestPrefilterFrontEnd()
99 f = TestPrefilterFrontEnd()
98 f.input_buffer = 'print 1'
100 f.input_buffer = 'print 1'
99 f._on_enter()
101 f._on_enter()
100 out_value = f.out.getvalue()
102 out_value = f.out.getvalue()
101 assert_equal(out_value, '1\n')
103 assert_equal(out_value, '1\n')
102
104
103
105
104 @isolate_ipython0
106 @isolate_ipython0
105 def test_multiline():
107 def test_multiline():
106 """ Test execution of a multiline command.
108 """ Test execution of a multiline command.
107 """
109 """
108 f = TestPrefilterFrontEnd()
110 f = TestPrefilterFrontEnd()
109 f.input_buffer = 'if True:'
111 f.input_buffer = 'if True:'
110 f._on_enter()
112 f._on_enter()
111 f.input_buffer += 'print 1'
113 f.input_buffer += 'print 1'
112 f._on_enter()
114 f._on_enter()
113 out_value = f.out.getvalue()
115 out_value = f.out.getvalue()
114 yield assert_equal, out_value, ''
116 yield assert_equal, out_value, ''
115 f._on_enter()
117 f._on_enter()
116 out_value = f.out.getvalue()
118 out_value = f.out.getvalue()
117 yield assert_equal, out_value, '1\n'
119 yield assert_equal, out_value, '1\n'
118 f = TestPrefilterFrontEnd()
120 f = TestPrefilterFrontEnd()
119 f.input_buffer='(1 +'
121 f.input_buffer='(1 +'
120 f._on_enter()
122 f._on_enter()
121 f.input_buffer += '0)'
123 f.input_buffer += '0)'
122 f._on_enter()
124 f._on_enter()
123 out_value = f.out.getvalue()
125 out_value = f.out.getvalue()
124 yield assert_equal, out_value, ''
126 yield assert_equal, out_value, ''
125 f._on_enter()
127 f._on_enter()
126 out_value = f.out.getvalue()
128 out_value = f.out.getvalue()
127 yield assert_equal, out_value, '1\n'
129 yield assert_equal, out_value, '1\n'
128
130
129
131
130 @isolate_ipython0
132 @isolate_ipython0
131 def test_capture():
133 def test_capture():
132 """ Test the capture of output in different channels.
134 """ Test the capture of output in different channels.
133 """
135 """
134 # Test on the OS-level stdout, stderr.
136 # Test on the OS-level stdout, stderr.
135 f = TestPrefilterFrontEnd()
137 f = TestPrefilterFrontEnd()
136 f.input_buffer = \
138 f.input_buffer = \
137 'import os; out=os.fdopen(1, "w"); out.write("1") ; out.flush()'
139 'import os; out=os.fdopen(1, "w"); out.write("1") ; out.flush()'
138 f._on_enter()
140 f._on_enter()
139 out_value = f.out.getvalue()
141 out_value = f.out.getvalue()
140 yield assert_equal, out_value, '1'
142 yield assert_equal, out_value, '1'
141 f = TestPrefilterFrontEnd()
143 f = TestPrefilterFrontEnd()
142 f.input_buffer = \
144 f.input_buffer = \
143 'import os; out=os.fdopen(2, "w"); out.write("1") ; out.flush()'
145 'import os; out=os.fdopen(2, "w"); out.write("1") ; out.flush()'
144 f._on_enter()
146 f._on_enter()
145 out_value = f.out.getvalue()
147 out_value = f.out.getvalue()
146 yield assert_equal, out_value, '1'
148 yield assert_equal, out_value, '1'
147
149
148
150
149 @isolate_ipython0
151 @isolate_ipython0
150 def test_magic():
152 def test_magic():
151 """ Test the magic expansion and history.
153 """ Test the magic expansion and history.
152
154
153 This test is fairly fragile and will break when magics change.
155 This test is fairly fragile and will break when magics change.
154 """
156 """
155 f = TestPrefilterFrontEnd()
157 f = TestPrefilterFrontEnd()
158 # Before checking the interactive namespace, make sure it's clear (it can
159 # otherwise pick up things stored in the user's local db)
160 f.input_buffer += '%reset -f'
161 f._on_enter()
162 f.complete_current_input()
163 # Now, run the %who magic and check output
156 f.input_buffer += '%who'
164 f.input_buffer += '%who'
157 f._on_enter()
165 f._on_enter()
158 out_value = f.out.getvalue()
166 out_value = f.out.getvalue()
159 assert_equal(out_value, 'Interactive namespace is empty.\n')
167 assert_equal(out_value, 'Interactive namespace is empty.\n')
160
168
161
169
162 @isolate_ipython0
170 @isolate_ipython0
163 def test_help():
171 def test_help():
164 """ Test object inspection.
172 """ Test object inspection.
165 """
173 """
166 f = TestPrefilterFrontEnd()
174 f = TestPrefilterFrontEnd()
167 f.input_buffer += "def f():"
175 f.input_buffer += "def f():"
168 f._on_enter()
176 f._on_enter()
169 f.input_buffer += "'foobar'"
177 f.input_buffer += "'foobar'"
170 f._on_enter()
178 f._on_enter()
171 f.input_buffer += "pass"
179 f.input_buffer += "pass"
172 f._on_enter()
180 f._on_enter()
173 f._on_enter()
181 f._on_enter()
174 f.input_buffer += "f?"
182 f.input_buffer += "f?"
175 f._on_enter()
183 f._on_enter()
176 assert 'traceback' not in f.last_result
184 assert 'traceback' not in f.last_result
177 ## XXX: ipython doctest magic breaks this. I have no clue why
185 ## XXX: ipython doctest magic breaks this. I have no clue why
178 #out_value = f.out.getvalue()
186 #out_value = f.out.getvalue()
179 #assert out_value.split()[-1] == 'foobar'
187 #assert out_value.split()[-1] == 'foobar'
180
188
181
189
182 @isolate_ipython0
190 @isolate_ipython0
183 def test_completion_simple():
191 def test_completion_simple():
184 """ Test command-line completion on trivial examples.
192 """ Test command-line completion on trivial examples.
185 """
193 """
186 f = TestPrefilterFrontEnd()
194 f = TestPrefilterFrontEnd()
187 f.input_buffer = 'zzza = 1'
195 f.input_buffer = 'zzza = 1'
188 f._on_enter()
196 f._on_enter()
189 f.input_buffer = 'zzzb = 2'
197 f.input_buffer = 'zzzb = 2'
190 f._on_enter()
198 f._on_enter()
191 f.input_buffer = 'zz'
199 f.input_buffer = 'zz'
192 f.complete_current_input()
200 f.complete_current_input()
193 out_value = f.out.getvalue()
201 out_value = f.out.getvalue()
194 yield assert_equal, out_value, '\nzzza zzzb '
202 yield assert_equal, out_value, '\nzzza zzzb '
195 yield assert_equal, f.input_buffer, 'zzz'
203 yield assert_equal, f.input_buffer, 'zzz'
196
204
197
205
198 @isolate_ipython0
206 @isolate_ipython0
199 def test_completion_parenthesis():
207 def test_completion_parenthesis():
200 """ Test command-line completion when a parenthesis is open.
208 """ Test command-line completion when a parenthesis is open.
201 """
209 """
202 f = TestPrefilterFrontEnd()
210 f = TestPrefilterFrontEnd()
203 f.input_buffer = 'zzza = 1'
211 f.input_buffer = 'zzza = 1'
204 f._on_enter()
212 f._on_enter()
205 f.input_buffer = 'zzzb = 2'
213 f.input_buffer = 'zzzb = 2'
206 f._on_enter()
214 f._on_enter()
207 f.input_buffer = 'map(zz'
215 f.input_buffer = 'map(zz'
208 f.complete_current_input()
216 f.complete_current_input()
209 out_value = f.out.getvalue()
217 out_value = f.out.getvalue()
210 yield assert_equal, out_value, '\nzzza zzzb '
218 yield assert_equal, out_value, '\nzzza zzzb '
211 yield assert_equal, f.input_buffer, 'map(zzz'
219 yield assert_equal, f.input_buffer, 'map(zzz'
212
220
213
221
214 @isolate_ipython0
222 @isolate_ipython0
215 def test_completion_indexing():
223 def test_completion_indexing():
216 """ Test command-line completion when indexing on objects.
224 """ Test command-line completion when indexing on objects.
217 """
225 """
218 f = TestPrefilterFrontEnd()
226 f = TestPrefilterFrontEnd()
219 f.input_buffer = 'a = [0]'
227 f.input_buffer = 'a = [0]'
220 f._on_enter()
228 f._on_enter()
221 f.input_buffer = 'a[0].'
229 f.input_buffer = 'a[0].'
222 f.complete_current_input()
230 f.complete_current_input()
223 assert_equal(f.input_buffer, 'a[0].__')
231 assert_equal(f.input_buffer, 'a[0].__')
224
232
225
233
226 @isolate_ipython0
234 @isolate_ipython0
227 def test_completion_equal():
235 def test_completion_equal():
228 """ Test command-line completion when the delimiter is "=", not " ".
236 """ Test command-line completion when the delimiter is "=", not " ".
229 """
237 """
230 f = TestPrefilterFrontEnd()
238 f = TestPrefilterFrontEnd()
231 f.input_buffer = 'a=1.'
239 f.input_buffer = 'a=1.'
232 f.complete_current_input()
240 f.complete_current_input()
233 assert_equal(f.input_buffer, 'a=1.__')
241 assert_equal(f.input_buffer, 'a=1.__')
234
242
235
243
236
244
237 if __name__ == '__main__':
245 if __name__ == '__main__':
238 test_magic()
246 test_magic()
239 test_help()
247 test_help()
240 test_execution()
248 test_execution()
241 test_multiline()
249 test_multiline()
242 test_capture()
250 test_capture()
243 test_completion_simple()
251 test_completion_simple()
244 test_completion_complex()
252 test_completion_complex()
General Comments 0
You need to be logged in to leave comments. Login now