##// END OF EJS Templates
Better code isolation in tests.
Gael Varoquaux -
Show More
@@ -1,177 +1,180 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 cStringIO import StringIO
15 from cStringIO import StringIO
16 import string
16 import string
17
17
18 from IPython.ipapi import get as get_ipython0
18 from IPython.ipapi import get as get_ipython0
19 from IPython.frontend.prefilterfrontend import PrefilterFrontEnd
19 from IPython.frontend.prefilterfrontend import PrefilterFrontEnd
20 from copy import deepcopy
20
21
21 class TestPrefilterFrontEnd(PrefilterFrontEnd):
22 class TestPrefilterFrontEnd(PrefilterFrontEnd):
22
23
23 input_prompt_template = string.Template('')
24 input_prompt_template = string.Template('')
24 output_prompt_template = string.Template('')
25 output_prompt_template = string.Template('')
25 banner = ''
26 banner = ''
26
27
27 def __init__(self):
28 def __init__(self):
28 ipython0 = get_ipython0().IP
29 ipython0 = get_ipython0().IP
29 self.out = StringIO()
30 self.out = StringIO()
30 PrefilterFrontEnd.__init__(self, ipython0=ipython0)
31 PrefilterFrontEnd.__init__(self, ipython0=ipython0)
31 # Clean up the namespace for isolation between tests
32 # Clean up the namespace for isolation between tests
32 user_ns = self.ipython0.user_ns
33 user_ns = self.ipython0.user_ns
33 # We need to keep references to things so that they don't
34 # We need to keep references to things so that they don't
34 # get garbage collected (this stinks).
35 # get garbage collected (this stinks).
35 self.shadow_ns = dict()
36 self.shadow_ns = dict()
36 for i in self.ipython0.magic_who_ls():
37 for i in self.ipython0.magic_who_ls():
37 self.shadow_ns[i] = user_ns.pop(i)
38 self.shadow_ns[i] = user_ns.pop(i)
38 # Some more code for isolation (yeah, crazy)
39 # Some more code for isolation (yeah, crazy)
39 self._on_enter()
40 self._on_enter()
40 self.out.flush()
41 self.out.flush()
41 self.out.reset()
42 self.out.reset()
42 self.out.truncate()
43 self.out.truncate()
43
44
44 def write(self, string, *args, **kwargs):
45 def write(self, string, *args, **kwargs):
45 self.out.write(string)
46 self.out.write(string)
46
47
47 def _on_enter(self):
48 def _on_enter(self):
48 self.input_buffer += '\n'
49 self.input_buffer += '\n'
49 PrefilterFrontEnd._on_enter(self)
50 PrefilterFrontEnd._on_enter(self)
50
51
51
52
52 def isolate_ipython0(func):
53 def isolate_ipython0(func):
53 """ Decorator to isolate execution that involves an iptyhon0.
54 """ Decorator to isolate execution that involves an iptyhon0.
54 """
55 """
55 def my_func(*args, **kwargs):
56 def my_func(*args, **kwargs):
56 ipython0 = get_ipython0().IP
57 ipython0 = get_ipython0().IP
57 user_ns = ipython0.user_ns
58 user_ns = deepcopy(ipython0.user_ns)
58 global_ns = ipython0.global_ns
59 global_ns = deepcopy(ipython0.global_ns)
59 func(*args, **kwargs)
60 try:
60 ipython0.user_ns = user_ns
61 func(*args, **kwargs)
61 ipython0.global_ns = global_ns
62 finally:
63 ipython0.user_ns = user_ns
64 ipython0.global_ns = global_ns
62
65
63 return my_func
66 return my_func
64
67
65
68
66 @isolate_ipython0
69 @isolate_ipython0
67 def test_execution():
70 def test_execution():
68 """ Test execution of a command.
71 """ Test execution of a command.
69 """
72 """
70 f = TestPrefilterFrontEnd()
73 f = TestPrefilterFrontEnd()
71 f.input_buffer = 'print 1'
74 f.input_buffer = 'print 1'
72 f._on_enter()
75 f._on_enter()
73 out_value = f.out.getvalue()
76 out_value = f.out.getvalue()
74 assert out_value == '1\n'
77 assert out_value == '1\n'
75
78
76
79
77 @isolate_ipython0
80 @isolate_ipython0
78 def test_multiline():
81 def test_multiline():
79 """ Test execution of a multiline command.
82 """ Test execution of a multiline command.
80 """
83 """
81 f = TestPrefilterFrontEnd()
84 f = TestPrefilterFrontEnd()
82 f.input_buffer = 'if True:'
85 f.input_buffer = 'if True:'
83 f._on_enter()
86 f._on_enter()
84 f.input_buffer += 'print 1'
87 f.input_buffer += 'print 1'
85 f._on_enter()
88 f._on_enter()
86 out_value = f.out.getvalue()
89 out_value = f.out.getvalue()
87 assert out_value == ''
90 assert out_value == ''
88 f._on_enter()
91 f._on_enter()
89 out_value = f.out.getvalue()
92 out_value = f.out.getvalue()
90 assert out_value == '1\n'
93 assert out_value == '1\n'
91 f = TestPrefilterFrontEnd()
94 f = TestPrefilterFrontEnd()
92 f.input_buffer='(1 +'
95 f.input_buffer='(1 +'
93 f._on_enter()
96 f._on_enter()
94 f.input_buffer += '0)'
97 f.input_buffer += '0)'
95 f._on_enter()
98 f._on_enter()
96 out_value = f.out.getvalue()
99 out_value = f.out.getvalue()
97 assert out_value == ''
100 assert out_value == ''
98 f._on_enter()
101 f._on_enter()
99 out_value = f.out.getvalue()
102 out_value = f.out.getvalue()
100 assert out_value == '1\n'
103 assert out_value == '1\n'
101
104
102
105
103 @isolate_ipython0
106 @isolate_ipython0
104 def test_capture():
107 def test_capture():
105 """ Test the capture of output in different channels.
108 """ Test the capture of output in different channels.
106 """
109 """
107 # Test on the OS-level stdout, stderr.
110 # Test on the OS-level stdout, stderr.
108 f = TestPrefilterFrontEnd()
111 f = TestPrefilterFrontEnd()
109 f.input_buffer = \
112 f.input_buffer = \
110 'import os; out=os.fdopen(1, "w"); out.write("1") ; out.flush()'
113 'import os; out=os.fdopen(1, "w"); out.write("1") ; out.flush()'
111 f._on_enter()
114 f._on_enter()
112 out_value = f.out.getvalue()
115 out_value = f.out.getvalue()
113 assert out_value == '1'
116 assert out_value == '1'
114 f = TestPrefilterFrontEnd()
117 f = TestPrefilterFrontEnd()
115 f.input_buffer = \
118 f.input_buffer = \
116 'import os; out=os.fdopen(2, "w"); out.write("1") ; out.flush()'
119 'import os; out=os.fdopen(2, "w"); out.write("1") ; out.flush()'
117 f._on_enter()
120 f._on_enter()
118 out_value = f.out.getvalue()
121 out_value = f.out.getvalue()
119 assert out_value == '1'
122 assert out_value == '1'
120
123
121
124
122 @isolate_ipython0
125 @isolate_ipython0
123 def test_magic():
126 def test_magic():
124 """ Test the magic expansion and history.
127 """ Test the magic expansion and history.
125
128
126 This test is fairly fragile and will break when magics change.
129 This test is fairly fragile and will break when magics change.
127 """
130 """
128 f = TestPrefilterFrontEnd()
131 f = TestPrefilterFrontEnd()
129 f.input_buffer += '%who'
132 f.input_buffer += '%who'
130 f._on_enter()
133 f._on_enter()
131 out_value = f.out.getvalue()
134 out_value = f.out.getvalue()
132 assert out_value == 'Interactive namespace is empty.\n'
135 assert out_value == 'Interactive namespace is empty.\n'
133
136
134
137
135 @isolate_ipython0
138 @isolate_ipython0
136 def test_help():
139 def test_help():
137 """ Test object inspection.
140 """ Test object inspection.
138 """
141 """
139 f = TestPrefilterFrontEnd()
142 f = TestPrefilterFrontEnd()
140 f.input_buffer += "def f():"
143 f.input_buffer += "def f():"
141 f._on_enter()
144 f._on_enter()
142 f.input_buffer += "'foobar'"
145 f.input_buffer += "'foobar'"
143 f._on_enter()
146 f._on_enter()
144 f.input_buffer += "pass"
147 f.input_buffer += "pass"
145 f._on_enter()
148 f._on_enter()
146 f._on_enter()
149 f._on_enter()
147 f.input_buffer += "f?"
150 f.input_buffer += "f?"
148 f._on_enter()
151 f._on_enter()
149 assert 'traceback' not in f.last_result
152 assert 'traceback' not in f.last_result
150 ## XXX: ipython doctest magic breaks this. I have no clue why
153 ## XXX: ipython doctest magic breaks this. I have no clue why
151 #out_value = f.out.getvalue()
154 #out_value = f.out.getvalue()
152 #assert out_value.split()[-1] == 'foobar'
155 #assert out_value.split()[-1] == 'foobar'
153
156
154
157
155 @isolate_ipython0
158 @isolate_ipython0
156 def test_completion():
159 def test_completion():
157 """ Test command-line completion.
160 """ Test command-line completion.
158 """
161 """
159 f = TestPrefilterFrontEnd()
162 f = TestPrefilterFrontEnd()
160 f.input_buffer = 'zzza = 1'
163 f.input_buffer = 'zzza = 1'
161 f._on_enter()
164 f._on_enter()
162 f.input_buffer = 'zzzb = 2'
165 f.input_buffer = 'zzzb = 2'
163 f._on_enter()
166 f._on_enter()
164 f.input_buffer = 'zz'
167 f.input_buffer = 'zz'
165 f.complete_current_input()
168 f.complete_current_input()
166 out_value = f.out.getvalue()
169 out_value = f.out.getvalue()
167 assert out_value == '\nzzza zzzb '
170 assert out_value == '\nzzza zzzb '
168 assert f.input_buffer == 'zzz'
171 assert f.input_buffer == 'zzz'
169
172
170
173
171 if __name__ == '__main__':
174 if __name__ == '__main__':
172 test_magic()
175 test_magic()
173 test_help()
176 test_help()
174 test_execution()
177 test_execution()
175 test_multiline()
178 test_multiline()
176 test_capture()
179 test_capture()
177 test_completion()
180 test_completion()
General Comments 0
You need to be logged in to leave comments. Login now