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