##// END OF EJS Templates
s/nt.assert_equals/nt.assert_equal/
Bradley M. Froehle -
Show More
@@ -1,345 +1,345
1 """Tests for the IPython tab-completion machinery.
1 """Tests for the IPython tab-completion machinery.
2 """
2 """
3 #-----------------------------------------------------------------------------
3 #-----------------------------------------------------------------------------
4 # Module imports
4 # Module imports
5 #-----------------------------------------------------------------------------
5 #-----------------------------------------------------------------------------
6
6
7 # stdlib
7 # stdlib
8 import os
8 import os
9 import sys
9 import sys
10 import unittest
10 import unittest
11
11
12 # third party
12 # third party
13 import nose.tools as nt
13 import nose.tools as nt
14
14
15 # our own packages
15 # our own packages
16 from IPython.config.loader import Config
16 from IPython.config.loader import Config
17 from IPython.core import completer
17 from IPython.core import completer
18 from IPython.external.decorators import knownfailureif
18 from IPython.external.decorators import knownfailureif
19 from IPython.utils.tempdir import TemporaryDirectory
19 from IPython.utils.tempdir import TemporaryDirectory
20 from IPython.utils.generics import complete_object
20 from IPython.utils.generics import complete_object
21
21
22 #-----------------------------------------------------------------------------
22 #-----------------------------------------------------------------------------
23 # Test functions
23 # Test functions
24 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
25 def test_protect_filename():
25 def test_protect_filename():
26 pairs = [ ('abc','abc'),
26 pairs = [ ('abc','abc'),
27 (' abc',r'\ abc'),
27 (' abc',r'\ abc'),
28 ('a bc',r'a\ bc'),
28 ('a bc',r'a\ bc'),
29 ('a bc',r'a\ \ bc'),
29 ('a bc',r'a\ \ bc'),
30 (' bc',r'\ \ bc'),
30 (' bc',r'\ \ bc'),
31 ]
31 ]
32 # On posix, we also protect parens and other special characters
32 # On posix, we also protect parens and other special characters
33 if sys.platform != 'win32':
33 if sys.platform != 'win32':
34 pairs.extend( [('a(bc',r'a\(bc'),
34 pairs.extend( [('a(bc',r'a\(bc'),
35 ('a)bc',r'a\)bc'),
35 ('a)bc',r'a\)bc'),
36 ('a( )bc',r'a\(\ \)bc'),
36 ('a( )bc',r'a\(\ \)bc'),
37 ('a[1]bc', r'a\[1\]bc'),
37 ('a[1]bc', r'a\[1\]bc'),
38 ('a{1}bc', r'a\{1\}bc'),
38 ('a{1}bc', r'a\{1\}bc'),
39 ('a#bc', r'a\#bc'),
39 ('a#bc', r'a\#bc'),
40 ('a?bc', r'a\?bc'),
40 ('a?bc', r'a\?bc'),
41 ('a=bc', r'a\=bc'),
41 ('a=bc', r'a\=bc'),
42 ('a\\bc', r'a\\bc'),
42 ('a\\bc', r'a\\bc'),
43 ('a|bc', r'a\|bc'),
43 ('a|bc', r'a\|bc'),
44 ('a;bc', r'a\;bc'),
44 ('a;bc', r'a\;bc'),
45 ('a:bc', r'a\:bc'),
45 ('a:bc', r'a\:bc'),
46 ("a'bc", r"a\'bc"),
46 ("a'bc", r"a\'bc"),
47 ('a*bc', r'a\*bc'),
47 ('a*bc', r'a\*bc'),
48 ('a"bc', r'a\"bc'),
48 ('a"bc', r'a\"bc'),
49 ('a^bc', r'a\^bc'),
49 ('a^bc', r'a\^bc'),
50 ('a&bc', r'a\&bc'),
50 ('a&bc', r'a\&bc'),
51 ] )
51 ] )
52 # run the actual tests
52 # run the actual tests
53 for s1, s2 in pairs:
53 for s1, s2 in pairs:
54 s1p = completer.protect_filename(s1)
54 s1p = completer.protect_filename(s1)
55 nt.assert_equals(s1p, s2)
55 nt.assert_equal(s1p, s2)
56
56
57
57
58 def check_line_split(splitter, test_specs):
58 def check_line_split(splitter, test_specs):
59 for part1, part2, split in test_specs:
59 for part1, part2, split in test_specs:
60 cursor_pos = len(part1)
60 cursor_pos = len(part1)
61 line = part1+part2
61 line = part1+part2
62 out = splitter.split_line(line, cursor_pos)
62 out = splitter.split_line(line, cursor_pos)
63 nt.assert_equal(out, split)
63 nt.assert_equal(out, split)
64
64
65
65
66 def test_line_split():
66 def test_line_split():
67 """Basice line splitter test with default specs."""
67 """Basice line splitter test with default specs."""
68 sp = completer.CompletionSplitter()
68 sp = completer.CompletionSplitter()
69 # The format of the test specs is: part1, part2, expected answer. Parts 1
69 # The format of the test specs is: part1, part2, expected answer. Parts 1
70 # and 2 are joined into the 'line' sent to the splitter, as if the cursor
70 # and 2 are joined into the 'line' sent to the splitter, as if the cursor
71 # was at the end of part1. So an empty part2 represents someone hitting
71 # was at the end of part1. So an empty part2 represents someone hitting
72 # tab at the end of the line, the most common case.
72 # tab at the end of the line, the most common case.
73 t = [('run some/scrip', '', 'some/scrip'),
73 t = [('run some/scrip', '', 'some/scrip'),
74 ('run scripts/er', 'ror.py foo', 'scripts/er'),
74 ('run scripts/er', 'ror.py foo', 'scripts/er'),
75 ('echo $HOM', '', 'HOM'),
75 ('echo $HOM', '', 'HOM'),
76 ('print sys.pa', '', 'sys.pa'),
76 ('print sys.pa', '', 'sys.pa'),
77 ('print(sys.pa', '', 'sys.pa'),
77 ('print(sys.pa', '', 'sys.pa'),
78 ("execfile('scripts/er", '', 'scripts/er'),
78 ("execfile('scripts/er", '', 'scripts/er'),
79 ('a[x.', '', 'x.'),
79 ('a[x.', '', 'x.'),
80 ('a[x.', 'y', 'x.'),
80 ('a[x.', 'y', 'x.'),
81 ('cd "some_file/', '', 'some_file/'),
81 ('cd "some_file/', '', 'some_file/'),
82 ]
82 ]
83 check_line_split(sp, t)
83 check_line_split(sp, t)
84 # Ensure splitting works OK with unicode by re-running the tests with
84 # Ensure splitting works OK with unicode by re-running the tests with
85 # all inputs turned into unicode
85 # all inputs turned into unicode
86 check_line_split(sp, [ map(unicode, p) for p in t] )
86 check_line_split(sp, [ map(unicode, p) for p in t] )
87
87
88
88
89 def test_custom_completion_error():
89 def test_custom_completion_error():
90 """Test that errors from custom attribute completers are silenced."""
90 """Test that errors from custom attribute completers are silenced."""
91 ip = get_ipython()
91 ip = get_ipython()
92 class A(object): pass
92 class A(object): pass
93 ip.user_ns['a'] = A()
93 ip.user_ns['a'] = A()
94
94
95 @complete_object.when_type(A)
95 @complete_object.when_type(A)
96 def complete_A(a, existing_completions):
96 def complete_A(a, existing_completions):
97 raise TypeError("this should be silenced")
97 raise TypeError("this should be silenced")
98
98
99 ip.complete("a.")
99 ip.complete("a.")
100
100
101
101
102 def test_unicode_completions():
102 def test_unicode_completions():
103 ip = get_ipython()
103 ip = get_ipython()
104 # Some strings that trigger different types of completion. Check them both
104 # Some strings that trigger different types of completion. Check them both
105 # in str and unicode forms
105 # in str and unicode forms
106 s = ['ru', '%ru', 'cd /', 'floa', 'float(x)/']
106 s = ['ru', '%ru', 'cd /', 'floa', 'float(x)/']
107 for t in s + map(unicode, s):
107 for t in s + map(unicode, s):
108 # We don't need to check exact completion values (they may change
108 # We don't need to check exact completion values (they may change
109 # depending on the state of the namespace, but at least no exceptions
109 # depending on the state of the namespace, but at least no exceptions
110 # should be thrown and the return value should be a pair of text, list
110 # should be thrown and the return value should be a pair of text, list
111 # values.
111 # values.
112 text, matches = ip.complete(t)
112 text, matches = ip.complete(t)
113 nt.assert_true(isinstance(text, basestring))
113 nt.assert_true(isinstance(text, basestring))
114 nt.assert_true(isinstance(matches, list))
114 nt.assert_true(isinstance(matches, list))
115
115
116
116
117 class CompletionSplitterTestCase(unittest.TestCase):
117 class CompletionSplitterTestCase(unittest.TestCase):
118 def setUp(self):
118 def setUp(self):
119 self.sp = completer.CompletionSplitter()
119 self.sp = completer.CompletionSplitter()
120
120
121 def test_delim_setting(self):
121 def test_delim_setting(self):
122 self.sp.delims = ' '
122 self.sp.delims = ' '
123 nt.assert_equal(self.sp.delims, ' ')
123 nt.assert_equal(self.sp.delims, ' ')
124 nt.assert_equal(self.sp._delim_expr, '[\ ]')
124 nt.assert_equal(self.sp._delim_expr, '[\ ]')
125
125
126 def test_spaces(self):
126 def test_spaces(self):
127 """Test with only spaces as split chars."""
127 """Test with only spaces as split chars."""
128 self.sp.delims = ' '
128 self.sp.delims = ' '
129 t = [('foo', '', 'foo'),
129 t = [('foo', '', 'foo'),
130 ('run foo', '', 'foo'),
130 ('run foo', '', 'foo'),
131 ('run foo', 'bar', 'foo'),
131 ('run foo', 'bar', 'foo'),
132 ]
132 ]
133 check_line_split(self.sp, t)
133 check_line_split(self.sp, t)
134
134
135
135
136 def test_has_open_quotes1():
136 def test_has_open_quotes1():
137 for s in ["'", "'''", "'hi' '"]:
137 for s in ["'", "'''", "'hi' '"]:
138 nt.assert_equal(completer.has_open_quotes(s), "'")
138 nt.assert_equal(completer.has_open_quotes(s), "'")
139
139
140
140
141 def test_has_open_quotes2():
141 def test_has_open_quotes2():
142 for s in ['"', '"""', '"hi" "']:
142 for s in ['"', '"""', '"hi" "']:
143 nt.assert_equal(completer.has_open_quotes(s), '"')
143 nt.assert_equal(completer.has_open_quotes(s), '"')
144
144
145
145
146 def test_has_open_quotes3():
146 def test_has_open_quotes3():
147 for s in ["''", "''' '''", "'hi' 'ipython'"]:
147 for s in ["''", "''' '''", "'hi' 'ipython'"]:
148 nt.assert_false(completer.has_open_quotes(s))
148 nt.assert_false(completer.has_open_quotes(s))
149
149
150
150
151 def test_has_open_quotes4():
151 def test_has_open_quotes4():
152 for s in ['""', '""" """', '"hi" "ipython"']:
152 for s in ['""', '""" """', '"hi" "ipython"']:
153 nt.assert_false(completer.has_open_quotes(s))
153 nt.assert_false(completer.has_open_quotes(s))
154
154
155
155
156 @knownfailureif(sys.platform == 'win32', "abspath completions fail on Windows")
156 @knownfailureif(sys.platform == 'win32', "abspath completions fail on Windows")
157 def test_abspath_file_completions():
157 def test_abspath_file_completions():
158 ip = get_ipython()
158 ip = get_ipython()
159 with TemporaryDirectory() as tmpdir:
159 with TemporaryDirectory() as tmpdir:
160 prefix = os.path.join(tmpdir, 'foo')
160 prefix = os.path.join(tmpdir, 'foo')
161 suffixes = map(str, [1,2])
161 suffixes = map(str, [1,2])
162 names = [prefix+s for s in suffixes]
162 names = [prefix+s for s in suffixes]
163 for n in names:
163 for n in names:
164 open(n, 'w').close()
164 open(n, 'w').close()
165
165
166 # Check simple completion
166 # Check simple completion
167 c = ip.complete(prefix)[1]
167 c = ip.complete(prefix)[1]
168 nt.assert_equal(c, names)
168 nt.assert_equal(c, names)
169
169
170 # Now check with a function call
170 # Now check with a function call
171 cmd = 'a = f("%s' % prefix
171 cmd = 'a = f("%s' % prefix
172 c = ip.complete(prefix, cmd)[1]
172 c = ip.complete(prefix, cmd)[1]
173 comp = [prefix+s for s in suffixes]
173 comp = [prefix+s for s in suffixes]
174 nt.assert_equal(c, comp)
174 nt.assert_equal(c, comp)
175
175
176
176
177 def test_local_file_completions():
177 def test_local_file_completions():
178 ip = get_ipython()
178 ip = get_ipython()
179 cwd = os.getcwdu()
179 cwd = os.getcwdu()
180 try:
180 try:
181 with TemporaryDirectory() as tmpdir:
181 with TemporaryDirectory() as tmpdir:
182 os.chdir(tmpdir)
182 os.chdir(tmpdir)
183 prefix = './foo'
183 prefix = './foo'
184 suffixes = map(str, [1,2])
184 suffixes = map(str, [1,2])
185 names = [prefix+s for s in suffixes]
185 names = [prefix+s for s in suffixes]
186 for n in names:
186 for n in names:
187 open(n, 'w').close()
187 open(n, 'w').close()
188
188
189 # Check simple completion
189 # Check simple completion
190 c = ip.complete(prefix)[1]
190 c = ip.complete(prefix)[1]
191 nt.assert_equal(c, names)
191 nt.assert_equal(c, names)
192
192
193 # Now check with a function call
193 # Now check with a function call
194 cmd = 'a = f("%s' % prefix
194 cmd = 'a = f("%s' % prefix
195 c = ip.complete(prefix, cmd)[1]
195 c = ip.complete(prefix, cmd)[1]
196 comp = [prefix+s for s in suffixes]
196 comp = [prefix+s for s in suffixes]
197 nt.assert_equal(c, comp)
197 nt.assert_equal(c, comp)
198 finally:
198 finally:
199 # prevent failures from making chdir stick
199 # prevent failures from making chdir stick
200 os.chdir(cwd)
200 os.chdir(cwd)
201
201
202
202
203 def test_greedy_completions():
203 def test_greedy_completions():
204 ip = get_ipython()
204 ip = get_ipython()
205 greedy_original = ip.Completer.greedy
205 greedy_original = ip.Completer.greedy
206 try:
206 try:
207 ip.Completer.greedy = False
207 ip.Completer.greedy = False
208 ip.ex('a=range(5)')
208 ip.ex('a=range(5)')
209 _,c = ip.complete('.',line='a[0].')
209 _,c = ip.complete('.',line='a[0].')
210 nt.assert_false('a[0].real' in c,
210 nt.assert_false('a[0].real' in c,
211 "Shouldn't have completed on a[0]: %s"%c)
211 "Shouldn't have completed on a[0]: %s"%c)
212 ip.Completer.greedy = True
212 ip.Completer.greedy = True
213 _,c = ip.complete('.',line='a[0].')
213 _,c = ip.complete('.',line='a[0].')
214 nt.assert_true('a[0].real' in c, "Should have completed on a[0]: %s"%c)
214 nt.assert_true('a[0].real' in c, "Should have completed on a[0]: %s"%c)
215 finally:
215 finally:
216 ip.Completer.greedy = greedy_original
216 ip.Completer.greedy = greedy_original
217
217
218
218
219 def test_omit__names():
219 def test_omit__names():
220 # also happens to test IPCompleter as a configurable
220 # also happens to test IPCompleter as a configurable
221 ip = get_ipython()
221 ip = get_ipython()
222 ip._hidden_attr = 1
222 ip._hidden_attr = 1
223 c = ip.Completer
223 c = ip.Completer
224 ip.ex('ip=get_ipython()')
224 ip.ex('ip=get_ipython()')
225 cfg = Config()
225 cfg = Config()
226 cfg.IPCompleter.omit__names = 0
226 cfg.IPCompleter.omit__names = 0
227 c.update_config(cfg)
227 c.update_config(cfg)
228 s,matches = c.complete('ip.')
228 s,matches = c.complete('ip.')
229 nt.assert_true('ip.__str__' in matches)
229 nt.assert_true('ip.__str__' in matches)
230 nt.assert_true('ip._hidden_attr' in matches)
230 nt.assert_true('ip._hidden_attr' in matches)
231 cfg.IPCompleter.omit__names = 1
231 cfg.IPCompleter.omit__names = 1
232 c.update_config(cfg)
232 c.update_config(cfg)
233 s,matches = c.complete('ip.')
233 s,matches = c.complete('ip.')
234 nt.assert_false('ip.__str__' in matches)
234 nt.assert_false('ip.__str__' in matches)
235 nt.assert_true('ip._hidden_attr' in matches)
235 nt.assert_true('ip._hidden_attr' in matches)
236 cfg.IPCompleter.omit__names = 2
236 cfg.IPCompleter.omit__names = 2
237 c.update_config(cfg)
237 c.update_config(cfg)
238 s,matches = c.complete('ip.')
238 s,matches = c.complete('ip.')
239 nt.assert_false('ip.__str__' in matches)
239 nt.assert_false('ip.__str__' in matches)
240 nt.assert_false('ip._hidden_attr' in matches)
240 nt.assert_false('ip._hidden_attr' in matches)
241 del ip._hidden_attr
241 del ip._hidden_attr
242
242
243
243
244 def test_limit_to__all__False_ok():
244 def test_limit_to__all__False_ok():
245 ip = get_ipython()
245 ip = get_ipython()
246 c = ip.Completer
246 c = ip.Completer
247 ip.ex('class D: x=24')
247 ip.ex('class D: x=24')
248 ip.ex('d=D()')
248 ip.ex('d=D()')
249 cfg = Config()
249 cfg = Config()
250 cfg.IPCompleter.limit_to__all__ = False
250 cfg.IPCompleter.limit_to__all__ = False
251 c.update_config(cfg)
251 c.update_config(cfg)
252 s, matches = c.complete('d.')
252 s, matches = c.complete('d.')
253 nt.assert_true('d.x' in matches)
253 nt.assert_true('d.x' in matches)
254
254
255
255
256 def test_limit_to__all__True_ok():
256 def test_limit_to__all__True_ok():
257 ip = get_ipython()
257 ip = get_ipython()
258 c = ip.Completer
258 c = ip.Completer
259 ip.ex('class D: x=24')
259 ip.ex('class D: x=24')
260 ip.ex('d=D()')
260 ip.ex('d=D()')
261 ip.ex("d.__all__=['z']")
261 ip.ex("d.__all__=['z']")
262 cfg = Config()
262 cfg = Config()
263 cfg.IPCompleter.limit_to__all__ = True
263 cfg.IPCompleter.limit_to__all__ = True
264 c.update_config(cfg)
264 c.update_config(cfg)
265 s, matches = c.complete('d.')
265 s, matches = c.complete('d.')
266 nt.assert_true('d.z' in matches)
266 nt.assert_true('d.z' in matches)
267 nt.assert_false('d.x' in matches)
267 nt.assert_false('d.x' in matches)
268
268
269
269
270 def test_get__all__entries_ok():
270 def test_get__all__entries_ok():
271 class A(object):
271 class A(object):
272 __all__ = ['x', 1]
272 __all__ = ['x', 1]
273 words = completer.get__all__entries(A())
273 words = completer.get__all__entries(A())
274 nt.assert_equal(words, ['x'])
274 nt.assert_equal(words, ['x'])
275
275
276
276
277 def test_get__all__entries_no__all__ok():
277 def test_get__all__entries_no__all__ok():
278 class A(object):
278 class A(object):
279 pass
279 pass
280 words = completer.get__all__entries(A())
280 words = completer.get__all__entries(A())
281 nt.assert_equal(words, [])
281 nt.assert_equal(words, [])
282
282
283
283
284 def test_func_kw_completions():
284 def test_func_kw_completions():
285 ip = get_ipython()
285 ip = get_ipython()
286 c = ip.Completer
286 c = ip.Completer
287 ip.ex('def myfunc(a=1,b=2): return a+b')
287 ip.ex('def myfunc(a=1,b=2): return a+b')
288 s, matches = c.complete(None, 'myfunc(1,b')
288 s, matches = c.complete(None, 'myfunc(1,b')
289 nt.assert_in('b=', matches)
289 nt.assert_in('b=', matches)
290 # Simulate completing with cursor right after b (pos==10):
290 # Simulate completing with cursor right after b (pos==10):
291 s, matches = c.complete(None,'myfunc(1,b)', 10)
291 s, matches = c.complete(None,'myfunc(1,b)', 10)
292 nt.assert_in('b=', matches)
292 nt.assert_in('b=', matches)
293 s, matches = c.complete(None,'myfunc(a="escaped\\")string",b')
293 s, matches = c.complete(None,'myfunc(a="escaped\\")string",b')
294 nt.assert_in('b=', matches)
294 nt.assert_in('b=', matches)
295
295
296
296
297 def test_line_magics():
297 def test_line_magics():
298 ip = get_ipython()
298 ip = get_ipython()
299 c = ip.Completer
299 c = ip.Completer
300 s, matches = c.complete(None, 'lsmag')
300 s, matches = c.complete(None, 'lsmag')
301 nt.assert_in('%lsmagic', matches)
301 nt.assert_in('%lsmagic', matches)
302 s, matches = c.complete(None, '%lsmag')
302 s, matches = c.complete(None, '%lsmag')
303 nt.assert_in('%lsmagic', matches)
303 nt.assert_in('%lsmagic', matches)
304
304
305
305
306 def test_cell_magics():
306 def test_cell_magics():
307 from IPython.core.magic import register_cell_magic
307 from IPython.core.magic import register_cell_magic
308
308
309 @register_cell_magic
309 @register_cell_magic
310 def _foo_cellm(line, cell):
310 def _foo_cellm(line, cell):
311 pass
311 pass
312
312
313 ip = get_ipython()
313 ip = get_ipython()
314 c = ip.Completer
314 c = ip.Completer
315
315
316 s, matches = c.complete(None, '_foo_ce')
316 s, matches = c.complete(None, '_foo_ce')
317 nt.assert_in('%%_foo_cellm', matches)
317 nt.assert_in('%%_foo_cellm', matches)
318 s, matches = c.complete(None, '%%_foo_ce')
318 s, matches = c.complete(None, '%%_foo_ce')
319 nt.assert_in('%%_foo_cellm', matches)
319 nt.assert_in('%%_foo_cellm', matches)
320
320
321
321
322 def test_line_cell_magics():
322 def test_line_cell_magics():
323 from IPython.core.magic import register_line_cell_magic
323 from IPython.core.magic import register_line_cell_magic
324
324
325 @register_line_cell_magic
325 @register_line_cell_magic
326 def _bar_cellm(line, cell):
326 def _bar_cellm(line, cell):
327 pass
327 pass
328
328
329 ip = get_ipython()
329 ip = get_ipython()
330 c = ip.Completer
330 c = ip.Completer
331
331
332 # The policy here is trickier, see comments in completion code. The
332 # The policy here is trickier, see comments in completion code. The
333 # returned values depend on whether the user passes %% or not explicitly,
333 # returned values depend on whether the user passes %% or not explicitly,
334 # and this will show a difference if the same name is both a line and cell
334 # and this will show a difference if the same name is both a line and cell
335 # magic.
335 # magic.
336 s, matches = c.complete(None, '_bar_ce')
336 s, matches = c.complete(None, '_bar_ce')
337 nt.assert_in('%_bar_cellm', matches)
337 nt.assert_in('%_bar_cellm', matches)
338 nt.assert_in('%%_bar_cellm', matches)
338 nt.assert_in('%%_bar_cellm', matches)
339 s, matches = c.complete(None, '%_bar_ce')
339 s, matches = c.complete(None, '%_bar_ce')
340 nt.assert_in('%_bar_cellm', matches)
340 nt.assert_in('%_bar_cellm', matches)
341 nt.assert_in('%%_bar_cellm', matches)
341 nt.assert_in('%%_bar_cellm', matches)
342 s, matches = c.complete(None, '%%_bar_ce')
342 s, matches = c.complete(None, '%%_bar_ce')
343 nt.assert_not_in('%_bar_cellm', matches)
343 nt.assert_not_in('%_bar_cellm', matches)
344 nt.assert_in('%%_bar_cellm', matches)
344 nt.assert_in('%%_bar_cellm', matches)
345
345
@@ -1,35 +1,35
1 """Tests for debugging machinery.
1 """Tests for debugging machinery.
2 """
2 """
3 #-----------------------------------------------------------------------------
3 #-----------------------------------------------------------------------------
4 # Copyright (c) 2012, The IPython Development Team.
4 # Copyright (c) 2012, The IPython Development Team.
5 #
5 #
6 # Distributed under the terms of the Modified BSD License.
6 # Distributed under the terms of the Modified BSD License.
7 #
7 #
8 # The full license is in the file COPYING.txt, distributed with this software.
8 # The full license is in the file COPYING.txt, distributed with this software.
9 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
10
10
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12 # Imports
12 # Imports
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14
14
15 # third-party
15 # third-party
16 import nose.tools as nt
16 import nose.tools as nt
17
17
18 # Our own
18 # Our own
19 from IPython.core import debugger
19 from IPython.core import debugger
20
20
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22 # Tests
22 # Tests
23 #-----------------------------------------------------------------------------
23 #-----------------------------------------------------------------------------
24
24
25 def test_longer_repr():
25 def test_longer_repr():
26 from repr import repr as trepr
26 from repr import repr as trepr
27
27
28 a = '1234567890'* 7
28 a = '1234567890'* 7
29 ar = "'1234567890123456789012345678901234567890123456789012345678901234567890'"
29 ar = "'1234567890123456789012345678901234567890123456789012345678901234567890'"
30 a_trunc = "'123456789012...8901234567890'"
30 a_trunc = "'123456789012...8901234567890'"
31 nt.assert_equals(trepr(a), a_trunc)
31 nt.assert_equal(trepr(a), a_trunc)
32 # The creation of our tracer modifies the repr module's repr function
32 # The creation of our tracer modifies the repr module's repr function
33 # in-place, since that global is used directly by the stdlib's pdb module.
33 # in-place, since that global is used directly by the stdlib's pdb module.
34 t = debugger.Tracer()
34 t = debugger.Tracer()
35 nt.assert_equals(trepr(a), ar)
35 nt.assert_equal(trepr(a), ar)
@@ -1,91 +1,91
1 """Tests for the Formatters.
1 """Tests for the Formatters.
2 """
2 """
3
3
4 from math import pi
4 from math import pi
5
5
6 try:
6 try:
7 import numpy
7 import numpy
8 except:
8 except:
9 numpy = None
9 numpy = None
10 import nose.tools as nt
10 import nose.tools as nt
11
11
12 from IPython.core.formatters import FormatterABC, PlainTextFormatter
12 from IPython.core.formatters import FormatterABC, PlainTextFormatter
13 from IPython.lib import pretty
13 from IPython.lib import pretty
14
14
15 class A(object):
15 class A(object):
16 def __repr__(self):
16 def __repr__(self):
17 return 'A()'
17 return 'A()'
18
18
19 class B(A):
19 class B(A):
20 def __repr__(self):
20 def __repr__(self):
21 return 'B()'
21 return 'B()'
22
22
23 class BadPretty(object):
23 class BadPretty(object):
24 _repr_pretty_ = None
24 _repr_pretty_ = None
25
25
26 class GoodPretty(object):
26 class GoodPretty(object):
27 def _repr_pretty_(self, pp, cycle):
27 def _repr_pretty_(self, pp, cycle):
28 pp.text('foo')
28 pp.text('foo')
29
29
30 def __repr__(self):
30 def __repr__(self):
31 return 'GoodPretty()'
31 return 'GoodPretty()'
32
32
33 def foo_printer(obj, pp, cycle):
33 def foo_printer(obj, pp, cycle):
34 pp.text('foo')
34 pp.text('foo')
35
35
36 def test_pretty():
36 def test_pretty():
37 f = PlainTextFormatter()
37 f = PlainTextFormatter()
38 f.for_type(A, foo_printer)
38 f.for_type(A, foo_printer)
39 nt.assert_equals(f(A()), 'foo')
39 nt.assert_equal(f(A()), 'foo')
40 nt.assert_equals(f(B()), 'foo')
40 nt.assert_equal(f(B()), 'foo')
41 nt.assert_equals(f(GoodPretty()), 'foo')
41 nt.assert_equal(f(GoodPretty()), 'foo')
42 # Just don't raise an exception for the following:
42 # Just don't raise an exception for the following:
43 f(BadPretty())
43 f(BadPretty())
44
44
45 f.pprint = False
45 f.pprint = False
46 nt.assert_equals(f(A()), 'A()')
46 nt.assert_equal(f(A()), 'A()')
47 nt.assert_equals(f(B()), 'B()')
47 nt.assert_equal(f(B()), 'B()')
48 nt.assert_equals(f(GoodPretty()), 'GoodPretty()')
48 nt.assert_equal(f(GoodPretty()), 'GoodPretty()')
49
49
50
50
51 def test_deferred():
51 def test_deferred():
52 f = PlainTextFormatter()
52 f = PlainTextFormatter()
53
53
54 def test_precision():
54 def test_precision():
55 """test various values for float_precision."""
55 """test various values for float_precision."""
56 f = PlainTextFormatter()
56 f = PlainTextFormatter()
57 nt.assert_equals(f(pi), repr(pi))
57 nt.assert_equal(f(pi), repr(pi))
58 f.float_precision = 0
58 f.float_precision = 0
59 if numpy:
59 if numpy:
60 po = numpy.get_printoptions()
60 po = numpy.get_printoptions()
61 nt.assert_equals(po['precision'], 0)
61 nt.assert_equal(po['precision'], 0)
62 nt.assert_equals(f(pi), '3')
62 nt.assert_equal(f(pi), '3')
63 f.float_precision = 2
63 f.float_precision = 2
64 if numpy:
64 if numpy:
65 po = numpy.get_printoptions()
65 po = numpy.get_printoptions()
66 nt.assert_equals(po['precision'], 2)
66 nt.assert_equal(po['precision'], 2)
67 nt.assert_equals(f(pi), '3.14')
67 nt.assert_equal(f(pi), '3.14')
68 f.float_precision = '%g'
68 f.float_precision = '%g'
69 if numpy:
69 if numpy:
70 po = numpy.get_printoptions()
70 po = numpy.get_printoptions()
71 nt.assert_equals(po['precision'], 2)
71 nt.assert_equal(po['precision'], 2)
72 nt.assert_equals(f(pi), '3.14159')
72 nt.assert_equal(f(pi), '3.14159')
73 f.float_precision = '%e'
73 f.float_precision = '%e'
74 nt.assert_equals(f(pi), '3.141593e+00')
74 nt.assert_equal(f(pi), '3.141593e+00')
75 f.float_precision = ''
75 f.float_precision = ''
76 if numpy:
76 if numpy:
77 po = numpy.get_printoptions()
77 po = numpy.get_printoptions()
78 nt.assert_equals(po['precision'], 8)
78 nt.assert_equal(po['precision'], 8)
79 nt.assert_equals(f(pi), repr(pi))
79 nt.assert_equal(f(pi), repr(pi))
80
80
81 def test_bad_precision():
81 def test_bad_precision():
82 """test various invalid values for float_precision."""
82 """test various invalid values for float_precision."""
83 f = PlainTextFormatter()
83 f = PlainTextFormatter()
84 def set_fp(p):
84 def set_fp(p):
85 f.float_precision=p
85 f.float_precision=p
86 nt.assert_raises(ValueError, set_fp, '%')
86 nt.assert_raises(ValueError, set_fp, '%')
87 nt.assert_raises(ValueError, set_fp, '%.3f%i')
87 nt.assert_raises(ValueError, set_fp, '%.3f%i')
88 nt.assert_raises(ValueError, set_fp, 'foo')
88 nt.assert_raises(ValueError, set_fp, 'foo')
89 nt.assert_raises(ValueError, set_fp, -1)
89 nt.assert_raises(ValueError, set_fp, -1)
90
90
91
91
@@ -1,169 +1,169
1 """Tests for input handlers.
1 """Tests for input handlers.
2 """
2 """
3 #-----------------------------------------------------------------------------
3 #-----------------------------------------------------------------------------
4 # Module imports
4 # Module imports
5 #-----------------------------------------------------------------------------
5 #-----------------------------------------------------------------------------
6
6
7 # third party
7 # third party
8 import nose.tools as nt
8 import nose.tools as nt
9
9
10 # our own packages
10 # our own packages
11 from IPython.core import autocall
11 from IPython.core import autocall
12 from IPython.testing import tools as tt
12 from IPython.testing import tools as tt
13 from IPython.testing.globalipapp import get_ipython
13 from IPython.testing.globalipapp import get_ipython
14 from IPython.utils import py3compat
14 from IPython.utils import py3compat
15
15
16 #-----------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
17 # Globals
17 # Globals
18 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
19
19
20 # Get the public instance of IPython
20 # Get the public instance of IPython
21 ip = get_ipython()
21 ip = get_ipython()
22
22
23 failures = []
23 failures = []
24 num_tests = 0
24 num_tests = 0
25
25
26 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
27 # Test functions
27 # Test functions
28 #-----------------------------------------------------------------------------
28 #-----------------------------------------------------------------------------
29
29
30 class CallableIndexable(object):
30 class CallableIndexable(object):
31 def __getitem__(self, idx): return True
31 def __getitem__(self, idx): return True
32 def __call__(self, *args, **kws): return True
32 def __call__(self, *args, **kws): return True
33
33
34
34
35 class Autocallable(autocall.IPyAutocall):
35 class Autocallable(autocall.IPyAutocall):
36 def __call__(self):
36 def __call__(self):
37 return "called"
37 return "called"
38
38
39
39
40 def run(tests):
40 def run(tests):
41 """Loop through a list of (pre, post) inputs, where pre is the string
41 """Loop through a list of (pre, post) inputs, where pre is the string
42 handed to ipython, and post is how that string looks after it's been
42 handed to ipython, and post is how that string looks after it's been
43 transformed (i.e. ipython's notion of _i)"""
43 transformed (i.e. ipython's notion of _i)"""
44 tt.check_pairs(ip.prefilter_manager.prefilter_lines, tests)
44 tt.check_pairs(ip.prefilter_manager.prefilter_lines, tests)
45
45
46
46
47 def test_handlers():
47 def test_handlers():
48 # alias expansion
48 # alias expansion
49
49
50 # We're using 'true' as our syscall of choice because it doesn't
50 # We're using 'true' as our syscall of choice because it doesn't
51 # write anything to stdout.
51 # write anything to stdout.
52
52
53 # Turn off actual execution of aliases, because it's noisy
53 # Turn off actual execution of aliases, because it's noisy
54 old_system_cmd = ip.system
54 old_system_cmd = ip.system
55 ip.system = lambda cmd: None
55 ip.system = lambda cmd: None
56
56
57
57
58 ip.alias_manager.alias_table['an_alias'] = (0, 'true')
58 ip.alias_manager.alias_table['an_alias'] = (0, 'true')
59 # These are useful for checking a particular recursive alias issue
59 # These are useful for checking a particular recursive alias issue
60 ip.alias_manager.alias_table['top'] = (0, 'd:/cygwin/top')
60 ip.alias_manager.alias_table['top'] = (0, 'd:/cygwin/top')
61 ip.alias_manager.alias_table['d'] = (0, 'true')
61 ip.alias_manager.alias_table['d'] = (0, 'true')
62 run([(i,py3compat.u_format(o)) for i,o in \
62 run([(i,py3compat.u_format(o)) for i,o in \
63 [("an_alias", "get_ipython().system({u}'true ')"), # alias
63 [("an_alias", "get_ipython().system({u}'true ')"), # alias
64 # Below: recursive aliases should expand whitespace-surrounded
64 # Below: recursive aliases should expand whitespace-surrounded
65 # chars, *not* initial chars which happen to be aliases:
65 # chars, *not* initial chars which happen to be aliases:
66 ("top", "get_ipython().system({u}'d:/cygwin/top ')"),
66 ("top", "get_ipython().system({u}'d:/cygwin/top ')"),
67 ]])
67 ]])
68 ip.system = old_system_cmd
68 ip.system = old_system_cmd
69
69
70 call_idx = CallableIndexable()
70 call_idx = CallableIndexable()
71 ip.user_ns['call_idx'] = call_idx
71 ip.user_ns['call_idx'] = call_idx
72
72
73 # For many of the below, we're also checking that leading whitespace
73 # For many of the below, we're also checking that leading whitespace
74 # turns off the esc char, which it should unless there is a continuation
74 # turns off the esc char, which it should unless there is a continuation
75 # line.
75 # line.
76 run([(i,py3compat.u_format(o)) for i,o in \
76 run([(i,py3compat.u_format(o)) for i,o in \
77 [('"no change"', '"no change"'), # normal
77 [('"no change"', '"no change"'), # normal
78 (u"!true", "get_ipython().system({u}'true')"), # shell_escapes
78 (u"!true", "get_ipython().system({u}'true')"), # shell_escapes
79 (u"!! true", "get_ipython().magic({u}'sx true')"), # shell_escapes + magic
79 (u"!! true", "get_ipython().magic({u}'sx true')"), # shell_escapes + magic
80 (u"!!true", "get_ipython().magic({u}'sx true')"), # shell_escapes + magic
80 (u"!!true", "get_ipython().magic({u}'sx true')"), # shell_escapes + magic
81 (u"%lsmagic", "get_ipython().magic({u}'lsmagic ')"), # magic
81 (u"%lsmagic", "get_ipython().magic({u}'lsmagic ')"), # magic
82 (u"lsmagic", "get_ipython().magic({u}'lsmagic ')"), # magic
82 (u"lsmagic", "get_ipython().magic({u}'lsmagic ')"), # magic
83 #("a = b # PYTHON-MODE", '_i'), # emacs -- avoids _in cache
83 #("a = b # PYTHON-MODE", '_i'), # emacs -- avoids _in cache
84
84
85 # post-esc-char whitespace goes inside
85 # post-esc-char whitespace goes inside
86 (u"! true", "get_ipython().system({u}' true')"),
86 (u"! true", "get_ipython().system({u}' true')"),
87
87
88 # handle_help
88 # handle_help
89
89
90 # These are weak tests -- just looking at what the help handlers
90 # These are weak tests -- just looking at what the help handlers
91 # logs, which is not how it really does its work. But it still
91 # logs, which is not how it really does its work. But it still
92 # lets us check the key paths through the handler.
92 # lets us check the key paths through the handler.
93
93
94 ("x=1 # what?", "x=1 # what?"), # no help if valid python
94 ("x=1 # what?", "x=1 # what?"), # no help if valid python
95 ]])
95 ]])
96
96
97 # multi_line_specials
97 # multi_line_specials
98 ip.prefilter_manager.multi_line_specials = False
98 ip.prefilter_manager.multi_line_specials = False
99 # W/ multi_line_specials off, leading ws kills esc chars/autoexpansion
99 # W/ multi_line_specials off, leading ws kills esc chars/autoexpansion
100 run([
100 run([
101 (u'if 1:\n !true', u'if 1:\n !true'),
101 (u'if 1:\n !true', u'if 1:\n !true'),
102 (u'if 1:\n lsmagic', u'if 1:\n lsmagic'),
102 (u'if 1:\n lsmagic', u'if 1:\n lsmagic'),
103 (u'if 1:\n an_alias', u'if 1:\n an_alias'),
103 (u'if 1:\n an_alias', u'if 1:\n an_alias'),
104 ])
104 ])
105
105
106 ip.prefilter_manager.multi_line_specials = True
106 ip.prefilter_manager.multi_line_specials = True
107 # initial indents must be preserved.
107 # initial indents must be preserved.
108 run([(i,py3compat.u_format(o)) for i,o in \
108 run([(i,py3compat.u_format(o)) for i,o in \
109 [(u'if 1:\n !true', "if 1:\n get_ipython().system({u}'true')"),
109 [(u'if 1:\n !true', "if 1:\n get_ipython().system({u}'true')"),
110 (u'if 2:\n lsmagic', "if 2:\n get_ipython().magic({u}'lsmagic ')"),
110 (u'if 2:\n lsmagic', "if 2:\n get_ipython().magic({u}'lsmagic ')"),
111 (u'if 1:\n an_alias', "if 1:\n get_ipython().system({u}'true ')"),
111 (u'if 1:\n an_alias', "if 1:\n get_ipython().system({u}'true ')"),
112 # Weird one
112 # Weird one
113 (u'if 1:\n !!true', "if 1:\n get_ipython().magic({u}'sx true')"),
113 (u'if 1:\n !!true', "if 1:\n get_ipython().magic({u}'sx true')"),
114
114
115 # Even with m_l_s on, autocall is off even with special chars
115 # Even with m_l_s on, autocall is off even with special chars
116 ('if 1:\n /fun 1 2', 'if 1:\n /fun 1 2'),
116 ('if 1:\n /fun 1 2', 'if 1:\n /fun 1 2'),
117 ('if 1:\n ;fun 1 2', 'if 1:\n ;fun 1 2'),
117 ('if 1:\n ;fun 1 2', 'if 1:\n ;fun 1 2'),
118 ('if 1:\n ,fun 1 2', 'if 1:\n ,fun 1 2'),
118 ('if 1:\n ,fun 1 2', 'if 1:\n ,fun 1 2'),
119 ('if 1:\n ?fun 1 2', 'if 1:\n ?fun 1 2'),
119 ('if 1:\n ?fun 1 2', 'if 1:\n ?fun 1 2'),
120 # What about !!
120 # What about !!
121 ]])
121 ]])
122
122
123 # Objects which are instances of IPyAutocall are *always* autocalled
123 # Objects which are instances of IPyAutocall are *always* autocalled
124 autocallable = Autocallable()
124 autocallable = Autocallable()
125 ip.user_ns['autocallable'] = autocallable
125 ip.user_ns['autocallable'] = autocallable
126
126
127 # auto
127 # auto
128 ip.magic('autocall 0')
128 ip.magic('autocall 0')
129 # Only explicit escapes or instances of IPyAutocallable should get
129 # Only explicit escapes or instances of IPyAutocallable should get
130 # expanded
130 # expanded
131 run([
131 run([
132 ('len "abc"', 'len "abc"'),
132 ('len "abc"', 'len "abc"'),
133 ('autocallable', 'autocallable()'),
133 ('autocallable', 'autocallable()'),
134 # Don't add extra brackets (gh-1117)
134 # Don't add extra brackets (gh-1117)
135 ('autocallable()', 'autocallable()'),
135 ('autocallable()', 'autocallable()'),
136 (",list 1 2 3", 'list("1", "2", "3")'),
136 (",list 1 2 3", 'list("1", "2", "3")'),
137 (";list 1 2 3", 'list("1 2 3")'),
137 (";list 1 2 3", 'list("1 2 3")'),
138 ("/len range(1,4)", 'len(range(1,4))'),
138 ("/len range(1,4)", 'len(range(1,4))'),
139 ])
139 ])
140 ip.magic('autocall 1')
140 ip.magic('autocall 1')
141 run([
141 run([
142 (",list 1 2 3", 'list("1", "2", "3")'),
142 (",list 1 2 3", 'list("1", "2", "3")'),
143 (";list 1 2 3", 'list("1 2 3")'),
143 (";list 1 2 3", 'list("1 2 3")'),
144 ("/len range(1,4)", 'len(range(1,4))'),
144 ("/len range(1,4)", 'len(range(1,4))'),
145 ('len "abc"', 'len("abc")'),
145 ('len "abc"', 'len("abc")'),
146 ('len "abc";', 'len("abc");'), # ; is special -- moves out of parens
146 ('len "abc";', 'len("abc");'), # ; is special -- moves out of parens
147 # Autocall is turned off if first arg is [] and the object
147 # Autocall is turned off if first arg is [] and the object
148 # is both callable and indexable. Like so:
148 # is both callable and indexable. Like so:
149 ('len [1,2]', 'len([1,2])'), # len doesn't support __getitem__...
149 ('len [1,2]', 'len([1,2])'), # len doesn't support __getitem__...
150 ('call_idx [1]', 'call_idx [1]'), # call_idx *does*..
150 ('call_idx [1]', 'call_idx [1]'), # call_idx *does*..
151 ('call_idx 1', 'call_idx(1)'),
151 ('call_idx 1', 'call_idx(1)'),
152 ('len', 'len'), # only at 2 does it auto-call on single args
152 ('len', 'len'), # only at 2 does it auto-call on single args
153 ])
153 ])
154 ip.magic('autocall 2')
154 ip.magic('autocall 2')
155 run([
155 run([
156 (",list 1 2 3", 'list("1", "2", "3")'),
156 (",list 1 2 3", 'list("1", "2", "3")'),
157 (";list 1 2 3", 'list("1 2 3")'),
157 (";list 1 2 3", 'list("1 2 3")'),
158 ("/len range(1,4)", 'len(range(1,4))'),
158 ("/len range(1,4)", 'len(range(1,4))'),
159 ('len "abc"', 'len("abc")'),
159 ('len "abc"', 'len("abc")'),
160 ('len "abc";', 'len("abc");'),
160 ('len "abc";', 'len("abc");'),
161 ('len [1,2]', 'len([1,2])'),
161 ('len [1,2]', 'len([1,2])'),
162 ('call_idx [1]', 'call_idx [1]'),
162 ('call_idx [1]', 'call_idx [1]'),
163 ('call_idx 1', 'call_idx(1)'),
163 ('call_idx 1', 'call_idx(1)'),
164 # This is what's different:
164 # This is what's different:
165 ('len', 'len()'), # only at 2 does it auto-call on single args
165 ('len', 'len()'), # only at 2 does it auto-call on single args
166 ])
166 ])
167 ip.magic('autocall 1')
167 ip.magic('autocall 1')
168
168
169 nt.assert_equals(failures, [])
169 nt.assert_equal(failures, [])
@@ -1,151 +1,151
1 # coding: utf-8
1 # coding: utf-8
2 """Tests for the IPython tab-completion machinery.
2 """Tests for the IPython tab-completion machinery.
3 """
3 """
4 #-----------------------------------------------------------------------------
4 #-----------------------------------------------------------------------------
5 # Module imports
5 # Module imports
6 #-----------------------------------------------------------------------------
6 #-----------------------------------------------------------------------------
7
7
8 # stdlib
8 # stdlib
9 import os
9 import os
10 import shutil
10 import shutil
11 import sys
11 import sys
12 import tempfile
12 import tempfile
13 import unittest
13 import unittest
14 from datetime import datetime
14 from datetime import datetime
15
15
16 # third party
16 # third party
17 import nose.tools as nt
17 import nose.tools as nt
18
18
19 # our own packages
19 # our own packages
20 from IPython.config.loader import Config
20 from IPython.config.loader import Config
21 from IPython.utils.tempdir import TemporaryDirectory
21 from IPython.utils.tempdir import TemporaryDirectory
22 from IPython.core.history import HistoryManager, extract_hist_ranges
22 from IPython.core.history import HistoryManager, extract_hist_ranges
23 from IPython.utils import py3compat
23 from IPython.utils import py3compat
24
24
25 def setUp():
25 def setUp():
26 nt.assert_equal(sys.getdefaultencoding(), "utf-8" if py3compat.PY3 else "ascii")
26 nt.assert_equal(sys.getdefaultencoding(), "utf-8" if py3compat.PY3 else "ascii")
27
27
28 def test_history():
28 def test_history():
29 ip = get_ipython()
29 ip = get_ipython()
30 with TemporaryDirectory() as tmpdir:
30 with TemporaryDirectory() as tmpdir:
31 hist_manager_ori = ip.history_manager
31 hist_manager_ori = ip.history_manager
32 hist_file = os.path.join(tmpdir, 'history.sqlite')
32 hist_file = os.path.join(tmpdir, 'history.sqlite')
33 try:
33 try:
34 ip.history_manager = HistoryManager(shell=ip, hist_file=hist_file)
34 ip.history_manager = HistoryManager(shell=ip, hist_file=hist_file)
35 hist = [u'a=1', u'def f():\n test = 1\n return test', u"b='β‚¬Γ†ΒΎΓ·ΓŸ'"]
35 hist = [u'a=1', u'def f():\n test = 1\n return test', u"b='β‚¬Γ†ΒΎΓ·ΓŸ'"]
36 for i, h in enumerate(hist, start=1):
36 for i, h in enumerate(hist, start=1):
37 ip.history_manager.store_inputs(i, h)
37 ip.history_manager.store_inputs(i, h)
38
38
39 ip.history_manager.db_log_output = True
39 ip.history_manager.db_log_output = True
40 # Doesn't match the input, but we'll just check it's stored.
40 # Doesn't match the input, but we'll just check it's stored.
41 ip.history_manager.output_hist_reprs[3] = "spam"
41 ip.history_manager.output_hist_reprs[3] = "spam"
42 ip.history_manager.store_output(3)
42 ip.history_manager.store_output(3)
43
43
44 nt.assert_equal(ip.history_manager.input_hist_raw, [''] + hist)
44 nt.assert_equal(ip.history_manager.input_hist_raw, [''] + hist)
45
45
46 # Detailed tests for _get_range_session
46 # Detailed tests for _get_range_session
47 grs = ip.history_manager._get_range_session
47 grs = ip.history_manager._get_range_session
48 nt.assert_equal(list(grs(start=2,stop=-1)), zip([0], [2], hist[1:-1]))
48 nt.assert_equal(list(grs(start=2,stop=-1)), zip([0], [2], hist[1:-1]))
49 nt.assert_equal(list(grs(start=-2)), zip([0,0], [2,3], hist[-2:]))
49 nt.assert_equal(list(grs(start=-2)), zip([0,0], [2,3], hist[-2:]))
50 nt.assert_equal(list(grs(output=True)), zip([0,0,0], [1,2,3], zip(hist, [None,None,'spam'])))
50 nt.assert_equal(list(grs(output=True)), zip([0,0,0], [1,2,3], zip(hist, [None,None,'spam'])))
51
51
52 # Check whether specifying a range beyond the end of the current
52 # Check whether specifying a range beyond the end of the current
53 # session results in an error (gh-804)
53 # session results in an error (gh-804)
54 ip.magic('%hist 2-500')
54 ip.magic('%hist 2-500')
55
55
56 # Check that we can write non-ascii characters to a file
56 # Check that we can write non-ascii characters to a file
57 ip.magic("%%hist -f %s" % os.path.join(tmpdir, "test1"))
57 ip.magic("%%hist -f %s" % os.path.join(tmpdir, "test1"))
58 ip.magic("%%hist -pf %s" % os.path.join(tmpdir, "test2"))
58 ip.magic("%%hist -pf %s" % os.path.join(tmpdir, "test2"))
59 ip.magic("%%hist -nf %s" % os.path.join(tmpdir, "test3"))
59 ip.magic("%%hist -nf %s" % os.path.join(tmpdir, "test3"))
60 ip.magic("%%save %s 1-10" % os.path.join(tmpdir, "test4"))
60 ip.magic("%%save %s 1-10" % os.path.join(tmpdir, "test4"))
61
61
62 # New session
62 # New session
63 ip.history_manager.reset()
63 ip.history_manager.reset()
64 newcmds = ["z=5","class X(object):\n pass", "k='p'"]
64 newcmds = ["z=5","class X(object):\n pass", "k='p'"]
65 for i, cmd in enumerate(newcmds, start=1):
65 for i, cmd in enumerate(newcmds, start=1):
66 ip.history_manager.store_inputs(i, cmd)
66 ip.history_manager.store_inputs(i, cmd)
67 gothist = ip.history_manager.get_range(start=1, stop=4)
67 gothist = ip.history_manager.get_range(start=1, stop=4)
68 nt.assert_equal(list(gothist), zip([0,0,0],[1,2,3], newcmds))
68 nt.assert_equal(list(gothist), zip([0,0,0],[1,2,3], newcmds))
69 # Previous session:
69 # Previous session:
70 gothist = ip.history_manager.get_range(-1, 1, 4)
70 gothist = ip.history_manager.get_range(-1, 1, 4)
71 nt.assert_equal(list(gothist), zip([1,1,1],[1,2,3], hist))
71 nt.assert_equal(list(gothist), zip([1,1,1],[1,2,3], hist))
72
72
73 # Check get_hist_tail
73 # Check get_hist_tail
74 gothist = ip.history_manager.get_tail(4, output=True,
74 gothist = ip.history_manager.get_tail(4, output=True,
75 include_latest=True)
75 include_latest=True)
76 expected = [(1, 3, (hist[-1], "spam")),
76 expected = [(1, 3, (hist[-1], "spam")),
77 (2, 1, (newcmds[0], None)),
77 (2, 1, (newcmds[0], None)),
78 (2, 2, (newcmds[1], None)),
78 (2, 2, (newcmds[1], None)),
79 (2, 3, (newcmds[2], None)),]
79 (2, 3, (newcmds[2], None)),]
80 nt.assert_equal(list(gothist), expected)
80 nt.assert_equal(list(gothist), expected)
81
81
82 gothist = ip.history_manager.get_tail(2)
82 gothist = ip.history_manager.get_tail(2)
83 expected = [(2, 1, newcmds[0]),
83 expected = [(2, 1, newcmds[0]),
84 (2, 2, newcmds[1])]
84 (2, 2, newcmds[1])]
85 nt.assert_equal(list(gothist), expected)
85 nt.assert_equal(list(gothist), expected)
86
86
87 # Check get_hist_search
87 # Check get_hist_search
88 gothist = ip.history_manager.search("*test*")
88 gothist = ip.history_manager.search("*test*")
89 nt.assert_equal(list(gothist), [(1,2,hist[1])] )
89 nt.assert_equal(list(gothist), [(1,2,hist[1])] )
90 gothist = ip.history_manager.search("b*", output=True)
90 gothist = ip.history_manager.search("b*", output=True)
91 nt.assert_equal(list(gothist), [(1,3,(hist[2],"spam"))] )
91 nt.assert_equal(list(gothist), [(1,3,(hist[2],"spam"))] )
92
92
93 # Cross testing: check that magic %save can get previous session.
93 # Cross testing: check that magic %save can get previous session.
94 testfilename = os.path.realpath(os.path.join(tmpdir, "test.py"))
94 testfilename = os.path.realpath(os.path.join(tmpdir, "test.py"))
95 ip.magic("save " + testfilename + " ~1/1-3")
95 ip.magic("save " + testfilename + " ~1/1-3")
96 with py3compat.open(testfilename, encoding='utf-8') as testfile:
96 with py3compat.open(testfilename, encoding='utf-8') as testfile:
97 nt.assert_equal(testfile.read(),
97 nt.assert_equal(testfile.read(),
98 u"# coding: utf-8\n" + u"\n".join(hist)+u"\n")
98 u"# coding: utf-8\n" + u"\n".join(hist)+u"\n")
99
99
100 # Duplicate line numbers - check that it doesn't crash, and
100 # Duplicate line numbers - check that it doesn't crash, and
101 # gets a new session
101 # gets a new session
102 ip.history_manager.store_inputs(1, "rogue")
102 ip.history_manager.store_inputs(1, "rogue")
103 ip.history_manager.writeout_cache()
103 ip.history_manager.writeout_cache()
104 nt.assert_equal(ip.history_manager.session_number, 3)
104 nt.assert_equal(ip.history_manager.session_number, 3)
105 finally:
105 finally:
106 # Restore history manager
106 # Restore history manager
107 ip.history_manager = hist_manager_ori
107 ip.history_manager = hist_manager_ori
108
108
109
109
110 def test_extract_hist_ranges():
110 def test_extract_hist_ranges():
111 instr = "1 2/3 ~4/5-6 ~4/7-~4/9 ~9/2-~7/5"
111 instr = "1 2/3 ~4/5-6 ~4/7-~4/9 ~9/2-~7/5"
112 expected = [(0, 1, 2), # 0 == current session
112 expected = [(0, 1, 2), # 0 == current session
113 (2, 3, 4),
113 (2, 3, 4),
114 (-4, 5, 7),
114 (-4, 5, 7),
115 (-4, 7, 10),
115 (-4, 7, 10),
116 (-9, 2, None), # None == to end
116 (-9, 2, None), # None == to end
117 (-8, 1, None),
117 (-8, 1, None),
118 (-7, 1, 6)]
118 (-7, 1, 6)]
119 actual = list(extract_hist_ranges(instr))
119 actual = list(extract_hist_ranges(instr))
120 nt.assert_equal(actual, expected)
120 nt.assert_equal(actual, expected)
121
121
122 def test_magic_rerun():
122 def test_magic_rerun():
123 """Simple test for %rerun (no args -> rerun last line)"""
123 """Simple test for %rerun (no args -> rerun last line)"""
124 ip = get_ipython()
124 ip = get_ipython()
125 ip.run_cell("a = 10", store_history=True)
125 ip.run_cell("a = 10", store_history=True)
126 ip.run_cell("a += 1", store_history=True)
126 ip.run_cell("a += 1", store_history=True)
127 nt.assert_equal(ip.user_ns["a"], 11)
127 nt.assert_equal(ip.user_ns["a"], 11)
128 ip.run_cell("%rerun", store_history=True)
128 ip.run_cell("%rerun", store_history=True)
129 nt.assert_equal(ip.user_ns["a"], 12)
129 nt.assert_equal(ip.user_ns["a"], 12)
130
130
131 def test_timestamp_type():
131 def test_timestamp_type():
132 ip = get_ipython()
132 ip = get_ipython()
133 info = ip.history_manager.get_session_info()
133 info = ip.history_manager.get_session_info()
134 nt.assert_true(isinstance(info[1], datetime))
134 nt.assert_true(isinstance(info[1], datetime))
135
135
136 def test_hist_file_config():
136 def test_hist_file_config():
137 cfg = Config()
137 cfg = Config()
138 tfile = tempfile.NamedTemporaryFile(delete=False)
138 tfile = tempfile.NamedTemporaryFile(delete=False)
139 cfg.HistoryManager.hist_file = tfile.name
139 cfg.HistoryManager.hist_file = tfile.name
140 try:
140 try:
141 hm = HistoryManager(shell=get_ipython(), config=cfg)
141 hm = HistoryManager(shell=get_ipython(), config=cfg)
142 nt.assert_equals(hm.hist_file, cfg.HistoryManager.hist_file)
142 nt.assert_equal(hm.hist_file, cfg.HistoryManager.hist_file)
143 finally:
143 finally:
144 try:
144 try:
145 os.remove(tfile.name)
145 os.remove(tfile.name)
146 except OSError:
146 except OSError:
147 # same catch as in testing.tools.TempFileMixin
147 # same catch as in testing.tools.TempFileMixin
148 # On Windows, even though we close the file, we still can't
148 # On Windows, even though we close the file, we still can't
149 # delete it. I have no clue why
149 # delete it. I have no clue why
150 pass
150 pass
151
151
@@ -1,845 +1,845
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Tests for the inputsplitter module.
2 """Tests for the inputsplitter module.
3
3
4 Authors
4 Authors
5 -------
5 -------
6 * Fernando Perez
6 * Fernando Perez
7 * Robert Kern
7 * Robert Kern
8 """
8 """
9 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
10 # Copyright (C) 2010-2011 The IPython Development Team
10 # Copyright (C) 2010-2011 The IPython Development Team
11 #
11 #
12 # Distributed under the terms of the BSD License. The full license is in
12 # Distributed under the terms of the BSD License. The full license is in
13 # the file COPYING, distributed as part of this software.
13 # the file COPYING, distributed as part of this software.
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15
15
16 #-----------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
17 # Imports
17 # Imports
18 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
19 # stdlib
19 # stdlib
20 import unittest
20 import unittest
21 import sys
21 import sys
22
22
23 # Third party
23 # Third party
24 import nose.tools as nt
24 import nose.tools as nt
25
25
26 # Our own
26 # Our own
27 from IPython.core import inputsplitter as isp
27 from IPython.core import inputsplitter as isp
28 from IPython.testing import tools as tt
28 from IPython.testing import tools as tt
29 from IPython.utils import py3compat
29 from IPython.utils import py3compat
30
30
31 #-----------------------------------------------------------------------------
31 #-----------------------------------------------------------------------------
32 # Semi-complete examples (also used as tests)
32 # Semi-complete examples (also used as tests)
33 #-----------------------------------------------------------------------------
33 #-----------------------------------------------------------------------------
34
34
35 # Note: at the bottom, there's a slightly more complete version of this that
35 # Note: at the bottom, there's a slightly more complete version of this that
36 # can be useful during development of code here.
36 # can be useful during development of code here.
37
37
38 def mini_interactive_loop(input_func):
38 def mini_interactive_loop(input_func):
39 """Minimal example of the logic of an interactive interpreter loop.
39 """Minimal example of the logic of an interactive interpreter loop.
40
40
41 This serves as an example, and it is used by the test system with a fake
41 This serves as an example, and it is used by the test system with a fake
42 raw_input that simulates interactive input."""
42 raw_input that simulates interactive input."""
43
43
44 from IPython.core.inputsplitter import InputSplitter
44 from IPython.core.inputsplitter import InputSplitter
45
45
46 isp = InputSplitter()
46 isp = InputSplitter()
47 # In practice, this input loop would be wrapped in an outside loop to read
47 # In practice, this input loop would be wrapped in an outside loop to read
48 # input indefinitely, until some exit/quit command was issued. Here we
48 # input indefinitely, until some exit/quit command was issued. Here we
49 # only illustrate the basic inner loop.
49 # only illustrate the basic inner loop.
50 while isp.push_accepts_more():
50 while isp.push_accepts_more():
51 indent = ' '*isp.indent_spaces
51 indent = ' '*isp.indent_spaces
52 prompt = '>>> ' + indent
52 prompt = '>>> ' + indent
53 line = indent + input_func(prompt)
53 line = indent + input_func(prompt)
54 isp.push(line)
54 isp.push(line)
55
55
56 # Here we just return input so we can use it in a test suite, but a real
56 # Here we just return input so we can use it in a test suite, but a real
57 # interpreter would instead send it for execution somewhere.
57 # interpreter would instead send it for execution somewhere.
58 src = isp.source_reset()
58 src = isp.source_reset()
59 #print 'Input source was:\n', src # dbg
59 #print 'Input source was:\n', src # dbg
60 return src
60 return src
61
61
62 #-----------------------------------------------------------------------------
62 #-----------------------------------------------------------------------------
63 # Test utilities, just for local use
63 # Test utilities, just for local use
64 #-----------------------------------------------------------------------------
64 #-----------------------------------------------------------------------------
65
65
66 def assemble(block):
66 def assemble(block):
67 """Assemble a block into multi-line sub-blocks."""
67 """Assemble a block into multi-line sub-blocks."""
68 return ['\n'.join(sub_block)+'\n' for sub_block in block]
68 return ['\n'.join(sub_block)+'\n' for sub_block in block]
69
69
70
70
71 def pseudo_input(lines):
71 def pseudo_input(lines):
72 """Return a function that acts like raw_input but feeds the input list."""
72 """Return a function that acts like raw_input but feeds the input list."""
73 ilines = iter(lines)
73 ilines = iter(lines)
74 def raw_in(prompt):
74 def raw_in(prompt):
75 try:
75 try:
76 return next(ilines)
76 return next(ilines)
77 except StopIteration:
77 except StopIteration:
78 return ''
78 return ''
79 return raw_in
79 return raw_in
80
80
81 #-----------------------------------------------------------------------------
81 #-----------------------------------------------------------------------------
82 # Tests
82 # Tests
83 #-----------------------------------------------------------------------------
83 #-----------------------------------------------------------------------------
84 def test_spaces():
84 def test_spaces():
85 tests = [('', 0),
85 tests = [('', 0),
86 (' ', 1),
86 (' ', 1),
87 ('\n', 0),
87 ('\n', 0),
88 (' \n', 1),
88 (' \n', 1),
89 ('x', 0),
89 ('x', 0),
90 (' x', 1),
90 (' x', 1),
91 (' x',2),
91 (' x',2),
92 (' x',4),
92 (' x',4),
93 # Note: tabs are counted as a single whitespace!
93 # Note: tabs are counted as a single whitespace!
94 ('\tx', 1),
94 ('\tx', 1),
95 ('\t x', 2),
95 ('\t x', 2),
96 ]
96 ]
97 tt.check_pairs(isp.num_ini_spaces, tests)
97 tt.check_pairs(isp.num_ini_spaces, tests)
98
98
99
99
100 def test_remove_comments():
100 def test_remove_comments():
101 tests = [('text', 'text'),
101 tests = [('text', 'text'),
102 ('text # comment', 'text '),
102 ('text # comment', 'text '),
103 ('text # comment\n', 'text \n'),
103 ('text # comment\n', 'text \n'),
104 ('text # comment \n', 'text \n'),
104 ('text # comment \n', 'text \n'),
105 ('line # c \nline\n','line \nline\n'),
105 ('line # c \nline\n','line \nline\n'),
106 ('line # c \nline#c2 \nline\nline #c\n\n',
106 ('line # c \nline#c2 \nline\nline #c\n\n',
107 'line \nline\nline\nline \n\n'),
107 'line \nline\nline\nline \n\n'),
108 ]
108 ]
109 tt.check_pairs(isp.remove_comments, tests)
109 tt.check_pairs(isp.remove_comments, tests)
110
110
111 def test_has_comment():
111 def test_has_comment():
112 tests = [('text', False),
112 tests = [('text', False),
113 ('text #comment', True),
113 ('text #comment', True),
114 ('text #comment\n', True),
114 ('text #comment\n', True),
115 ('#comment', True),
115 ('#comment', True),
116 ('#comment\n', True),
116 ('#comment\n', True),
117 ('a = "#string"', False),
117 ('a = "#string"', False),
118 ('a = "#string" # comment', True),
118 ('a = "#string" # comment', True),
119 ('a #comment not "string"', True),
119 ('a #comment not "string"', True),
120 ]
120 ]
121 tt.check_pairs(isp.has_comment, tests)
121 tt.check_pairs(isp.has_comment, tests)
122
122
123
123
124 def test_get_input_encoding():
124 def test_get_input_encoding():
125 encoding = isp.get_input_encoding()
125 encoding = isp.get_input_encoding()
126 nt.assert_true(isinstance(encoding, basestring))
126 nt.assert_true(isinstance(encoding, basestring))
127 # simple-minded check that at least encoding a simple string works with the
127 # simple-minded check that at least encoding a simple string works with the
128 # encoding we got.
128 # encoding we got.
129 nt.assert_equal(u'test'.encode(encoding), b'test')
129 nt.assert_equal(u'test'.encode(encoding), b'test')
130
130
131
131
132 class NoInputEncodingTestCase(unittest.TestCase):
132 class NoInputEncodingTestCase(unittest.TestCase):
133 def setUp(self):
133 def setUp(self):
134 self.old_stdin = sys.stdin
134 self.old_stdin = sys.stdin
135 class X: pass
135 class X: pass
136 fake_stdin = X()
136 fake_stdin = X()
137 sys.stdin = fake_stdin
137 sys.stdin = fake_stdin
138
138
139 def test(self):
139 def test(self):
140 # Verify that if sys.stdin has no 'encoding' attribute we do the right
140 # Verify that if sys.stdin has no 'encoding' attribute we do the right
141 # thing
141 # thing
142 enc = isp.get_input_encoding()
142 enc = isp.get_input_encoding()
143 self.assertEqual(enc, 'ascii')
143 self.assertEqual(enc, 'ascii')
144
144
145 def tearDown(self):
145 def tearDown(self):
146 sys.stdin = self.old_stdin
146 sys.stdin = self.old_stdin
147
147
148
148
149 class InputSplitterTestCase(unittest.TestCase):
149 class InputSplitterTestCase(unittest.TestCase):
150 def setUp(self):
150 def setUp(self):
151 self.isp = isp.InputSplitter()
151 self.isp = isp.InputSplitter()
152
152
153 def test_reset(self):
153 def test_reset(self):
154 isp = self.isp
154 isp = self.isp
155 isp.push('x=1')
155 isp.push('x=1')
156 isp.reset()
156 isp.reset()
157 self.assertEqual(isp._buffer, [])
157 self.assertEqual(isp._buffer, [])
158 self.assertEqual(isp.indent_spaces, 0)
158 self.assertEqual(isp.indent_spaces, 0)
159 self.assertEqual(isp.source, '')
159 self.assertEqual(isp.source, '')
160 self.assertEqual(isp.code, None)
160 self.assertEqual(isp.code, None)
161 self.assertEqual(isp._is_complete, False)
161 self.assertEqual(isp._is_complete, False)
162
162
163 def test_source(self):
163 def test_source(self):
164 self.isp._store('1')
164 self.isp._store('1')
165 self.isp._store('2')
165 self.isp._store('2')
166 self.assertEqual(self.isp.source, '1\n2\n')
166 self.assertEqual(self.isp.source, '1\n2\n')
167 self.assertTrue(len(self.isp._buffer)>0)
167 self.assertTrue(len(self.isp._buffer)>0)
168 self.assertEqual(self.isp.source_reset(), '1\n2\n')
168 self.assertEqual(self.isp.source_reset(), '1\n2\n')
169 self.assertEqual(self.isp._buffer, [])
169 self.assertEqual(self.isp._buffer, [])
170 self.assertEqual(self.isp.source, '')
170 self.assertEqual(self.isp.source, '')
171
171
172 def test_indent(self):
172 def test_indent(self):
173 isp = self.isp # shorthand
173 isp = self.isp # shorthand
174 isp.push('x=1')
174 isp.push('x=1')
175 self.assertEqual(isp.indent_spaces, 0)
175 self.assertEqual(isp.indent_spaces, 0)
176 isp.push('if 1:\n x=1')
176 isp.push('if 1:\n x=1')
177 self.assertEqual(isp.indent_spaces, 4)
177 self.assertEqual(isp.indent_spaces, 4)
178 isp.push('y=2\n')
178 isp.push('y=2\n')
179 self.assertEqual(isp.indent_spaces, 0)
179 self.assertEqual(isp.indent_spaces, 0)
180
180
181 def test_indent2(self):
181 def test_indent2(self):
182 # In cell mode, inputs must be fed in whole blocks, so skip this test
182 # In cell mode, inputs must be fed in whole blocks, so skip this test
183 if self.isp.input_mode == 'cell': return
183 if self.isp.input_mode == 'cell': return
184
184
185 isp = self.isp
185 isp = self.isp
186 isp.push('if 1:')
186 isp.push('if 1:')
187 self.assertEqual(isp.indent_spaces, 4)
187 self.assertEqual(isp.indent_spaces, 4)
188 isp.push(' x=1')
188 isp.push(' x=1')
189 self.assertEqual(isp.indent_spaces, 4)
189 self.assertEqual(isp.indent_spaces, 4)
190 # Blank lines shouldn't change the indent level
190 # Blank lines shouldn't change the indent level
191 isp.push(' '*2)
191 isp.push(' '*2)
192 self.assertEqual(isp.indent_spaces, 4)
192 self.assertEqual(isp.indent_spaces, 4)
193
193
194 def test_indent3(self):
194 def test_indent3(self):
195 # In cell mode, inputs must be fed in whole blocks, so skip this test
195 # In cell mode, inputs must be fed in whole blocks, so skip this test
196 if self.isp.input_mode == 'cell': return
196 if self.isp.input_mode == 'cell': return
197
197
198 isp = self.isp
198 isp = self.isp
199 # When a multiline statement contains parens or multiline strings, we
199 # When a multiline statement contains parens or multiline strings, we
200 # shouldn't get confused.
200 # shouldn't get confused.
201 isp.push("if 1:")
201 isp.push("if 1:")
202 isp.push(" x = (1+\n 2)")
202 isp.push(" x = (1+\n 2)")
203 self.assertEqual(isp.indent_spaces, 4)
203 self.assertEqual(isp.indent_spaces, 4)
204
204
205 def test_indent4(self):
205 def test_indent4(self):
206 # In cell mode, inputs must be fed in whole blocks, so skip this test
206 # In cell mode, inputs must be fed in whole blocks, so skip this test
207 if self.isp.input_mode == 'cell': return
207 if self.isp.input_mode == 'cell': return
208
208
209 isp = self.isp
209 isp = self.isp
210 # whitespace after ':' should not screw up indent level
210 # whitespace after ':' should not screw up indent level
211 isp.push('if 1: \n x=1')
211 isp.push('if 1: \n x=1')
212 self.assertEqual(isp.indent_spaces, 4)
212 self.assertEqual(isp.indent_spaces, 4)
213 isp.push('y=2\n')
213 isp.push('y=2\n')
214 self.assertEqual(isp.indent_spaces, 0)
214 self.assertEqual(isp.indent_spaces, 0)
215 isp.push('if 1:\t\n x=1')
215 isp.push('if 1:\t\n x=1')
216 self.assertEqual(isp.indent_spaces, 4)
216 self.assertEqual(isp.indent_spaces, 4)
217 isp.push('y=2\n')
217 isp.push('y=2\n')
218 self.assertEqual(isp.indent_spaces, 0)
218 self.assertEqual(isp.indent_spaces, 0)
219
219
220 def test_dedent_pass(self):
220 def test_dedent_pass(self):
221 isp = self.isp # shorthand
221 isp = self.isp # shorthand
222 # should NOT cause dedent
222 # should NOT cause dedent
223 isp.push('if 1:\n passes = 5')
223 isp.push('if 1:\n passes = 5')
224 self.assertEqual(isp.indent_spaces, 4)
224 self.assertEqual(isp.indent_spaces, 4)
225 isp.push('if 1:\n pass')
225 isp.push('if 1:\n pass')
226 self.assertEqual(isp.indent_spaces, 0)
226 self.assertEqual(isp.indent_spaces, 0)
227 isp.push('if 1:\n pass ')
227 isp.push('if 1:\n pass ')
228 self.assertEqual(isp.indent_spaces, 0)
228 self.assertEqual(isp.indent_spaces, 0)
229
229
230 def test_dedent_break(self):
230 def test_dedent_break(self):
231 isp = self.isp # shorthand
231 isp = self.isp # shorthand
232 # should NOT cause dedent
232 # should NOT cause dedent
233 isp.push('while 1:\n breaks = 5')
233 isp.push('while 1:\n breaks = 5')
234 self.assertEqual(isp.indent_spaces, 4)
234 self.assertEqual(isp.indent_spaces, 4)
235 isp.push('while 1:\n break')
235 isp.push('while 1:\n break')
236 self.assertEqual(isp.indent_spaces, 0)
236 self.assertEqual(isp.indent_spaces, 0)
237 isp.push('while 1:\n break ')
237 isp.push('while 1:\n break ')
238 self.assertEqual(isp.indent_spaces, 0)
238 self.assertEqual(isp.indent_spaces, 0)
239
239
240 def test_dedent_continue(self):
240 def test_dedent_continue(self):
241 isp = self.isp # shorthand
241 isp = self.isp # shorthand
242 # should NOT cause dedent
242 # should NOT cause dedent
243 isp.push('while 1:\n continues = 5')
243 isp.push('while 1:\n continues = 5')
244 self.assertEqual(isp.indent_spaces, 4)
244 self.assertEqual(isp.indent_spaces, 4)
245 isp.push('while 1:\n continue')
245 isp.push('while 1:\n continue')
246 self.assertEqual(isp.indent_spaces, 0)
246 self.assertEqual(isp.indent_spaces, 0)
247 isp.push('while 1:\n continue ')
247 isp.push('while 1:\n continue ')
248 self.assertEqual(isp.indent_spaces, 0)
248 self.assertEqual(isp.indent_spaces, 0)
249
249
250 def test_dedent_raise(self):
250 def test_dedent_raise(self):
251 isp = self.isp # shorthand
251 isp = self.isp # shorthand
252 # should NOT cause dedent
252 # should NOT cause dedent
253 isp.push('if 1:\n raised = 4')
253 isp.push('if 1:\n raised = 4')
254 self.assertEqual(isp.indent_spaces, 4)
254 self.assertEqual(isp.indent_spaces, 4)
255 isp.push('if 1:\n raise TypeError()')
255 isp.push('if 1:\n raise TypeError()')
256 self.assertEqual(isp.indent_spaces, 0)
256 self.assertEqual(isp.indent_spaces, 0)
257 isp.push('if 1:\n raise')
257 isp.push('if 1:\n raise')
258 self.assertEqual(isp.indent_spaces, 0)
258 self.assertEqual(isp.indent_spaces, 0)
259 isp.push('if 1:\n raise ')
259 isp.push('if 1:\n raise ')
260 self.assertEqual(isp.indent_spaces, 0)
260 self.assertEqual(isp.indent_spaces, 0)
261
261
262 def test_dedent_return(self):
262 def test_dedent_return(self):
263 isp = self.isp # shorthand
263 isp = self.isp # shorthand
264 # should NOT cause dedent
264 # should NOT cause dedent
265 isp.push('if 1:\n returning = 4')
265 isp.push('if 1:\n returning = 4')
266 self.assertEqual(isp.indent_spaces, 4)
266 self.assertEqual(isp.indent_spaces, 4)
267 isp.push('if 1:\n return 5 + 493')
267 isp.push('if 1:\n return 5 + 493')
268 self.assertEqual(isp.indent_spaces, 0)
268 self.assertEqual(isp.indent_spaces, 0)
269 isp.push('if 1:\n return')
269 isp.push('if 1:\n return')
270 self.assertEqual(isp.indent_spaces, 0)
270 self.assertEqual(isp.indent_spaces, 0)
271 isp.push('if 1:\n return ')
271 isp.push('if 1:\n return ')
272 self.assertEqual(isp.indent_spaces, 0)
272 self.assertEqual(isp.indent_spaces, 0)
273 isp.push('if 1:\n return(0)')
273 isp.push('if 1:\n return(0)')
274 self.assertEqual(isp.indent_spaces, 0)
274 self.assertEqual(isp.indent_spaces, 0)
275
275
276 def test_push(self):
276 def test_push(self):
277 isp = self.isp
277 isp = self.isp
278 self.assertTrue(isp.push('x=1'))
278 self.assertTrue(isp.push('x=1'))
279
279
280 def test_push2(self):
280 def test_push2(self):
281 isp = self.isp
281 isp = self.isp
282 self.assertFalse(isp.push('if 1:'))
282 self.assertFalse(isp.push('if 1:'))
283 for line in [' x=1', '# a comment', ' y=2']:
283 for line in [' x=1', '# a comment', ' y=2']:
284 self.assertTrue(isp.push(line))
284 self.assertTrue(isp.push(line))
285
285
286 def test_push3(self):
286 def test_push3(self):
287 isp = self.isp
287 isp = self.isp
288 isp.push('if True:')
288 isp.push('if True:')
289 isp.push(' a = 1')
289 isp.push(' a = 1')
290 self.assertFalse(isp.push('b = [1,'))
290 self.assertFalse(isp.push('b = [1,'))
291
291
292 def test_replace_mode(self):
292 def test_replace_mode(self):
293 isp = self.isp
293 isp = self.isp
294 isp.input_mode = 'cell'
294 isp.input_mode = 'cell'
295 isp.push('x=1')
295 isp.push('x=1')
296 self.assertEqual(isp.source, 'x=1\n')
296 self.assertEqual(isp.source, 'x=1\n')
297 isp.push('x=2')
297 isp.push('x=2')
298 self.assertEqual(isp.source, 'x=2\n')
298 self.assertEqual(isp.source, 'x=2\n')
299
299
300 def test_push_accepts_more(self):
300 def test_push_accepts_more(self):
301 isp = self.isp
301 isp = self.isp
302 isp.push('x=1')
302 isp.push('x=1')
303 self.assertFalse(isp.push_accepts_more())
303 self.assertFalse(isp.push_accepts_more())
304
304
305 def test_push_accepts_more2(self):
305 def test_push_accepts_more2(self):
306 # In cell mode, inputs must be fed in whole blocks, so skip this test
306 # In cell mode, inputs must be fed in whole blocks, so skip this test
307 if self.isp.input_mode == 'cell': return
307 if self.isp.input_mode == 'cell': return
308
308
309 isp = self.isp
309 isp = self.isp
310 isp.push('if 1:')
310 isp.push('if 1:')
311 self.assertTrue(isp.push_accepts_more())
311 self.assertTrue(isp.push_accepts_more())
312 isp.push(' x=1')
312 isp.push(' x=1')
313 self.assertTrue(isp.push_accepts_more())
313 self.assertTrue(isp.push_accepts_more())
314 isp.push('')
314 isp.push('')
315 self.assertFalse(isp.push_accepts_more())
315 self.assertFalse(isp.push_accepts_more())
316
316
317 def test_push_accepts_more3(self):
317 def test_push_accepts_more3(self):
318 isp = self.isp
318 isp = self.isp
319 isp.push("x = (2+\n3)")
319 isp.push("x = (2+\n3)")
320 self.assertFalse(isp.push_accepts_more())
320 self.assertFalse(isp.push_accepts_more())
321
321
322 def test_push_accepts_more4(self):
322 def test_push_accepts_more4(self):
323 # In cell mode, inputs must be fed in whole blocks, so skip this test
323 # In cell mode, inputs must be fed in whole blocks, so skip this test
324 if self.isp.input_mode == 'cell': return
324 if self.isp.input_mode == 'cell': return
325
325
326 isp = self.isp
326 isp = self.isp
327 # When a multiline statement contains parens or multiline strings, we
327 # When a multiline statement contains parens or multiline strings, we
328 # shouldn't get confused.
328 # shouldn't get confused.
329 # FIXME: we should be able to better handle de-dents in statements like
329 # FIXME: we should be able to better handle de-dents in statements like
330 # multiline strings and multiline expressions (continued with \ or
330 # multiline strings and multiline expressions (continued with \ or
331 # parens). Right now we aren't handling the indentation tracking quite
331 # parens). Right now we aren't handling the indentation tracking quite
332 # correctly with this, though in practice it may not be too much of a
332 # correctly with this, though in practice it may not be too much of a
333 # problem. We'll need to see.
333 # problem. We'll need to see.
334 isp.push("if 1:")
334 isp.push("if 1:")
335 isp.push(" x = (2+")
335 isp.push(" x = (2+")
336 isp.push(" 3)")
336 isp.push(" 3)")
337 self.assertTrue(isp.push_accepts_more())
337 self.assertTrue(isp.push_accepts_more())
338 isp.push(" y = 3")
338 isp.push(" y = 3")
339 self.assertTrue(isp.push_accepts_more())
339 self.assertTrue(isp.push_accepts_more())
340 isp.push('')
340 isp.push('')
341 self.assertFalse(isp.push_accepts_more())
341 self.assertFalse(isp.push_accepts_more())
342
342
343 def test_push_accepts_more5(self):
343 def test_push_accepts_more5(self):
344 # In cell mode, inputs must be fed in whole blocks, so skip this test
344 # In cell mode, inputs must be fed in whole blocks, so skip this test
345 if self.isp.input_mode == 'cell': return
345 if self.isp.input_mode == 'cell': return
346
346
347 isp = self.isp
347 isp = self.isp
348 isp.push('try:')
348 isp.push('try:')
349 isp.push(' a = 5')
349 isp.push(' a = 5')
350 isp.push('except:')
350 isp.push('except:')
351 isp.push(' raise')
351 isp.push(' raise')
352 self.assertTrue(isp.push_accepts_more())
352 self.assertTrue(isp.push_accepts_more())
353
353
354 def test_continuation(self):
354 def test_continuation(self):
355 isp = self.isp
355 isp = self.isp
356 isp.push("import os, \\")
356 isp.push("import os, \\")
357 self.assertTrue(isp.push_accepts_more())
357 self.assertTrue(isp.push_accepts_more())
358 isp.push("sys")
358 isp.push("sys")
359 self.assertFalse(isp.push_accepts_more())
359 self.assertFalse(isp.push_accepts_more())
360
360
361 def test_syntax_error(self):
361 def test_syntax_error(self):
362 isp = self.isp
362 isp = self.isp
363 # Syntax errors immediately produce a 'ready' block, so the invalid
363 # Syntax errors immediately produce a 'ready' block, so the invalid
364 # Python can be sent to the kernel for evaluation with possible ipython
364 # Python can be sent to the kernel for evaluation with possible ipython
365 # special-syntax conversion.
365 # special-syntax conversion.
366 isp.push('run foo')
366 isp.push('run foo')
367 self.assertFalse(isp.push_accepts_more())
367 self.assertFalse(isp.push_accepts_more())
368
368
369 def test_unicode(self):
369 def test_unicode(self):
370 self.isp.push(u"PΓ©rez")
370 self.isp.push(u"PΓ©rez")
371 self.isp.push(u'\xc3\xa9')
371 self.isp.push(u'\xc3\xa9')
372 self.isp.push(u"u'\xc3\xa9'")
372 self.isp.push(u"u'\xc3\xa9'")
373
373
374 def test_line_continuation(self):
374 def test_line_continuation(self):
375 """ Test issue #2108."""
375 """ Test issue #2108."""
376 isp = self.isp
376 isp = self.isp
377 # A blank line after a line continuation should not accept more
377 # A blank line after a line continuation should not accept more
378 isp.push("1 \\\n\n")
378 isp.push("1 \\\n\n")
379 self.assertFalse(isp.push_accepts_more())
379 self.assertFalse(isp.push_accepts_more())
380 # Whitespace after a \ is a SyntaxError. The only way to test that
380 # Whitespace after a \ is a SyntaxError. The only way to test that
381 # here is to test that push doesn't accept more (as with
381 # here is to test that push doesn't accept more (as with
382 # test_syntax_error() above).
382 # test_syntax_error() above).
383 isp.push(r"1 \ ")
383 isp.push(r"1 \ ")
384 self.assertFalse(isp.push_accepts_more())
384 self.assertFalse(isp.push_accepts_more())
385 # Even if the line is continuable (c.f. the regular Python
385 # Even if the line is continuable (c.f. the regular Python
386 # interpreter)
386 # interpreter)
387 isp.push(r"(1 \ ")
387 isp.push(r"(1 \ ")
388 self.assertFalse(isp.push_accepts_more())
388 self.assertFalse(isp.push_accepts_more())
389
389
390 class InteractiveLoopTestCase(unittest.TestCase):
390 class InteractiveLoopTestCase(unittest.TestCase):
391 """Tests for an interactive loop like a python shell.
391 """Tests for an interactive loop like a python shell.
392 """
392 """
393 def check_ns(self, lines, ns):
393 def check_ns(self, lines, ns):
394 """Validate that the given input lines produce the resulting namespace.
394 """Validate that the given input lines produce the resulting namespace.
395
395
396 Note: the input lines are given exactly as they would be typed in an
396 Note: the input lines are given exactly as they would be typed in an
397 auto-indenting environment, as mini_interactive_loop above already does
397 auto-indenting environment, as mini_interactive_loop above already does
398 auto-indenting and prepends spaces to the input.
398 auto-indenting and prepends spaces to the input.
399 """
399 """
400 src = mini_interactive_loop(pseudo_input(lines))
400 src = mini_interactive_loop(pseudo_input(lines))
401 test_ns = {}
401 test_ns = {}
402 exec src in test_ns
402 exec src in test_ns
403 # We can't check that the provided ns is identical to the test_ns,
403 # We can't check that the provided ns is identical to the test_ns,
404 # because Python fills test_ns with extra keys (copyright, etc). But
404 # because Python fills test_ns with extra keys (copyright, etc). But
405 # we can check that the given dict is *contained* in test_ns
405 # we can check that the given dict is *contained* in test_ns
406 for k,v in ns.iteritems():
406 for k,v in ns.iteritems():
407 self.assertEqual(test_ns[k], v)
407 self.assertEqual(test_ns[k], v)
408
408
409 def test_simple(self):
409 def test_simple(self):
410 self.check_ns(['x=1'], dict(x=1))
410 self.check_ns(['x=1'], dict(x=1))
411
411
412 def test_simple2(self):
412 def test_simple2(self):
413 self.check_ns(['if 1:', 'x=2'], dict(x=2))
413 self.check_ns(['if 1:', 'x=2'], dict(x=2))
414
414
415 def test_xy(self):
415 def test_xy(self):
416 self.check_ns(['x=1; y=2'], dict(x=1, y=2))
416 self.check_ns(['x=1; y=2'], dict(x=1, y=2))
417
417
418 def test_abc(self):
418 def test_abc(self):
419 self.check_ns(['if 1:','a=1','b=2','c=3'], dict(a=1, b=2, c=3))
419 self.check_ns(['if 1:','a=1','b=2','c=3'], dict(a=1, b=2, c=3))
420
420
421 def test_multi(self):
421 def test_multi(self):
422 self.check_ns(['x =(1+','1+','2)'], dict(x=4))
422 self.check_ns(['x =(1+','1+','2)'], dict(x=4))
423
423
424
424
425 def test_LineInfo():
425 def test_LineInfo():
426 """Simple test for LineInfo construction and str()"""
426 """Simple test for LineInfo construction and str()"""
427 linfo = isp.LineInfo(' %cd /home')
427 linfo = isp.LineInfo(' %cd /home')
428 nt.assert_equals(str(linfo), 'LineInfo [ |%|cd|/home]')
428 nt.assert_equal(str(linfo), 'LineInfo [ |%|cd|/home]')
429
429
430 # Transformer tests
430 # Transformer tests
431 def transform_checker(tests, func):
431 def transform_checker(tests, func):
432 """Utility to loop over test inputs"""
432 """Utility to loop over test inputs"""
433 for inp, tr in tests:
433 for inp, tr in tests:
434 nt.assert_equals(func(inp), tr)
434 nt.assert_equal(func(inp), tr)
435
435
436 # Data for all the syntax tests in the form of lists of pairs of
436 # Data for all the syntax tests in the form of lists of pairs of
437 # raw/transformed input. We store it here as a global dict so that we can use
437 # raw/transformed input. We store it here as a global dict so that we can use
438 # it both within single-function tests and also to validate the behavior of the
438 # it both within single-function tests and also to validate the behavior of the
439 # larger objects
439 # larger objects
440
440
441 syntax = \
441 syntax = \
442 dict(assign_system =
442 dict(assign_system =
443 [(i,py3compat.u_format(o)) for i,o in \
443 [(i,py3compat.u_format(o)) for i,o in \
444 [(u'a =! ls', "a = get_ipython().getoutput({u}'ls')"),
444 [(u'a =! ls', "a = get_ipython().getoutput({u}'ls')"),
445 (u'b = !ls', "b = get_ipython().getoutput({u}'ls')"),
445 (u'b = !ls', "b = get_ipython().getoutput({u}'ls')"),
446 ('x=1', 'x=1'), # normal input is unmodified
446 ('x=1', 'x=1'), # normal input is unmodified
447 (' ',' '), # blank lines are kept intact
447 (' ',' '), # blank lines are kept intact
448 ]],
448 ]],
449
449
450 assign_magic =
450 assign_magic =
451 [(i,py3compat.u_format(o)) for i,o in \
451 [(i,py3compat.u_format(o)) for i,o in \
452 [(u'a =% who', "a = get_ipython().magic({u}'who')"),
452 [(u'a =% who', "a = get_ipython().magic({u}'who')"),
453 (u'b = %who', "b = get_ipython().magic({u}'who')"),
453 (u'b = %who', "b = get_ipython().magic({u}'who')"),
454 ('x=1', 'x=1'), # normal input is unmodified
454 ('x=1', 'x=1'), # normal input is unmodified
455 (' ',' '), # blank lines are kept intact
455 (' ',' '), # blank lines are kept intact
456 ]],
456 ]],
457
457
458 classic_prompt =
458 classic_prompt =
459 [('>>> x=1', 'x=1'),
459 [('>>> x=1', 'x=1'),
460 ('x=1', 'x=1'), # normal input is unmodified
460 ('x=1', 'x=1'), # normal input is unmodified
461 (' ', ' '), # blank lines are kept intact
461 (' ', ' '), # blank lines are kept intact
462 ('... ', ''), # continuation prompts
462 ('... ', ''), # continuation prompts
463 ],
463 ],
464
464
465 ipy_prompt =
465 ipy_prompt =
466 [('In [1]: x=1', 'x=1'),
466 [('In [1]: x=1', 'x=1'),
467 ('x=1', 'x=1'), # normal input is unmodified
467 ('x=1', 'x=1'), # normal input is unmodified
468 (' ',' '), # blank lines are kept intact
468 (' ',' '), # blank lines are kept intact
469 (' ....: ', ''), # continuation prompts
469 (' ....: ', ''), # continuation prompts
470 ],
470 ],
471
471
472 # Tests for the escape transformer to leave normal code alone
472 # Tests for the escape transformer to leave normal code alone
473 escaped_noesc =
473 escaped_noesc =
474 [ (' ', ' '),
474 [ (' ', ' '),
475 ('x=1', 'x=1'),
475 ('x=1', 'x=1'),
476 ],
476 ],
477
477
478 # System calls
478 # System calls
479 escaped_shell =
479 escaped_shell =
480 [(i,py3compat.u_format(o)) for i,o in \
480 [(i,py3compat.u_format(o)) for i,o in \
481 [ (u'!ls', "get_ipython().system({u}'ls')"),
481 [ (u'!ls', "get_ipython().system({u}'ls')"),
482 # Double-escape shell, this means to capture the output of the
482 # Double-escape shell, this means to capture the output of the
483 # subprocess and return it
483 # subprocess and return it
484 (u'!!ls', "get_ipython().getoutput({u}'ls')"),
484 (u'!!ls', "get_ipython().getoutput({u}'ls')"),
485 ]],
485 ]],
486
486
487 # Help/object info
487 # Help/object info
488 escaped_help =
488 escaped_help =
489 [(i,py3compat.u_format(o)) for i,o in \
489 [(i,py3compat.u_format(o)) for i,o in \
490 [ (u'?', 'get_ipython().show_usage()'),
490 [ (u'?', 'get_ipython().show_usage()'),
491 (u'?x1', "get_ipython().magic({u}'pinfo x1')"),
491 (u'?x1', "get_ipython().magic({u}'pinfo x1')"),
492 (u'??x2', "get_ipython().magic({u}'pinfo2 x2')"),
492 (u'??x2', "get_ipython().magic({u}'pinfo2 x2')"),
493 (u'?a.*s', "get_ipython().magic({u}'psearch a.*s')"),
493 (u'?a.*s', "get_ipython().magic({u}'psearch a.*s')"),
494 (u'?%hist1', "get_ipython().magic({u}'pinfo %hist1')"),
494 (u'?%hist1', "get_ipython().magic({u}'pinfo %hist1')"),
495 (u'?%%hist2', "get_ipython().magic({u}'pinfo %%hist2')"),
495 (u'?%%hist2', "get_ipython().magic({u}'pinfo %%hist2')"),
496 (u'?abc = qwe', "get_ipython().magic({u}'pinfo abc')"),
496 (u'?abc = qwe', "get_ipython().magic({u}'pinfo abc')"),
497 ]],
497 ]],
498
498
499 end_help =
499 end_help =
500 [(i,py3compat.u_format(o)) for i,o in \
500 [(i,py3compat.u_format(o)) for i,o in \
501 [ (u'x3?', "get_ipython().magic({u}'pinfo x3')"),
501 [ (u'x3?', "get_ipython().magic({u}'pinfo x3')"),
502 (u'x4??', "get_ipython().magic({u}'pinfo2 x4')"),
502 (u'x4??', "get_ipython().magic({u}'pinfo2 x4')"),
503 (u'%hist1?', "get_ipython().magic({u}'pinfo %hist1')"),
503 (u'%hist1?', "get_ipython().magic({u}'pinfo %hist1')"),
504 (u'%hist2??', "get_ipython().magic({u}'pinfo2 %hist2')"),
504 (u'%hist2??', "get_ipython().magic({u}'pinfo2 %hist2')"),
505 (u'%%hist3?', "get_ipython().magic({u}'pinfo %%hist3')"),
505 (u'%%hist3?', "get_ipython().magic({u}'pinfo %%hist3')"),
506 (u'%%hist4??', "get_ipython().magic({u}'pinfo2 %%hist4')"),
506 (u'%%hist4??', "get_ipython().magic({u}'pinfo2 %%hist4')"),
507 (u'f*?', "get_ipython().magic({u}'psearch f*')"),
507 (u'f*?', "get_ipython().magic({u}'psearch f*')"),
508 (u'ax.*aspe*?', "get_ipython().magic({u}'psearch ax.*aspe*')"),
508 (u'ax.*aspe*?', "get_ipython().magic({u}'psearch ax.*aspe*')"),
509 (u'a = abc?', "get_ipython().set_next_input({u}'a = abc');"
509 (u'a = abc?', "get_ipython().set_next_input({u}'a = abc');"
510 "get_ipython().magic({u}'pinfo abc')"),
510 "get_ipython().magic({u}'pinfo abc')"),
511 (u'a = abc.qe??', "get_ipython().set_next_input({u}'a = abc.qe');"
511 (u'a = abc.qe??', "get_ipython().set_next_input({u}'a = abc.qe');"
512 "get_ipython().magic({u}'pinfo2 abc.qe')"),
512 "get_ipython().magic({u}'pinfo2 abc.qe')"),
513 (u'a = *.items?', "get_ipython().set_next_input({u}'a = *.items');"
513 (u'a = *.items?', "get_ipython().set_next_input({u}'a = *.items');"
514 "get_ipython().magic({u}'psearch *.items')"),
514 "get_ipython().magic({u}'psearch *.items')"),
515 (u'plot(a?', "get_ipython().set_next_input({u}'plot(a');"
515 (u'plot(a?', "get_ipython().set_next_input({u}'plot(a');"
516 "get_ipython().magic({u}'pinfo a')"),
516 "get_ipython().magic({u}'pinfo a')"),
517 (u'a*2 #comment?', 'a*2 #comment?'),
517 (u'a*2 #comment?', 'a*2 #comment?'),
518 ]],
518 ]],
519
519
520 # Explicit magic calls
520 # Explicit magic calls
521 escaped_magic =
521 escaped_magic =
522 [(i,py3compat.u_format(o)) for i,o in \
522 [(i,py3compat.u_format(o)) for i,o in \
523 [ (u'%cd', "get_ipython().magic({u}'cd')"),
523 [ (u'%cd', "get_ipython().magic({u}'cd')"),
524 (u'%cd /home', "get_ipython().magic({u}'cd /home')"),
524 (u'%cd /home', "get_ipython().magic({u}'cd /home')"),
525 # Backslashes need to be escaped.
525 # Backslashes need to be escaped.
526 (u'%cd C:\\User', "get_ipython().magic({u}'cd C:\\\\User')"),
526 (u'%cd C:\\User', "get_ipython().magic({u}'cd C:\\\\User')"),
527 (u' %magic', " get_ipython().magic({u}'magic')"),
527 (u' %magic', " get_ipython().magic({u}'magic')"),
528 ]],
528 ]],
529
529
530 # Quoting with separate arguments
530 # Quoting with separate arguments
531 escaped_quote =
531 escaped_quote =
532 [ (',f', 'f("")'),
532 [ (',f', 'f("")'),
533 (',f x', 'f("x")'),
533 (',f x', 'f("x")'),
534 (' ,f y', ' f("y")'),
534 (' ,f y', ' f("y")'),
535 (',f a b', 'f("a", "b")'),
535 (',f a b', 'f("a", "b")'),
536 ],
536 ],
537
537
538 # Quoting with single argument
538 # Quoting with single argument
539 escaped_quote2 =
539 escaped_quote2 =
540 [ (';f', 'f("")'),
540 [ (';f', 'f("")'),
541 (';f x', 'f("x")'),
541 (';f x', 'f("x")'),
542 (' ;f y', ' f("y")'),
542 (' ;f y', ' f("y")'),
543 (';f a b', 'f("a b")'),
543 (';f a b', 'f("a b")'),
544 ],
544 ],
545
545
546 # Simply apply parens
546 # Simply apply parens
547 escaped_paren =
547 escaped_paren =
548 [ ('/f', 'f()'),
548 [ ('/f', 'f()'),
549 ('/f x', 'f(x)'),
549 ('/f x', 'f(x)'),
550 (' /f y', ' f(y)'),
550 (' /f y', ' f(y)'),
551 ('/f a b', 'f(a, b)'),
551 ('/f a b', 'f(a, b)'),
552 ],
552 ],
553
553
554 # Check that we transform prompts before other transforms
554 # Check that we transform prompts before other transforms
555 mixed =
555 mixed =
556 [(i,py3compat.u_format(o)) for i,o in \
556 [(i,py3compat.u_format(o)) for i,o in \
557 [ (u'In [1]: %lsmagic', "get_ipython().magic({u}'lsmagic')"),
557 [ (u'In [1]: %lsmagic', "get_ipython().magic({u}'lsmagic')"),
558 (u'>>> %lsmagic', "get_ipython().magic({u}'lsmagic')"),
558 (u'>>> %lsmagic', "get_ipython().magic({u}'lsmagic')"),
559 (u'In [2]: !ls', "get_ipython().system({u}'ls')"),
559 (u'In [2]: !ls', "get_ipython().system({u}'ls')"),
560 (u'In [3]: abs?', "get_ipython().magic({u}'pinfo abs')"),
560 (u'In [3]: abs?', "get_ipython().magic({u}'pinfo abs')"),
561 (u'In [4]: b = %who', "b = get_ipython().magic({u}'who')"),
561 (u'In [4]: b = %who', "b = get_ipython().magic({u}'who')"),
562 ]],
562 ]],
563 )
563 )
564
564
565 # multiline syntax examples. Each of these should be a list of lists, with
565 # multiline syntax examples. Each of these should be a list of lists, with
566 # each entry itself having pairs of raw/transformed input. The union (with
566 # each entry itself having pairs of raw/transformed input. The union (with
567 # '\n'.join() of the transformed inputs is what the splitter should produce
567 # '\n'.join() of the transformed inputs is what the splitter should produce
568 # when fed the raw lines one at a time via push.
568 # when fed the raw lines one at a time via push.
569 syntax_ml = \
569 syntax_ml = \
570 dict(classic_prompt =
570 dict(classic_prompt =
571 [ [('>>> for i in range(10):','for i in range(10):'),
571 [ [('>>> for i in range(10):','for i in range(10):'),
572 ('... print i',' print i'),
572 ('... print i',' print i'),
573 ('... ', ''),
573 ('... ', ''),
574 ],
574 ],
575 ],
575 ],
576
576
577 ipy_prompt =
577 ipy_prompt =
578 [ [('In [24]: for i in range(10):','for i in range(10):'),
578 [ [('In [24]: for i in range(10):','for i in range(10):'),
579 (' ....: print i',' print i'),
579 (' ....: print i',' print i'),
580 (' ....: ', ''),
580 (' ....: ', ''),
581 ],
581 ],
582 ],
582 ],
583
583
584 multiline_datastructure =
584 multiline_datastructure =
585 [ [('>>> a = [1,','a = [1,'),
585 [ [('>>> a = [1,','a = [1,'),
586 ('... 2]','2]'),
586 ('... 2]','2]'),
587 ],
587 ],
588 ],
588 ],
589 )
589 )
590
590
591
591
592 def test_assign_system():
592 def test_assign_system():
593 tt.check_pairs(isp.transform_assign_system, syntax['assign_system'])
593 tt.check_pairs(isp.transform_assign_system, syntax['assign_system'])
594
594
595
595
596 def test_assign_magic():
596 def test_assign_magic():
597 tt.check_pairs(isp.transform_assign_magic, syntax['assign_magic'])
597 tt.check_pairs(isp.transform_assign_magic, syntax['assign_magic'])
598
598
599
599
600 def test_classic_prompt():
600 def test_classic_prompt():
601 transform_checker(syntax['classic_prompt'], isp.transform_classic_prompt)
601 transform_checker(syntax['classic_prompt'], isp.transform_classic_prompt)
602 for example in syntax_ml['classic_prompt']:
602 for example in syntax_ml['classic_prompt']:
603 transform_checker(example, isp.transform_classic_prompt)
603 transform_checker(example, isp.transform_classic_prompt)
604
604
605
605
606 def test_ipy_prompt():
606 def test_ipy_prompt():
607 transform_checker(syntax['ipy_prompt'], isp.transform_ipy_prompt)
607 transform_checker(syntax['ipy_prompt'], isp.transform_ipy_prompt)
608 for example in syntax_ml['ipy_prompt']:
608 for example in syntax_ml['ipy_prompt']:
609 transform_checker(example, isp.transform_ipy_prompt)
609 transform_checker(example, isp.transform_ipy_prompt)
610
610
611 def test_end_help():
611 def test_end_help():
612 tt.check_pairs(isp.transform_help_end, syntax['end_help'])
612 tt.check_pairs(isp.transform_help_end, syntax['end_help'])
613
613
614 def test_escaped_noesc():
614 def test_escaped_noesc():
615 tt.check_pairs(isp.transform_escaped, syntax['escaped_noesc'])
615 tt.check_pairs(isp.transform_escaped, syntax['escaped_noesc'])
616
616
617
617
618 def test_escaped_shell():
618 def test_escaped_shell():
619 tt.check_pairs(isp.transform_escaped, syntax['escaped_shell'])
619 tt.check_pairs(isp.transform_escaped, syntax['escaped_shell'])
620
620
621
621
622 def test_escaped_help():
622 def test_escaped_help():
623 tt.check_pairs(isp.transform_escaped, syntax['escaped_help'])
623 tt.check_pairs(isp.transform_escaped, syntax['escaped_help'])
624
624
625
625
626 def test_escaped_magic():
626 def test_escaped_magic():
627 tt.check_pairs(isp.transform_escaped, syntax['escaped_magic'])
627 tt.check_pairs(isp.transform_escaped, syntax['escaped_magic'])
628
628
629
629
630 def test_escaped_quote():
630 def test_escaped_quote():
631 tt.check_pairs(isp.transform_escaped, syntax['escaped_quote'])
631 tt.check_pairs(isp.transform_escaped, syntax['escaped_quote'])
632
632
633
633
634 def test_escaped_quote2():
634 def test_escaped_quote2():
635 tt.check_pairs(isp.transform_escaped, syntax['escaped_quote2'])
635 tt.check_pairs(isp.transform_escaped, syntax['escaped_quote2'])
636
636
637
637
638 def test_escaped_paren():
638 def test_escaped_paren():
639 tt.check_pairs(isp.transform_escaped, syntax['escaped_paren'])
639 tt.check_pairs(isp.transform_escaped, syntax['escaped_paren'])
640
640
641
641
642 class IPythonInputTestCase(InputSplitterTestCase):
642 class IPythonInputTestCase(InputSplitterTestCase):
643 """By just creating a new class whose .isp is a different instance, we
643 """By just creating a new class whose .isp is a different instance, we
644 re-run the same test battery on the new input splitter.
644 re-run the same test battery on the new input splitter.
645
645
646 In addition, this runs the tests over the syntax and syntax_ml dicts that
646 In addition, this runs the tests over the syntax and syntax_ml dicts that
647 were tested by individual functions, as part of the OO interface.
647 were tested by individual functions, as part of the OO interface.
648
648
649 It also makes some checks on the raw buffer storage.
649 It also makes some checks on the raw buffer storage.
650 """
650 """
651
651
652 def setUp(self):
652 def setUp(self):
653 self.isp = isp.IPythonInputSplitter(input_mode='line')
653 self.isp = isp.IPythonInputSplitter(input_mode='line')
654
654
655 def test_syntax(self):
655 def test_syntax(self):
656 """Call all single-line syntax tests from the main object"""
656 """Call all single-line syntax tests from the main object"""
657 isp = self.isp
657 isp = self.isp
658 for example in syntax.itervalues():
658 for example in syntax.itervalues():
659 for raw, out_t in example:
659 for raw, out_t in example:
660 if raw.startswith(' '):
660 if raw.startswith(' '):
661 continue
661 continue
662
662
663 isp.push(raw+'\n')
663 isp.push(raw+'\n')
664 out, out_raw = isp.source_raw_reset()
664 out, out_raw = isp.source_raw_reset()
665 self.assertEqual(out.rstrip(), out_t,
665 self.assertEqual(out.rstrip(), out_t,
666 tt.pair_fail_msg.format("inputsplitter",raw, out_t, out))
666 tt.pair_fail_msg.format("inputsplitter",raw, out_t, out))
667 self.assertEqual(out_raw.rstrip(), raw.rstrip())
667 self.assertEqual(out_raw.rstrip(), raw.rstrip())
668
668
669 def test_syntax_multiline(self):
669 def test_syntax_multiline(self):
670 isp = self.isp
670 isp = self.isp
671 for example in syntax_ml.itervalues():
671 for example in syntax_ml.itervalues():
672 out_t_parts = []
672 out_t_parts = []
673 raw_parts = []
673 raw_parts = []
674 for line_pairs in example:
674 for line_pairs in example:
675 for lraw, out_t_part in line_pairs:
675 for lraw, out_t_part in line_pairs:
676 isp.push(lraw)
676 isp.push(lraw)
677 out_t_parts.append(out_t_part)
677 out_t_parts.append(out_t_part)
678 raw_parts.append(lraw)
678 raw_parts.append(lraw)
679
679
680 out, out_raw = isp.source_raw_reset()
680 out, out_raw = isp.source_raw_reset()
681 out_t = '\n'.join(out_t_parts).rstrip()
681 out_t = '\n'.join(out_t_parts).rstrip()
682 raw = '\n'.join(raw_parts).rstrip()
682 raw = '\n'.join(raw_parts).rstrip()
683 self.assertEqual(out.rstrip(), out_t)
683 self.assertEqual(out.rstrip(), out_t)
684 self.assertEqual(out_raw.rstrip(), raw)
684 self.assertEqual(out_raw.rstrip(), raw)
685
685
686
686
687 class BlockIPythonInputTestCase(IPythonInputTestCase):
687 class BlockIPythonInputTestCase(IPythonInputTestCase):
688
688
689 # Deactivate tests that don't make sense for the block mode
689 # Deactivate tests that don't make sense for the block mode
690 test_push3 = test_split = lambda s: None
690 test_push3 = test_split = lambda s: None
691
691
692 def setUp(self):
692 def setUp(self):
693 self.isp = isp.IPythonInputSplitter(input_mode='cell')
693 self.isp = isp.IPythonInputSplitter(input_mode='cell')
694
694
695 def test_syntax_multiline(self):
695 def test_syntax_multiline(self):
696 isp = self.isp
696 isp = self.isp
697 for example in syntax_ml.itervalues():
697 for example in syntax_ml.itervalues():
698 raw_parts = []
698 raw_parts = []
699 out_t_parts = []
699 out_t_parts = []
700 for line_pairs in example:
700 for line_pairs in example:
701 for raw, out_t_part in line_pairs:
701 for raw, out_t_part in line_pairs:
702 raw_parts.append(raw)
702 raw_parts.append(raw)
703 out_t_parts.append(out_t_part)
703 out_t_parts.append(out_t_part)
704
704
705 raw = '\n'.join(raw_parts)
705 raw = '\n'.join(raw_parts)
706 out_t = '\n'.join(out_t_parts)
706 out_t = '\n'.join(out_t_parts)
707
707
708 isp.push(raw)
708 isp.push(raw)
709 out, out_raw = isp.source_raw_reset()
709 out, out_raw = isp.source_raw_reset()
710 # Match ignoring trailing whitespace
710 # Match ignoring trailing whitespace
711 self.assertEqual(out.rstrip(), out_t.rstrip())
711 self.assertEqual(out.rstrip(), out_t.rstrip())
712 self.assertEqual(out_raw.rstrip(), raw.rstrip())
712 self.assertEqual(out_raw.rstrip(), raw.rstrip())
713
713
714 def test_syntax_multiline_cell(self):
714 def test_syntax_multiline_cell(self):
715 isp = self.isp
715 isp = self.isp
716 for example in syntax_ml.itervalues():
716 for example in syntax_ml.itervalues():
717
717
718 out_t_parts = []
718 out_t_parts = []
719 for line_pairs in example:
719 for line_pairs in example:
720 raw = '\n'.join(r for r, _ in line_pairs)
720 raw = '\n'.join(r for r, _ in line_pairs)
721 out_t = '\n'.join(t for _,t in line_pairs)
721 out_t = '\n'.join(t for _,t in line_pairs)
722 out = isp.transform_cell(raw)
722 out = isp.transform_cell(raw)
723 # Match ignoring trailing whitespace
723 # Match ignoring trailing whitespace
724 self.assertEqual(out.rstrip(), out_t.rstrip())
724 self.assertEqual(out.rstrip(), out_t.rstrip())
725
725
726 #-----------------------------------------------------------------------------
726 #-----------------------------------------------------------------------------
727 # Main - use as a script, mostly for developer experiments
727 # Main - use as a script, mostly for developer experiments
728 #-----------------------------------------------------------------------------
728 #-----------------------------------------------------------------------------
729
729
730 if __name__ == '__main__':
730 if __name__ == '__main__':
731 # A simple demo for interactive experimentation. This code will not get
731 # A simple demo for interactive experimentation. This code will not get
732 # picked up by any test suite.
732 # picked up by any test suite.
733 from IPython.core.inputsplitter import InputSplitter, IPythonInputSplitter
733 from IPython.core.inputsplitter import InputSplitter, IPythonInputSplitter
734
734
735 # configure here the syntax to use, prompt and whether to autoindent
735 # configure here the syntax to use, prompt and whether to autoindent
736 #isp, start_prompt = InputSplitter(), '>>> '
736 #isp, start_prompt = InputSplitter(), '>>> '
737 isp, start_prompt = IPythonInputSplitter(), 'In> '
737 isp, start_prompt = IPythonInputSplitter(), 'In> '
738
738
739 autoindent = True
739 autoindent = True
740 #autoindent = False
740 #autoindent = False
741
741
742 try:
742 try:
743 while True:
743 while True:
744 prompt = start_prompt
744 prompt = start_prompt
745 while isp.push_accepts_more():
745 while isp.push_accepts_more():
746 indent = ' '*isp.indent_spaces
746 indent = ' '*isp.indent_spaces
747 if autoindent:
747 if autoindent:
748 line = indent + raw_input(prompt+indent)
748 line = indent + raw_input(prompt+indent)
749 else:
749 else:
750 line = raw_input(prompt)
750 line = raw_input(prompt)
751 isp.push(line)
751 isp.push(line)
752 prompt = '... '
752 prompt = '... '
753
753
754 # Here we just return input so we can use it in a test suite, but a
754 # Here we just return input so we can use it in a test suite, but a
755 # real interpreter would instead send it for execution somewhere.
755 # real interpreter would instead send it for execution somewhere.
756 #src = isp.source; raise EOFError # dbg
756 #src = isp.source; raise EOFError # dbg
757 src, raw = isp.source_raw_reset()
757 src, raw = isp.source_raw_reset()
758 print 'Input source was:\n', src
758 print 'Input source was:\n', src
759 print 'Raw source was:\n', raw
759 print 'Raw source was:\n', raw
760 except EOFError:
760 except EOFError:
761 print 'Bye'
761 print 'Bye'
762
762
763 # Tests for cell magics support
763 # Tests for cell magics support
764
764
765 def test_last_blank():
765 def test_last_blank():
766 nt.assert_false(isp.last_blank(''))
766 nt.assert_false(isp.last_blank(''))
767 nt.assert_false(isp.last_blank('abc'))
767 nt.assert_false(isp.last_blank('abc'))
768 nt.assert_false(isp.last_blank('abc\n'))
768 nt.assert_false(isp.last_blank('abc\n'))
769 nt.assert_false(isp.last_blank('abc\na'))
769 nt.assert_false(isp.last_blank('abc\na'))
770
770
771 nt.assert_true(isp.last_blank('\n'))
771 nt.assert_true(isp.last_blank('\n'))
772 nt.assert_true(isp.last_blank('\n '))
772 nt.assert_true(isp.last_blank('\n '))
773 nt.assert_true(isp.last_blank('abc\n '))
773 nt.assert_true(isp.last_blank('abc\n '))
774 nt.assert_true(isp.last_blank('abc\n\n'))
774 nt.assert_true(isp.last_blank('abc\n\n'))
775 nt.assert_true(isp.last_blank('abc\nd\n\n'))
775 nt.assert_true(isp.last_blank('abc\nd\n\n'))
776 nt.assert_true(isp.last_blank('abc\nd\ne\n\n'))
776 nt.assert_true(isp.last_blank('abc\nd\ne\n\n'))
777 nt.assert_true(isp.last_blank('abc \n \n \n\n'))
777 nt.assert_true(isp.last_blank('abc \n \n \n\n'))
778
778
779
779
780 def test_last_two_blanks():
780 def test_last_two_blanks():
781 nt.assert_false(isp.last_two_blanks(''))
781 nt.assert_false(isp.last_two_blanks(''))
782 nt.assert_false(isp.last_two_blanks('abc'))
782 nt.assert_false(isp.last_two_blanks('abc'))
783 nt.assert_false(isp.last_two_blanks('abc\n'))
783 nt.assert_false(isp.last_two_blanks('abc\n'))
784 nt.assert_false(isp.last_two_blanks('abc\n\na'))
784 nt.assert_false(isp.last_two_blanks('abc\n\na'))
785 nt.assert_false(isp.last_two_blanks('abc\n \n'))
785 nt.assert_false(isp.last_two_blanks('abc\n \n'))
786 nt.assert_false(isp.last_two_blanks('abc\n\n'))
786 nt.assert_false(isp.last_two_blanks('abc\n\n'))
787
787
788 nt.assert_true(isp.last_two_blanks('\n\n'))
788 nt.assert_true(isp.last_two_blanks('\n\n'))
789 nt.assert_true(isp.last_two_blanks('\n\n '))
789 nt.assert_true(isp.last_two_blanks('\n\n '))
790 nt.assert_true(isp.last_two_blanks('\n \n'))
790 nt.assert_true(isp.last_two_blanks('\n \n'))
791 nt.assert_true(isp.last_two_blanks('abc\n\n '))
791 nt.assert_true(isp.last_two_blanks('abc\n\n '))
792 nt.assert_true(isp.last_two_blanks('abc\n\n\n'))
792 nt.assert_true(isp.last_two_blanks('abc\n\n\n'))
793 nt.assert_true(isp.last_two_blanks('abc\n\n \n'))
793 nt.assert_true(isp.last_two_blanks('abc\n\n \n'))
794 nt.assert_true(isp.last_two_blanks('abc\n\n \n '))
794 nt.assert_true(isp.last_two_blanks('abc\n\n \n '))
795 nt.assert_true(isp.last_two_blanks('abc\n\n \n \n'))
795 nt.assert_true(isp.last_two_blanks('abc\n\n \n \n'))
796 nt.assert_true(isp.last_two_blanks('abc\nd\n\n\n'))
796 nt.assert_true(isp.last_two_blanks('abc\nd\n\n\n'))
797 nt.assert_true(isp.last_two_blanks('abc\nd\ne\nf\n\n\n'))
797 nt.assert_true(isp.last_two_blanks('abc\nd\ne\nf\n\n\n'))
798
798
799
799
800 class CellMagicsCommon(object):
800 class CellMagicsCommon(object):
801
801
802 def test_whole_cell(self):
802 def test_whole_cell(self):
803 src = "%%cellm line\nbody\n"
803 src = "%%cellm line\nbody\n"
804 sp = self.sp
804 sp = self.sp
805 sp.push(src)
805 sp.push(src)
806 nt.assert_equal(sp.cell_magic_parts, ['body\n'])
806 nt.assert_equal(sp.cell_magic_parts, ['body\n'])
807 out = sp.source
807 out = sp.source
808 ref = u"get_ipython()._run_cached_cell_magic({u}'cellm', {u}'line')\n"
808 ref = u"get_ipython()._run_cached_cell_magic({u}'cellm', {u}'line')\n"
809 nt.assert_equal(out, py3compat.u_format(ref))
809 nt.assert_equal(out, py3compat.u_format(ref))
810
810
811 def tearDown(self):
811 def tearDown(self):
812 self.sp.reset()
812 self.sp.reset()
813
813
814
814
815 class CellModeCellMagics(CellMagicsCommon, unittest.TestCase):
815 class CellModeCellMagics(CellMagicsCommon, unittest.TestCase):
816 sp = isp.IPythonInputSplitter(input_mode='cell')
816 sp = isp.IPythonInputSplitter(input_mode='cell')
817
817
818 def test_incremental(self):
818 def test_incremental(self):
819 sp = self.sp
819 sp = self.sp
820 src = '%%cellm line2\n'
820 src = '%%cellm line2\n'
821 sp.push(src)
821 sp.push(src)
822 nt.assert_true(sp.push_accepts_more()) #1
822 nt.assert_true(sp.push_accepts_more()) #1
823 src += '\n'
823 src += '\n'
824 sp.push(src)
824 sp.push(src)
825 # Note: if we ever change the logic to allow full blank lines (see
825 # Note: if we ever change the logic to allow full blank lines (see
826 # _handle_cell_magic), then the following test should change to true
826 # _handle_cell_magic), then the following test should change to true
827 nt.assert_false(sp.push_accepts_more()) #2
827 nt.assert_false(sp.push_accepts_more()) #2
828 # By now, even with full blanks allowed, a second blank should signal
828 # By now, even with full blanks allowed, a second blank should signal
829 # the end. For now this test is only a redundancy safety, but don't
829 # the end. For now this test is only a redundancy safety, but don't
830 # delete it in case we change our mind and the previous one goes to
830 # delete it in case we change our mind and the previous one goes to
831 # true.
831 # true.
832 src += '\n'
832 src += '\n'
833 sp.push(src)
833 sp.push(src)
834 nt.assert_false(sp.push_accepts_more()) #3
834 nt.assert_false(sp.push_accepts_more()) #3
835
835
836
836
837 class LineModeCellMagics(CellMagicsCommon, unittest.TestCase):
837 class LineModeCellMagics(CellMagicsCommon, unittest.TestCase):
838 sp = isp.IPythonInputSplitter(input_mode='line')
838 sp = isp.IPythonInputSplitter(input_mode='line')
839
839
840 def test_incremental(self):
840 def test_incremental(self):
841 sp = self.sp
841 sp = self.sp
842 sp.push('%%cellm line2\n')
842 sp.push('%%cellm line2\n')
843 nt.assert_true(sp.push_accepts_more()) #1
843 nt.assert_true(sp.push_accepts_more()) #1
844 sp.push('\n')
844 sp.push('\n')
845 nt.assert_false(sp.push_accepts_more()) #2
845 nt.assert_false(sp.push_accepts_more()) #2
@@ -1,260 +1,260
1 """Tests for the key interactiveshell module, where the main ipython class is defined.
1 """Tests for the key interactiveshell module, where the main ipython class is defined.
2 """
2 """
3 #-----------------------------------------------------------------------------
3 #-----------------------------------------------------------------------------
4 # Module imports
4 # Module imports
5 #-----------------------------------------------------------------------------
5 #-----------------------------------------------------------------------------
6
6
7 # stdlib
7 # stdlib
8 import os
8 import os
9 import shutil
9 import shutil
10 import tempfile
10 import tempfile
11
11
12 # third party
12 # third party
13 import nose.tools as nt
13 import nose.tools as nt
14
14
15 # our own packages
15 # our own packages
16 from IPython.testing.globalipapp import get_ipython
16 from IPython.testing.globalipapp import get_ipython
17 from IPython.utils import py3compat
17 from IPython.utils import py3compat
18
18
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20 # Globals
20 # Globals
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22
22
23 # Get the public instance of IPython
23 # Get the public instance of IPython
24 ip = get_ipython()
24 ip = get_ipython()
25
25
26 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
27 # Test functions
27 # Test functions
28 #-----------------------------------------------------------------------------
28 #-----------------------------------------------------------------------------
29
29
30 def test_reset():
30 def test_reset():
31 """reset must clear most namespaces."""
31 """reset must clear most namespaces."""
32
32
33 # Check that reset runs without error
33 # Check that reset runs without error
34 ip.reset()
34 ip.reset()
35
35
36 # Once we've reset it (to clear of any junk that might have been there from
36 # Once we've reset it (to clear of any junk that might have been there from
37 # other tests, we can count how many variables are in the user's namespace
37 # other tests, we can count how many variables are in the user's namespace
38 nvars_user_ns = len(ip.user_ns)
38 nvars_user_ns = len(ip.user_ns)
39 nvars_hidden = len(ip.user_ns_hidden)
39 nvars_hidden = len(ip.user_ns_hidden)
40
40
41 # Now add a few variables to user_ns, and check that reset clears them
41 # Now add a few variables to user_ns, and check that reset clears them
42 ip.user_ns['x'] = 1
42 ip.user_ns['x'] = 1
43 ip.user_ns['y'] = 1
43 ip.user_ns['y'] = 1
44 ip.reset()
44 ip.reset()
45
45
46 # Finally, check that all namespaces have only as many variables as we
46 # Finally, check that all namespaces have only as many variables as we
47 # expect to find in them:
47 # expect to find in them:
48 nt.assert_equals(len(ip.user_ns), nvars_user_ns)
48 nt.assert_equal(len(ip.user_ns), nvars_user_ns)
49 nt.assert_equals(len(ip.user_ns_hidden), nvars_hidden)
49 nt.assert_equal(len(ip.user_ns_hidden), nvars_hidden)
50
50
51
51
52 # Tests for reporting of exceptions in various modes, handling of SystemExit,
52 # Tests for reporting of exceptions in various modes, handling of SystemExit,
53 # and %tb functionality. This is really a mix of testing ultraTB and interactiveshell.
53 # and %tb functionality. This is really a mix of testing ultraTB and interactiveshell.
54
54
55 def doctest_tb_plain():
55 def doctest_tb_plain():
56 """
56 """
57 In [18]: xmode plain
57 In [18]: xmode plain
58 Exception reporting mode: Plain
58 Exception reporting mode: Plain
59
59
60 In [19]: run simpleerr.py
60 In [19]: run simpleerr.py
61 Traceback (most recent call last):
61 Traceback (most recent call last):
62 ...line 32, in <module>
62 ...line 32, in <module>
63 bar(mode)
63 bar(mode)
64 ...line 16, in bar
64 ...line 16, in bar
65 div0()
65 div0()
66 ...line 8, in div0
66 ...line 8, in div0
67 x/y
67 x/y
68 ZeroDivisionError: ...
68 ZeroDivisionError: ...
69 """
69 """
70
70
71
71
72 def doctest_tb_context():
72 def doctest_tb_context():
73 """
73 """
74 In [3]: xmode context
74 In [3]: xmode context
75 Exception reporting mode: Context
75 Exception reporting mode: Context
76
76
77 In [4]: run simpleerr.py
77 In [4]: run simpleerr.py
78 ---------------------------------------------------------------------------
78 ---------------------------------------------------------------------------
79 ZeroDivisionError Traceback (most recent call last)
79 ZeroDivisionError Traceback (most recent call last)
80 <BLANKLINE>
80 <BLANKLINE>
81 ... in <module>()
81 ... in <module>()
82 30 mode = 'div'
82 30 mode = 'div'
83 31
83 31
84 ---> 32 bar(mode)
84 ---> 32 bar(mode)
85 <BLANKLINE>
85 <BLANKLINE>
86 ... in bar(mode)
86 ... in bar(mode)
87 14 "bar"
87 14 "bar"
88 15 if mode=='div':
88 15 if mode=='div':
89 ---> 16 div0()
89 ---> 16 div0()
90 17 elif mode=='exit':
90 17 elif mode=='exit':
91 18 try:
91 18 try:
92 <BLANKLINE>
92 <BLANKLINE>
93 ... in div0()
93 ... in div0()
94 6 x = 1
94 6 x = 1
95 7 y = 0
95 7 y = 0
96 ----> 8 x/y
96 ----> 8 x/y
97 9
97 9
98 10 def sysexit(stat, mode):
98 10 def sysexit(stat, mode):
99 <BLANKLINE>
99 <BLANKLINE>
100 ZeroDivisionError: ...
100 ZeroDivisionError: ...
101 """
101 """
102
102
103
103
104 def doctest_tb_verbose():
104 def doctest_tb_verbose():
105 """
105 """
106 In [5]: xmode verbose
106 In [5]: xmode verbose
107 Exception reporting mode: Verbose
107 Exception reporting mode: Verbose
108
108
109 In [6]: run simpleerr.py
109 In [6]: run simpleerr.py
110 ---------------------------------------------------------------------------
110 ---------------------------------------------------------------------------
111 ZeroDivisionError Traceback (most recent call last)
111 ZeroDivisionError Traceback (most recent call last)
112 <BLANKLINE>
112 <BLANKLINE>
113 ... in <module>()
113 ... in <module>()
114 30 mode = 'div'
114 30 mode = 'div'
115 31
115 31
116 ---> 32 bar(mode)
116 ---> 32 bar(mode)
117 global bar = <function bar at ...>
117 global bar = <function bar at ...>
118 global mode = 'div'
118 global mode = 'div'
119 <BLANKLINE>
119 <BLANKLINE>
120 ... in bar(mode='div')
120 ... in bar(mode='div')
121 14 "bar"
121 14 "bar"
122 15 if mode=='div':
122 15 if mode=='div':
123 ---> 16 div0()
123 ---> 16 div0()
124 global div0 = <function div0 at ...>
124 global div0 = <function div0 at ...>
125 17 elif mode=='exit':
125 17 elif mode=='exit':
126 18 try:
126 18 try:
127 <BLANKLINE>
127 <BLANKLINE>
128 ... in div0()
128 ... in div0()
129 6 x = 1
129 6 x = 1
130 7 y = 0
130 7 y = 0
131 ----> 8 x/y
131 ----> 8 x/y
132 x = 1
132 x = 1
133 y = 0
133 y = 0
134 9
134 9
135 10 def sysexit(stat, mode):
135 10 def sysexit(stat, mode):
136 <BLANKLINE>
136 <BLANKLINE>
137 ZeroDivisionError: ...
137 ZeroDivisionError: ...
138 """
138 """
139
139
140 def doctest_tb_sysexit():
140 def doctest_tb_sysexit():
141 """
141 """
142 In [17]: %xmode plain
142 In [17]: %xmode plain
143 Exception reporting mode: Plain
143 Exception reporting mode: Plain
144
144
145 In [18]: %run simpleerr.py exit
145 In [18]: %run simpleerr.py exit
146 An exception has occurred, use %tb to see the full traceback.
146 An exception has occurred, use %tb to see the full traceback.
147 SystemExit: (1, 'Mode = exit')
147 SystemExit: (1, 'Mode = exit')
148
148
149 In [19]: %run simpleerr.py exit 2
149 In [19]: %run simpleerr.py exit 2
150 An exception has occurred, use %tb to see the full traceback.
150 An exception has occurred, use %tb to see the full traceback.
151 SystemExit: (2, 'Mode = exit')
151 SystemExit: (2, 'Mode = exit')
152
152
153 In [20]: %tb
153 In [20]: %tb
154 Traceback (most recent call last):
154 Traceback (most recent call last):
155 File ... in <module>
155 File ... in <module>
156 bar(mode)
156 bar(mode)
157 File ... line 22, in bar
157 File ... line 22, in bar
158 sysexit(stat, mode)
158 sysexit(stat, mode)
159 File ... line 11, in sysexit
159 File ... line 11, in sysexit
160 raise SystemExit(stat, 'Mode = %s' % mode)
160 raise SystemExit(stat, 'Mode = %s' % mode)
161 SystemExit: (2, 'Mode = exit')
161 SystemExit: (2, 'Mode = exit')
162
162
163 In [21]: %xmode context
163 In [21]: %xmode context
164 Exception reporting mode: Context
164 Exception reporting mode: Context
165
165
166 In [22]: %tb
166 In [22]: %tb
167 ---------------------------------------------------------------------------
167 ---------------------------------------------------------------------------
168 SystemExit Traceback (most recent call last)
168 SystemExit Traceback (most recent call last)
169 <BLANKLINE>
169 <BLANKLINE>
170 ...<module>()
170 ...<module>()
171 30 mode = 'div'
171 30 mode = 'div'
172 31
172 31
173 ---> 32 bar(mode)
173 ---> 32 bar(mode)
174 <BLANKLINE>
174 <BLANKLINE>
175 ...bar(mode)
175 ...bar(mode)
176 20 except:
176 20 except:
177 21 stat = 1
177 21 stat = 1
178 ---> 22 sysexit(stat, mode)
178 ---> 22 sysexit(stat, mode)
179 23 else:
179 23 else:
180 24 raise ValueError('Unknown mode')
180 24 raise ValueError('Unknown mode')
181 <BLANKLINE>
181 <BLANKLINE>
182 ...sysexit(stat, mode)
182 ...sysexit(stat, mode)
183 9
183 9
184 10 def sysexit(stat, mode):
184 10 def sysexit(stat, mode):
185 ---> 11 raise SystemExit(stat, 'Mode = %s' % mode)
185 ---> 11 raise SystemExit(stat, 'Mode = %s' % mode)
186 12
186 12
187 13 def bar(mode):
187 13 def bar(mode):
188 <BLANKLINE>
188 <BLANKLINE>
189 SystemExit: (2, 'Mode = exit')
189 SystemExit: (2, 'Mode = exit')
190
190
191 In [23]: %xmode verbose
191 In [23]: %xmode verbose
192 Exception reporting mode: Verbose
192 Exception reporting mode: Verbose
193
193
194 In [24]: %tb
194 In [24]: %tb
195 ---------------------------------------------------------------------------
195 ---------------------------------------------------------------------------
196 SystemExit Traceback (most recent call last)
196 SystemExit Traceback (most recent call last)
197 <BLANKLINE>
197 <BLANKLINE>
198 ... in <module>()
198 ... in <module>()
199 30 mode = 'div'
199 30 mode = 'div'
200 31
200 31
201 ---> 32 bar(mode)
201 ---> 32 bar(mode)
202 global bar = <function bar at ...>
202 global bar = <function bar at ...>
203 global mode = 'exit'
203 global mode = 'exit'
204 <BLANKLINE>
204 <BLANKLINE>
205 ... in bar(mode='exit')
205 ... in bar(mode='exit')
206 20 except:
206 20 except:
207 21 stat = 1
207 21 stat = 1
208 ---> 22 sysexit(stat, mode)
208 ---> 22 sysexit(stat, mode)
209 global sysexit = <function sysexit at ...>
209 global sysexit = <function sysexit at ...>
210 stat = 2
210 stat = 2
211 mode = 'exit'
211 mode = 'exit'
212 23 else:
212 23 else:
213 24 raise ValueError('Unknown mode')
213 24 raise ValueError('Unknown mode')
214 <BLANKLINE>
214 <BLANKLINE>
215 ... in sysexit(stat=2, mode='exit')
215 ... in sysexit(stat=2, mode='exit')
216 9
216 9
217 10 def sysexit(stat, mode):
217 10 def sysexit(stat, mode):
218 ---> 11 raise SystemExit(stat, 'Mode = %s' % mode)
218 ---> 11 raise SystemExit(stat, 'Mode = %s' % mode)
219 global SystemExit = undefined
219 global SystemExit = undefined
220 stat = 2
220 stat = 2
221 mode = 'exit'
221 mode = 'exit'
222 12
222 12
223 13 def bar(mode):
223 13 def bar(mode):
224 <BLANKLINE>
224 <BLANKLINE>
225 SystemExit: (2, 'Mode = exit')
225 SystemExit: (2, 'Mode = exit')
226 """
226 """
227
227
228
228
229 def test_run_cell():
229 def test_run_cell():
230 import textwrap
230 import textwrap
231 ip.run_cell('a = 10\na+=1')
231 ip.run_cell('a = 10\na+=1')
232 ip.run_cell('assert a == 11\nassert 1')
232 ip.run_cell('assert a == 11\nassert 1')
233
233
234 nt.assert_equals(ip.user_ns['a'], 11)
234 nt.assert_equal(ip.user_ns['a'], 11)
235 complex = textwrap.dedent("""
235 complex = textwrap.dedent("""
236 if 1:
236 if 1:
237 print "hello"
237 print "hello"
238 if 1:
238 if 1:
239 print "world"
239 print "world"
240
240
241 if 2:
241 if 2:
242 print "foo"
242 print "foo"
243
243
244 if 3:
244 if 3:
245 print "bar"
245 print "bar"
246
246
247 if 4:
247 if 4:
248 print "bar"
248 print "bar"
249
249
250 """)
250 """)
251 # Simply verifies that this kind of input is run
251 # Simply verifies that this kind of input is run
252 ip.run_cell(complex)
252 ip.run_cell(complex)
253
253
254
254
255 def test_db():
255 def test_db():
256 """Test the internal database used for variable persistence."""
256 """Test the internal database used for variable persistence."""
257 ip.db['__unittest_'] = 12
257 ip.db['__unittest_'] = 12
258 nt.assert_equals(ip.db['__unittest_'], 12)
258 nt.assert_equal(ip.db['__unittest_'], 12)
259 del ip.db['__unittest_']
259 del ip.db['__unittest_']
260 assert '__unittest_' not in ip.db
260 assert '__unittest_' not in ip.db
@@ -1,764 +1,764
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Tests for various magic functions.
2 """Tests for various magic functions.
3
3
4 Needs to be run by nose (to make ipython session available).
4 Needs to be run by nose (to make ipython session available).
5 """
5 """
6 from __future__ import absolute_import
6 from __future__ import absolute_import
7
7
8 #-----------------------------------------------------------------------------
8 #-----------------------------------------------------------------------------
9 # Imports
9 # Imports
10 #-----------------------------------------------------------------------------
10 #-----------------------------------------------------------------------------
11
11
12 import io
12 import io
13 import os
13 import os
14 import sys
14 import sys
15 from StringIO import StringIO
15 from StringIO import StringIO
16 from unittest import TestCase
16 from unittest import TestCase
17
17
18 try:
18 try:
19 from importlib import invalidate_caches # Required from Python 3.3
19 from importlib import invalidate_caches # Required from Python 3.3
20 except ImportError:
20 except ImportError:
21 def invalidate_caches():
21 def invalidate_caches():
22 pass
22 pass
23
23
24 import nose.tools as nt
24 import nose.tools as nt
25
25
26 from IPython.core import magic
26 from IPython.core import magic
27 from IPython.core.magic import (Magics, magics_class, line_magic,
27 from IPython.core.magic import (Magics, magics_class, line_magic,
28 cell_magic, line_cell_magic,
28 cell_magic, line_cell_magic,
29 register_line_magic, register_cell_magic,
29 register_line_magic, register_cell_magic,
30 register_line_cell_magic)
30 register_line_cell_magic)
31 from IPython.core.magics import execution, script
31 from IPython.core.magics import execution, script
32 from IPython.nbformat.v3.tests.nbexamples import nb0
32 from IPython.nbformat.v3.tests.nbexamples import nb0
33 from IPython.nbformat import current
33 from IPython.nbformat import current
34 from IPython.testing import decorators as dec
34 from IPython.testing import decorators as dec
35 from IPython.testing import tools as tt
35 from IPython.testing import tools as tt
36 from IPython.utils import py3compat
36 from IPython.utils import py3compat
37 from IPython.utils.tempdir import TemporaryDirectory
37 from IPython.utils.tempdir import TemporaryDirectory
38 from IPython.utils.process import find_cmd
38 from IPython.utils.process import find_cmd
39
39
40 #-----------------------------------------------------------------------------
40 #-----------------------------------------------------------------------------
41 # Test functions begin
41 # Test functions begin
42 #-----------------------------------------------------------------------------
42 #-----------------------------------------------------------------------------
43
43
44 @magic.magics_class
44 @magic.magics_class
45 class DummyMagics(magic.Magics): pass
45 class DummyMagics(magic.Magics): pass
46
46
47 def test_rehashx():
47 def test_rehashx():
48 # clear up everything
48 # clear up everything
49 _ip = get_ipython()
49 _ip = get_ipython()
50 _ip.alias_manager.alias_table.clear()
50 _ip.alias_manager.alias_table.clear()
51 del _ip.db['syscmdlist']
51 del _ip.db['syscmdlist']
52
52
53 _ip.magic('rehashx')
53 _ip.magic('rehashx')
54 # Practically ALL ipython development systems will have more than 10 aliases
54 # Practically ALL ipython development systems will have more than 10 aliases
55
55
56 yield (nt.assert_true, len(_ip.alias_manager.alias_table) > 10)
56 yield (nt.assert_true, len(_ip.alias_manager.alias_table) > 10)
57 for key, val in _ip.alias_manager.alias_table.iteritems():
57 for key, val in _ip.alias_manager.alias_table.iteritems():
58 # we must strip dots from alias names
58 # we must strip dots from alias names
59 nt.assert_true('.' not in key)
59 nt.assert_true('.' not in key)
60
60
61 # rehashx must fill up syscmdlist
61 # rehashx must fill up syscmdlist
62 scoms = _ip.db['syscmdlist']
62 scoms = _ip.db['syscmdlist']
63 yield (nt.assert_true, len(scoms) > 10)
63 yield (nt.assert_true, len(scoms) > 10)
64
64
65
65
66 def test_magic_parse_options():
66 def test_magic_parse_options():
67 """Test that we don't mangle paths when parsing magic options."""
67 """Test that we don't mangle paths when parsing magic options."""
68 ip = get_ipython()
68 ip = get_ipython()
69 path = 'c:\\x'
69 path = 'c:\\x'
70 m = DummyMagics(ip)
70 m = DummyMagics(ip)
71 opts = m.parse_options('-f %s' % path,'f:')[0]
71 opts = m.parse_options('-f %s' % path,'f:')[0]
72 # argv splitting is os-dependent
72 # argv splitting is os-dependent
73 if os.name == 'posix':
73 if os.name == 'posix':
74 expected = 'c:x'
74 expected = 'c:x'
75 else:
75 else:
76 expected = path
76 expected = path
77 nt.assert_equals(opts['f'], expected)
77 nt.assert_equal(opts['f'], expected)
78
78
79 def test_magic_parse_long_options():
79 def test_magic_parse_long_options():
80 """Magic.parse_options can handle --foo=bar long options"""
80 """Magic.parse_options can handle --foo=bar long options"""
81 ip = get_ipython()
81 ip = get_ipython()
82 m = DummyMagics(ip)
82 m = DummyMagics(ip)
83 opts, _ = m.parse_options('--foo --bar=bubble', 'a', 'foo', 'bar=')
83 opts, _ = m.parse_options('--foo --bar=bubble', 'a', 'foo', 'bar=')
84 nt.assert_true('foo' in opts)
84 nt.assert_true('foo' in opts)
85 nt.assert_true('bar' in opts)
85 nt.assert_true('bar' in opts)
86 nt.assert_true(opts['bar'], "bubble")
86 nt.assert_true(opts['bar'], "bubble")
87
87
88
88
89 @dec.skip_without('sqlite3')
89 @dec.skip_without('sqlite3')
90 def doctest_hist_f():
90 def doctest_hist_f():
91 """Test %hist -f with temporary filename.
91 """Test %hist -f with temporary filename.
92
92
93 In [9]: import tempfile
93 In [9]: import tempfile
94
94
95 In [10]: tfile = tempfile.mktemp('.py','tmp-ipython-')
95 In [10]: tfile = tempfile.mktemp('.py','tmp-ipython-')
96
96
97 In [11]: %hist -nl -f $tfile 3
97 In [11]: %hist -nl -f $tfile 3
98
98
99 In [13]: import os; os.unlink(tfile)
99 In [13]: import os; os.unlink(tfile)
100 """
100 """
101
101
102
102
103 @dec.skip_without('sqlite3')
103 @dec.skip_without('sqlite3')
104 def doctest_hist_r():
104 def doctest_hist_r():
105 """Test %hist -r
105 """Test %hist -r
106
106
107 XXX - This test is not recording the output correctly. For some reason, in
107 XXX - This test is not recording the output correctly. For some reason, in
108 testing mode the raw history isn't getting populated. No idea why.
108 testing mode the raw history isn't getting populated. No idea why.
109 Disabling the output checking for now, though at least we do run it.
109 Disabling the output checking for now, though at least we do run it.
110
110
111 In [1]: 'hist' in _ip.lsmagic()
111 In [1]: 'hist' in _ip.lsmagic()
112 Out[1]: True
112 Out[1]: True
113
113
114 In [2]: x=1
114 In [2]: x=1
115
115
116 In [3]: %hist -rl 2
116 In [3]: %hist -rl 2
117 x=1 # random
117 x=1 # random
118 %hist -r 2
118 %hist -r 2
119 """
119 """
120
120
121
121
122 @dec.skip_without('sqlite3')
122 @dec.skip_without('sqlite3')
123 def doctest_hist_op():
123 def doctest_hist_op():
124 """Test %hist -op
124 """Test %hist -op
125
125
126 In [1]: class b(float):
126 In [1]: class b(float):
127 ...: pass
127 ...: pass
128 ...:
128 ...:
129
129
130 In [2]: class s(object):
130 In [2]: class s(object):
131 ...: def __str__(self):
131 ...: def __str__(self):
132 ...: return 's'
132 ...: return 's'
133 ...:
133 ...:
134
134
135 In [3]:
135 In [3]:
136
136
137 In [4]: class r(b):
137 In [4]: class r(b):
138 ...: def __repr__(self):
138 ...: def __repr__(self):
139 ...: return 'r'
139 ...: return 'r'
140 ...:
140 ...:
141
141
142 In [5]: class sr(s,r): pass
142 In [5]: class sr(s,r): pass
143 ...:
143 ...:
144
144
145 In [6]:
145 In [6]:
146
146
147 In [7]: bb=b()
147 In [7]: bb=b()
148
148
149 In [8]: ss=s()
149 In [8]: ss=s()
150
150
151 In [9]: rr=r()
151 In [9]: rr=r()
152
152
153 In [10]: ssrr=sr()
153 In [10]: ssrr=sr()
154
154
155 In [11]: 4.5
155 In [11]: 4.5
156 Out[11]: 4.5
156 Out[11]: 4.5
157
157
158 In [12]: str(ss)
158 In [12]: str(ss)
159 Out[12]: 's'
159 Out[12]: 's'
160
160
161 In [13]:
161 In [13]:
162
162
163 In [14]: %hist -op
163 In [14]: %hist -op
164 >>> class b:
164 >>> class b:
165 ... pass
165 ... pass
166 ...
166 ...
167 >>> class s(b):
167 >>> class s(b):
168 ... def __str__(self):
168 ... def __str__(self):
169 ... return 's'
169 ... return 's'
170 ...
170 ...
171 >>>
171 >>>
172 >>> class r(b):
172 >>> class r(b):
173 ... def __repr__(self):
173 ... def __repr__(self):
174 ... return 'r'
174 ... return 'r'
175 ...
175 ...
176 >>> class sr(s,r): pass
176 >>> class sr(s,r): pass
177 >>>
177 >>>
178 >>> bb=b()
178 >>> bb=b()
179 >>> ss=s()
179 >>> ss=s()
180 >>> rr=r()
180 >>> rr=r()
181 >>> ssrr=sr()
181 >>> ssrr=sr()
182 >>> 4.5
182 >>> 4.5
183 4.5
183 4.5
184 >>> str(ss)
184 >>> str(ss)
185 's'
185 's'
186 >>>
186 >>>
187 """
187 """
188
188
189
189
190 @dec.skip_without('sqlite3')
190 @dec.skip_without('sqlite3')
191 def test_macro():
191 def test_macro():
192 ip = get_ipython()
192 ip = get_ipython()
193 ip.history_manager.reset() # Clear any existing history.
193 ip.history_manager.reset() # Clear any existing history.
194 cmds = ["a=1", "def b():\n return a**2", "print(a,b())"]
194 cmds = ["a=1", "def b():\n return a**2", "print(a,b())"]
195 for i, cmd in enumerate(cmds, start=1):
195 for i, cmd in enumerate(cmds, start=1):
196 ip.history_manager.store_inputs(i, cmd)
196 ip.history_manager.store_inputs(i, cmd)
197 ip.magic("macro test 1-3")
197 ip.magic("macro test 1-3")
198 nt.assert_equal(ip.user_ns["test"].value, "\n".join(cmds)+"\n")
198 nt.assert_equal(ip.user_ns["test"].value, "\n".join(cmds)+"\n")
199
199
200 # List macros.
200 # List macros.
201 assert "test" in ip.magic("macro")
201 assert "test" in ip.magic("macro")
202
202
203
203
204 @dec.skip_without('sqlite3')
204 @dec.skip_without('sqlite3')
205 def test_macro_run():
205 def test_macro_run():
206 """Test that we can run a multi-line macro successfully."""
206 """Test that we can run a multi-line macro successfully."""
207 ip = get_ipython()
207 ip = get_ipython()
208 ip.history_manager.reset()
208 ip.history_manager.reset()
209 cmds = ["a=10", "a+=1", py3compat.doctest_refactor_print("print a"),
209 cmds = ["a=10", "a+=1", py3compat.doctest_refactor_print("print a"),
210 "%macro test 2-3"]
210 "%macro test 2-3"]
211 for cmd in cmds:
211 for cmd in cmds:
212 ip.run_cell(cmd, store_history=True)
212 ip.run_cell(cmd, store_history=True)
213 nt.assert_equal(ip.user_ns["test"].value,
213 nt.assert_equal(ip.user_ns["test"].value,
214 py3compat.doctest_refactor_print("a+=1\nprint a\n"))
214 py3compat.doctest_refactor_print("a+=1\nprint a\n"))
215 with tt.AssertPrints("12"):
215 with tt.AssertPrints("12"):
216 ip.run_cell("test")
216 ip.run_cell("test")
217 with tt.AssertPrints("13"):
217 with tt.AssertPrints("13"):
218 ip.run_cell("test")
218 ip.run_cell("test")
219
219
220
220
221 @dec.skipif_not_numpy
221 @dec.skipif_not_numpy
222 def test_numpy_reset_array_undec():
222 def test_numpy_reset_array_undec():
223 "Test '%reset array' functionality"
223 "Test '%reset array' functionality"
224 _ip.ex('import numpy as np')
224 _ip.ex('import numpy as np')
225 _ip.ex('a = np.empty(2)')
225 _ip.ex('a = np.empty(2)')
226 yield (nt.assert_true, 'a' in _ip.user_ns)
226 yield (nt.assert_true, 'a' in _ip.user_ns)
227 _ip.magic('reset -f array')
227 _ip.magic('reset -f array')
228 yield (nt.assert_false, 'a' in _ip.user_ns)
228 yield (nt.assert_false, 'a' in _ip.user_ns)
229
229
230 def test_reset_out():
230 def test_reset_out():
231 "Test '%reset out' magic"
231 "Test '%reset out' magic"
232 _ip.run_cell("parrot = 'dead'", store_history=True)
232 _ip.run_cell("parrot = 'dead'", store_history=True)
233 # test '%reset -f out', make an Out prompt
233 # test '%reset -f out', make an Out prompt
234 _ip.run_cell("parrot", store_history=True)
234 _ip.run_cell("parrot", store_history=True)
235 nt.assert_true('dead' in [_ip.user_ns[x] for x in '_','__','___'])
235 nt.assert_true('dead' in [_ip.user_ns[x] for x in '_','__','___'])
236 _ip.magic('reset -f out')
236 _ip.magic('reset -f out')
237 nt.assert_false('dead' in [_ip.user_ns[x] for x in '_','__','___'])
237 nt.assert_false('dead' in [_ip.user_ns[x] for x in '_','__','___'])
238 nt.assert_true(len(_ip.user_ns['Out']) == 0)
238 nt.assert_true(len(_ip.user_ns['Out']) == 0)
239
239
240 def test_reset_in():
240 def test_reset_in():
241 "Test '%reset in' magic"
241 "Test '%reset in' magic"
242 # test '%reset -f in'
242 # test '%reset -f in'
243 _ip.run_cell("parrot", store_history=True)
243 _ip.run_cell("parrot", store_history=True)
244 nt.assert_true('parrot' in [_ip.user_ns[x] for x in '_i','_ii','_iii'])
244 nt.assert_true('parrot' in [_ip.user_ns[x] for x in '_i','_ii','_iii'])
245 _ip.magic('%reset -f in')
245 _ip.magic('%reset -f in')
246 nt.assert_false('parrot' in [_ip.user_ns[x] for x in '_i','_ii','_iii'])
246 nt.assert_false('parrot' in [_ip.user_ns[x] for x in '_i','_ii','_iii'])
247 nt.assert_true(len(set(_ip.user_ns['In'])) == 1)
247 nt.assert_true(len(set(_ip.user_ns['In'])) == 1)
248
248
249 def test_reset_dhist():
249 def test_reset_dhist():
250 "Test '%reset dhist' magic"
250 "Test '%reset dhist' magic"
251 _ip.run_cell("tmp = [d for d in _dh]") # copy before clearing
251 _ip.run_cell("tmp = [d for d in _dh]") # copy before clearing
252 _ip.magic('cd ' + os.path.dirname(nt.__file__))
252 _ip.magic('cd ' + os.path.dirname(nt.__file__))
253 _ip.magic('cd -')
253 _ip.magic('cd -')
254 nt.assert_true(len(_ip.user_ns['_dh']) > 0)
254 nt.assert_true(len(_ip.user_ns['_dh']) > 0)
255 _ip.magic('reset -f dhist')
255 _ip.magic('reset -f dhist')
256 nt.assert_true(len(_ip.user_ns['_dh']) == 0)
256 nt.assert_true(len(_ip.user_ns['_dh']) == 0)
257 _ip.run_cell("_dh = [d for d in tmp]") #restore
257 _ip.run_cell("_dh = [d for d in tmp]") #restore
258
258
259 def test_reset_in_length():
259 def test_reset_in_length():
260 "Test that '%reset in' preserves In[] length"
260 "Test that '%reset in' preserves In[] length"
261 _ip.run_cell("print 'foo'")
261 _ip.run_cell("print 'foo'")
262 _ip.run_cell("reset -f in")
262 _ip.run_cell("reset -f in")
263 nt.assert_true(len(_ip.user_ns['In']) == _ip.displayhook.prompt_count+1)
263 nt.assert_true(len(_ip.user_ns['In']) == _ip.displayhook.prompt_count+1)
264
264
265 def test_time():
265 def test_time():
266 _ip.magic('time None')
266 _ip.magic('time None')
267
267
268 def test_tb_syntaxerror():
268 def test_tb_syntaxerror():
269 """test %tb after a SyntaxError"""
269 """test %tb after a SyntaxError"""
270 ip = get_ipython()
270 ip = get_ipython()
271 ip.run_cell("for")
271 ip.run_cell("for")
272
272
273 # trap and validate stdout
273 # trap and validate stdout
274 save_stdout = sys.stdout
274 save_stdout = sys.stdout
275 try:
275 try:
276 sys.stdout = StringIO()
276 sys.stdout = StringIO()
277 ip.run_cell("%tb")
277 ip.run_cell("%tb")
278 out = sys.stdout.getvalue()
278 out = sys.stdout.getvalue()
279 finally:
279 finally:
280 sys.stdout = save_stdout
280 sys.stdout = save_stdout
281 # trim output, and only check the last line
281 # trim output, and only check the last line
282 last_line = out.rstrip().splitlines()[-1].strip()
282 last_line = out.rstrip().splitlines()[-1].strip()
283 nt.assert_equals(last_line, "SyntaxError: invalid syntax")
283 nt.assert_equal(last_line, "SyntaxError: invalid syntax")
284
284
285
285
286 @py3compat.doctest_refactor_print
286 @py3compat.doctest_refactor_print
287 def doctest_time():
287 def doctest_time():
288 """
288 """
289 In [10]: %time None
289 In [10]: %time None
290 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
290 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
291 Wall time: 0.00 s
291 Wall time: 0.00 s
292
292
293 In [11]: def f(kmjy):
293 In [11]: def f(kmjy):
294 ....: %time print 2*kmjy
294 ....: %time print 2*kmjy
295
295
296 In [12]: f(3)
296 In [12]: f(3)
297 6
297 6
298 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
298 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
299 Wall time: 0.00 s
299 Wall time: 0.00 s
300 """
300 """
301
301
302
302
303 def test_doctest_mode():
303 def test_doctest_mode():
304 "Toggle doctest_mode twice, it should be a no-op and run without error"
304 "Toggle doctest_mode twice, it should be a no-op and run without error"
305 _ip.magic('doctest_mode')
305 _ip.magic('doctest_mode')
306 _ip.magic('doctest_mode')
306 _ip.magic('doctest_mode')
307
307
308
308
309 def test_parse_options():
309 def test_parse_options():
310 """Tests for basic options parsing in magics."""
310 """Tests for basic options parsing in magics."""
311 # These are only the most minimal of tests, more should be added later. At
311 # These are only the most minimal of tests, more should be added later. At
312 # the very least we check that basic text/unicode calls work OK.
312 # the very least we check that basic text/unicode calls work OK.
313 m = DummyMagics(_ip)
313 m = DummyMagics(_ip)
314 nt.assert_equal(m.parse_options('foo', '')[1], 'foo')
314 nt.assert_equal(m.parse_options('foo', '')[1], 'foo')
315 nt.assert_equal(m.parse_options(u'foo', '')[1], u'foo')
315 nt.assert_equal(m.parse_options(u'foo', '')[1], u'foo')
316
316
317
317
318 def test_dirops():
318 def test_dirops():
319 """Test various directory handling operations."""
319 """Test various directory handling operations."""
320 # curpath = lambda :os.path.splitdrive(os.getcwdu())[1].replace('\\','/')
320 # curpath = lambda :os.path.splitdrive(os.getcwdu())[1].replace('\\','/')
321 curpath = os.getcwdu
321 curpath = os.getcwdu
322 startdir = os.getcwdu()
322 startdir = os.getcwdu()
323 ipdir = os.path.realpath(_ip.ipython_dir)
323 ipdir = os.path.realpath(_ip.ipython_dir)
324 try:
324 try:
325 _ip.magic('cd "%s"' % ipdir)
325 _ip.magic('cd "%s"' % ipdir)
326 nt.assert_equal(curpath(), ipdir)
326 nt.assert_equal(curpath(), ipdir)
327 _ip.magic('cd -')
327 _ip.magic('cd -')
328 nt.assert_equal(curpath(), startdir)
328 nt.assert_equal(curpath(), startdir)
329 _ip.magic('pushd "%s"' % ipdir)
329 _ip.magic('pushd "%s"' % ipdir)
330 nt.assert_equal(curpath(), ipdir)
330 nt.assert_equal(curpath(), ipdir)
331 _ip.magic('popd')
331 _ip.magic('popd')
332 nt.assert_equal(curpath(), startdir)
332 nt.assert_equal(curpath(), startdir)
333 finally:
333 finally:
334 os.chdir(startdir)
334 os.chdir(startdir)
335
335
336
336
337 def test_xmode():
337 def test_xmode():
338 # Calling xmode three times should be a no-op
338 # Calling xmode three times should be a no-op
339 xmode = _ip.InteractiveTB.mode
339 xmode = _ip.InteractiveTB.mode
340 for i in range(3):
340 for i in range(3):
341 _ip.magic("xmode")
341 _ip.magic("xmode")
342 nt.assert_equal(_ip.InteractiveTB.mode, xmode)
342 nt.assert_equal(_ip.InteractiveTB.mode, xmode)
343
343
344 def test_reset_hard():
344 def test_reset_hard():
345 monitor = []
345 monitor = []
346 class A(object):
346 class A(object):
347 def __del__(self):
347 def __del__(self):
348 monitor.append(1)
348 monitor.append(1)
349 def __repr__(self):
349 def __repr__(self):
350 return "<A instance>"
350 return "<A instance>"
351
351
352 _ip.user_ns["a"] = A()
352 _ip.user_ns["a"] = A()
353 _ip.run_cell("a")
353 _ip.run_cell("a")
354
354
355 nt.assert_equal(monitor, [])
355 nt.assert_equal(monitor, [])
356 _ip.magic("reset -f")
356 _ip.magic("reset -f")
357 nt.assert_equal(monitor, [1])
357 nt.assert_equal(monitor, [1])
358
358
359 class TestXdel(tt.TempFileMixin):
359 class TestXdel(tt.TempFileMixin):
360 def test_xdel(self):
360 def test_xdel(self):
361 """Test that references from %run are cleared by xdel."""
361 """Test that references from %run are cleared by xdel."""
362 src = ("class A(object):\n"
362 src = ("class A(object):\n"
363 " monitor = []\n"
363 " monitor = []\n"
364 " def __del__(self):\n"
364 " def __del__(self):\n"
365 " self.monitor.append(1)\n"
365 " self.monitor.append(1)\n"
366 "a = A()\n")
366 "a = A()\n")
367 self.mktmp(src)
367 self.mktmp(src)
368 # %run creates some hidden references...
368 # %run creates some hidden references...
369 _ip.magic("run %s" % self.fname)
369 _ip.magic("run %s" % self.fname)
370 # ... as does the displayhook.
370 # ... as does the displayhook.
371 _ip.run_cell("a")
371 _ip.run_cell("a")
372
372
373 monitor = _ip.user_ns["A"].monitor
373 monitor = _ip.user_ns["A"].monitor
374 nt.assert_equal(monitor, [])
374 nt.assert_equal(monitor, [])
375
375
376 _ip.magic("xdel a")
376 _ip.magic("xdel a")
377
377
378 # Check that a's __del__ method has been called.
378 # Check that a's __del__ method has been called.
379 nt.assert_equal(monitor, [1])
379 nt.assert_equal(monitor, [1])
380
380
381 def doctest_who():
381 def doctest_who():
382 """doctest for %who
382 """doctest for %who
383
383
384 In [1]: %reset -f
384 In [1]: %reset -f
385
385
386 In [2]: alpha = 123
386 In [2]: alpha = 123
387
387
388 In [3]: beta = 'beta'
388 In [3]: beta = 'beta'
389
389
390 In [4]: %who int
390 In [4]: %who int
391 alpha
391 alpha
392
392
393 In [5]: %who str
393 In [5]: %who str
394 beta
394 beta
395
395
396 In [6]: %whos
396 In [6]: %whos
397 Variable Type Data/Info
397 Variable Type Data/Info
398 ----------------------------
398 ----------------------------
399 alpha int 123
399 alpha int 123
400 beta str beta
400 beta str beta
401
401
402 In [7]: %who_ls
402 In [7]: %who_ls
403 Out[7]: ['alpha', 'beta']
403 Out[7]: ['alpha', 'beta']
404 """
404 """
405
405
406 def test_whos():
406 def test_whos():
407 """Check that whos is protected against objects where repr() fails."""
407 """Check that whos is protected against objects where repr() fails."""
408 class A(object):
408 class A(object):
409 def __repr__(self):
409 def __repr__(self):
410 raise Exception()
410 raise Exception()
411 _ip.user_ns['a'] = A()
411 _ip.user_ns['a'] = A()
412 _ip.magic("whos")
412 _ip.magic("whos")
413
413
414 @py3compat.u_format
414 @py3compat.u_format
415 def doctest_precision():
415 def doctest_precision():
416 """doctest for %precision
416 """doctest for %precision
417
417
418 In [1]: f = get_ipython().display_formatter.formatters['text/plain']
418 In [1]: f = get_ipython().display_formatter.formatters['text/plain']
419
419
420 In [2]: %precision 5
420 In [2]: %precision 5
421 Out[2]: {u}'%.5f'
421 Out[2]: {u}'%.5f'
422
422
423 In [3]: f.float_format
423 In [3]: f.float_format
424 Out[3]: {u}'%.5f'
424 Out[3]: {u}'%.5f'
425
425
426 In [4]: %precision %e
426 In [4]: %precision %e
427 Out[4]: {u}'%e'
427 Out[4]: {u}'%e'
428
428
429 In [5]: f(3.1415927)
429 In [5]: f(3.1415927)
430 Out[5]: {u}'3.141593e+00'
430 Out[5]: {u}'3.141593e+00'
431 """
431 """
432
432
433 def test_psearch():
433 def test_psearch():
434 with tt.AssertPrints("dict.fromkeys"):
434 with tt.AssertPrints("dict.fromkeys"):
435 _ip.run_cell("dict.fr*?")
435 _ip.run_cell("dict.fr*?")
436
436
437 def test_timeit_shlex():
437 def test_timeit_shlex():
438 """test shlex issues with timeit (#1109)"""
438 """test shlex issues with timeit (#1109)"""
439 _ip.ex("def f(*a,**kw): pass")
439 _ip.ex("def f(*a,**kw): pass")
440 _ip.magic('timeit -n1 "this is a bug".count(" ")')
440 _ip.magic('timeit -n1 "this is a bug".count(" ")')
441 _ip.magic('timeit -r1 -n1 f(" ", 1)')
441 _ip.magic('timeit -r1 -n1 f(" ", 1)')
442 _ip.magic('timeit -r1 -n1 f(" ", 1, " ", 2, " ")')
442 _ip.magic('timeit -r1 -n1 f(" ", 1, " ", 2, " ")')
443 _ip.magic('timeit -r1 -n1 ("a " + "b")')
443 _ip.magic('timeit -r1 -n1 ("a " + "b")')
444 _ip.magic('timeit -r1 -n1 f("a " + "b")')
444 _ip.magic('timeit -r1 -n1 f("a " + "b")')
445 _ip.magic('timeit -r1 -n1 f("a " + "b ")')
445 _ip.magic('timeit -r1 -n1 f("a " + "b ")')
446
446
447
447
448 def test_timeit_arguments():
448 def test_timeit_arguments():
449 "Test valid timeit arguments, should not cause SyntaxError (GH #1269)"
449 "Test valid timeit arguments, should not cause SyntaxError (GH #1269)"
450 _ip.magic("timeit ('#')")
450 _ip.magic("timeit ('#')")
451
451
452
452
453 def test_timeit_special_syntax():
453 def test_timeit_special_syntax():
454 "Test %%timeit with IPython special syntax"
454 "Test %%timeit with IPython special syntax"
455 from IPython.core.magic import register_line_magic
455 from IPython.core.magic import register_line_magic
456
456
457 @register_line_magic
457 @register_line_magic
458 def lmagic(line):
458 def lmagic(line):
459 ip = get_ipython()
459 ip = get_ipython()
460 ip.user_ns['lmagic_out'] = line
460 ip.user_ns['lmagic_out'] = line
461
461
462 # line mode test
462 # line mode test
463 _ip.run_line_magic('timeit', '-n1 -r1 %lmagic my line')
463 _ip.run_line_magic('timeit', '-n1 -r1 %lmagic my line')
464 nt.assert_equal(_ip.user_ns['lmagic_out'], 'my line')
464 nt.assert_equal(_ip.user_ns['lmagic_out'], 'my line')
465 # cell mode test
465 # cell mode test
466 _ip.run_cell_magic('timeit', '-n1 -r1', '%lmagic my line2')
466 _ip.run_cell_magic('timeit', '-n1 -r1', '%lmagic my line2')
467 nt.assert_equal(_ip.user_ns['lmagic_out'], 'my line2')
467 nt.assert_equal(_ip.user_ns['lmagic_out'], 'my line2')
468
468
469
469
470 @dec.skipif(execution.profile is None)
470 @dec.skipif(execution.profile is None)
471 def test_prun_quotes():
471 def test_prun_quotes():
472 "Test that prun does not clobber string escapes (GH #1302)"
472 "Test that prun does not clobber string escapes (GH #1302)"
473 _ip.magic(r"prun -q x = '\t'")
473 _ip.magic(r"prun -q x = '\t'")
474 nt.assert_equal(_ip.user_ns['x'], '\t')
474 nt.assert_equal(_ip.user_ns['x'], '\t')
475
475
476 def test_extension():
476 def test_extension():
477 tmpdir = TemporaryDirectory()
477 tmpdir = TemporaryDirectory()
478 orig_ipython_dir = _ip.ipython_dir
478 orig_ipython_dir = _ip.ipython_dir
479 try:
479 try:
480 _ip.ipython_dir = tmpdir.name
480 _ip.ipython_dir = tmpdir.name
481 nt.assert_raises(ImportError, _ip.magic, "load_ext daft_extension")
481 nt.assert_raises(ImportError, _ip.magic, "load_ext daft_extension")
482 url = os.path.join(os.path.dirname(__file__), "daft_extension.py")
482 url = os.path.join(os.path.dirname(__file__), "daft_extension.py")
483 _ip.magic("install_ext %s" % url)
483 _ip.magic("install_ext %s" % url)
484 _ip.user_ns.pop('arq', None)
484 _ip.user_ns.pop('arq', None)
485 invalidate_caches() # Clear import caches
485 invalidate_caches() # Clear import caches
486 _ip.magic("load_ext daft_extension")
486 _ip.magic("load_ext daft_extension")
487 tt.assert_equal(_ip.user_ns['arq'], 185)
487 tt.assert_equal(_ip.user_ns['arq'], 185)
488 _ip.magic("unload_ext daft_extension")
488 _ip.magic("unload_ext daft_extension")
489 assert 'arq' not in _ip.user_ns
489 assert 'arq' not in _ip.user_ns
490 finally:
490 finally:
491 _ip.ipython_dir = orig_ipython_dir
491 _ip.ipython_dir = orig_ipython_dir
492 tmpdir.cleanup()
492 tmpdir.cleanup()
493
493
494 def test_notebook_export_json():
494 def test_notebook_export_json():
495 with TemporaryDirectory() as td:
495 with TemporaryDirectory() as td:
496 outfile = os.path.join(td, "nb.ipynb")
496 outfile = os.path.join(td, "nb.ipynb")
497 _ip.ex(py3compat.u_format(u"u = {u}'hΓ©llo'"))
497 _ip.ex(py3compat.u_format(u"u = {u}'hΓ©llo'"))
498 _ip.magic("notebook -e %s" % outfile)
498 _ip.magic("notebook -e %s" % outfile)
499
499
500 def test_notebook_export_py():
500 def test_notebook_export_py():
501 with TemporaryDirectory() as td:
501 with TemporaryDirectory() as td:
502 outfile = os.path.join(td, "nb.py")
502 outfile = os.path.join(td, "nb.py")
503 _ip.ex(py3compat.u_format(u"u = {u}'hΓ©llo'"))
503 _ip.ex(py3compat.u_format(u"u = {u}'hΓ©llo'"))
504 _ip.magic("notebook -e %s" % outfile)
504 _ip.magic("notebook -e %s" % outfile)
505
505
506 def test_notebook_reformat_py():
506 def test_notebook_reformat_py():
507 with TemporaryDirectory() as td:
507 with TemporaryDirectory() as td:
508 infile = os.path.join(td, "nb.ipynb")
508 infile = os.path.join(td, "nb.ipynb")
509 with io.open(infile, 'w', encoding='utf-8') as f:
509 with io.open(infile, 'w', encoding='utf-8') as f:
510 current.write(nb0, f, 'json')
510 current.write(nb0, f, 'json')
511
511
512 _ip.ex(py3compat.u_format(u"u = {u}'hΓ©llo'"))
512 _ip.ex(py3compat.u_format(u"u = {u}'hΓ©llo'"))
513 _ip.magic("notebook -f py %s" % infile)
513 _ip.magic("notebook -f py %s" % infile)
514
514
515 def test_notebook_reformat_json():
515 def test_notebook_reformat_json():
516 with TemporaryDirectory() as td:
516 with TemporaryDirectory() as td:
517 infile = os.path.join(td, "nb.py")
517 infile = os.path.join(td, "nb.py")
518 with io.open(infile, 'w', encoding='utf-8') as f:
518 with io.open(infile, 'w', encoding='utf-8') as f:
519 current.write(nb0, f, 'py')
519 current.write(nb0, f, 'py')
520
520
521 _ip.ex(py3compat.u_format(u"u = {u}'hΓ©llo'"))
521 _ip.ex(py3compat.u_format(u"u = {u}'hΓ©llo'"))
522 _ip.magic("notebook -f ipynb %s" % infile)
522 _ip.magic("notebook -f ipynb %s" % infile)
523 _ip.magic("notebook -f json %s" % infile)
523 _ip.magic("notebook -f json %s" % infile)
524
524
525 def test_env():
525 def test_env():
526 env = _ip.magic("env")
526 env = _ip.magic("env")
527 assert isinstance(env, dict), type(env)
527 assert isinstance(env, dict), type(env)
528
528
529
529
530 class CellMagicTestCase(TestCase):
530 class CellMagicTestCase(TestCase):
531
531
532 def check_ident(self, magic):
532 def check_ident(self, magic):
533 # Manually called, we get the result
533 # Manually called, we get the result
534 out = _ip.run_cell_magic(magic, 'a', 'b')
534 out = _ip.run_cell_magic(magic, 'a', 'b')
535 nt.assert_equals(out, ('a','b'))
535 nt.assert_equal(out, ('a','b'))
536 # Via run_cell, it goes into the user's namespace via displayhook
536 # Via run_cell, it goes into the user's namespace via displayhook
537 _ip.run_cell('%%' + magic +' c\nd')
537 _ip.run_cell('%%' + magic +' c\nd')
538 nt.assert_equals(_ip.user_ns['_'], ('c','d'))
538 nt.assert_equal(_ip.user_ns['_'], ('c','d'))
539
539
540 def test_cell_magic_func_deco(self):
540 def test_cell_magic_func_deco(self):
541 "Cell magic using simple decorator"
541 "Cell magic using simple decorator"
542 @register_cell_magic
542 @register_cell_magic
543 def cellm(line, cell):
543 def cellm(line, cell):
544 return line, cell
544 return line, cell
545
545
546 self.check_ident('cellm')
546 self.check_ident('cellm')
547
547
548 def test_cell_magic_reg(self):
548 def test_cell_magic_reg(self):
549 "Cell magic manually registered"
549 "Cell magic manually registered"
550 def cellm(line, cell):
550 def cellm(line, cell):
551 return line, cell
551 return line, cell
552
552
553 _ip.register_magic_function(cellm, 'cell', 'cellm2')
553 _ip.register_magic_function(cellm, 'cell', 'cellm2')
554 self.check_ident('cellm2')
554 self.check_ident('cellm2')
555
555
556 def test_cell_magic_class(self):
556 def test_cell_magic_class(self):
557 "Cell magics declared via a class"
557 "Cell magics declared via a class"
558 @magics_class
558 @magics_class
559 class MyMagics(Magics):
559 class MyMagics(Magics):
560
560
561 @cell_magic
561 @cell_magic
562 def cellm3(self, line, cell):
562 def cellm3(self, line, cell):
563 return line, cell
563 return line, cell
564
564
565 _ip.register_magics(MyMagics)
565 _ip.register_magics(MyMagics)
566 self.check_ident('cellm3')
566 self.check_ident('cellm3')
567
567
568 def test_cell_magic_class2(self):
568 def test_cell_magic_class2(self):
569 "Cell magics declared via a class, #2"
569 "Cell magics declared via a class, #2"
570 @magics_class
570 @magics_class
571 class MyMagics2(Magics):
571 class MyMagics2(Magics):
572
572
573 @cell_magic('cellm4')
573 @cell_magic('cellm4')
574 def cellm33(self, line, cell):
574 def cellm33(self, line, cell):
575 return line, cell
575 return line, cell
576
576
577 _ip.register_magics(MyMagics2)
577 _ip.register_magics(MyMagics2)
578 self.check_ident('cellm4')
578 self.check_ident('cellm4')
579 # Check that nothing is registered as 'cellm33'
579 # Check that nothing is registered as 'cellm33'
580 c33 = _ip.find_cell_magic('cellm33')
580 c33 = _ip.find_cell_magic('cellm33')
581 nt.assert_equals(c33, None)
581 nt.assert_equal(c33, None)
582
582
583 def test_file():
583 def test_file():
584 """Basic %%file"""
584 """Basic %%file"""
585 ip = get_ipython()
585 ip = get_ipython()
586 with TemporaryDirectory() as td:
586 with TemporaryDirectory() as td:
587 fname = os.path.join(td, 'file1')
587 fname = os.path.join(td, 'file1')
588 ip.run_cell_magic("file", fname, u'\n'.join([
588 ip.run_cell_magic("file", fname, u'\n'.join([
589 'line1',
589 'line1',
590 'line2',
590 'line2',
591 ]))
591 ]))
592 with open(fname) as f:
592 with open(fname) as f:
593 s = f.read()
593 s = f.read()
594 nt.assert_in('line1\n', s)
594 nt.assert_in('line1\n', s)
595 nt.assert_in('line2', s)
595 nt.assert_in('line2', s)
596
596
597 def test_file_unicode():
597 def test_file_unicode():
598 """%%file with unicode cell"""
598 """%%file with unicode cell"""
599 ip = get_ipython()
599 ip = get_ipython()
600 with TemporaryDirectory() as td:
600 with TemporaryDirectory() as td:
601 fname = os.path.join(td, 'file1')
601 fname = os.path.join(td, 'file1')
602 ip.run_cell_magic("file", fname, u'\n'.join([
602 ip.run_cell_magic("file", fname, u'\n'.join([
603 u'linΓ©1',
603 u'linΓ©1',
604 u'linΓ©2',
604 u'linΓ©2',
605 ]))
605 ]))
606 with io.open(fname, encoding='utf-8') as f:
606 with io.open(fname, encoding='utf-8') as f:
607 s = f.read()
607 s = f.read()
608 nt.assert_in(u'linΓ©1\n', s)
608 nt.assert_in(u'linΓ©1\n', s)
609 nt.assert_in(u'linΓ©2', s)
609 nt.assert_in(u'linΓ©2', s)
610
610
611 def test_file_amend():
611 def test_file_amend():
612 """%%file -a amends files"""
612 """%%file -a amends files"""
613 ip = get_ipython()
613 ip = get_ipython()
614 with TemporaryDirectory() as td:
614 with TemporaryDirectory() as td:
615 fname = os.path.join(td, 'file2')
615 fname = os.path.join(td, 'file2')
616 ip.run_cell_magic("file", fname, u'\n'.join([
616 ip.run_cell_magic("file", fname, u'\n'.join([
617 'line1',
617 'line1',
618 'line2',
618 'line2',
619 ]))
619 ]))
620 ip.run_cell_magic("file", "-a %s" % fname, u'\n'.join([
620 ip.run_cell_magic("file", "-a %s" % fname, u'\n'.join([
621 'line3',
621 'line3',
622 'line4',
622 'line4',
623 ]))
623 ]))
624 with open(fname) as f:
624 with open(fname) as f:
625 s = f.read()
625 s = f.read()
626 nt.assert_in('line1\n', s)
626 nt.assert_in('line1\n', s)
627 nt.assert_in('line3\n', s)
627 nt.assert_in('line3\n', s)
628
628
629
629
630 def test_script_config():
630 def test_script_config():
631 ip = get_ipython()
631 ip = get_ipython()
632 ip.config.ScriptMagics.script_magics = ['whoda']
632 ip.config.ScriptMagics.script_magics = ['whoda']
633 sm = script.ScriptMagics(shell=ip)
633 sm = script.ScriptMagics(shell=ip)
634 nt.assert_in('whoda', sm.magics['cell'])
634 nt.assert_in('whoda', sm.magics['cell'])
635
635
636 @dec.skip_win32
636 @dec.skip_win32
637 def test_script_out():
637 def test_script_out():
638 ip = get_ipython()
638 ip = get_ipython()
639 ip.run_cell_magic("script", "--out output sh", "echo 'hi'")
639 ip.run_cell_magic("script", "--out output sh", "echo 'hi'")
640 nt.assert_equals(ip.user_ns['output'], 'hi\n')
640 nt.assert_equal(ip.user_ns['output'], 'hi\n')
641
641
642 @dec.skip_win32
642 @dec.skip_win32
643 def test_script_err():
643 def test_script_err():
644 ip = get_ipython()
644 ip = get_ipython()
645 ip.run_cell_magic("script", "--err error sh", "echo 'hello' >&2")
645 ip.run_cell_magic("script", "--err error sh", "echo 'hello' >&2")
646 nt.assert_equals(ip.user_ns['error'], 'hello\n')
646 nt.assert_equal(ip.user_ns['error'], 'hello\n')
647
647
648 @dec.skip_win32
648 @dec.skip_win32
649 def test_script_out_err():
649 def test_script_out_err():
650 ip = get_ipython()
650 ip = get_ipython()
651 ip.run_cell_magic("script", "--out output --err error sh", "echo 'hi'\necho 'hello' >&2")
651 ip.run_cell_magic("script", "--out output --err error sh", "echo 'hi'\necho 'hello' >&2")
652 nt.assert_equals(ip.user_ns['output'], 'hi\n')
652 nt.assert_equal(ip.user_ns['output'], 'hi\n')
653 nt.assert_equals(ip.user_ns['error'], 'hello\n')
653 nt.assert_equal(ip.user_ns['error'], 'hello\n')
654
654
655 @dec.skip_win32
655 @dec.skip_win32
656 def test_script_bg_out():
656 def test_script_bg_out():
657 ip = get_ipython()
657 ip = get_ipython()
658 ip.run_cell_magic("script", "--bg --out output sh", "echo 'hi'")
658 ip.run_cell_magic("script", "--bg --out output sh", "echo 'hi'")
659 nt.assert_equals(ip.user_ns['output'].read(), b'hi\n')
659 nt.assert_equal(ip.user_ns['output'].read(), b'hi\n')
660
660
661 @dec.skip_win32
661 @dec.skip_win32
662 def test_script_bg_err():
662 def test_script_bg_err():
663 ip = get_ipython()
663 ip = get_ipython()
664 ip.run_cell_magic("script", "--bg --err error sh", "echo 'hello' >&2")
664 ip.run_cell_magic("script", "--bg --err error sh", "echo 'hello' >&2")
665 nt.assert_equals(ip.user_ns['error'].read(), b'hello\n')
665 nt.assert_equal(ip.user_ns['error'].read(), b'hello\n')
666
666
667 @dec.skip_win32
667 @dec.skip_win32
668 def test_script_bg_out_err():
668 def test_script_bg_out_err():
669 ip = get_ipython()
669 ip = get_ipython()
670 ip.run_cell_magic("script", "--bg --out output --err error sh", "echo 'hi'\necho 'hello' >&2")
670 ip.run_cell_magic("script", "--bg --out output --err error sh", "echo 'hi'\necho 'hello' >&2")
671 nt.assert_equals(ip.user_ns['output'].read(), b'hi\n')
671 nt.assert_equal(ip.user_ns['output'].read(), b'hi\n')
672 nt.assert_equals(ip.user_ns['error'].read(), b'hello\n')
672 nt.assert_equal(ip.user_ns['error'].read(), b'hello\n')
673
673
674 def test_script_defaults():
674 def test_script_defaults():
675 ip = get_ipython()
675 ip = get_ipython()
676 for cmd in ['sh', 'bash', 'perl', 'ruby']:
676 for cmd in ['sh', 'bash', 'perl', 'ruby']:
677 try:
677 try:
678 find_cmd(cmd)
678 find_cmd(cmd)
679 except Exception:
679 except Exception:
680 pass
680 pass
681 else:
681 else:
682 nt.assert_in(cmd, ip.magics_manager.magics['cell'])
682 nt.assert_in(cmd, ip.magics_manager.magics['cell'])
683
683
684
684
685 @magics_class
685 @magics_class
686 class FooFoo(Magics):
686 class FooFoo(Magics):
687 """class with both %foo and %%foo magics"""
687 """class with both %foo and %%foo magics"""
688 @line_magic('foo')
688 @line_magic('foo')
689 def line_foo(self, line):
689 def line_foo(self, line):
690 "I am line foo"
690 "I am line foo"
691 pass
691 pass
692
692
693 @cell_magic("foo")
693 @cell_magic("foo")
694 def cell_foo(self, line, cell):
694 def cell_foo(self, line, cell):
695 "I am cell foo, not line foo"
695 "I am cell foo, not line foo"
696 pass
696 pass
697
697
698 def test_line_cell_info():
698 def test_line_cell_info():
699 """%%foo and %foo magics are distinguishable to inspect"""
699 """%%foo and %foo magics are distinguishable to inspect"""
700 ip = get_ipython()
700 ip = get_ipython()
701 ip.magics_manager.register(FooFoo)
701 ip.magics_manager.register(FooFoo)
702 oinfo = ip.object_inspect('foo')
702 oinfo = ip.object_inspect('foo')
703 nt.assert_true(oinfo['found'])
703 nt.assert_true(oinfo['found'])
704 nt.assert_true(oinfo['ismagic'])
704 nt.assert_true(oinfo['ismagic'])
705
705
706 oinfo = ip.object_inspect('%%foo')
706 oinfo = ip.object_inspect('%%foo')
707 nt.assert_true(oinfo['found'])
707 nt.assert_true(oinfo['found'])
708 nt.assert_true(oinfo['ismagic'])
708 nt.assert_true(oinfo['ismagic'])
709 nt.assert_equals(oinfo['docstring'], FooFoo.cell_foo.__doc__)
709 nt.assert_equal(oinfo['docstring'], FooFoo.cell_foo.__doc__)
710
710
711 oinfo = ip.object_inspect('%foo')
711 oinfo = ip.object_inspect('%foo')
712 nt.assert_true(oinfo['found'])
712 nt.assert_true(oinfo['found'])
713 nt.assert_true(oinfo['ismagic'])
713 nt.assert_true(oinfo['ismagic'])
714 nt.assert_equals(oinfo['docstring'], FooFoo.line_foo.__doc__)
714 nt.assert_equal(oinfo['docstring'], FooFoo.line_foo.__doc__)
715
715
716 def test_multiple_magics():
716 def test_multiple_magics():
717 ip = get_ipython()
717 ip = get_ipython()
718 foo1 = FooFoo(ip)
718 foo1 = FooFoo(ip)
719 foo2 = FooFoo(ip)
719 foo2 = FooFoo(ip)
720 mm = ip.magics_manager
720 mm = ip.magics_manager
721 mm.register(foo1)
721 mm.register(foo1)
722 nt.assert_true(mm.magics['line']['foo'].im_self is foo1)
722 nt.assert_true(mm.magics['line']['foo'].im_self is foo1)
723 mm.register(foo2)
723 mm.register(foo2)
724 nt.assert_true(mm.magics['line']['foo'].im_self is foo2)
724 nt.assert_true(mm.magics['line']['foo'].im_self is foo2)
725
725
726 def test_alias_magic():
726 def test_alias_magic():
727 """Test %alias_magic."""
727 """Test %alias_magic."""
728 ip = get_ipython()
728 ip = get_ipython()
729 mm = ip.magics_manager
729 mm = ip.magics_manager
730
730
731 # Basic operation: both cell and line magics are created, if possible.
731 # Basic operation: both cell and line magics are created, if possible.
732 ip.run_line_magic('alias_magic', 'timeit_alias timeit')
732 ip.run_line_magic('alias_magic', 'timeit_alias timeit')
733 nt.assert_true('timeit_alias' in mm.magics['line'])
733 nt.assert_true('timeit_alias' in mm.magics['line'])
734 nt.assert_true('timeit_alias' in mm.magics['cell'])
734 nt.assert_true('timeit_alias' in mm.magics['cell'])
735
735
736 # --cell is specified, line magic not created.
736 # --cell is specified, line magic not created.
737 ip.run_line_magic('alias_magic', '--cell timeit_cell_alias timeit')
737 ip.run_line_magic('alias_magic', '--cell timeit_cell_alias timeit')
738 nt.assert_false('timeit_cell_alias' in mm.magics['line'])
738 nt.assert_false('timeit_cell_alias' in mm.magics['line'])
739 nt.assert_true('timeit_cell_alias' in mm.magics['cell'])
739 nt.assert_true('timeit_cell_alias' in mm.magics['cell'])
740
740
741 # Test that line alias is created successfully.
741 # Test that line alias is created successfully.
742 ip.run_line_magic('alias_magic', '--line env_alias env')
742 ip.run_line_magic('alias_magic', '--line env_alias env')
743 nt.assert_equal(ip.run_line_magic('env', ''),
743 nt.assert_equal(ip.run_line_magic('env', ''),
744 ip.run_line_magic('env_alias', ''))
744 ip.run_line_magic('env_alias', ''))
745
745
746 def test_save():
746 def test_save():
747 """Test %save."""
747 """Test %save."""
748 ip = get_ipython()
748 ip = get_ipython()
749 ip.history_manager.reset() # Clear any existing history.
749 ip.history_manager.reset() # Clear any existing history.
750 cmds = [u"a=1", u"def b():\n return a**2", u"print(a, b())"]
750 cmds = [u"a=1", u"def b():\n return a**2", u"print(a, b())"]
751 for i, cmd in enumerate(cmds, start=1):
751 for i, cmd in enumerate(cmds, start=1):
752 ip.history_manager.store_inputs(i, cmd)
752 ip.history_manager.store_inputs(i, cmd)
753 with TemporaryDirectory() as tmpdir:
753 with TemporaryDirectory() as tmpdir:
754 file = os.path.join(tmpdir, "testsave.py")
754 file = os.path.join(tmpdir, "testsave.py")
755 ip.run_line_magic("save", "%s 1-10" % file)
755 ip.run_line_magic("save", "%s 1-10" % file)
756 with open(file) as f:
756 with open(file) as f:
757 content = f.read()
757 content = f.read()
758 nt.assert_equal(content.count(cmds[0]), 1)
758 nt.assert_equal(content.count(cmds[0]), 1)
759 nt.assert_true('coding: utf-8' in content)
759 nt.assert_true('coding: utf-8' in content)
760 ip.run_line_magic("save", "-a %s 1-10" % file)
760 ip.run_line_magic("save", "-a %s 1-10" % file)
761 with open(file) as f:
761 with open(file) as f:
762 content = f.read()
762 content = f.read()
763 nt.assert_equal(content.count(cmds[0]), 2)
763 nt.assert_equal(content.count(cmds[0]), 2)
764 nt.assert_true('coding: utf-8' in content)
764 nt.assert_true('coding: utf-8' in content)
@@ -1,204 +1,204
1 """Tests for various magic functions specific to the terminal frontend.
1 """Tests for various magic functions specific to the terminal frontend.
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 from __future__ import absolute_import
5 from __future__ import absolute_import
6
6
7 #-----------------------------------------------------------------------------
7 #-----------------------------------------------------------------------------
8 # Imports
8 # Imports
9 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
10
10
11 import sys
11 import sys
12 from StringIO import StringIO
12 from StringIO import StringIO
13 from unittest import TestCase
13 from unittest import TestCase
14
14
15 import nose.tools as nt
15 import nose.tools as nt
16
16
17 from IPython.testing import tools as tt
17 from IPython.testing import tools as tt
18
18
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20 # Globals
20 # Globals
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22 ip = get_ipython()
22 ip = get_ipython()
23
23
24 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
25 # Test functions begin
25 # Test functions begin
26 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
27
27
28 def check_cpaste(code, should_fail=False):
28 def check_cpaste(code, should_fail=False):
29 """Execute code via 'cpaste' and ensure it was executed, unless
29 """Execute code via 'cpaste' and ensure it was executed, unless
30 should_fail is set.
30 should_fail is set.
31 """
31 """
32 ip.user_ns['code_ran'] = False
32 ip.user_ns['code_ran'] = False
33
33
34 src = StringIO()
34 src = StringIO()
35 if not hasattr(src, 'encoding'):
35 if not hasattr(src, 'encoding'):
36 # IPython expects stdin to have an encoding attribute
36 # IPython expects stdin to have an encoding attribute
37 src.encoding = None
37 src.encoding = None
38 src.write(code)
38 src.write(code)
39 src.write('\n--\n')
39 src.write('\n--\n')
40 src.seek(0)
40 src.seek(0)
41
41
42 stdin_save = sys.stdin
42 stdin_save = sys.stdin
43 sys.stdin = src
43 sys.stdin = src
44
44
45 try:
45 try:
46 context = tt.AssertPrints if should_fail else tt.AssertNotPrints
46 context = tt.AssertPrints if should_fail else tt.AssertNotPrints
47 with context("Traceback (most recent call last)"):
47 with context("Traceback (most recent call last)"):
48 ip.magic('cpaste')
48 ip.magic('cpaste')
49
49
50 if not should_fail:
50 if not should_fail:
51 assert ip.user_ns['code_ran']
51 assert ip.user_ns['code_ran']
52 finally:
52 finally:
53 sys.stdin = stdin_save
53 sys.stdin = stdin_save
54
54
55 PY31 = sys.version_info[:2] == (3,1)
55 PY31 = sys.version_info[:2] == (3,1)
56
56
57 def test_cpaste():
57 def test_cpaste():
58 """Test cpaste magic"""
58 """Test cpaste magic"""
59
59
60 def runf():
60 def runf():
61 """Marker function: sets a flag when executed.
61 """Marker function: sets a flag when executed.
62 """
62 """
63 ip.user_ns['code_ran'] = True
63 ip.user_ns['code_ran'] = True
64 return 'runf' # return string so '+ runf()' doesn't result in success
64 return 'runf' # return string so '+ runf()' doesn't result in success
65
65
66 tests = {'pass': ["runf()",
66 tests = {'pass': ["runf()",
67 "In [1]: runf()",
67 "In [1]: runf()",
68 "In [1]: if 1:\n ...: runf()",
68 "In [1]: if 1:\n ...: runf()",
69 "> > > runf()",
69 "> > > runf()",
70 ">>> runf()",
70 ">>> runf()",
71 " >>> runf()",
71 " >>> runf()",
72 ],
72 ],
73
73
74 'fail': ["1 + runf()",
74 'fail': ["1 + runf()",
75 ]}
75 ]}
76
76
77 # I don't know why this is failing specifically on Python 3.1. I've
77 # I don't know why this is failing specifically on Python 3.1. I've
78 # checked it manually interactively, but we don't care enough about 3.1
78 # checked it manually interactively, but we don't care enough about 3.1
79 # to spend time fiddling with the tests, so we just skip it.
79 # to spend time fiddling with the tests, so we just skip it.
80 if not PY31:
80 if not PY31:
81 tests['fail'].append("++ runf()")
81 tests['fail'].append("++ runf()")
82
82
83 ip.user_ns['runf'] = runf
83 ip.user_ns['runf'] = runf
84
84
85 for code in tests['pass']:
85 for code in tests['pass']:
86 check_cpaste(code)
86 check_cpaste(code)
87
87
88 for code in tests['fail']:
88 for code in tests['fail']:
89 check_cpaste(code, should_fail=True)
89 check_cpaste(code, should_fail=True)
90
90
91
91
92 class PasteTestCase(TestCase):
92 class PasteTestCase(TestCase):
93 """Multiple tests for clipboard pasting"""
93 """Multiple tests for clipboard pasting"""
94
94
95 def paste(self, txt, flags='-q'):
95 def paste(self, txt, flags='-q'):
96 """Paste input text, by default in quiet mode"""
96 """Paste input text, by default in quiet mode"""
97 ip.hooks.clipboard_get = lambda : txt
97 ip.hooks.clipboard_get = lambda : txt
98 ip.magic('paste '+flags)
98 ip.magic('paste '+flags)
99
99
100 def setUp(self):
100 def setUp(self):
101 # Inject fake clipboard hook but save original so we can restore it later
101 # Inject fake clipboard hook but save original so we can restore it later
102 self.original_clip = ip.hooks.clipboard_get
102 self.original_clip = ip.hooks.clipboard_get
103
103
104 def tearDown(self):
104 def tearDown(self):
105 # Restore original hook
105 # Restore original hook
106 ip.hooks.clipboard_get = self.original_clip
106 ip.hooks.clipboard_get = self.original_clip
107
107
108 def test_paste(self):
108 def test_paste(self):
109 ip.user_ns.pop('x', None)
109 ip.user_ns.pop('x', None)
110 self.paste('x = 1')
110 self.paste('x = 1')
111 nt.assert_equal(ip.user_ns['x'], 1)
111 nt.assert_equal(ip.user_ns['x'], 1)
112 ip.user_ns.pop('x')
112 ip.user_ns.pop('x')
113
113
114 def test_paste_pyprompt(self):
114 def test_paste_pyprompt(self):
115 ip.user_ns.pop('x', None)
115 ip.user_ns.pop('x', None)
116 self.paste('>>> x=2')
116 self.paste('>>> x=2')
117 nt.assert_equal(ip.user_ns['x'], 2)
117 nt.assert_equal(ip.user_ns['x'], 2)
118 ip.user_ns.pop('x')
118 ip.user_ns.pop('x')
119
119
120 def test_paste_py_multi(self):
120 def test_paste_py_multi(self):
121 self.paste("""
121 self.paste("""
122 >>> x = [1,2,3]
122 >>> x = [1,2,3]
123 >>> y = []
123 >>> y = []
124 >>> for i in x:
124 >>> for i in x:
125 ... y.append(i**2)
125 ... y.append(i**2)
126 ...
126 ...
127 """)
127 """)
128 nt.assert_equal(ip.user_ns['x'], [1,2,3])
128 nt.assert_equal(ip.user_ns['x'], [1,2,3])
129 nt.assert_equal(ip.user_ns['y'], [1,4,9])
129 nt.assert_equal(ip.user_ns['y'], [1,4,9])
130
130
131 def test_paste_py_multi_r(self):
131 def test_paste_py_multi_r(self):
132 "Now, test that self.paste -r works"
132 "Now, test that self.paste -r works"
133 nt.assert_equal(ip.user_ns.pop('x'), [1,2,3])
133 nt.assert_equal(ip.user_ns.pop('x'), [1,2,3])
134 nt.assert_equal(ip.user_ns.pop('y'), [1,4,9])
134 nt.assert_equal(ip.user_ns.pop('y'), [1,4,9])
135 nt.assert_false('x' in ip.user_ns)
135 nt.assert_false('x' in ip.user_ns)
136 ip.magic('paste -r')
136 ip.magic('paste -r')
137 nt.assert_equal(ip.user_ns['x'], [1,2,3])
137 nt.assert_equal(ip.user_ns['x'], [1,2,3])
138 nt.assert_equal(ip.user_ns['y'], [1,4,9])
138 nt.assert_equal(ip.user_ns['y'], [1,4,9])
139
139
140 def test_paste_email(self):
140 def test_paste_email(self):
141 "Test pasting of email-quoted contents"
141 "Test pasting of email-quoted contents"
142 self.paste("""\
142 self.paste("""\
143 >> def foo(x):
143 >> def foo(x):
144 >> return x + 1
144 >> return x + 1
145 >> xx = foo(1.1)""")
145 >> xx = foo(1.1)""")
146 nt.assert_equal(ip.user_ns['xx'], 2.1)
146 nt.assert_equal(ip.user_ns['xx'], 2.1)
147
147
148 def test_paste_email2(self):
148 def test_paste_email2(self):
149 "Email again; some programs add a space also at each quoting level"
149 "Email again; some programs add a space also at each quoting level"
150 self.paste("""\
150 self.paste("""\
151 > > def foo(x):
151 > > def foo(x):
152 > > return x + 1
152 > > return x + 1
153 > > yy = foo(2.1) """)
153 > > yy = foo(2.1) """)
154 nt.assert_equal(ip.user_ns['yy'], 3.1)
154 nt.assert_equal(ip.user_ns['yy'], 3.1)
155
155
156 def test_paste_email_py(self):
156 def test_paste_email_py(self):
157 "Email quoting of interactive input"
157 "Email quoting of interactive input"
158 self.paste("""\
158 self.paste("""\
159 >> >>> def f(x):
159 >> >>> def f(x):
160 >> ... return x+1
160 >> ... return x+1
161 >> ...
161 >> ...
162 >> >>> zz = f(2.5) """)
162 >> >>> zz = f(2.5) """)
163 nt.assert_equal(ip.user_ns['zz'], 3.5)
163 nt.assert_equal(ip.user_ns['zz'], 3.5)
164
164
165 def test_paste_echo(self):
165 def test_paste_echo(self):
166 "Also test self.paste echoing, by temporarily faking the writer"
166 "Also test self.paste echoing, by temporarily faking the writer"
167 w = StringIO()
167 w = StringIO()
168 writer = ip.write
168 writer = ip.write
169 ip.write = w.write
169 ip.write = w.write
170 code = """
170 code = """
171 a = 100
171 a = 100
172 b = 200"""
172 b = 200"""
173 try:
173 try:
174 self.paste(code,'')
174 self.paste(code,'')
175 out = w.getvalue()
175 out = w.getvalue()
176 finally:
176 finally:
177 ip.write = writer
177 ip.write = writer
178 nt.assert_equal(ip.user_ns['a'], 100)
178 nt.assert_equal(ip.user_ns['a'], 100)
179 nt.assert_equal(ip.user_ns['b'], 200)
179 nt.assert_equal(ip.user_ns['b'], 200)
180 nt.assert_equal(out, code+"\n## -- End pasted text --\n")
180 nt.assert_equal(out, code+"\n## -- End pasted text --\n")
181
181
182 def test_paste_leading_commas(self):
182 def test_paste_leading_commas(self):
183 "Test multiline strings with leading commas"
183 "Test multiline strings with leading commas"
184 tm = ip.magics_manager.registry['TerminalMagics']
184 tm = ip.magics_manager.registry['TerminalMagics']
185 s = '''\
185 s = '''\
186 a = """
186 a = """
187 ,1,2,3
187 ,1,2,3
188 """'''
188 """'''
189 ip.user_ns.pop('foo', None)
189 ip.user_ns.pop('foo', None)
190 tm.store_or_execute(s, 'foo')
190 tm.store_or_execute(s, 'foo')
191 nt.assert_in('foo', ip.user_ns)
191 nt.assert_in('foo', ip.user_ns)
192
192
193
193
194 def test_paste_trailing_question(self):
194 def test_paste_trailing_question(self):
195 "Test pasting sources with trailing question marks"
195 "Test pasting sources with trailing question marks"
196 tm = ip.magics_manager.registry['TerminalMagics']
196 tm = ip.magics_manager.registry['TerminalMagics']
197 s = '''\
197 s = '''\
198 def funcfoo():
198 def funcfoo():
199 if True: #am i true?
199 if True: #am i true?
200 return 'fooresult'
200 return 'fooresult'
201 '''
201 '''
202 ip.user_ns.pop('funcfoo', None)
202 ip.user_ns.pop('funcfoo', None)
203 self.paste(s)
203 self.paste(s)
204 nt.assert_equals(ip.user_ns['funcfoo'](), 'fooresult')
204 nt.assert_equal(ip.user_ns['funcfoo'](), 'fooresult')
@@ -1,110 +1,110
1 """Tests for input manipulation machinery."""
1 """Tests for input manipulation machinery."""
2
2
3 #-----------------------------------------------------------------------------
3 #-----------------------------------------------------------------------------
4 # Imports
4 # Imports
5 #-----------------------------------------------------------------------------
5 #-----------------------------------------------------------------------------
6 import nose.tools as nt
6 import nose.tools as nt
7
7
8 from IPython.core.prefilter import AutocallChecker
8 from IPython.core.prefilter import AutocallChecker
9 from IPython.testing import tools as tt, decorators as dec
9 from IPython.testing import tools as tt, decorators as dec
10 from IPython.testing.globalipapp import get_ipython
10 from IPython.testing.globalipapp import get_ipython
11
11
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13 # Tests
13 # Tests
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15 ip = get_ipython()
15 ip = get_ipython()
16
16
17 @dec.parametric
17 @dec.parametric
18 def test_prefilter():
18 def test_prefilter():
19 """Test user input conversions"""
19 """Test user input conversions"""
20
20
21 # pairs of (raw, expected correct) input
21 # pairs of (raw, expected correct) input
22 pairs = [ ('2+2','2+2'),
22 pairs = [ ('2+2','2+2'),
23 ('>>> 2+2','2+2'),
23 ('>>> 2+2','2+2'),
24 ('>>> # This is a comment\n'
24 ('>>> # This is a comment\n'
25 '... 2+2',
25 '... 2+2',
26 '# This is a comment\n'
26 '# This is a comment\n'
27 '2+2'),
27 '2+2'),
28 # Some IPython input
28 # Some IPython input
29 ('In [1]: 1', '1'),
29 ('In [1]: 1', '1'),
30 ('In [2]: for i in range(5):\n'
30 ('In [2]: for i in range(5):\n'
31 ' ...: print i,',
31 ' ...: print i,',
32 'for i in range(5):\n'
32 'for i in range(5):\n'
33 ' print i,'),
33 ' print i,'),
34 ]
34 ]
35
35
36 for raw, correct in pairs:
36 for raw, correct in pairs:
37 yield nt.assert_equals(ip.prefilter(raw), correct)
37 yield nt.assert_equal(ip.prefilter(raw), correct)
38
38
39
39
40 @dec.parametric
40 @dec.parametric
41 def test_autocall_binops():
41 def test_autocall_binops():
42 """See https://github.com/ipython/ipython/issues/81"""
42 """See https://github.com/ipython/ipython/issues/81"""
43 ip.magic('autocall 2')
43 ip.magic('autocall 2')
44 f = lambda x: x
44 f = lambda x: x
45 ip.user_ns['f'] = f
45 ip.user_ns['f'] = f
46 try:
46 try:
47 yield nt.assert_equals(ip.prefilter('f 1'),'f(1)')
47 yield nt.assert_equal(ip.prefilter('f 1'),'f(1)')
48 for t in ['f +1', 'f -1']:
48 for t in ['f +1', 'f -1']:
49 yield nt.assert_equals(ip.prefilter(t), t)
49 yield nt.assert_equal(ip.prefilter(t), t)
50
50
51 # Run tests again with a more permissive exclude_regexp, which will
51 # Run tests again with a more permissive exclude_regexp, which will
52 # allow transformation of binary operations ('f -1' -> 'f(-1)').
52 # allow transformation of binary operations ('f -1' -> 'f(-1)').
53 pm = ip.prefilter_manager
53 pm = ip.prefilter_manager
54 ac = AutocallChecker(shell=pm.shell, prefilter_manager=pm,
54 ac = AutocallChecker(shell=pm.shell, prefilter_manager=pm,
55 config=pm.config)
55 config=pm.config)
56 try:
56 try:
57 ac.priority = 1
57 ac.priority = 1
58 ac.exclude_regexp = r'^[,&^\|\*/]|^is |^not |^in |^and |^or '
58 ac.exclude_regexp = r'^[,&^\|\*/]|^is |^not |^in |^and |^or '
59 pm.sort_checkers()
59 pm.sort_checkers()
60
60
61 yield nt.assert_equals(ip.prefilter('f -1'), 'f(-1)')
61 yield nt.assert_equal(ip.prefilter('f -1'), 'f(-1)')
62 yield nt.assert_equals(ip.prefilter('f +1'), 'f(+1)')
62 yield nt.assert_equal(ip.prefilter('f +1'), 'f(+1)')
63 finally:
63 finally:
64 pm.unregister_checker(ac)
64 pm.unregister_checker(ac)
65 finally:
65 finally:
66 ip.magic('autocall 0')
66 ip.magic('autocall 0')
67 del ip.user_ns['f']
67 del ip.user_ns['f']
68
68
69
69
70 @dec.parametric
70 @dec.parametric
71 def test_issue_114():
71 def test_issue_114():
72 """Check that multiline string literals don't expand as magic
72 """Check that multiline string literals don't expand as magic
73 see http://github.com/ipython/ipython/issues/114"""
73 see http://github.com/ipython/ipython/issues/114"""
74
74
75 template = '"""\n%s\n"""'
75 template = '"""\n%s\n"""'
76 # Store the current value of multi_line_specials and turn it off before
76 # Store the current value of multi_line_specials and turn it off before
77 # running test, since it could be true (case in which the test doesn't make
77 # running test, since it could be true (case in which the test doesn't make
78 # sense, as multiline string literals *will* expand as magic in that case).
78 # sense, as multiline string literals *will* expand as magic in that case).
79 msp = ip.prefilter_manager.multi_line_specials
79 msp = ip.prefilter_manager.multi_line_specials
80 ip.prefilter_manager.multi_line_specials = False
80 ip.prefilter_manager.multi_line_specials = False
81 try:
81 try:
82 for mgk in ip.magics_manager.lsmagic()['line']:
82 for mgk in ip.magics_manager.lsmagic()['line']:
83 raw = template % mgk
83 raw = template % mgk
84 yield nt.assert_equals(ip.prefilter(raw), raw)
84 yield nt.assert_equal(ip.prefilter(raw), raw)
85 finally:
85 finally:
86 ip.prefilter_manager.multi_line_specials = msp
86 ip.prefilter_manager.multi_line_specials = msp
87
87
88
88
89 def test_prefilter_attribute_errors():
89 def test_prefilter_attribute_errors():
90 """Capture exceptions thrown by user objects on attribute access.
90 """Capture exceptions thrown by user objects on attribute access.
91
91
92 See http://github.com/ipython/ipython/issues/988."""
92 See http://github.com/ipython/ipython/issues/988."""
93
93
94 class X(object):
94 class X(object):
95 def __getattr__(self, k):
95 def __getattr__(self, k):
96 raise ValueError('broken object')
96 raise ValueError('broken object')
97 def __call__(self, x):
97 def __call__(self, x):
98 return x
98 return x
99
99
100 # Create a callable broken object
100 # Create a callable broken object
101 ip.user_ns['x'] = X()
101 ip.user_ns['x'] = X()
102 ip.magic('autocall 2')
102 ip.magic('autocall 2')
103 try:
103 try:
104 # Even if x throws an attribute error when looking at its rewrite
104 # Even if x throws an attribute error when looking at its rewrite
105 # attribute, we should not crash. So the test here is simply making
105 # attribute, we should not crash. So the test here is simply making
106 # the prefilter call and not having an exception.
106 # the prefilter call and not having an exception.
107 ip.prefilter('x 1')
107 ip.prefilter('x 1')
108 finally:
108 finally:
109 del ip.user_ns['x']
109 del ip.user_ns['x']
110 ip.magic('autocall 0')
110 ip.magic('autocall 0')
@@ -1,151 +1,151
1 # coding: utf-8
1 # coding: utf-8
2 """Tests for profile-related functions.
2 """Tests for profile-related functions.
3
3
4 Currently only the startup-dir functionality is tested, but more tests should
4 Currently only the startup-dir functionality is tested, but more tests should
5 be added for:
5 be added for:
6
6
7 * ipython profile create
7 * ipython profile create
8 * ipython profile list
8 * ipython profile list
9 * ipython profile create --parallel
9 * ipython profile create --parallel
10 * security dir permissions
10 * security dir permissions
11
11
12 Authors
12 Authors
13 -------
13 -------
14
14
15 * MinRK
15 * MinRK
16
16
17 """
17 """
18 from __future__ import absolute_import
18 from __future__ import absolute_import
19
19
20 #-----------------------------------------------------------------------------
20 #-----------------------------------------------------------------------------
21 # Imports
21 # Imports
22 #-----------------------------------------------------------------------------
22 #-----------------------------------------------------------------------------
23
23
24 import os
24 import os
25 import shutil
25 import shutil
26 import sys
26 import sys
27 import tempfile
27 import tempfile
28
28
29 from unittest import TestCase
29 from unittest import TestCase
30
30
31 import nose.tools as nt
31 import nose.tools as nt
32 from nose import SkipTest
32 from nose import SkipTest
33
33
34 from IPython.core.profileapp import list_profiles_in, list_bundled_profiles
34 from IPython.core.profileapp import list_profiles_in, list_bundled_profiles
35 from IPython.core.profiledir import ProfileDir
35 from IPython.core.profiledir import ProfileDir
36
36
37 from IPython.testing import decorators as dec
37 from IPython.testing import decorators as dec
38 from IPython.testing import tools as tt
38 from IPython.testing import tools as tt
39 from IPython.utils import py3compat
39 from IPython.utils import py3compat
40
40
41
41
42 #-----------------------------------------------------------------------------
42 #-----------------------------------------------------------------------------
43 # Globals
43 # Globals
44 #-----------------------------------------------------------------------------
44 #-----------------------------------------------------------------------------
45 TMP_TEST_DIR = tempfile.mkdtemp()
45 TMP_TEST_DIR = tempfile.mkdtemp()
46 HOME_TEST_DIR = os.path.join(TMP_TEST_DIR, "home_test_dir")
46 HOME_TEST_DIR = os.path.join(TMP_TEST_DIR, "home_test_dir")
47 IP_TEST_DIR = os.path.join(HOME_TEST_DIR,'.ipython')
47 IP_TEST_DIR = os.path.join(HOME_TEST_DIR,'.ipython')
48
48
49 #
49 #
50 # Setup/teardown functions/decorators
50 # Setup/teardown functions/decorators
51 #
51 #
52
52
53 def setup():
53 def setup():
54 """Setup test environment for the module:
54 """Setup test environment for the module:
55
55
56 - Adds dummy home dir tree
56 - Adds dummy home dir tree
57 """
57 """
58 # Do not mask exceptions here. In particular, catching WindowsError is a
58 # Do not mask exceptions here. In particular, catching WindowsError is a
59 # problem because that exception is only defined on Windows...
59 # problem because that exception is only defined on Windows...
60 os.makedirs(IP_TEST_DIR)
60 os.makedirs(IP_TEST_DIR)
61
61
62
62
63 def teardown():
63 def teardown():
64 """Teardown test environment for the module:
64 """Teardown test environment for the module:
65
65
66 - Remove dummy home dir tree
66 - Remove dummy home dir tree
67 """
67 """
68 # Note: we remove the parent test dir, which is the root of all test
68 # Note: we remove the parent test dir, which is the root of all test
69 # subdirs we may have created. Use shutil instead of os.removedirs, so
69 # subdirs we may have created. Use shutil instead of os.removedirs, so
70 # that non-empty directories are all recursively removed.
70 # that non-empty directories are all recursively removed.
71 shutil.rmtree(TMP_TEST_DIR)
71 shutil.rmtree(TMP_TEST_DIR)
72
72
73
73
74 #-----------------------------------------------------------------------------
74 #-----------------------------------------------------------------------------
75 # Test functions
75 # Test functions
76 #-----------------------------------------------------------------------------
76 #-----------------------------------------------------------------------------
77 def win32_without_pywin32():
77 def win32_without_pywin32():
78 if sys.platform == 'win32':
78 if sys.platform == 'win32':
79 try:
79 try:
80 import pywin32
80 import pywin32
81 except ImportError:
81 except ImportError:
82 return True
82 return True
83 return False
83 return False
84
84
85
85
86 class ProfileStartupTest(TestCase):
86 class ProfileStartupTest(TestCase):
87 def setUp(self):
87 def setUp(self):
88 # create profile dir
88 # create profile dir
89 self.pd = ProfileDir.create_profile_dir_by_name(IP_TEST_DIR, 'test')
89 self.pd = ProfileDir.create_profile_dir_by_name(IP_TEST_DIR, 'test')
90 self.options = ['--ipython-dir', IP_TEST_DIR, '--profile', 'test']
90 self.options = ['--ipython-dir', IP_TEST_DIR, '--profile', 'test']
91 self.fname = os.path.join(TMP_TEST_DIR, 'test.py')
91 self.fname = os.path.join(TMP_TEST_DIR, 'test.py')
92
92
93 def tearDown(self):
93 def tearDown(self):
94 # We must remove this profile right away so its presence doesn't
94 # We must remove this profile right away so its presence doesn't
95 # confuse other tests.
95 # confuse other tests.
96 shutil.rmtree(self.pd.location)
96 shutil.rmtree(self.pd.location)
97
97
98 def init(self, startup_file, startup, test):
98 def init(self, startup_file, startup, test):
99 # write startup python file
99 # write startup python file
100 with open(os.path.join(self.pd.startup_dir, startup_file), 'w') as f:
100 with open(os.path.join(self.pd.startup_dir, startup_file), 'w') as f:
101 f.write(startup)
101 f.write(startup)
102 # write simple test file, to check that the startup file was run
102 # write simple test file, to check that the startup file was run
103 with open(self.fname, 'w') as f:
103 with open(self.fname, 'w') as f:
104 f.write(py3compat.doctest_refactor_print(test))
104 f.write(py3compat.doctest_refactor_print(test))
105
105
106 def validate(self, output):
106 def validate(self, output):
107 tt.ipexec_validate(self.fname, output, '', options=self.options)
107 tt.ipexec_validate(self.fname, output, '', options=self.options)
108
108
109 @dec.skipif(win32_without_pywin32(), "Test requires pywin32 on Windows")
109 @dec.skipif(win32_without_pywin32(), "Test requires pywin32 on Windows")
110 def test_startup_py(self):
110 def test_startup_py(self):
111 self.init('00-start.py', 'zzz=123\n',
111 self.init('00-start.py', 'zzz=123\n',
112 py3compat.doctest_refactor_print('print zzz\n'))
112 py3compat.doctest_refactor_print('print zzz\n'))
113 self.validate('123')
113 self.validate('123')
114
114
115 @dec.skipif(win32_without_pywin32(), "Test requires pywin32 on Windows")
115 @dec.skipif(win32_without_pywin32(), "Test requires pywin32 on Windows")
116 def test_startup_ipy(self):
116 def test_startup_ipy(self):
117 self.init('00-start.ipy', '%profile\n', '')
117 self.init('00-start.ipy', '%profile\n', '')
118 self.validate('test')
118 self.validate('test')
119
119
120
120
121 def test_list_profiles_in():
121 def test_list_profiles_in():
122 # No need to remove these directories and files, as they will get nuked in
122 # No need to remove these directories and files, as they will get nuked in
123 # the module-level teardown.
123 # the module-level teardown.
124 td = tempfile.mkdtemp(dir=TMP_TEST_DIR)
124 td = tempfile.mkdtemp(dir=TMP_TEST_DIR)
125 td = py3compat.str_to_unicode(td)
125 td = py3compat.str_to_unicode(td)
126 for name in ('profile_foo', u'profile_ΓΌnicode', 'profile_hello',
126 for name in ('profile_foo', u'profile_ΓΌnicode', 'profile_hello',
127 'not_a_profile'):
127 'not_a_profile'):
128 os.mkdir(os.path.join(td, name))
128 os.mkdir(os.path.join(td, name))
129 with open(os.path.join(td, 'profile_file'), 'w') as f:
129 with open(os.path.join(td, 'profile_file'), 'w') as f:
130 f.write("I am not a profile directory")
130 f.write("I am not a profile directory")
131 profiles = list_profiles_in(td)
131 profiles = list_profiles_in(td)
132
132
133 # unicode normalization can turn u'ΓΌnicode' into u'u\0308nicode',
133 # unicode normalization can turn u'ΓΌnicode' into u'u\0308nicode',
134 # so only check for *nicode, and that creating a ProfileDir from the
134 # so only check for *nicode, and that creating a ProfileDir from the
135 # name remains valid
135 # name remains valid
136 found_unicode = False
136 found_unicode = False
137 for p in list(profiles):
137 for p in list(profiles):
138 if p.endswith('nicode'):
138 if p.endswith('nicode'):
139 pd = ProfileDir.find_profile_dir_by_name(td, p)
139 pd = ProfileDir.find_profile_dir_by_name(td, p)
140 profiles.remove(p)
140 profiles.remove(p)
141 found_unicode = True
141 found_unicode = True
142 break
142 break
143 nt.assert_true(found_unicode)
143 nt.assert_true(found_unicode)
144 nt.assert_equals(set(profiles), set(['foo', 'hello']))
144 nt.assert_equal(set(profiles), set(['foo', 'hello']))
145
145
146
146
147 def test_list_bundled_profiles():
147 def test_list_bundled_profiles():
148 # This variable will need to be updated when a new profile gets bundled
148 # This variable will need to be updated when a new profile gets bundled
149 bundled_true = [u'cluster', u'math', u'pysh', u'sympy']
149 bundled_true = [u'cluster', u'math', u'pysh', u'sympy']
150 bundled = sorted(list_bundled_profiles())
150 bundled = sorted(list_bundled_profiles())
151 nt.assert_equals(bundled, bundled_true)
151 nt.assert_equal(bundled, bundled_true)
@@ -1,250 +1,250
1 # encoding: utf-8
1 # encoding: utf-8
2 """Tests for code execution (%run and related), which is particularly tricky.
2 """Tests for code execution (%run and related), which is particularly tricky.
3
3
4 Because of how %run manages namespaces, and the fact that we are trying here to
4 Because of how %run manages namespaces, and the fact that we are trying here to
5 verify subtle object deletion and reference counting issues, the %run tests
5 verify subtle object deletion and reference counting issues, the %run tests
6 will be kept in this separate file. This makes it easier to aggregate in one
6 will be kept in this separate file. This makes it easier to aggregate in one
7 place the tricks needed to handle it; most other magics are much easier to test
7 place the tricks needed to handle it; most other magics are much easier to test
8 and we do so in a common test_magic file.
8 and we do so in a common test_magic file.
9 """
9 """
10 from __future__ import absolute_import
10 from __future__ import absolute_import
11
11
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13 # Imports
13 # Imports
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15
15
16 import os
16 import os
17 import sys
17 import sys
18 import tempfile
18 import tempfile
19
19
20 import nose.tools as nt
20 import nose.tools as nt
21 from nose import SkipTest
21 from nose import SkipTest
22
22
23 from IPython.testing import decorators as dec
23 from IPython.testing import decorators as dec
24 from IPython.testing import tools as tt
24 from IPython.testing import tools as tt
25 from IPython.utils import py3compat
25 from IPython.utils import py3compat
26
26
27 #-----------------------------------------------------------------------------
27 #-----------------------------------------------------------------------------
28 # Test functions begin
28 # Test functions begin
29 #-----------------------------------------------------------------------------
29 #-----------------------------------------------------------------------------
30
30
31 def doctest_refbug():
31 def doctest_refbug():
32 """Very nasty problem with references held by multiple runs of a script.
32 """Very nasty problem with references held by multiple runs of a script.
33 See: https://github.com/ipython/ipython/issues/141
33 See: https://github.com/ipython/ipython/issues/141
34
34
35 In [1]: _ip.clear_main_mod_cache()
35 In [1]: _ip.clear_main_mod_cache()
36 # random
36 # random
37
37
38 In [2]: %run refbug
38 In [2]: %run refbug
39
39
40 In [3]: call_f()
40 In [3]: call_f()
41 lowercased: hello
41 lowercased: hello
42
42
43 In [4]: %run refbug
43 In [4]: %run refbug
44
44
45 In [5]: call_f()
45 In [5]: call_f()
46 lowercased: hello
46 lowercased: hello
47 lowercased: hello
47 lowercased: hello
48 """
48 """
49
49
50
50
51 def doctest_run_builtins():
51 def doctest_run_builtins():
52 r"""Check that %run doesn't damage __builtins__.
52 r"""Check that %run doesn't damage __builtins__.
53
53
54 In [1]: import tempfile
54 In [1]: import tempfile
55
55
56 In [2]: bid1 = id(__builtins__)
56 In [2]: bid1 = id(__builtins__)
57
57
58 In [3]: fname = tempfile.mkstemp('.py')[1]
58 In [3]: fname = tempfile.mkstemp('.py')[1]
59
59
60 In [3]: f = open(fname,'w')
60 In [3]: f = open(fname,'w')
61
61
62 In [4]: dummy= f.write('pass\n')
62 In [4]: dummy= f.write('pass\n')
63
63
64 In [5]: f.flush()
64 In [5]: f.flush()
65
65
66 In [6]: t1 = type(__builtins__)
66 In [6]: t1 = type(__builtins__)
67
67
68 In [7]: %run $fname
68 In [7]: %run $fname
69
69
70 In [7]: f.close()
70 In [7]: f.close()
71
71
72 In [8]: bid2 = id(__builtins__)
72 In [8]: bid2 = id(__builtins__)
73
73
74 In [9]: t2 = type(__builtins__)
74 In [9]: t2 = type(__builtins__)
75
75
76 In [10]: t1 == t2
76 In [10]: t1 == t2
77 Out[10]: True
77 Out[10]: True
78
78
79 In [10]: bid1 == bid2
79 In [10]: bid1 == bid2
80 Out[10]: True
80 Out[10]: True
81
81
82 In [12]: try:
82 In [12]: try:
83 ....: os.unlink(fname)
83 ....: os.unlink(fname)
84 ....: except:
84 ....: except:
85 ....: pass
85 ....: pass
86 ....:
86 ....:
87 """
87 """
88
88
89 @py3compat.doctest_refactor_print
89 @py3compat.doctest_refactor_print
90 def doctest_reset_del():
90 def doctest_reset_del():
91 """Test that resetting doesn't cause errors in __del__ methods.
91 """Test that resetting doesn't cause errors in __del__ methods.
92
92
93 In [2]: class A(object):
93 In [2]: class A(object):
94 ...: def __del__(self):
94 ...: def __del__(self):
95 ...: print str("Hi")
95 ...: print str("Hi")
96 ...:
96 ...:
97
97
98 In [3]: a = A()
98 In [3]: a = A()
99
99
100 In [4]: get_ipython().reset()
100 In [4]: get_ipython().reset()
101 Hi
101 Hi
102
102
103 In [5]: 1+1
103 In [5]: 1+1
104 Out[5]: 2
104 Out[5]: 2
105 """
105 """
106
106
107 # For some tests, it will be handy to organize them in a class with a common
107 # For some tests, it will be handy to organize them in a class with a common
108 # setup that makes a temp file
108 # setup that makes a temp file
109
109
110 class TestMagicRunPass(tt.TempFileMixin):
110 class TestMagicRunPass(tt.TempFileMixin):
111
111
112 def setup(self):
112 def setup(self):
113 """Make a valid python temp file."""
113 """Make a valid python temp file."""
114 self.mktmp('pass\n')
114 self.mktmp('pass\n')
115
115
116 def run_tmpfile(self):
116 def run_tmpfile(self):
117 _ip = get_ipython()
117 _ip = get_ipython()
118 # This fails on Windows if self.tmpfile.name has spaces or "~" in it.
118 # This fails on Windows if self.tmpfile.name has spaces or "~" in it.
119 # See below and ticket https://bugs.launchpad.net/bugs/366353
119 # See below and ticket https://bugs.launchpad.net/bugs/366353
120 _ip.magic('run %s' % self.fname)
120 _ip.magic('run %s' % self.fname)
121
121
122 def run_tmpfile_p(self):
122 def run_tmpfile_p(self):
123 _ip = get_ipython()
123 _ip = get_ipython()
124 # This fails on Windows if self.tmpfile.name has spaces or "~" in it.
124 # This fails on Windows if self.tmpfile.name has spaces or "~" in it.
125 # See below and ticket https://bugs.launchpad.net/bugs/366353
125 # See below and ticket https://bugs.launchpad.net/bugs/366353
126 _ip.magic('run -p %s' % self.fname)
126 _ip.magic('run -p %s' % self.fname)
127
127
128 def test_builtins_id(self):
128 def test_builtins_id(self):
129 """Check that %run doesn't damage __builtins__ """
129 """Check that %run doesn't damage __builtins__ """
130 _ip = get_ipython()
130 _ip = get_ipython()
131 # Test that the id of __builtins__ is not modified by %run
131 # Test that the id of __builtins__ is not modified by %run
132 bid1 = id(_ip.user_ns['__builtins__'])
132 bid1 = id(_ip.user_ns['__builtins__'])
133 self.run_tmpfile()
133 self.run_tmpfile()
134 bid2 = id(_ip.user_ns['__builtins__'])
134 bid2 = id(_ip.user_ns['__builtins__'])
135 tt.assert_equals(bid1, bid2)
135 tt.assert_equals(bid1, bid2)
136
136
137 def test_builtins_type(self):
137 def test_builtins_type(self):
138 """Check that the type of __builtins__ doesn't change with %run.
138 """Check that the type of __builtins__ doesn't change with %run.
139
139
140 However, the above could pass if __builtins__ was already modified to
140 However, the above could pass if __builtins__ was already modified to
141 be a dict (it should be a module) by a previous use of %run. So we
141 be a dict (it should be a module) by a previous use of %run. So we
142 also check explicitly that it really is a module:
142 also check explicitly that it really is a module:
143 """
143 """
144 _ip = get_ipython()
144 _ip = get_ipython()
145 self.run_tmpfile()
145 self.run_tmpfile()
146 tt.assert_equals(type(_ip.user_ns['__builtins__']),type(sys))
146 tt.assert_equals(type(_ip.user_ns['__builtins__']),type(sys))
147
147
148 def test_prompts(self):
148 def test_prompts(self):
149 """Test that prompts correctly generate after %run"""
149 """Test that prompts correctly generate after %run"""
150 self.run_tmpfile()
150 self.run_tmpfile()
151 _ip = get_ipython()
151 _ip = get_ipython()
152 p2 = _ip.prompt_manager.render('in2').strip()
152 p2 = _ip.prompt_manager.render('in2').strip()
153 nt.assert_equals(p2[:3], '...')
153 nt.assert_equal(p2[:3], '...')
154
154
155 def test_run_profile( self ):
155 def test_run_profile( self ):
156 """Test that the option -p, which invokes the profiler, do not
156 """Test that the option -p, which invokes the profiler, do not
157 crash by invoking execfile"""
157 crash by invoking execfile"""
158 _ip = get_ipython()
158 _ip = get_ipython()
159 self.run_tmpfile_p()
159 self.run_tmpfile_p()
160
160
161
161
162 class TestMagicRunSimple(tt.TempFileMixin):
162 class TestMagicRunSimple(tt.TempFileMixin):
163
163
164 def test_simpledef(self):
164 def test_simpledef(self):
165 """Test that simple class definitions work."""
165 """Test that simple class definitions work."""
166 src = ("class foo: pass\n"
166 src = ("class foo: pass\n"
167 "def f(): return foo()")
167 "def f(): return foo()")
168 self.mktmp(src)
168 self.mktmp(src)
169 _ip.magic('run %s' % self.fname)
169 _ip.magic('run %s' % self.fname)
170 _ip.run_cell('t = isinstance(f(), foo)')
170 _ip.run_cell('t = isinstance(f(), foo)')
171 nt.assert_true(_ip.user_ns['t'])
171 nt.assert_true(_ip.user_ns['t'])
172
172
173 def test_obj_del(self):
173 def test_obj_del(self):
174 """Test that object's __del__ methods are called on exit."""
174 """Test that object's __del__ methods are called on exit."""
175 if sys.platform == 'win32':
175 if sys.platform == 'win32':
176 try:
176 try:
177 import win32api
177 import win32api
178 except ImportError:
178 except ImportError:
179 raise SkipTest("Test requires pywin32")
179 raise SkipTest("Test requires pywin32")
180 src = ("class A(object):\n"
180 src = ("class A(object):\n"
181 " def __del__(self):\n"
181 " def __del__(self):\n"
182 " print 'object A deleted'\n"
182 " print 'object A deleted'\n"
183 "a = A()\n")
183 "a = A()\n")
184 self.mktmp(py3compat.doctest_refactor_print(src))
184 self.mktmp(py3compat.doctest_refactor_print(src))
185 if dec.module_not_available('sqlite3'):
185 if dec.module_not_available('sqlite3'):
186 err = 'WARNING: IPython History requires SQLite, your history will not be saved\n'
186 err = 'WARNING: IPython History requires SQLite, your history will not be saved\n'
187 else:
187 else:
188 err = None
188 err = None
189 tt.ipexec_validate(self.fname, 'object A deleted', err)
189 tt.ipexec_validate(self.fname, 'object A deleted', err)
190
190
191 @dec.skip_known_failure
191 @dec.skip_known_failure
192 def test_aggressive_namespace_cleanup(self):
192 def test_aggressive_namespace_cleanup(self):
193 """Test that namespace cleanup is not too aggressive GH-238
193 """Test that namespace cleanup is not too aggressive GH-238
194
194
195 Returning from another run magic deletes the namespace"""
195 Returning from another run magic deletes the namespace"""
196 # see ticket https://github.com/ipython/ipython/issues/238
196 # see ticket https://github.com/ipython/ipython/issues/238
197 class secondtmp(tt.TempFileMixin): pass
197 class secondtmp(tt.TempFileMixin): pass
198 empty = secondtmp()
198 empty = secondtmp()
199 empty.mktmp('')
199 empty.mktmp('')
200 src = ("ip = get_ipython()\n"
200 src = ("ip = get_ipython()\n"
201 "for i in range(5):\n"
201 "for i in range(5):\n"
202 " try:\n"
202 " try:\n"
203 " ip.magic('run %s')\n"
203 " ip.magic('run %s')\n"
204 " except NameError as e:\n"
204 " except NameError as e:\n"
205 " print i;break\n" % empty.fname)
205 " print i;break\n" % empty.fname)
206 self.mktmp(py3compat.doctest_refactor_print(src))
206 self.mktmp(py3compat.doctest_refactor_print(src))
207 _ip.magic('run %s' % self.fname)
207 _ip.magic('run %s' % self.fname)
208 _ip.run_cell('ip == get_ipython()')
208 _ip.run_cell('ip == get_ipython()')
209 tt.assert_equals(_ip.user_ns['i'], 5)
209 tt.assert_equals(_ip.user_ns['i'], 5)
210
210
211 @dec.skip_win32
211 @dec.skip_win32
212 def test_tclass(self):
212 def test_tclass(self):
213 mydir = os.path.dirname(__file__)
213 mydir = os.path.dirname(__file__)
214 tc = os.path.join(mydir, 'tclass')
214 tc = os.path.join(mydir, 'tclass')
215 src = ("%%run '%s' C-first\n"
215 src = ("%%run '%s' C-first\n"
216 "%%run '%s' C-second\n"
216 "%%run '%s' C-second\n"
217 "%%run '%s' C-third\n") % (tc, tc, tc)
217 "%%run '%s' C-third\n") % (tc, tc, tc)
218 self.mktmp(src, '.ipy')
218 self.mktmp(src, '.ipy')
219 out = """\
219 out = """\
220 ARGV 1-: ['C-first']
220 ARGV 1-: ['C-first']
221 ARGV 1-: ['C-second']
221 ARGV 1-: ['C-second']
222 tclass.py: deleting object: C-first
222 tclass.py: deleting object: C-first
223 ARGV 1-: ['C-third']
223 ARGV 1-: ['C-third']
224 tclass.py: deleting object: C-second
224 tclass.py: deleting object: C-second
225 tclass.py: deleting object: C-third
225 tclass.py: deleting object: C-third
226 """
226 """
227 if dec.module_not_available('sqlite3'):
227 if dec.module_not_available('sqlite3'):
228 err = 'WARNING: IPython History requires SQLite, your history will not be saved\n'
228 err = 'WARNING: IPython History requires SQLite, your history will not be saved\n'
229 else:
229 else:
230 err = None
230 err = None
231 tt.ipexec_validate(self.fname, out, err)
231 tt.ipexec_validate(self.fname, out, err)
232
232
233 def test_run_i_after_reset(self):
233 def test_run_i_after_reset(self):
234 """Check that %run -i still works after %reset (gh-693)"""
234 """Check that %run -i still works after %reset (gh-693)"""
235 src = "yy = zz\n"
235 src = "yy = zz\n"
236 self.mktmp(src)
236 self.mktmp(src)
237 _ip.run_cell("zz = 23")
237 _ip.run_cell("zz = 23")
238 _ip.magic('run -i %s' % self.fname)
238 _ip.magic('run -i %s' % self.fname)
239 tt.assert_equals(_ip.user_ns['yy'], 23)
239 tt.assert_equals(_ip.user_ns['yy'], 23)
240 _ip.magic('reset -f')
240 _ip.magic('reset -f')
241 _ip.run_cell("zz = 23")
241 _ip.run_cell("zz = 23")
242 _ip.magic('run -i %s' % self.fname)
242 _ip.magic('run -i %s' % self.fname)
243 tt.assert_equals(_ip.user_ns['yy'], 23)
243 tt.assert_equals(_ip.user_ns['yy'], 23)
244
244
245 def test_unicode(self):
245 def test_unicode(self):
246 """Check that files in odd encodings are accepted."""
246 """Check that files in odd encodings are accepted."""
247 mydir = os.path.dirname(__file__)
247 mydir = os.path.dirname(__file__)
248 na = os.path.join(mydir, 'nonascii.py')
248 na = os.path.join(mydir, 'nonascii.py')
249 _ip.magic('run "%s"' % na)
249 _ip.magic('run "%s"' % na)
250 tt.assert_equals(_ip.user_ns['u'], u'ΠŽΡ‚β„–Π€')
250 tt.assert_equals(_ip.user_ns['u'], u'ΠŽΡ‚β„–Π€')
@@ -1,58 +1,58
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Tests for the Cython magics extension."""
2 """Tests for the Cython magics extension."""
3
3
4 import os
4 import os
5 import nose.tools as nt
5 import nose.tools as nt
6
6
7 from IPython.testing import decorators as dec
7 from IPython.testing import decorators as dec
8 from IPython.utils import py3compat
8 from IPython.utils import py3compat
9
9
10 code = py3compat.str_to_unicode("""def f(x):
10 code = py3compat.str_to_unicode("""def f(x):
11 return 2*x
11 return 2*x
12 """)
12 """)
13
13
14 try:
14 try:
15 import Cython
15 import Cython
16 except:
16 except:
17 __test__ = False
17 __test__ = False
18
18
19 ip = get_ipython()
19 ip = get_ipython()
20
20
21
21
22 def setup():
22 def setup():
23 ip.extension_manager.load_extension('cythonmagic')
23 ip.extension_manager.load_extension('cythonmagic')
24
24
25
25
26 def test_cython_inline():
26 def test_cython_inline():
27 ip.ex('a=10; b=20')
27 ip.ex('a=10; b=20')
28 result = ip.run_cell_magic('cython_inline','','return a+b')
28 result = ip.run_cell_magic('cython_inline','','return a+b')
29 nt.assert_equals(result, 30)
29 nt.assert_equal(result, 30)
30
30
31
31
32 def test_cython_pyximport():
32 def test_cython_pyximport():
33 module_name = '_test_cython_pyximport'
33 module_name = '_test_cython_pyximport'
34 ip.run_cell_magic('cython_pyximport', module_name, code)
34 ip.run_cell_magic('cython_pyximport', module_name, code)
35 ip.ex('g = f(10)')
35 ip.ex('g = f(10)')
36 nt.assert_equals(ip.user_ns['g'], 20.0)
36 nt.assert_equal(ip.user_ns['g'], 20.0)
37 try:
37 try:
38 os.remove(module_name+'.pyx')
38 os.remove(module_name+'.pyx')
39 except OSError:
39 except OSError:
40 pass
40 pass
41
41
42
42
43 def test_cython():
43 def test_cython():
44 ip.run_cell_magic('cython', '', code)
44 ip.run_cell_magic('cython', '', code)
45 ip.ex('g = f(10)')
45 ip.ex('g = f(10)')
46 nt.assert_equals(ip.user_ns['g'], 20.0)
46 nt.assert_equal(ip.user_ns['g'], 20.0)
47
47
48
48
49 @dec.skip_win32
49 @dec.skip_win32
50 def test_extlibs():
50 def test_extlibs():
51 code = py3compat.str_to_unicode("""
51 code = py3compat.str_to_unicode("""
52 from libc.math cimport sin
52 from libc.math cimport sin
53 x = sin(0.0)
53 x = sin(0.0)
54 """)
54 """)
55 ip.user_ns['x'] = 1
55 ip.user_ns['x'] = 1
56 ip.run_cell_magic('cython', '-l m', code)
56 ip.run_cell_magic('cython', '-l m', code)
57 nt.assert_equals(ip.user_ns['x'], 0)
57 nt.assert_equal(ip.user_ns['x'], 0)
58
58
@@ -1,59 +1,59
1 """Tests for two-process terminal frontend
1 """Tests for two-process terminal frontend
2
2
3 Currenlty only has the most simple test possible, starting a console and running
3 Currenlty only has the most simple test possible, starting a console and running
4 a single command.
4 a single command.
5
5
6 Authors:
6 Authors:
7
7
8 * Min RK
8 * Min RK
9 """
9 """
10
10
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12 # Imports
12 # Imports
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14
14
15 import time
15 import time
16
16
17 import nose.tools as nt
17 import nose.tools as nt
18 from nose import SkipTest
18 from nose import SkipTest
19
19
20 from IPython.testing import decorators as dec
20 from IPython.testing import decorators as dec
21 from IPython.testing import tools as tt
21 from IPython.testing import tools as tt
22 from IPython.utils import py3compat
22 from IPython.utils import py3compat
23 from IPython.utils.process import find_cmd
23 from IPython.utils.process import find_cmd
24
24
25 #-----------------------------------------------------------------------------
25 #-----------------------------------------------------------------------------
26 # Test functions begin
26 # Test functions begin
27 #-----------------------------------------------------------------------------
27 #-----------------------------------------------------------------------------
28
28
29 @dec.skip_win32
29 @dec.skip_win32
30 def test_console_starts():
30 def test_console_starts():
31 """test that `ipython console` starts a terminal"""
31 """test that `ipython console` starts a terminal"""
32 from IPython.external import pexpect
32 from IPython.external import pexpect
33
33
34 # weird IOErrors prevent this from firing sometimes:
34 # weird IOErrors prevent this from firing sometimes:
35 ipython_cmd = None
35 ipython_cmd = None
36 for i in range(5):
36 for i in range(5):
37 try:
37 try:
38 ipython_cmd = find_cmd('ipython3' if py3compat.PY3 else 'ipython')
38 ipython_cmd = find_cmd('ipython3' if py3compat.PY3 else 'ipython')
39 except IOError:
39 except IOError:
40 time.sleep(0.1)
40 time.sleep(0.1)
41 else:
41 else:
42 break
42 break
43 if ipython_cmd is None:
43 if ipython_cmd is None:
44 raise SkipTest("Could not determine ipython command")
44 raise SkipTest("Could not determine ipython command")
45
45
46 p = pexpect.spawn(ipython_cmd, args=['console', '--colors=NoColor'])
46 p = pexpect.spawn(ipython_cmd, args=['console', '--colors=NoColor'])
47 idx = p.expect([r'In \[\d+\]', pexpect.EOF], timeout=15)
47 idx = p.expect([r'In \[\d+\]', pexpect.EOF], timeout=15)
48 nt.assert_equals(idx, 0, "expected in prompt")
48 nt.assert_equal(idx, 0, "expected in prompt")
49 p.sendline('5')
49 p.sendline('5')
50 idx = p.expect([r'Out\[\d+\]: 5', pexpect.EOF], timeout=5)
50 idx = p.expect([r'Out\[\d+\]: 5', pexpect.EOF], timeout=5)
51 nt.assert_equals(idx, 0, "expected out prompt")
51 nt.assert_equal(idx, 0, "expected out prompt")
52 idx = p.expect([r'In \[\d+\]', pexpect.EOF], timeout=5)
52 idx = p.expect([r'In \[\d+\]', pexpect.EOF], timeout=5)
53 nt.assert_equals(idx, 0, "expected second in prompt")
53 nt.assert_equal(idx, 0, "expected second in prompt")
54 # send ctrl-D;ctrl-D to exit
54 # send ctrl-D;ctrl-D to exit
55 p.sendeof()
55 p.sendeof()
56 p.sendeof()
56 p.sendeof()
57 p.expect([pexpect.EOF, pexpect.TIMEOUT], timeout=5)
57 p.expect([pexpect.EOF, pexpect.TIMEOUT], timeout=5)
58 if p.isalive():
58 if p.isalive():
59 p.terminate()
59 p.terminate()
@@ -1,91 +1,91
1 """Tests for pylab tools module.
1 """Tests for pylab tools module.
2 """
2 """
3 #-----------------------------------------------------------------------------
3 #-----------------------------------------------------------------------------
4 # Copyright (c) 2011, the IPython Development Team.
4 # Copyright (c) 2011, the IPython Development Team.
5 #
5 #
6 # Distributed under the terms of the Modified BSD License.
6 # Distributed under the terms of the Modified BSD License.
7 #
7 #
8 # The full license is in the file COPYING.txt, distributed with this software.
8 # The full license is in the file COPYING.txt, distributed with this software.
9 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
10
10
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12 # Imports
12 # Imports
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 from __future__ import print_function
14 from __future__ import print_function
15
15
16 # Stdlib imports
16 # Stdlib imports
17 import sys
17 import sys
18 import time
18 import time
19
19
20 # Third-party imports
20 # Third-party imports
21 import nose.tools as nt
21 import nose.tools as nt
22
22
23 # Our own imports
23 # Our own imports
24 from IPython.lib import backgroundjobs as bg
24 from IPython.lib import backgroundjobs as bg
25 from IPython.testing import decorators as dec
25 from IPython.testing import decorators as dec
26
26
27 #-----------------------------------------------------------------------------
27 #-----------------------------------------------------------------------------
28 # Globals and constants
28 # Globals and constants
29 #-----------------------------------------------------------------------------
29 #-----------------------------------------------------------------------------
30 t_short = 0.0001 # very short interval to wait on jobs
30 t_short = 0.0001 # very short interval to wait on jobs
31
31
32 #-----------------------------------------------------------------------------
32 #-----------------------------------------------------------------------------
33 # Local utilities
33 # Local utilities
34 #-----------------------------------------------------------------------------
34 #-----------------------------------------------------------------------------
35 def sleeper(interval=t_short, *a, **kw):
35 def sleeper(interval=t_short, *a, **kw):
36 args = dict(interval=interval,
36 args = dict(interval=interval,
37 other_args=a,
37 other_args=a,
38 kw_args=kw)
38 kw_args=kw)
39 time.sleep(interval)
39 time.sleep(interval)
40 return args
40 return args
41
41
42 def crasher(interval=t_short, *a, **kw):
42 def crasher(interval=t_short, *a, **kw):
43 time.sleep(interval)
43 time.sleep(interval)
44 raise Exception("Dead job with interval %s" % interval)
44 raise Exception("Dead job with interval %s" % interval)
45
45
46 #-----------------------------------------------------------------------------
46 #-----------------------------------------------------------------------------
47 # Classes and functions
47 # Classes and functions
48 #-----------------------------------------------------------------------------
48 #-----------------------------------------------------------------------------
49
49
50 def test_result():
50 def test_result():
51 """Test job submission and result retrieval"""
51 """Test job submission and result retrieval"""
52 jobs = bg.BackgroundJobManager()
52 jobs = bg.BackgroundJobManager()
53 j = jobs.new(sleeper)
53 j = jobs.new(sleeper)
54 j.join()
54 j.join()
55 nt.assert_equals(j.result['interval'], t_short)
55 nt.assert_equal(j.result['interval'], t_short)
56
56
57
57
58 def test_flush():
58 def test_flush():
59 """Test job control"""
59 """Test job control"""
60 jobs = bg.BackgroundJobManager()
60 jobs = bg.BackgroundJobManager()
61 j = jobs.new(sleeper)
61 j = jobs.new(sleeper)
62 j.join()
62 j.join()
63 nt.assert_equals(len(jobs.completed), 1)
63 nt.assert_equal(len(jobs.completed), 1)
64 nt.assert_equals(len(jobs.dead), 0)
64 nt.assert_equal(len(jobs.dead), 0)
65 jobs.flush()
65 jobs.flush()
66 nt.assert_equals(len(jobs.completed), 0)
66 nt.assert_equal(len(jobs.completed), 0)
67
67
68
68
69 def test_dead():
69 def test_dead():
70 """Test control of dead jobs"""
70 """Test control of dead jobs"""
71 jobs = bg.BackgroundJobManager()
71 jobs = bg.BackgroundJobManager()
72 j = jobs.new(crasher)
72 j = jobs.new(crasher)
73 j.join()
73 j.join()
74 nt.assert_equals(len(jobs.completed), 0)
74 nt.assert_equal(len(jobs.completed), 0)
75 nt.assert_equals(len(jobs.dead), 1)
75 nt.assert_equal(len(jobs.dead), 1)
76 jobs.flush()
76 jobs.flush()
77 nt.assert_equals(len(jobs.dead), 0)
77 nt.assert_equal(len(jobs.dead), 0)
78
78
79
79
80 def test_longer():
80 def test_longer():
81 """Test control of longer-running jobs"""
81 """Test control of longer-running jobs"""
82 jobs = bg.BackgroundJobManager()
82 jobs = bg.BackgroundJobManager()
83 # Sleep for long enough for the following two checks to still report the
83 # Sleep for long enough for the following two checks to still report the
84 # job as running, but not so long that it makes the test suite noticeably
84 # job as running, but not so long that it makes the test suite noticeably
85 # slower.
85 # slower.
86 j = jobs.new(sleeper, 0.1)
86 j = jobs.new(sleeper, 0.1)
87 nt.assert_equals(len(jobs.running), 1)
87 nt.assert_equal(len(jobs.running), 1)
88 nt.assert_equals(len(jobs.completed), 0)
88 nt.assert_equal(len(jobs.completed), 0)
89 j.join()
89 j.join()
90 nt.assert_equals(len(jobs.running), 0)
90 nt.assert_equal(len(jobs.running), 0)
91 nt.assert_equals(len(jobs.completed), 1)
91 nt.assert_equal(len(jobs.completed), 1)
@@ -1,84 +1,84
1 """Tests for IPython.lib.pretty.
1 """Tests for IPython.lib.pretty.
2 """
2 """
3 #-----------------------------------------------------------------------------
3 #-----------------------------------------------------------------------------
4 # Copyright (c) 2011, the IPython Development Team.
4 # Copyright (c) 2011, the IPython Development Team.
5 #
5 #
6 # Distributed under the terms of the Modified BSD License.
6 # Distributed under the terms of the Modified BSD License.
7 #
7 #
8 # The full license is in the file COPYING.txt, distributed with this software.
8 # The full license is in the file COPYING.txt, distributed with this software.
9 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
10
10
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12 # Imports
12 # Imports
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 from __future__ import print_function
14 from __future__ import print_function
15
15
16 # Third-party imports
16 # Third-party imports
17 import nose.tools as nt
17 import nose.tools as nt
18
18
19 # Our own imports
19 # Our own imports
20 from IPython.lib import pretty
20 from IPython.lib import pretty
21
21
22 #-----------------------------------------------------------------------------
22 #-----------------------------------------------------------------------------
23 # Classes and functions
23 # Classes and functions
24 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
25
25
26 class MyList(object):
26 class MyList(object):
27 def __init__(self, content):
27 def __init__(self, content):
28 self.content = content
28 self.content = content
29 def _repr_pretty_(self, p, cycle):
29 def _repr_pretty_(self, p, cycle):
30 if cycle:
30 if cycle:
31 p.text("MyList(...)")
31 p.text("MyList(...)")
32 else:
32 else:
33 with p.group(3, "MyList(", ")"):
33 with p.group(3, "MyList(", ")"):
34 for (i, child) in enumerate(self.content):
34 for (i, child) in enumerate(self.content):
35 if i:
35 if i:
36 p.text(",")
36 p.text(",")
37 p.breakable()
37 p.breakable()
38 else:
38 else:
39 p.breakable("")
39 p.breakable("")
40 p.pretty(child)
40 p.pretty(child)
41
41
42
42
43 class MyDict(dict):
43 class MyDict(dict):
44 def _repr_pretty_(self, p, cycle):
44 def _repr_pretty_(self, p, cycle):
45 p.text("MyDict(...)")
45 p.text("MyDict(...)")
46
46
47
47
48 class Dummy1(object):
48 class Dummy1(object):
49 def _repr_pretty_(self, p, cycle):
49 def _repr_pretty_(self, p, cycle):
50 p.text("Dummy1(...)")
50 p.text("Dummy1(...)")
51
51
52 class Dummy2(Dummy1):
52 class Dummy2(Dummy1):
53 _repr_pretty_ = None
53 _repr_pretty_ = None
54
54
55
55
56 def test_indentation():
56 def test_indentation():
57 """Test correct indentation in groups"""
57 """Test correct indentation in groups"""
58 count = 40
58 count = 40
59 gotoutput = pretty.pretty(MyList(range(count)))
59 gotoutput = pretty.pretty(MyList(range(count)))
60 expectedoutput = "MyList(\n" + ",\n".join(" %d" % i for i in range(count)) + ")"
60 expectedoutput = "MyList(\n" + ",\n".join(" %d" % i for i in range(count)) + ")"
61
61
62 nt.assert_equals(gotoutput, expectedoutput)
62 nt.assert_equal(gotoutput, expectedoutput)
63
63
64
64
65 def test_dispatch():
65 def test_dispatch():
66 """
66 """
67 Test correct dispatching: The _repr_pretty_ method for MyDict
67 Test correct dispatching: The _repr_pretty_ method for MyDict
68 must be found before the registered printer for dict.
68 must be found before the registered printer for dict.
69 """
69 """
70 gotoutput = pretty.pretty(MyDict())
70 gotoutput = pretty.pretty(MyDict())
71 expectedoutput = "MyDict(...)"
71 expectedoutput = "MyDict(...)"
72
72
73 nt.assert_equals(gotoutput, expectedoutput)
73 nt.assert_equal(gotoutput, expectedoutput)
74
74
75
75
76 def test_callability_checking():
76 def test_callability_checking():
77 """
77 """
78 Test that the _repr_pretty_ method is tested for callability and skipped if
78 Test that the _repr_pretty_ method is tested for callability and skipped if
79 not.
79 not.
80 """
80 """
81 gotoutput = pretty.pretty(Dummy2())
81 gotoutput = pretty.pretty(Dummy2())
82 expectedoutput = "Dummy1(...)"
82 expectedoutput = "Dummy1(...)"
83
83
84 nt.assert_equals(gotoutput, expectedoutput)
84 nt.assert_equal(gotoutput, expectedoutput)
@@ -1,21 +1,21
1 from IPython.lib import passwd
1 from IPython.lib import passwd
2 from IPython.lib.security import passwd_check, salt_len
2 from IPython.lib.security import passwd_check, salt_len
3 import nose.tools as nt
3 import nose.tools as nt
4
4
5 def test_passwd_structure():
5 def test_passwd_structure():
6 p = passwd('passphrase')
6 p = passwd('passphrase')
7 algorithm, salt, hashed = p.split(':')
7 algorithm, salt, hashed = p.split(':')
8 nt.assert_equals(algorithm, 'sha1')
8 nt.assert_equal(algorithm, 'sha1')
9 nt.assert_equals(len(salt), salt_len)
9 nt.assert_equal(len(salt), salt_len)
10 nt.assert_equals(len(hashed), 40)
10 nt.assert_equal(len(hashed), 40)
11
11
12 def test_roundtrip():
12 def test_roundtrip():
13 p = passwd('passphrase')
13 p = passwd('passphrase')
14 nt.assert_equals(passwd_check(p, 'passphrase'), True)
14 nt.assert_equal(passwd_check(p, 'passphrase'), True)
15
15
16 def test_bad():
16 def test_bad():
17 p = passwd('passphrase')
17 p = passwd('passphrase')
18 nt.assert_equals(passwd_check(p, p), False)
18 nt.assert_equal(passwd_check(p, p), False)
19 nt.assert_equals(passwd_check(p, 'a:b:c:d'), False)
19 nt.assert_equal(passwd_check(p, 'a:b:c:d'), False)
20 nt.assert_equals(passwd_check(p, 'a:b'), False)
20 nt.assert_equal(passwd_check(p, 'a:b'), False)
21
21
@@ -1,392 +1,392
1 """Generic testing tools.
1 """Generic testing tools.
2
2
3 In particular, this module exposes a set of top-level assert* functions that
3 In particular, this module exposes a set of top-level assert* functions that
4 can be used in place of nose.tools.assert* in method generators (the ones in
4 can be used in place of nose.tools.assert* in method generators (the ones in
5 nose can not, at least as of nose 0.10.4).
5 nose can not, at least as of nose 0.10.4).
6
6
7
7
8 Authors
8 Authors
9 -------
9 -------
10 - Fernando Perez <Fernando.Perez@berkeley.edu>
10 - Fernando Perez <Fernando.Perez@berkeley.edu>
11 """
11 """
12
12
13 from __future__ import absolute_import
13 from __future__ import absolute_import
14
14
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16 # Copyright (C) 2009-2011 The IPython Development Team
16 # Copyright (C) 2009-2011 The IPython Development Team
17 #
17 #
18 # Distributed under the terms of the BSD License. The full license is in
18 # Distributed under the terms of the BSD License. The full license is in
19 # the file COPYING, distributed as part of this software.
19 # the file COPYING, distributed as part of this software.
20 #-----------------------------------------------------------------------------
20 #-----------------------------------------------------------------------------
21
21
22 #-----------------------------------------------------------------------------
22 #-----------------------------------------------------------------------------
23 # Imports
23 # Imports
24 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
25
25
26 import os
26 import os
27 import re
27 import re
28 import sys
28 import sys
29 import tempfile
29 import tempfile
30
30
31 from contextlib import contextmanager
31 from contextlib import contextmanager
32 from io import StringIO
32 from io import StringIO
33
33
34 try:
34 try:
35 # These tools are used by parts of the runtime, so we make the nose
35 # These tools are used by parts of the runtime, so we make the nose
36 # dependency optional at this point. Nose is a hard dependency to run the
36 # dependency optional at this point. Nose is a hard dependency to run the
37 # test suite, but NOT to use ipython itself.
37 # test suite, but NOT to use ipython itself.
38 import nose.tools as nt
38 import nose.tools as nt
39 has_nose = True
39 has_nose = True
40 except ImportError:
40 except ImportError:
41 has_nose = False
41 has_nose = False
42
42
43 from IPython.config.loader import Config
43 from IPython.config.loader import Config
44 from IPython.utils.process import find_cmd, getoutputerror
44 from IPython.utils.process import find_cmd, getoutputerror
45 from IPython.utils.text import list_strings
45 from IPython.utils.text import list_strings
46 from IPython.utils.io import temp_pyfile, Tee
46 from IPython.utils.io import temp_pyfile, Tee
47 from IPython.utils import py3compat
47 from IPython.utils import py3compat
48 from IPython.utils.encoding import DEFAULT_ENCODING
48 from IPython.utils.encoding import DEFAULT_ENCODING
49
49
50 from . import decorators as dec
50 from . import decorators as dec
51 from . import skipdoctest
51 from . import skipdoctest
52
52
53 #-----------------------------------------------------------------------------
53 #-----------------------------------------------------------------------------
54 # Globals
54 # Globals
55 #-----------------------------------------------------------------------------
55 #-----------------------------------------------------------------------------
56
56
57 # Make a bunch of nose.tools assert wrappers that can be used in test
57 # Make a bunch of nose.tools assert wrappers that can be used in test
58 # generators. This will expose an assert* function for each one in nose.tools.
58 # generators. This will expose an assert* function for each one in nose.tools.
59
59
60 _tpl = """
60 _tpl = """
61 def %(name)s(*a,**kw):
61 def %(name)s(*a,**kw):
62 return nt.%(name)s(*a,**kw)
62 return nt.%(name)s(*a,**kw)
63 """
63 """
64
64
65 if has_nose:
65 if has_nose:
66 for _x in [a for a in dir(nt) if a.startswith('assert')]:
66 for _x in [a for a in dir(nt) if a.startswith('assert')]:
67 exec _tpl % dict(name=_x)
67 exec _tpl % dict(name=_x)
68
68
69 #-----------------------------------------------------------------------------
69 #-----------------------------------------------------------------------------
70 # Functions and classes
70 # Functions and classes
71 #-----------------------------------------------------------------------------
71 #-----------------------------------------------------------------------------
72
72
73 # The docstring for full_path doctests differently on win32 (different path
73 # The docstring for full_path doctests differently on win32 (different path
74 # separator) so just skip the doctest there. The example remains informative.
74 # separator) so just skip the doctest there. The example remains informative.
75 doctest_deco = skipdoctest.skip_doctest if sys.platform == 'win32' else dec.null_deco
75 doctest_deco = skipdoctest.skip_doctest if sys.platform == 'win32' else dec.null_deco
76
76
77 @doctest_deco
77 @doctest_deco
78 def full_path(startPath,files):
78 def full_path(startPath,files):
79 """Make full paths for all the listed files, based on startPath.
79 """Make full paths for all the listed files, based on startPath.
80
80
81 Only the base part of startPath is kept, since this routine is typically
81 Only the base part of startPath is kept, since this routine is typically
82 used with a script's __file__ variable as startPath. The base of startPath
82 used with a script's __file__ variable as startPath. The base of startPath
83 is then prepended to all the listed files, forming the output list.
83 is then prepended to all the listed files, forming the output list.
84
84
85 Parameters
85 Parameters
86 ----------
86 ----------
87 startPath : string
87 startPath : string
88 Initial path to use as the base for the results. This path is split
88 Initial path to use as the base for the results. This path is split
89 using os.path.split() and only its first component is kept.
89 using os.path.split() and only its first component is kept.
90
90
91 files : string or list
91 files : string or list
92 One or more files.
92 One or more files.
93
93
94 Examples
94 Examples
95 --------
95 --------
96
96
97 >>> full_path('/foo/bar.py',['a.txt','b.txt'])
97 >>> full_path('/foo/bar.py',['a.txt','b.txt'])
98 ['/foo/a.txt', '/foo/b.txt']
98 ['/foo/a.txt', '/foo/b.txt']
99
99
100 >>> full_path('/foo',['a.txt','b.txt'])
100 >>> full_path('/foo',['a.txt','b.txt'])
101 ['/a.txt', '/b.txt']
101 ['/a.txt', '/b.txt']
102
102
103 If a single file is given, the output is still a list:
103 If a single file is given, the output is still a list:
104 >>> full_path('/foo','a.txt')
104 >>> full_path('/foo','a.txt')
105 ['/a.txt']
105 ['/a.txt']
106 """
106 """
107
107
108 files = list_strings(files)
108 files = list_strings(files)
109 base = os.path.split(startPath)[0]
109 base = os.path.split(startPath)[0]
110 return [ os.path.join(base,f) for f in files ]
110 return [ os.path.join(base,f) for f in files ]
111
111
112
112
113 def parse_test_output(txt):
113 def parse_test_output(txt):
114 """Parse the output of a test run and return errors, failures.
114 """Parse the output of a test run and return errors, failures.
115
115
116 Parameters
116 Parameters
117 ----------
117 ----------
118 txt : str
118 txt : str
119 Text output of a test run, assumed to contain a line of one of the
119 Text output of a test run, assumed to contain a line of one of the
120 following forms::
120 following forms::
121 'FAILED (errors=1)'
121 'FAILED (errors=1)'
122 'FAILED (failures=1)'
122 'FAILED (failures=1)'
123 'FAILED (errors=1, failures=1)'
123 'FAILED (errors=1, failures=1)'
124
124
125 Returns
125 Returns
126 -------
126 -------
127 nerr, nfail: number of errors and failures.
127 nerr, nfail: number of errors and failures.
128 """
128 """
129
129
130 err_m = re.search(r'^FAILED \(errors=(\d+)\)', txt, re.MULTILINE)
130 err_m = re.search(r'^FAILED \(errors=(\d+)\)', txt, re.MULTILINE)
131 if err_m:
131 if err_m:
132 nerr = int(err_m.group(1))
132 nerr = int(err_m.group(1))
133 nfail = 0
133 nfail = 0
134 return nerr, nfail
134 return nerr, nfail
135
135
136 fail_m = re.search(r'^FAILED \(failures=(\d+)\)', txt, re.MULTILINE)
136 fail_m = re.search(r'^FAILED \(failures=(\d+)\)', txt, re.MULTILINE)
137 if fail_m:
137 if fail_m:
138 nerr = 0
138 nerr = 0
139 nfail = int(fail_m.group(1))
139 nfail = int(fail_m.group(1))
140 return nerr, nfail
140 return nerr, nfail
141
141
142 both_m = re.search(r'^FAILED \(errors=(\d+), failures=(\d+)\)', txt,
142 both_m = re.search(r'^FAILED \(errors=(\d+), failures=(\d+)\)', txt,
143 re.MULTILINE)
143 re.MULTILINE)
144 if both_m:
144 if both_m:
145 nerr = int(both_m.group(1))
145 nerr = int(both_m.group(1))
146 nfail = int(both_m.group(2))
146 nfail = int(both_m.group(2))
147 return nerr, nfail
147 return nerr, nfail
148
148
149 # If the input didn't match any of these forms, assume no error/failures
149 # If the input didn't match any of these forms, assume no error/failures
150 return 0, 0
150 return 0, 0
151
151
152
152
153 # So nose doesn't think this is a test
153 # So nose doesn't think this is a test
154 parse_test_output.__test__ = False
154 parse_test_output.__test__ = False
155
155
156
156
157 def default_argv():
157 def default_argv():
158 """Return a valid default argv for creating testing instances of ipython"""
158 """Return a valid default argv for creating testing instances of ipython"""
159
159
160 return ['--quick', # so no config file is loaded
160 return ['--quick', # so no config file is loaded
161 # Other defaults to minimize side effects on stdout
161 # Other defaults to minimize side effects on stdout
162 '--colors=NoColor', '--no-term-title','--no-banner',
162 '--colors=NoColor', '--no-term-title','--no-banner',
163 '--autocall=0']
163 '--autocall=0']
164
164
165
165
166 def default_config():
166 def default_config():
167 """Return a config object with good defaults for testing."""
167 """Return a config object with good defaults for testing."""
168 config = Config()
168 config = Config()
169 config.TerminalInteractiveShell.colors = 'NoColor'
169 config.TerminalInteractiveShell.colors = 'NoColor'
170 config.TerminalTerminalInteractiveShell.term_title = False,
170 config.TerminalTerminalInteractiveShell.term_title = False,
171 config.TerminalInteractiveShell.autocall = 0
171 config.TerminalInteractiveShell.autocall = 0
172 config.HistoryManager.hist_file = tempfile.mktemp(u'test_hist.sqlite')
172 config.HistoryManager.hist_file = tempfile.mktemp(u'test_hist.sqlite')
173 config.HistoryManager.db_cache_size = 10000
173 config.HistoryManager.db_cache_size = 10000
174 return config
174 return config
175
175
176
176
177 def ipexec(fname, options=None):
177 def ipexec(fname, options=None):
178 """Utility to call 'ipython filename'.
178 """Utility to call 'ipython filename'.
179
179
180 Starts IPython witha minimal and safe configuration to make startup as fast
180 Starts IPython witha minimal and safe configuration to make startup as fast
181 as possible.
181 as possible.
182
182
183 Note that this starts IPython in a subprocess!
183 Note that this starts IPython in a subprocess!
184
184
185 Parameters
185 Parameters
186 ----------
186 ----------
187 fname : str
187 fname : str
188 Name of file to be executed (should have .py or .ipy extension).
188 Name of file to be executed (should have .py or .ipy extension).
189
189
190 options : optional, list
190 options : optional, list
191 Extra command-line flags to be passed to IPython.
191 Extra command-line flags to be passed to IPython.
192
192
193 Returns
193 Returns
194 -------
194 -------
195 (stdout, stderr) of ipython subprocess.
195 (stdout, stderr) of ipython subprocess.
196 """
196 """
197 if options is None: options = []
197 if options is None: options = []
198
198
199 # For these subprocess calls, eliminate all prompt printing so we only see
199 # For these subprocess calls, eliminate all prompt printing so we only see
200 # output from script execution
200 # output from script execution
201 prompt_opts = [ '--PromptManager.in_template=""',
201 prompt_opts = [ '--PromptManager.in_template=""',
202 '--PromptManager.in2_template=""',
202 '--PromptManager.in2_template=""',
203 '--PromptManager.out_template=""'
203 '--PromptManager.out_template=""'
204 ]
204 ]
205 cmdargs = ' '.join(default_argv() + prompt_opts + options)
205 cmdargs = ' '.join(default_argv() + prompt_opts + options)
206
206
207 _ip = get_ipython()
207 _ip = get_ipython()
208 test_dir = os.path.dirname(__file__)
208 test_dir = os.path.dirname(__file__)
209
209
210 ipython_cmd = find_cmd('ipython3' if py3compat.PY3 else 'ipython')
210 ipython_cmd = find_cmd('ipython3' if py3compat.PY3 else 'ipython')
211 # Absolute path for filename
211 # Absolute path for filename
212 full_fname = os.path.join(test_dir, fname)
212 full_fname = os.path.join(test_dir, fname)
213 full_cmd = '%s %s %s' % (ipython_cmd, cmdargs, full_fname)
213 full_cmd = '%s %s %s' % (ipython_cmd, cmdargs, full_fname)
214 #print >> sys.stderr, 'FULL CMD:', full_cmd # dbg
214 #print >> sys.stderr, 'FULL CMD:', full_cmd # dbg
215 out, err = getoutputerror(full_cmd)
215 out, err = getoutputerror(full_cmd)
216 # `import readline` causes 'ESC[?1034h' to be output sometimes,
216 # `import readline` causes 'ESC[?1034h' to be output sometimes,
217 # so strip that out before doing comparisons
217 # so strip that out before doing comparisons
218 if out:
218 if out:
219 out = re.sub(r'\x1b\[[^h]+h', '', out)
219 out = re.sub(r'\x1b\[[^h]+h', '', out)
220 return out, err
220 return out, err
221
221
222
222
223 def ipexec_validate(fname, expected_out, expected_err='',
223 def ipexec_validate(fname, expected_out, expected_err='',
224 options=None):
224 options=None):
225 """Utility to call 'ipython filename' and validate output/error.
225 """Utility to call 'ipython filename' and validate output/error.
226
226
227 This function raises an AssertionError if the validation fails.
227 This function raises an AssertionError if the validation fails.
228
228
229 Note that this starts IPython in a subprocess!
229 Note that this starts IPython in a subprocess!
230
230
231 Parameters
231 Parameters
232 ----------
232 ----------
233 fname : str
233 fname : str
234 Name of the file to be executed (should have .py or .ipy extension).
234 Name of the file to be executed (should have .py or .ipy extension).
235
235
236 expected_out : str
236 expected_out : str
237 Expected stdout of the process.
237 Expected stdout of the process.
238
238
239 expected_err : optional, str
239 expected_err : optional, str
240 Expected stderr of the process.
240 Expected stderr of the process.
241
241
242 options : optional, list
242 options : optional, list
243 Extra command-line flags to be passed to IPython.
243 Extra command-line flags to be passed to IPython.
244
244
245 Returns
245 Returns
246 -------
246 -------
247 None
247 None
248 """
248 """
249
249
250 import nose.tools as nt
250 import nose.tools as nt
251
251
252 out, err = ipexec(fname, options)
252 out, err = ipexec(fname, options)
253 #print 'OUT', out # dbg
253 #print 'OUT', out # dbg
254 #print 'ERR', err # dbg
254 #print 'ERR', err # dbg
255 # If there are any errors, we must check those befor stdout, as they may be
255 # If there are any errors, we must check those befor stdout, as they may be
256 # more informative than simply having an empty stdout.
256 # more informative than simply having an empty stdout.
257 if err:
257 if err:
258 if expected_err:
258 if expected_err:
259 nt.assert_equals(err.strip(), expected_err.strip())
259 nt.assert_equal(err.strip(), expected_err.strip())
260 else:
260 else:
261 raise ValueError('Running file %r produced error: %r' %
261 raise ValueError('Running file %r produced error: %r' %
262 (fname, err))
262 (fname, err))
263 # If no errors or output on stderr was expected, match stdout
263 # If no errors or output on stderr was expected, match stdout
264 nt.assert_equals(out.strip(), expected_out.strip())
264 nt.assert_equal(out.strip(), expected_out.strip())
265
265
266
266
267 class TempFileMixin(object):
267 class TempFileMixin(object):
268 """Utility class to create temporary Python/IPython files.
268 """Utility class to create temporary Python/IPython files.
269
269
270 Meant as a mixin class for test cases."""
270 Meant as a mixin class for test cases."""
271
271
272 def mktmp(self, src, ext='.py'):
272 def mktmp(self, src, ext='.py'):
273 """Make a valid python temp file."""
273 """Make a valid python temp file."""
274 fname, f = temp_pyfile(src, ext)
274 fname, f = temp_pyfile(src, ext)
275 self.tmpfile = f
275 self.tmpfile = f
276 self.fname = fname
276 self.fname = fname
277
277
278 def tearDown(self):
278 def tearDown(self):
279 if hasattr(self, 'tmpfile'):
279 if hasattr(self, 'tmpfile'):
280 # If the tmpfile wasn't made because of skipped tests, like in
280 # If the tmpfile wasn't made because of skipped tests, like in
281 # win32, there's nothing to cleanup.
281 # win32, there's nothing to cleanup.
282 self.tmpfile.close()
282 self.tmpfile.close()
283 try:
283 try:
284 os.unlink(self.fname)
284 os.unlink(self.fname)
285 except:
285 except:
286 # On Windows, even though we close the file, we still can't
286 # On Windows, even though we close the file, we still can't
287 # delete it. I have no clue why
287 # delete it. I have no clue why
288 pass
288 pass
289
289
290 pair_fail_msg = ("Testing {0}\n\n"
290 pair_fail_msg = ("Testing {0}\n\n"
291 "In:\n"
291 "In:\n"
292 " {1!r}\n"
292 " {1!r}\n"
293 "Expected:\n"
293 "Expected:\n"
294 " {2!r}\n"
294 " {2!r}\n"
295 "Got:\n"
295 "Got:\n"
296 " {3!r}\n")
296 " {3!r}\n")
297 def check_pairs(func, pairs):
297 def check_pairs(func, pairs):
298 """Utility function for the common case of checking a function with a
298 """Utility function for the common case of checking a function with a
299 sequence of input/output pairs.
299 sequence of input/output pairs.
300
300
301 Parameters
301 Parameters
302 ----------
302 ----------
303 func : callable
303 func : callable
304 The function to be tested. Should accept a single argument.
304 The function to be tested. Should accept a single argument.
305 pairs : iterable
305 pairs : iterable
306 A list of (input, expected_output) tuples.
306 A list of (input, expected_output) tuples.
307
307
308 Returns
308 Returns
309 -------
309 -------
310 None. Raises an AssertionError if any output does not match the expected
310 None. Raises an AssertionError if any output does not match the expected
311 value.
311 value.
312 """
312 """
313 name = getattr(func, "func_name", getattr(func, "__name__", "<unknown>"))
313 name = getattr(func, "func_name", getattr(func, "__name__", "<unknown>"))
314 for inp, expected in pairs:
314 for inp, expected in pairs:
315 out = func(inp)
315 out = func(inp)
316 assert out == expected, pair_fail_msg.format(name, inp, expected, out)
316 assert out == expected, pair_fail_msg.format(name, inp, expected, out)
317
317
318
318
319 if py3compat.PY3:
319 if py3compat.PY3:
320 MyStringIO = StringIO
320 MyStringIO = StringIO
321 else:
321 else:
322 # In Python 2, stdout/stderr can have either bytes or unicode written to them,
322 # In Python 2, stdout/stderr can have either bytes or unicode written to them,
323 # so we need a class that can handle both.
323 # so we need a class that can handle both.
324 class MyStringIO(StringIO):
324 class MyStringIO(StringIO):
325 def write(self, s):
325 def write(self, s):
326 s = py3compat.cast_unicode(s, encoding=DEFAULT_ENCODING)
326 s = py3compat.cast_unicode(s, encoding=DEFAULT_ENCODING)
327 super(MyStringIO, self).write(s)
327 super(MyStringIO, self).write(s)
328
328
329 notprinted_msg = """Did not find {0!r} in printed output (on {1}):
329 notprinted_msg = """Did not find {0!r} in printed output (on {1}):
330 {2!r}"""
330 {2!r}"""
331
331
332 class AssertPrints(object):
332 class AssertPrints(object):
333 """Context manager for testing that code prints certain text.
333 """Context manager for testing that code prints certain text.
334
334
335 Examples
335 Examples
336 --------
336 --------
337 >>> with AssertPrints("abc", suppress=False):
337 >>> with AssertPrints("abc", suppress=False):
338 ... print "abcd"
338 ... print "abcd"
339 ... print "def"
339 ... print "def"
340 ...
340 ...
341 abcd
341 abcd
342 def
342 def
343 """
343 """
344 def __init__(self, s, channel='stdout', suppress=True):
344 def __init__(self, s, channel='stdout', suppress=True):
345 self.s = s
345 self.s = s
346 self.channel = channel
346 self.channel = channel
347 self.suppress = suppress
347 self.suppress = suppress
348
348
349 def __enter__(self):
349 def __enter__(self):
350 self.orig_stream = getattr(sys, self.channel)
350 self.orig_stream = getattr(sys, self.channel)
351 self.buffer = MyStringIO()
351 self.buffer = MyStringIO()
352 self.tee = Tee(self.buffer, channel=self.channel)
352 self.tee = Tee(self.buffer, channel=self.channel)
353 setattr(sys, self.channel, self.buffer if self.suppress else self.tee)
353 setattr(sys, self.channel, self.buffer if self.suppress else self.tee)
354
354
355 def __exit__(self, etype, value, traceback):
355 def __exit__(self, etype, value, traceback):
356 self.tee.flush()
356 self.tee.flush()
357 setattr(sys, self.channel, self.orig_stream)
357 setattr(sys, self.channel, self.orig_stream)
358 printed = self.buffer.getvalue()
358 printed = self.buffer.getvalue()
359 assert self.s in printed, notprinted_msg.format(self.s, self.channel, printed)
359 assert self.s in printed, notprinted_msg.format(self.s, self.channel, printed)
360 return False
360 return False
361
361
362 class AssertNotPrints(AssertPrints):
362 class AssertNotPrints(AssertPrints):
363 """Context manager for checking that certain output *isn't* produced.
363 """Context manager for checking that certain output *isn't* produced.
364
364
365 Counterpart of AssertPrints"""
365 Counterpart of AssertPrints"""
366 def __exit__(self, etype, value, traceback):
366 def __exit__(self, etype, value, traceback):
367 self.tee.flush()
367 self.tee.flush()
368 setattr(sys, self.channel, self.orig_stream)
368 setattr(sys, self.channel, self.orig_stream)
369 printed = self.buffer.getvalue()
369 printed = self.buffer.getvalue()
370 assert self.s not in printed, notprinted_msg.format(self.s, self.channel, printed)
370 assert self.s not in printed, notprinted_msg.format(self.s, self.channel, printed)
371 return False
371 return False
372
372
373 @contextmanager
373 @contextmanager
374 def mute_warn():
374 def mute_warn():
375 from IPython.utils import warn
375 from IPython.utils import warn
376 save_warn = warn.warn
376 save_warn = warn.warn
377 warn.warn = lambda *a, **kw: None
377 warn.warn = lambda *a, **kw: None
378 try:
378 try:
379 yield
379 yield
380 finally:
380 finally:
381 warn.warn = save_warn
381 warn.warn = save_warn
382
382
383 @contextmanager
383 @contextmanager
384 def make_tempfile(name):
384 def make_tempfile(name):
385 """ Create an empty, named, temporary file for the duration of the context.
385 """ Create an empty, named, temporary file for the duration of the context.
386 """
386 """
387 f = open(name, 'w')
387 f = open(name, 'w')
388 f.close()
388 f.close()
389 try:
389 try:
390 yield
390 yield
391 finally:
391 finally:
392 os.unlink(name)
392 os.unlink(name)
@@ -1,86 +1,86
1 # encoding: utf-8
1 # encoding: utf-8
2 """Tests for io.py"""
2 """Tests for io.py"""
3
3
4 #-----------------------------------------------------------------------------
4 #-----------------------------------------------------------------------------
5 # Copyright (C) 2008-2011 The IPython Development Team
5 # Copyright (C) 2008-2011 The IPython Development Team
6 #
6 #
7 # Distributed under the terms of the BSD License. The full license is in
7 # Distributed under the terms of the BSD License. The full license is in
8 # the file COPYING, distributed as part of this software.
8 # the file COPYING, distributed as part of this software.
9 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
10
10
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12 # Imports
12 # Imports
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 from __future__ import print_function
14 from __future__ import print_function
15
15
16 import sys
16 import sys
17
17
18 from StringIO import StringIO
18 from StringIO import StringIO
19 from subprocess import Popen, PIPE
19 from subprocess import Popen, PIPE
20
20
21 import nose.tools as nt
21 import nose.tools as nt
22
22
23 from IPython.testing import decorators as dec
23 from IPython.testing import decorators as dec
24 from IPython.utils.io import Tee, capture_output
24 from IPython.utils.io import Tee, capture_output
25 from IPython.utils.py3compat import doctest_refactor_print
25 from IPython.utils.py3compat import doctest_refactor_print
26
26
27 #-----------------------------------------------------------------------------
27 #-----------------------------------------------------------------------------
28 # Tests
28 # Tests
29 #-----------------------------------------------------------------------------
29 #-----------------------------------------------------------------------------
30
30
31
31
32 def test_tee_simple():
32 def test_tee_simple():
33 "Very simple check with stdout only"
33 "Very simple check with stdout only"
34 chan = StringIO()
34 chan = StringIO()
35 text = 'Hello'
35 text = 'Hello'
36 tee = Tee(chan, channel='stdout')
36 tee = Tee(chan, channel='stdout')
37 print(text, file=chan)
37 print(text, file=chan)
38 nt.assert_equal(chan.getvalue(), text+"\n")
38 nt.assert_equal(chan.getvalue(), text+"\n")
39
39
40
40
41 class TeeTestCase(dec.ParametricTestCase):
41 class TeeTestCase(dec.ParametricTestCase):
42
42
43 def tchan(self, channel, check='close'):
43 def tchan(self, channel, check='close'):
44 trap = StringIO()
44 trap = StringIO()
45 chan = StringIO()
45 chan = StringIO()
46 text = 'Hello'
46 text = 'Hello'
47
47
48 std_ori = getattr(sys, channel)
48 std_ori = getattr(sys, channel)
49 setattr(sys, channel, trap)
49 setattr(sys, channel, trap)
50
50
51 tee = Tee(chan, channel=channel)
51 tee = Tee(chan, channel=channel)
52 print(text, end='', file=chan)
52 print(text, end='', file=chan)
53 setattr(sys, channel, std_ori)
53 setattr(sys, channel, std_ori)
54 trap_val = trap.getvalue()
54 trap_val = trap.getvalue()
55 nt.assert_equals(chan.getvalue(), text)
55 nt.assert_equal(chan.getvalue(), text)
56 if check=='close':
56 if check=='close':
57 tee.close()
57 tee.close()
58 else:
58 else:
59 del tee
59 del tee
60
60
61 def test(self):
61 def test(self):
62 for chan in ['stdout', 'stderr']:
62 for chan in ['stdout', 'stderr']:
63 for check in ['close', 'del']:
63 for check in ['close', 'del']:
64 yield self.tchan(chan, check)
64 yield self.tchan(chan, check)
65
65
66 def test_io_init():
66 def test_io_init():
67 """Test that io.stdin/out/err exist at startup"""
67 """Test that io.stdin/out/err exist at startup"""
68 for name in ('stdin', 'stdout', 'stderr'):
68 for name in ('stdin', 'stdout', 'stderr'):
69 cmd = doctest_refactor_print("from IPython.utils import io;print io.%s.__class__"%name)
69 cmd = doctest_refactor_print("from IPython.utils import io;print io.%s.__class__"%name)
70 p = Popen([sys.executable, '-c', cmd],
70 p = Popen([sys.executable, '-c', cmd],
71 stdout=PIPE)
71 stdout=PIPE)
72 p.wait()
72 p.wait()
73 classname = p.stdout.read().strip().decode('ascii')
73 classname = p.stdout.read().strip().decode('ascii')
74 # __class__ is a reference to the class object in Python 3, so we can't
74 # __class__ is a reference to the class object in Python 3, so we can't
75 # just test for string equality.
75 # just test for string equality.
76 assert 'IPython.utils.io.IOStream' in classname, classname
76 assert 'IPython.utils.io.IOStream' in classname, classname
77
77
78 def test_capture_output():
78 def test_capture_output():
79 """capture_output() context works"""
79 """capture_output() context works"""
80
80
81 with capture_output() as io:
81 with capture_output() as io:
82 print('hi, stdout')
82 print('hi, stdout')
83 print('hi, stderr', file=sys.stderr)
83 print('hi, stderr', file=sys.stderr)
84
84
85 nt.assert_equals(io.stdout, 'hi, stdout\n')
85 nt.assert_equal(io.stdout, 'hi, stdout\n')
86 nt.assert_equals(io.stderr, 'hi, stderr\n')
86 nt.assert_equal(io.stderr, 'hi, stderr\n')
@@ -1,446 +1,446
1 # encoding: utf-8
1 # encoding: utf-8
2 """Tests for IPython.utils.path.py"""
2 """Tests for IPython.utils.path.py"""
3
3
4 #-----------------------------------------------------------------------------
4 #-----------------------------------------------------------------------------
5 # Copyright (C) 2008-2011 The IPython Development Team
5 # Copyright (C) 2008-2011 The IPython Development Team
6 #
6 #
7 # Distributed under the terms of the BSD License. The full license is in
7 # Distributed under the terms of the BSD License. The full license is in
8 # the file COPYING, distributed as part of this software.
8 # the file COPYING, distributed as part of this software.
9 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
10
10
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12 # Imports
12 # Imports
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14
14
15 from __future__ import with_statement
15 from __future__ import with_statement
16
16
17 import os
17 import os
18 import shutil
18 import shutil
19 import sys
19 import sys
20 import tempfile
20 import tempfile
21 from io import StringIO
21 from io import StringIO
22
22
23 from os.path import join, abspath, split
23 from os.path import join, abspath, split
24
24
25 import nose.tools as nt
25 import nose.tools as nt
26
26
27 from nose import with_setup
27 from nose import with_setup
28
28
29 import IPython
29 import IPython
30 from IPython.testing import decorators as dec
30 from IPython.testing import decorators as dec
31 from IPython.testing.decorators import skip_if_not_win32, skip_win32
31 from IPython.testing.decorators import skip_if_not_win32, skip_win32
32 from IPython.testing.tools import make_tempfile, AssertPrints
32 from IPython.testing.tools import make_tempfile, AssertPrints
33 from IPython.utils import path, io
33 from IPython.utils import path, io
34 from IPython.utils import py3compat
34 from IPython.utils import py3compat
35
35
36 # Platform-dependent imports
36 # Platform-dependent imports
37 try:
37 try:
38 import _winreg as wreg
38 import _winreg as wreg
39 except ImportError:
39 except ImportError:
40 #Fake _winreg module on none windows platforms
40 #Fake _winreg module on none windows platforms
41 import types
41 import types
42 wr_name = "winreg" if py3compat.PY3 else "_winreg"
42 wr_name = "winreg" if py3compat.PY3 else "_winreg"
43 sys.modules[wr_name] = types.ModuleType(wr_name)
43 sys.modules[wr_name] = types.ModuleType(wr_name)
44 import _winreg as wreg
44 import _winreg as wreg
45 #Add entries that needs to be stubbed by the testing code
45 #Add entries that needs to be stubbed by the testing code
46 (wreg.OpenKey, wreg.QueryValueEx,) = (None, None)
46 (wreg.OpenKey, wreg.QueryValueEx,) = (None, None)
47
47
48 try:
48 try:
49 reload
49 reload
50 except NameError: # Python 3
50 except NameError: # Python 3
51 from imp import reload
51 from imp import reload
52
52
53 #-----------------------------------------------------------------------------
53 #-----------------------------------------------------------------------------
54 # Globals
54 # Globals
55 #-----------------------------------------------------------------------------
55 #-----------------------------------------------------------------------------
56 env = os.environ
56 env = os.environ
57 TEST_FILE_PATH = split(abspath(__file__))[0]
57 TEST_FILE_PATH = split(abspath(__file__))[0]
58 TMP_TEST_DIR = tempfile.mkdtemp()
58 TMP_TEST_DIR = tempfile.mkdtemp()
59 HOME_TEST_DIR = join(TMP_TEST_DIR, "home_test_dir")
59 HOME_TEST_DIR = join(TMP_TEST_DIR, "home_test_dir")
60 XDG_TEST_DIR = join(HOME_TEST_DIR, "xdg_test_dir")
60 XDG_TEST_DIR = join(HOME_TEST_DIR, "xdg_test_dir")
61 IP_TEST_DIR = join(HOME_TEST_DIR,'.ipython')
61 IP_TEST_DIR = join(HOME_TEST_DIR,'.ipython')
62 #
62 #
63 # Setup/teardown functions/decorators
63 # Setup/teardown functions/decorators
64 #
64 #
65
65
66 def setup():
66 def setup():
67 """Setup testenvironment for the module:
67 """Setup testenvironment for the module:
68
68
69 - Adds dummy home dir tree
69 - Adds dummy home dir tree
70 """
70 """
71 # Do not mask exceptions here. In particular, catching WindowsError is a
71 # Do not mask exceptions here. In particular, catching WindowsError is a
72 # problem because that exception is only defined on Windows...
72 # problem because that exception is only defined on Windows...
73 os.makedirs(IP_TEST_DIR)
73 os.makedirs(IP_TEST_DIR)
74 os.makedirs(os.path.join(XDG_TEST_DIR, 'ipython'))
74 os.makedirs(os.path.join(XDG_TEST_DIR, 'ipython'))
75
75
76
76
77 def teardown():
77 def teardown():
78 """Teardown testenvironment for the module:
78 """Teardown testenvironment for the module:
79
79
80 - Remove dummy home dir tree
80 - Remove dummy home dir tree
81 """
81 """
82 # Note: we remove the parent test dir, which is the root of all test
82 # Note: we remove the parent test dir, which is the root of all test
83 # subdirs we may have created. Use shutil instead of os.removedirs, so
83 # subdirs we may have created. Use shutil instead of os.removedirs, so
84 # that non-empty directories are all recursively removed.
84 # that non-empty directories are all recursively removed.
85 shutil.rmtree(TMP_TEST_DIR)
85 shutil.rmtree(TMP_TEST_DIR)
86
86
87
87
88 def setup_environment():
88 def setup_environment():
89 """Setup testenvironment for some functions that are tested
89 """Setup testenvironment for some functions that are tested
90 in this module. In particular this functions stores attributes
90 in this module. In particular this functions stores attributes
91 and other things that we need to stub in some test functions.
91 and other things that we need to stub in some test functions.
92 This needs to be done on a function level and not module level because
92 This needs to be done on a function level and not module level because
93 each testfunction needs a pristine environment.
93 each testfunction needs a pristine environment.
94 """
94 """
95 global oldstuff, platformstuff
95 global oldstuff, platformstuff
96 oldstuff = (env.copy(), os.name, sys.platform, path.get_home_dir, IPython.__file__, os.getcwd())
96 oldstuff = (env.copy(), os.name, sys.platform, path.get_home_dir, IPython.__file__, os.getcwd())
97
97
98 if os.name == 'nt':
98 if os.name == 'nt':
99 platformstuff = (wreg.OpenKey, wreg.QueryValueEx,)
99 platformstuff = (wreg.OpenKey, wreg.QueryValueEx,)
100
100
101
101
102 def teardown_environment():
102 def teardown_environment():
103 """Restore things that were remebered by the setup_environment function
103 """Restore things that were remebered by the setup_environment function
104 """
104 """
105 (oldenv, os.name, sys.platform, path.get_home_dir, IPython.__file__, old_wd) = oldstuff
105 (oldenv, os.name, sys.platform, path.get_home_dir, IPython.__file__, old_wd) = oldstuff
106 os.chdir(old_wd)
106 os.chdir(old_wd)
107 reload(path)
107 reload(path)
108
108
109 for key in env.keys():
109 for key in env.keys():
110 if key not in oldenv:
110 if key not in oldenv:
111 del env[key]
111 del env[key]
112 env.update(oldenv)
112 env.update(oldenv)
113 if hasattr(sys, 'frozen'):
113 if hasattr(sys, 'frozen'):
114 del sys.frozen
114 del sys.frozen
115 if os.name == 'nt':
115 if os.name == 'nt':
116 (wreg.OpenKey, wreg.QueryValueEx,) = platformstuff
116 (wreg.OpenKey, wreg.QueryValueEx,) = platformstuff
117
117
118 # Build decorator that uses the setup_environment/setup_environment
118 # Build decorator that uses the setup_environment/setup_environment
119 with_environment = with_setup(setup_environment, teardown_environment)
119 with_environment = with_setup(setup_environment, teardown_environment)
120
120
121 @skip_if_not_win32
121 @skip_if_not_win32
122 @with_environment
122 @with_environment
123 def test_get_home_dir_1():
123 def test_get_home_dir_1():
124 """Testcase for py2exe logic, un-compressed lib
124 """Testcase for py2exe logic, un-compressed lib
125 """
125 """
126 sys.frozen = True
126 sys.frozen = True
127
127
128 #fake filename for IPython.__init__
128 #fake filename for IPython.__init__
129 IPython.__file__ = abspath(join(HOME_TEST_DIR, "Lib/IPython/__init__.py"))
129 IPython.__file__ = abspath(join(HOME_TEST_DIR, "Lib/IPython/__init__.py"))
130
130
131 home_dir = path.get_home_dir()
131 home_dir = path.get_home_dir()
132 nt.assert_equal(home_dir, abspath(HOME_TEST_DIR))
132 nt.assert_equal(home_dir, abspath(HOME_TEST_DIR))
133
133
134
134
135 @skip_if_not_win32
135 @skip_if_not_win32
136 @with_environment
136 @with_environment
137 def test_get_home_dir_2():
137 def test_get_home_dir_2():
138 """Testcase for py2exe logic, compressed lib
138 """Testcase for py2exe logic, compressed lib
139 """
139 """
140 sys.frozen = True
140 sys.frozen = True
141 #fake filename for IPython.__init__
141 #fake filename for IPython.__init__
142 IPython.__file__ = abspath(join(HOME_TEST_DIR, "Library.zip/IPython/__init__.py")).lower()
142 IPython.__file__ = abspath(join(HOME_TEST_DIR, "Library.zip/IPython/__init__.py")).lower()
143
143
144 home_dir = path.get_home_dir(True)
144 home_dir = path.get_home_dir(True)
145 nt.assert_equal(home_dir, abspath(HOME_TEST_DIR).lower())
145 nt.assert_equal(home_dir, abspath(HOME_TEST_DIR).lower())
146
146
147
147
148 @with_environment
148 @with_environment
149 def test_get_home_dir_3():
149 def test_get_home_dir_3():
150 """get_home_dir() uses $HOME if set"""
150 """get_home_dir() uses $HOME if set"""
151 env["HOME"] = HOME_TEST_DIR
151 env["HOME"] = HOME_TEST_DIR
152 home_dir = path.get_home_dir(True)
152 home_dir = path.get_home_dir(True)
153 # get_home_dir expands symlinks
153 # get_home_dir expands symlinks
154 nt.assert_equal(home_dir, os.path.realpath(env["HOME"]))
154 nt.assert_equal(home_dir, os.path.realpath(env["HOME"]))
155
155
156
156
157 @with_environment
157 @with_environment
158 def test_get_home_dir_4():
158 def test_get_home_dir_4():
159 """get_home_dir() still works if $HOME is not set"""
159 """get_home_dir() still works if $HOME is not set"""
160
160
161 if 'HOME' in env: del env['HOME']
161 if 'HOME' in env: del env['HOME']
162 # this should still succeed, but we don't care what the answer is
162 # this should still succeed, but we don't care what the answer is
163 home = path.get_home_dir(False)
163 home = path.get_home_dir(False)
164
164
165 @with_environment
165 @with_environment
166 def test_get_home_dir_5():
166 def test_get_home_dir_5():
167 """raise HomeDirError if $HOME is specified, but not a writable dir"""
167 """raise HomeDirError if $HOME is specified, but not a writable dir"""
168 env['HOME'] = abspath(HOME_TEST_DIR+'garbage')
168 env['HOME'] = abspath(HOME_TEST_DIR+'garbage')
169 # set os.name = posix, to prevent My Documents fallback on Windows
169 # set os.name = posix, to prevent My Documents fallback on Windows
170 os.name = 'posix'
170 os.name = 'posix'
171 nt.assert_raises(path.HomeDirError, path.get_home_dir, True)
171 nt.assert_raises(path.HomeDirError, path.get_home_dir, True)
172
172
173
173
174 # Should we stub wreg fully so we can run the test on all platforms?
174 # Should we stub wreg fully so we can run the test on all platforms?
175 @skip_if_not_win32
175 @skip_if_not_win32
176 @with_environment
176 @with_environment
177 def test_get_home_dir_8():
177 def test_get_home_dir_8():
178 """Using registry hack for 'My Documents', os=='nt'
178 """Using registry hack for 'My Documents', os=='nt'
179
179
180 HOMESHARE, HOMEDRIVE, HOMEPATH, USERPROFILE and others are missing.
180 HOMESHARE, HOMEDRIVE, HOMEPATH, USERPROFILE and others are missing.
181 """
181 """
182 os.name = 'nt'
182 os.name = 'nt'
183 # Remove from stub environment all keys that may be set
183 # Remove from stub environment all keys that may be set
184 for key in ['HOME', 'HOMESHARE', 'HOMEDRIVE', 'HOMEPATH', 'USERPROFILE']:
184 for key in ['HOME', 'HOMESHARE', 'HOMEDRIVE', 'HOMEPATH', 'USERPROFILE']:
185 env.pop(key, None)
185 env.pop(key, None)
186
186
187 #Stub windows registry functions
187 #Stub windows registry functions
188 def OpenKey(x, y):
188 def OpenKey(x, y):
189 class key:
189 class key:
190 def Close(self):
190 def Close(self):
191 pass
191 pass
192 return key()
192 return key()
193 def QueryValueEx(x, y):
193 def QueryValueEx(x, y):
194 return [abspath(HOME_TEST_DIR)]
194 return [abspath(HOME_TEST_DIR)]
195
195
196 wreg.OpenKey = OpenKey
196 wreg.OpenKey = OpenKey
197 wreg.QueryValueEx = QueryValueEx
197 wreg.QueryValueEx = QueryValueEx
198
198
199 home_dir = path.get_home_dir()
199 home_dir = path.get_home_dir()
200 nt.assert_equal(home_dir, abspath(HOME_TEST_DIR))
200 nt.assert_equal(home_dir, abspath(HOME_TEST_DIR))
201
201
202
202
203 @with_environment
203 @with_environment
204 def test_get_ipython_dir_1():
204 def test_get_ipython_dir_1():
205 """test_get_ipython_dir_1, Testcase to see if we can call get_ipython_dir without Exceptions."""
205 """test_get_ipython_dir_1, Testcase to see if we can call get_ipython_dir without Exceptions."""
206 env_ipdir = os.path.join("someplace", ".ipython")
206 env_ipdir = os.path.join("someplace", ".ipython")
207 path._writable_dir = lambda path: True
207 path._writable_dir = lambda path: True
208 env['IPYTHONDIR'] = env_ipdir
208 env['IPYTHONDIR'] = env_ipdir
209 ipdir = path.get_ipython_dir()
209 ipdir = path.get_ipython_dir()
210 nt.assert_equal(ipdir, env_ipdir)
210 nt.assert_equal(ipdir, env_ipdir)
211
211
212
212
213 @with_environment
213 @with_environment
214 def test_get_ipython_dir_2():
214 def test_get_ipython_dir_2():
215 """test_get_ipython_dir_2, Testcase to see if we can call get_ipython_dir without Exceptions."""
215 """test_get_ipython_dir_2, Testcase to see if we can call get_ipython_dir without Exceptions."""
216 path.get_home_dir = lambda : "someplace"
216 path.get_home_dir = lambda : "someplace"
217 path.get_xdg_dir = lambda : None
217 path.get_xdg_dir = lambda : None
218 path._writable_dir = lambda path: True
218 path._writable_dir = lambda path: True
219 os.name = "posix"
219 os.name = "posix"
220 env.pop('IPYTHON_DIR', None)
220 env.pop('IPYTHON_DIR', None)
221 env.pop('IPYTHONDIR', None)
221 env.pop('IPYTHONDIR', None)
222 env.pop('XDG_CONFIG_HOME', None)
222 env.pop('XDG_CONFIG_HOME', None)
223 ipdir = path.get_ipython_dir()
223 ipdir = path.get_ipython_dir()
224 nt.assert_equal(ipdir, os.path.join("someplace", ".ipython"))
224 nt.assert_equal(ipdir, os.path.join("someplace", ".ipython"))
225
225
226 @with_environment
226 @with_environment
227 def test_get_ipython_dir_3():
227 def test_get_ipython_dir_3():
228 """test_get_ipython_dir_3, use XDG if defined, and .ipython doesn't exist."""
228 """test_get_ipython_dir_3, use XDG if defined, and .ipython doesn't exist."""
229 path.get_home_dir = lambda : "someplace"
229 path.get_home_dir = lambda : "someplace"
230 path._writable_dir = lambda path: True
230 path._writable_dir = lambda path: True
231 os.name = "posix"
231 os.name = "posix"
232 env.pop('IPYTHON_DIR', None)
232 env.pop('IPYTHON_DIR', None)
233 env.pop('IPYTHONDIR', None)
233 env.pop('IPYTHONDIR', None)
234 env['XDG_CONFIG_HOME'] = XDG_TEST_DIR
234 env['XDG_CONFIG_HOME'] = XDG_TEST_DIR
235 ipdir = path.get_ipython_dir()
235 ipdir = path.get_ipython_dir()
236 if sys.platform == "darwin":
236 if sys.platform == "darwin":
237 expected = os.path.join("someplace", ".ipython")
237 expected = os.path.join("someplace", ".ipython")
238 else:
238 else:
239 expected = os.path.join(XDG_TEST_DIR, "ipython")
239 expected = os.path.join(XDG_TEST_DIR, "ipython")
240 nt.assert_equal(ipdir, expected)
240 nt.assert_equal(ipdir, expected)
241
241
242 @with_environment
242 @with_environment
243 def test_get_ipython_dir_4():
243 def test_get_ipython_dir_4():
244 """test_get_ipython_dir_4, use XDG if both exist."""
244 """test_get_ipython_dir_4, use XDG if both exist."""
245 path.get_home_dir = lambda : HOME_TEST_DIR
245 path.get_home_dir = lambda : HOME_TEST_DIR
246 os.name = "posix"
246 os.name = "posix"
247 env.pop('IPYTHON_DIR', None)
247 env.pop('IPYTHON_DIR', None)
248 env.pop('IPYTHONDIR', None)
248 env.pop('IPYTHONDIR', None)
249 env['XDG_CONFIG_HOME'] = XDG_TEST_DIR
249 env['XDG_CONFIG_HOME'] = XDG_TEST_DIR
250 ipdir = path.get_ipython_dir()
250 ipdir = path.get_ipython_dir()
251 if sys.platform == "darwin":
251 if sys.platform == "darwin":
252 expected = os.path.join(HOME_TEST_DIR, ".ipython")
252 expected = os.path.join(HOME_TEST_DIR, ".ipython")
253 else:
253 else:
254 expected = os.path.join(XDG_TEST_DIR, "ipython")
254 expected = os.path.join(XDG_TEST_DIR, "ipython")
255 nt.assert_equal(ipdir, expected)
255 nt.assert_equal(ipdir, expected)
256
256
257 @with_environment
257 @with_environment
258 def test_get_ipython_dir_5():
258 def test_get_ipython_dir_5():
259 """test_get_ipython_dir_5, use .ipython if exists and XDG defined, but doesn't exist."""
259 """test_get_ipython_dir_5, use .ipython if exists and XDG defined, but doesn't exist."""
260 path.get_home_dir = lambda : HOME_TEST_DIR
260 path.get_home_dir = lambda : HOME_TEST_DIR
261 os.name = "posix"
261 os.name = "posix"
262 env.pop('IPYTHON_DIR', None)
262 env.pop('IPYTHON_DIR', None)
263 env.pop('IPYTHONDIR', None)
263 env.pop('IPYTHONDIR', None)
264 env['XDG_CONFIG_HOME'] = XDG_TEST_DIR
264 env['XDG_CONFIG_HOME'] = XDG_TEST_DIR
265 os.rmdir(os.path.join(XDG_TEST_DIR, 'ipython'))
265 os.rmdir(os.path.join(XDG_TEST_DIR, 'ipython'))
266 ipdir = path.get_ipython_dir()
266 ipdir = path.get_ipython_dir()
267 nt.assert_equal(ipdir, IP_TEST_DIR)
267 nt.assert_equal(ipdir, IP_TEST_DIR)
268
268
269 @with_environment
269 @with_environment
270 def test_get_ipython_dir_6():
270 def test_get_ipython_dir_6():
271 """test_get_ipython_dir_6, use XDG if defined and neither exist."""
271 """test_get_ipython_dir_6, use XDG if defined and neither exist."""
272 xdg = os.path.join(HOME_TEST_DIR, 'somexdg')
272 xdg = os.path.join(HOME_TEST_DIR, 'somexdg')
273 os.mkdir(xdg)
273 os.mkdir(xdg)
274 shutil.rmtree(os.path.join(HOME_TEST_DIR, '.ipython'))
274 shutil.rmtree(os.path.join(HOME_TEST_DIR, '.ipython'))
275 path.get_home_dir = lambda : HOME_TEST_DIR
275 path.get_home_dir = lambda : HOME_TEST_DIR
276 path.get_xdg_dir = lambda : xdg
276 path.get_xdg_dir = lambda : xdg
277 os.name = "posix"
277 os.name = "posix"
278 env.pop('IPYTHON_DIR', None)
278 env.pop('IPYTHON_DIR', None)
279 env.pop('IPYTHONDIR', None)
279 env.pop('IPYTHONDIR', None)
280 env.pop('XDG_CONFIG_HOME', None)
280 env.pop('XDG_CONFIG_HOME', None)
281 xdg_ipdir = os.path.join(xdg, "ipython")
281 xdg_ipdir = os.path.join(xdg, "ipython")
282 ipdir = path.get_ipython_dir()
282 ipdir = path.get_ipython_dir()
283 nt.assert_equal(ipdir, xdg_ipdir)
283 nt.assert_equal(ipdir, xdg_ipdir)
284
284
285 @with_environment
285 @with_environment
286 def test_get_ipython_dir_7():
286 def test_get_ipython_dir_7():
287 """test_get_ipython_dir_7, test home directory expansion on IPYTHONDIR"""
287 """test_get_ipython_dir_7, test home directory expansion on IPYTHONDIR"""
288 path._writable_dir = lambda path: True
288 path._writable_dir = lambda path: True
289 home_dir = os.path.normpath(os.path.expanduser('~'))
289 home_dir = os.path.normpath(os.path.expanduser('~'))
290 env['IPYTHONDIR'] = os.path.join('~', 'somewhere')
290 env['IPYTHONDIR'] = os.path.join('~', 'somewhere')
291 ipdir = path.get_ipython_dir()
291 ipdir = path.get_ipython_dir()
292 nt.assert_equal(ipdir, os.path.join(home_dir, 'somewhere'))
292 nt.assert_equal(ipdir, os.path.join(home_dir, 'somewhere'))
293
293
294
294
295 @with_environment
295 @with_environment
296 def test_get_xdg_dir_0():
296 def test_get_xdg_dir_0():
297 """test_get_xdg_dir_0, check xdg_dir"""
297 """test_get_xdg_dir_0, check xdg_dir"""
298 reload(path)
298 reload(path)
299 path._writable_dir = lambda path: True
299 path._writable_dir = lambda path: True
300 path.get_home_dir = lambda : 'somewhere'
300 path.get_home_dir = lambda : 'somewhere'
301 os.name = "posix"
301 os.name = "posix"
302 sys.platform = "linux2"
302 sys.platform = "linux2"
303 env.pop('IPYTHON_DIR', None)
303 env.pop('IPYTHON_DIR', None)
304 env.pop('IPYTHONDIR', None)
304 env.pop('IPYTHONDIR', None)
305 env.pop('XDG_CONFIG_HOME', None)
305 env.pop('XDG_CONFIG_HOME', None)
306
306
307 nt.assert_equal(path.get_xdg_dir(), os.path.join('somewhere', '.config'))
307 nt.assert_equal(path.get_xdg_dir(), os.path.join('somewhere', '.config'))
308
308
309
309
310 @with_environment
310 @with_environment
311 def test_get_xdg_dir_1():
311 def test_get_xdg_dir_1():
312 """test_get_xdg_dir_1, check nonexistant xdg_dir"""
312 """test_get_xdg_dir_1, check nonexistant xdg_dir"""
313 reload(path)
313 reload(path)
314 path.get_home_dir = lambda : HOME_TEST_DIR
314 path.get_home_dir = lambda : HOME_TEST_DIR
315 os.name = "posix"
315 os.name = "posix"
316 sys.platform = "linux2"
316 sys.platform = "linux2"
317 env.pop('IPYTHON_DIR', None)
317 env.pop('IPYTHON_DIR', None)
318 env.pop('IPYTHONDIR', None)
318 env.pop('IPYTHONDIR', None)
319 env.pop('XDG_CONFIG_HOME', None)
319 env.pop('XDG_CONFIG_HOME', None)
320 nt.assert_equal(path.get_xdg_dir(), None)
320 nt.assert_equal(path.get_xdg_dir(), None)
321
321
322 @with_environment
322 @with_environment
323 def test_get_xdg_dir_2():
323 def test_get_xdg_dir_2():
324 """test_get_xdg_dir_2, check xdg_dir default to ~/.config"""
324 """test_get_xdg_dir_2, check xdg_dir default to ~/.config"""
325 reload(path)
325 reload(path)
326 path.get_home_dir = lambda : HOME_TEST_DIR
326 path.get_home_dir = lambda : HOME_TEST_DIR
327 os.name = "posix"
327 os.name = "posix"
328 sys.platform = "linux2"
328 sys.platform = "linux2"
329 env.pop('IPYTHON_DIR', None)
329 env.pop('IPYTHON_DIR', None)
330 env.pop('IPYTHONDIR', None)
330 env.pop('IPYTHONDIR', None)
331 env.pop('XDG_CONFIG_HOME', None)
331 env.pop('XDG_CONFIG_HOME', None)
332 cfgdir=os.path.join(path.get_home_dir(), '.config')
332 cfgdir=os.path.join(path.get_home_dir(), '.config')
333 if not os.path.exists(cfgdir):
333 if not os.path.exists(cfgdir):
334 os.makedirs(cfgdir)
334 os.makedirs(cfgdir)
335
335
336 nt.assert_equal(path.get_xdg_dir(), cfgdir)
336 nt.assert_equal(path.get_xdg_dir(), cfgdir)
337
337
338 @with_environment
338 @with_environment
339 def test_get_xdg_dir_3():
339 def test_get_xdg_dir_3():
340 """test_get_xdg_dir_3, check xdg_dir not used on OS X"""
340 """test_get_xdg_dir_3, check xdg_dir not used on OS X"""
341 reload(path)
341 reload(path)
342 path.get_home_dir = lambda : HOME_TEST_DIR
342 path.get_home_dir = lambda : HOME_TEST_DIR
343 os.name = "posix"
343 os.name = "posix"
344 sys.platform = "darwin"
344 sys.platform = "darwin"
345 env.pop('IPYTHON_DIR', None)
345 env.pop('IPYTHON_DIR', None)
346 env.pop('IPYTHONDIR', None)
346 env.pop('IPYTHONDIR', None)
347 env.pop('XDG_CONFIG_HOME', None)
347 env.pop('XDG_CONFIG_HOME', None)
348 cfgdir=os.path.join(path.get_home_dir(), '.config')
348 cfgdir=os.path.join(path.get_home_dir(), '.config')
349 if not os.path.exists(cfgdir):
349 if not os.path.exists(cfgdir):
350 os.makedirs(cfgdir)
350 os.makedirs(cfgdir)
351
351
352 nt.assert_equal(path.get_xdg_dir(), None)
352 nt.assert_equal(path.get_xdg_dir(), None)
353
353
354 def test_filefind():
354 def test_filefind():
355 """Various tests for filefind"""
355 """Various tests for filefind"""
356 f = tempfile.NamedTemporaryFile()
356 f = tempfile.NamedTemporaryFile()
357 # print 'fname:',f.name
357 # print 'fname:',f.name
358 alt_dirs = path.get_ipython_dir()
358 alt_dirs = path.get_ipython_dir()
359 t = path.filefind(f.name, alt_dirs)
359 t = path.filefind(f.name, alt_dirs)
360 # print 'found:',t
360 # print 'found:',t
361
361
362
362
363 def test_get_ipython_package_dir():
363 def test_get_ipython_package_dir():
364 ipdir = path.get_ipython_package_dir()
364 ipdir = path.get_ipython_package_dir()
365 nt.assert_true(os.path.isdir(ipdir))
365 nt.assert_true(os.path.isdir(ipdir))
366
366
367
367
368 def test_get_ipython_module_path():
368 def test_get_ipython_module_path():
369 ipapp_path = path.get_ipython_module_path('IPython.frontend.terminal.ipapp')
369 ipapp_path = path.get_ipython_module_path('IPython.frontend.terminal.ipapp')
370 nt.assert_true(os.path.isfile(ipapp_path))
370 nt.assert_true(os.path.isfile(ipapp_path))
371
371
372
372
373 @dec.skip_if_not_win32
373 @dec.skip_if_not_win32
374 def test_get_long_path_name_win32():
374 def test_get_long_path_name_win32():
375 p = path.get_long_path_name('c:\\docume~1')
375 p = path.get_long_path_name('c:\\docume~1')
376 nt.assert_equals(p,u'c:\\Documents and Settings')
376 nt.assert_equal(p,u'c:\\Documents and Settings')
377
377
378
378
379 @dec.skip_win32
379 @dec.skip_win32
380 def test_get_long_path_name():
380 def test_get_long_path_name():
381 p = path.get_long_path_name('/usr/local')
381 p = path.get_long_path_name('/usr/local')
382 nt.assert_equals(p,'/usr/local')
382 nt.assert_equal(p,'/usr/local')
383
383
384 @dec.skip_win32 # can't create not-user-writable dir on win
384 @dec.skip_win32 # can't create not-user-writable dir on win
385 @with_environment
385 @with_environment
386 def test_not_writable_ipdir():
386 def test_not_writable_ipdir():
387 tmpdir = tempfile.mkdtemp()
387 tmpdir = tempfile.mkdtemp()
388 os.name = "posix"
388 os.name = "posix"
389 env.pop('IPYTHON_DIR', None)
389 env.pop('IPYTHON_DIR', None)
390 env.pop('IPYTHONDIR', None)
390 env.pop('IPYTHONDIR', None)
391 env.pop('XDG_CONFIG_HOME', None)
391 env.pop('XDG_CONFIG_HOME', None)
392 env['HOME'] = tmpdir
392 env['HOME'] = tmpdir
393 ipdir = os.path.join(tmpdir, '.ipython')
393 ipdir = os.path.join(tmpdir, '.ipython')
394 os.mkdir(ipdir)
394 os.mkdir(ipdir)
395 os.chmod(ipdir, 600)
395 os.chmod(ipdir, 600)
396 with AssertPrints('is not a writable location', channel='stderr'):
396 with AssertPrints('is not a writable location', channel='stderr'):
397 ipdir = path.get_ipython_dir()
397 ipdir = path.get_ipython_dir()
398 env.pop('IPYTHON_DIR', None)
398 env.pop('IPYTHON_DIR', None)
399
399
400 def test_unquote_filename():
400 def test_unquote_filename():
401 for win32 in (True, False):
401 for win32 in (True, False):
402 nt.assert_equals(path.unquote_filename('foo.py', win32=win32), 'foo.py')
402 nt.assert_equal(path.unquote_filename('foo.py', win32=win32), 'foo.py')
403 nt.assert_equals(path.unquote_filename('foo bar.py', win32=win32), 'foo bar.py')
403 nt.assert_equal(path.unquote_filename('foo bar.py', win32=win32), 'foo bar.py')
404 nt.assert_equals(path.unquote_filename('"foo.py"', win32=True), 'foo.py')
404 nt.assert_equal(path.unquote_filename('"foo.py"', win32=True), 'foo.py')
405 nt.assert_equals(path.unquote_filename('"foo bar.py"', win32=True), 'foo bar.py')
405 nt.assert_equal(path.unquote_filename('"foo bar.py"', win32=True), 'foo bar.py')
406 nt.assert_equals(path.unquote_filename("'foo.py'", win32=True), 'foo.py')
406 nt.assert_equal(path.unquote_filename("'foo.py'", win32=True), 'foo.py')
407 nt.assert_equals(path.unquote_filename("'foo bar.py'", win32=True), 'foo bar.py')
407 nt.assert_equal(path.unquote_filename("'foo bar.py'", win32=True), 'foo bar.py')
408 nt.assert_equals(path.unquote_filename('"foo.py"', win32=False), '"foo.py"')
408 nt.assert_equal(path.unquote_filename('"foo.py"', win32=False), '"foo.py"')
409 nt.assert_equals(path.unquote_filename('"foo bar.py"', win32=False), '"foo bar.py"')
409 nt.assert_equal(path.unquote_filename('"foo bar.py"', win32=False), '"foo bar.py"')
410 nt.assert_equals(path.unquote_filename("'foo.py'", win32=False), "'foo.py'")
410 nt.assert_equal(path.unquote_filename("'foo.py'", win32=False), "'foo.py'")
411 nt.assert_equals(path.unquote_filename("'foo bar.py'", win32=False), "'foo bar.py'")
411 nt.assert_equal(path.unquote_filename("'foo bar.py'", win32=False), "'foo bar.py'")
412
412
413 @with_environment
413 @with_environment
414 def test_get_py_filename():
414 def test_get_py_filename():
415 os.chdir(TMP_TEST_DIR)
415 os.chdir(TMP_TEST_DIR)
416 for win32 in (True, False):
416 for win32 in (True, False):
417 with make_tempfile('foo.py'):
417 with make_tempfile('foo.py'):
418 nt.assert_equals(path.get_py_filename('foo.py', force_win32=win32), 'foo.py')
418 nt.assert_equal(path.get_py_filename('foo.py', force_win32=win32), 'foo.py')
419 nt.assert_equals(path.get_py_filename('foo', force_win32=win32), 'foo.py')
419 nt.assert_equal(path.get_py_filename('foo', force_win32=win32), 'foo.py')
420 with make_tempfile('foo'):
420 with make_tempfile('foo'):
421 nt.assert_equals(path.get_py_filename('foo', force_win32=win32), 'foo')
421 nt.assert_equal(path.get_py_filename('foo', force_win32=win32), 'foo')
422 nt.assert_raises(IOError, path.get_py_filename, 'foo.py', force_win32=win32)
422 nt.assert_raises(IOError, path.get_py_filename, 'foo.py', force_win32=win32)
423 nt.assert_raises(IOError, path.get_py_filename, 'foo', force_win32=win32)
423 nt.assert_raises(IOError, path.get_py_filename, 'foo', force_win32=win32)
424 nt.assert_raises(IOError, path.get_py_filename, 'foo.py', force_win32=win32)
424 nt.assert_raises(IOError, path.get_py_filename, 'foo.py', force_win32=win32)
425 true_fn = 'foo with spaces.py'
425 true_fn = 'foo with spaces.py'
426 with make_tempfile(true_fn):
426 with make_tempfile(true_fn):
427 nt.assert_equals(path.get_py_filename('foo with spaces', force_win32=win32), true_fn)
427 nt.assert_equal(path.get_py_filename('foo with spaces', force_win32=win32), true_fn)
428 nt.assert_equals(path.get_py_filename('foo with spaces.py', force_win32=win32), true_fn)
428 nt.assert_equal(path.get_py_filename('foo with spaces.py', force_win32=win32), true_fn)
429 if win32:
429 if win32:
430 nt.assert_equals(path.get_py_filename('"foo with spaces.py"', force_win32=True), true_fn)
430 nt.assert_equal(path.get_py_filename('"foo with spaces.py"', force_win32=True), true_fn)
431 nt.assert_equals(path.get_py_filename("'foo with spaces.py'", force_win32=True), true_fn)
431 nt.assert_equal(path.get_py_filename("'foo with spaces.py'", force_win32=True), true_fn)
432 else:
432 else:
433 nt.assert_raises(IOError, path.get_py_filename, '"foo with spaces.py"', force_win32=False)
433 nt.assert_raises(IOError, path.get_py_filename, '"foo with spaces.py"', force_win32=False)
434 nt.assert_raises(IOError, path.get_py_filename, "'foo with spaces.py'", force_win32=False)
434 nt.assert_raises(IOError, path.get_py_filename, "'foo with spaces.py'", force_win32=False)
435
435
436 def test_unicode_in_filename():
436 def test_unicode_in_filename():
437 """When a file doesn't exist, the exception raised should be safe to call
437 """When a file doesn't exist, the exception raised should be safe to call
438 str() on - i.e. in Python 2 it must only have ASCII characters.
438 str() on - i.e. in Python 2 it must only have ASCII characters.
439
439
440 https://github.com/ipython/ipython/issues/875
440 https://github.com/ipython/ipython/issues/875
441 """
441 """
442 try:
442 try:
443 # these calls should not throw unicode encode exceptions
443 # these calls should not throw unicode encode exceptions
444 path.get_py_filename(u'fooéè.py', force_win32=False)
444 path.get_py_filename(u'fooéè.py', force_win32=False)
445 except IOError as ex:
445 except IOError as ex:
446 str(ex)
446 str(ex)
@@ -1,131 +1,131
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 Tests for platutils.py
3 Tests for platutils.py
4 """
4 """
5
5
6 #-----------------------------------------------------------------------------
6 #-----------------------------------------------------------------------------
7 # Copyright (C) 2008-2011 The IPython Development Team
7 # Copyright (C) 2008-2011 The IPython Development Team
8 #
8 #
9 # Distributed under the terms of the BSD License. The full license is in
9 # Distributed under the terms of the BSD License. The full license is in
10 # the file COPYING, distributed as part of this software.
10 # the file COPYING, distributed as part of this software.
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12
12
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 # Imports
14 # Imports
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16
16
17 import sys
17 import sys
18 from unittest import TestCase
18 from unittest import TestCase
19
19
20 import nose.tools as nt
20 import nose.tools as nt
21
21
22 from IPython.utils.process import (find_cmd, FindCmdError, arg_split,
22 from IPython.utils.process import (find_cmd, FindCmdError, arg_split,
23 system, getoutput, getoutputerror)
23 system, getoutput, getoutputerror)
24 from IPython.testing import decorators as dec
24 from IPython.testing import decorators as dec
25 from IPython.testing import tools as tt
25 from IPython.testing import tools as tt
26
26
27 #-----------------------------------------------------------------------------
27 #-----------------------------------------------------------------------------
28 # Tests
28 # Tests
29 #-----------------------------------------------------------------------------
29 #-----------------------------------------------------------------------------
30
30
31 def test_find_cmd_python():
31 def test_find_cmd_python():
32 """Make sure we find sys.exectable for python."""
32 """Make sure we find sys.exectable for python."""
33 nt.assert_equals(find_cmd('python'), sys.executable)
33 nt.assert_equal(find_cmd('python'), sys.executable)
34
34
35
35
36 @dec.skip_win32
36 @dec.skip_win32
37 def test_find_cmd_ls():
37 def test_find_cmd_ls():
38 """Make sure we can find the full path to ls."""
38 """Make sure we can find the full path to ls."""
39 path = find_cmd('ls')
39 path = find_cmd('ls')
40 nt.assert_true(path.endswith('ls'))
40 nt.assert_true(path.endswith('ls'))
41
41
42
42
43 def has_pywin32():
43 def has_pywin32():
44 try:
44 try:
45 import win32api
45 import win32api
46 except ImportError:
46 except ImportError:
47 return False
47 return False
48 return True
48 return True
49
49
50
50
51 @dec.onlyif(has_pywin32, "This test requires win32api to run")
51 @dec.onlyif(has_pywin32, "This test requires win32api to run")
52 def test_find_cmd_pythonw():
52 def test_find_cmd_pythonw():
53 """Try to find pythonw on Windows."""
53 """Try to find pythonw on Windows."""
54 path = find_cmd('pythonw')
54 path = find_cmd('pythonw')
55 nt.assert_true(path.endswith('pythonw.exe'))
55 nt.assert_true(path.endswith('pythonw.exe'))
56
56
57
57
58 @dec.onlyif(lambda : sys.platform != 'win32' or has_pywin32(),
58 @dec.onlyif(lambda : sys.platform != 'win32' or has_pywin32(),
59 "This test runs on posix or in win32 with win32api installed")
59 "This test runs on posix or in win32 with win32api installed")
60 def test_find_cmd_fail():
60 def test_find_cmd_fail():
61 """Make sure that FindCmdError is raised if we can't find the cmd."""
61 """Make sure that FindCmdError is raised if we can't find the cmd."""
62 nt.assert_raises(FindCmdError,find_cmd,'asdfasdf')
62 nt.assert_raises(FindCmdError,find_cmd,'asdfasdf')
63
63
64
64
65 @dec.skip_win32
65 @dec.skip_win32
66 def test_arg_split():
66 def test_arg_split():
67 """Ensure that argument lines are correctly split like in a shell."""
67 """Ensure that argument lines are correctly split like in a shell."""
68 tests = [['hi', ['hi']],
68 tests = [['hi', ['hi']],
69 [u'hi', [u'hi']],
69 [u'hi', [u'hi']],
70 ['hello there', ['hello', 'there']],
70 ['hello there', ['hello', 'there']],
71 # \u01ce == \N{LATIN SMALL LETTER A WITH CARON}
71 # \u01ce == \N{LATIN SMALL LETTER A WITH CARON}
72 # Do not use \N because the tests crash with syntax error in
72 # Do not use \N because the tests crash with syntax error in
73 # some cases, for example windows python2.6.
73 # some cases, for example windows python2.6.
74 [u'h\u01cello', [u'h\u01cello']],
74 [u'h\u01cello', [u'h\u01cello']],
75 ['something "with quotes"', ['something', '"with quotes"']],
75 ['something "with quotes"', ['something', '"with quotes"']],
76 ]
76 ]
77 for argstr, argv in tests:
77 for argstr, argv in tests:
78 nt.assert_equal(arg_split(argstr), argv)
78 nt.assert_equal(arg_split(argstr), argv)
79
79
80 @dec.skip_if_not_win32
80 @dec.skip_if_not_win32
81 def test_arg_split_win32():
81 def test_arg_split_win32():
82 """Ensure that argument lines are correctly split like in a shell."""
82 """Ensure that argument lines are correctly split like in a shell."""
83 tests = [['hi', ['hi']],
83 tests = [['hi', ['hi']],
84 [u'hi', [u'hi']],
84 [u'hi', [u'hi']],
85 ['hello there', ['hello', 'there']],
85 ['hello there', ['hello', 'there']],
86 [u'h\u01cello', [u'h\u01cello']],
86 [u'h\u01cello', [u'h\u01cello']],
87 ['something "with quotes"', ['something', 'with quotes']],
87 ['something "with quotes"', ['something', 'with quotes']],
88 ]
88 ]
89 for argstr, argv in tests:
89 for argstr, argv in tests:
90 nt.assert_equal(arg_split(argstr), argv)
90 nt.assert_equal(arg_split(argstr), argv)
91
91
92
92
93 class SubProcessTestCase(TestCase, tt.TempFileMixin):
93 class SubProcessTestCase(TestCase, tt.TempFileMixin):
94 def setUp(self):
94 def setUp(self):
95 """Make a valid python temp file."""
95 """Make a valid python temp file."""
96 lines = ["from __future__ import print_function",
96 lines = ["from __future__ import print_function",
97 "import sys",
97 "import sys",
98 "print('on stdout', end='', file=sys.stdout)",
98 "print('on stdout', end='', file=sys.stdout)",
99 "print('on stderr', end='', file=sys.stderr)",
99 "print('on stderr', end='', file=sys.stderr)",
100 "sys.stdout.flush()",
100 "sys.stdout.flush()",
101 "sys.stderr.flush()"]
101 "sys.stderr.flush()"]
102 self.mktmp('\n'.join(lines))
102 self.mktmp('\n'.join(lines))
103
103
104 def test_system(self):
104 def test_system(self):
105 status = system('python "%s"' % self.fname)
105 status = system('python "%s"' % self.fname)
106 self.assertEqual(status, 0)
106 self.assertEqual(status, 0)
107
107
108 def test_system_quotes(self):
108 def test_system_quotes(self):
109 status = system('python -c "import sys"')
109 status = system('python -c "import sys"')
110 self.assertEqual(status, 0)
110 self.assertEqual(status, 0)
111
111
112 def test_getoutput(self):
112 def test_getoutput(self):
113 out = getoutput('python "%s"' % self.fname)
113 out = getoutput('python "%s"' % self.fname)
114 self.assertEqual(out, 'on stdout')
114 self.assertEqual(out, 'on stdout')
115
115
116 def test_getoutput_quoted(self):
116 def test_getoutput_quoted(self):
117 out = getoutput('python -c "print (1)"')
117 out = getoutput('python -c "print (1)"')
118 self.assertEqual(out.strip(), '1')
118 self.assertEqual(out.strip(), '1')
119
119
120 #Invalid quoting on windows
120 #Invalid quoting on windows
121 @dec.skip_win32
121 @dec.skip_win32
122 def test_getoutput_quoted2(self):
122 def test_getoutput_quoted2(self):
123 out = getoutput("python -c 'print (1)'")
123 out = getoutput("python -c 'print (1)'")
124 self.assertEqual(out.strip(), '1')
124 self.assertEqual(out.strip(), '1')
125 out = getoutput("python -c 'print (\"1\")'")
125 out = getoutput("python -c 'print (\"1\")'")
126 self.assertEqual(out.strip(), '1')
126 self.assertEqual(out.strip(), '1')
127
127
128 def test_getoutput(self):
128 def test_getoutput(self):
129 out, err = getoutputerror('python "%s"' % self.fname)
129 out, err = getoutputerror('python "%s"' % self.fname)
130 self.assertEqual(out, 'on stdout')
130 self.assertEqual(out, 'on stdout')
131 self.assertEqual(err, 'on stderr')
131 self.assertEqual(err, 'on stderr')
@@ -1,34 +1,34
1 """Test suite for our color utilities.
1 """Test suite for our color utilities.
2
2
3 Authors
3 Authors
4 -------
4 -------
5
5
6 * Min RK
6 * Min RK
7 """
7 """
8 #-----------------------------------------------------------------------------
8 #-----------------------------------------------------------------------------
9 # Copyright (C) 2011 The IPython Development Team
9 # Copyright (C) 2011 The IPython Development Team
10 #
10 #
11 # Distributed under the terms of the BSD License. The full license is in
11 # Distributed under the terms of the BSD License. The full license is in
12 # the file COPYING.txt, distributed as part of this software.
12 # the file COPYING.txt, distributed as part of this software.
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14
14
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16 # Imports
16 # Imports
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18
18
19 # third party
19 # third party
20 import nose.tools as nt
20 import nose.tools as nt
21
21
22 # our own
22 # our own
23 from IPython.utils.PyColorize import Parser
23 from IPython.utils.PyColorize import Parser
24
24
25 #-----------------------------------------------------------------------------
25 #-----------------------------------------------------------------------------
26 # Test functions
26 # Test functions
27 #-----------------------------------------------------------------------------
27 #-----------------------------------------------------------------------------
28
28
29 def test_unicode_colorize():
29 def test_unicode_colorize():
30 p = Parser()
30 p = Parser()
31 f1 = p.format('1/0', 'str')
31 f1 = p.format('1/0', 'str')
32 f2 = p.format(u'1/0', 'str')
32 f2 = p.format(u'1/0', 'str')
33 nt.assert_equals(f1, f2)
33 nt.assert_equal(f1, f2)
34
34
@@ -1,170 +1,170
1 # encoding: utf-8
1 # encoding: utf-8
2 """Tests for IPython.utils.text"""
2 """Tests for IPython.utils.text"""
3
3
4 #-----------------------------------------------------------------------------
4 #-----------------------------------------------------------------------------
5 # Copyright (C) 2011 The IPython Development Team
5 # Copyright (C) 2011 The IPython Development Team
6 #
6 #
7 # Distributed under the terms of the BSD License. The full license is in
7 # Distributed under the terms of the BSD License. The full license is in
8 # the file COPYING, distributed as part of this software.
8 # the file COPYING, distributed as part of this software.
9 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
10
10
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12 # Imports
12 # Imports
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14
14
15 import os
15 import os
16 import math
16 import math
17 import random
17 import random
18
18
19 import nose.tools as nt
19 import nose.tools as nt
20
20
21 from nose import with_setup
21 from nose import with_setup
22
22
23 from IPython.testing import decorators as dec
23 from IPython.testing import decorators as dec
24 from IPython.utils import text
24 from IPython.utils import text
25
25
26 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
27 # Globals
27 # Globals
28 #-----------------------------------------------------------------------------
28 #-----------------------------------------------------------------------------
29
29
30 def test_columnize():
30 def test_columnize():
31 """Basic columnize tests."""
31 """Basic columnize tests."""
32 size = 5
32 size = 5
33 items = [l*size for l in 'abc']
33 items = [l*size for l in 'abc']
34 out = text.columnize(items, displaywidth=80)
34 out = text.columnize(items, displaywidth=80)
35 nt.assert_equals(out, 'aaaaa bbbbb ccccc\n')
35 nt.assert_equal(out, 'aaaaa bbbbb ccccc\n')
36 out = text.columnize(items, displaywidth=12)
36 out = text.columnize(items, displaywidth=12)
37 nt.assert_equals(out, 'aaaaa ccccc\nbbbbb\n')
37 nt.assert_equal(out, 'aaaaa ccccc\nbbbbb\n')
38 out = text.columnize(items, displaywidth=10)
38 out = text.columnize(items, displaywidth=10)
39 nt.assert_equals(out, 'aaaaa\nbbbbb\nccccc\n')
39 nt.assert_equal(out, 'aaaaa\nbbbbb\nccccc\n')
40
40
41 def test_columnize_random():
41 def test_columnize_random():
42 """Test with random input to hopfully catch edge case """
42 """Test with random input to hopfully catch edge case """
43 for nitems in [random.randint(2,70) for i in range(2,20)]:
43 for nitems in [random.randint(2,70) for i in range(2,20)]:
44 displaywidth = random.randint(20,200)
44 displaywidth = random.randint(20,200)
45 rand_len = [random.randint(2,displaywidth) for i in range(nitems)]
45 rand_len = [random.randint(2,displaywidth) for i in range(nitems)]
46 items = ['x'*l for l in rand_len]
46 items = ['x'*l for l in rand_len]
47 out = text.columnize(items, displaywidth=displaywidth)
47 out = text.columnize(items, displaywidth=displaywidth)
48 longer_line = max([len(x) for x in out.split('\n')])
48 longer_line = max([len(x) for x in out.split('\n')])
49 longer_element = max(rand_len)
49 longer_element = max(rand_len)
50 if longer_line > displaywidth:
50 if longer_line > displaywidth:
51 print "Columnize displayed something lager than displaywidth : %s " % longer_line
51 print "Columnize displayed something lager than displaywidth : %s " % longer_line
52 print "longer element : %s " % longer_element
52 print "longer element : %s " % longer_element
53 print "displaywidth : %s " % displaywidth
53 print "displaywidth : %s " % displaywidth
54 print "number of element : %s " % nitems
54 print "number of element : %s " % nitems
55 print "size of each element :\n %s" % rand_len
55 print "size of each element :\n %s" % rand_len
56 assert False
56 assert False
57
57
58 def test_columnize_medium():
58 def test_columnize_medium():
59 """Test with inputs than shouldn't be wider tahn 80 """
59 """Test with inputs than shouldn't be wider tahn 80 """
60 size = 40
60 size = 40
61 items = [l*size for l in 'abc']
61 items = [l*size for l in 'abc']
62 out = text.columnize(items, displaywidth=80)
62 out = text.columnize(items, displaywidth=80)
63 nt.assert_equals(out, '\n'.join(items+['']))
63 nt.assert_equal(out, '\n'.join(items+['']))
64
64
65 def test_columnize_long():
65 def test_columnize_long():
66 """Test columnize with inputs longer than the display window"""
66 """Test columnize with inputs longer than the display window"""
67 size = 11
67 size = 11
68 items = [l*size for l in 'abc']
68 items = [l*size for l in 'abc']
69 out = text.columnize(items, displaywidth=size-1)
69 out = text.columnize(items, displaywidth=size-1)
70 nt.assert_equals(out, '\n'.join(items+['']))
70 nt.assert_equal(out, '\n'.join(items+['']))
71
71
72 def eval_formatter_check(f):
72 def eval_formatter_check(f):
73 ns = dict(n=12, pi=math.pi, stuff='hello there', os=os, u=u"cafΓ©", b="cafΓ©")
73 ns = dict(n=12, pi=math.pi, stuff='hello there', os=os, u=u"cafΓ©", b="cafΓ©")
74 s = f.format("{n} {n//4} {stuff.split()[0]}", **ns)
74 s = f.format("{n} {n//4} {stuff.split()[0]}", **ns)
75 nt.assert_equals(s, "12 3 hello")
75 nt.assert_equal(s, "12 3 hello")
76 s = f.format(' '.join(['{n//%i}'%i for i in range(1,8)]), **ns)
76 s = f.format(' '.join(['{n//%i}'%i for i in range(1,8)]), **ns)
77 nt.assert_equals(s, "12 6 4 3 2 2 1")
77 nt.assert_equal(s, "12 6 4 3 2 2 1")
78 s = f.format('{[n//i for i in range(1,8)]}', **ns)
78 s = f.format('{[n//i for i in range(1,8)]}', **ns)
79 nt.assert_equals(s, "[12, 6, 4, 3, 2, 2, 1]")
79 nt.assert_equal(s, "[12, 6, 4, 3, 2, 2, 1]")
80 s = f.format("{stuff!s}", **ns)
80 s = f.format("{stuff!s}", **ns)
81 nt.assert_equals(s, ns['stuff'])
81 nt.assert_equal(s, ns['stuff'])
82 s = f.format("{stuff!r}", **ns)
82 s = f.format("{stuff!r}", **ns)
83 nt.assert_equals(s, repr(ns['stuff']))
83 nt.assert_equal(s, repr(ns['stuff']))
84
84
85 # Check with unicode:
85 # Check with unicode:
86 s = f.format("{u}", **ns)
86 s = f.format("{u}", **ns)
87 nt.assert_equals(s, ns['u'])
87 nt.assert_equal(s, ns['u'])
88 # This decodes in a platform dependent manner, but it shouldn't error out
88 # This decodes in a platform dependent manner, but it shouldn't error out
89 s = f.format("{b}", **ns)
89 s = f.format("{b}", **ns)
90
90
91 nt.assert_raises(NameError, f.format, '{dne}', **ns)
91 nt.assert_raises(NameError, f.format, '{dne}', **ns)
92
92
93 def eval_formatter_slicing_check(f):
93 def eval_formatter_slicing_check(f):
94 ns = dict(n=12, pi=math.pi, stuff='hello there', os=os)
94 ns = dict(n=12, pi=math.pi, stuff='hello there', os=os)
95 s = f.format(" {stuff.split()[:]} ", **ns)
95 s = f.format(" {stuff.split()[:]} ", **ns)
96 nt.assert_equals(s, " ['hello', 'there'] ")
96 nt.assert_equal(s, " ['hello', 'there'] ")
97 s = f.format(" {stuff.split()[::-1]} ", **ns)
97 s = f.format(" {stuff.split()[::-1]} ", **ns)
98 nt.assert_equals(s, " ['there', 'hello'] ")
98 nt.assert_equal(s, " ['there', 'hello'] ")
99 s = f.format("{stuff[::2]}", **ns)
99 s = f.format("{stuff[::2]}", **ns)
100 nt.assert_equals(s, ns['stuff'][::2])
100 nt.assert_equal(s, ns['stuff'][::2])
101
101
102 nt.assert_raises(SyntaxError, f.format, "{n:x}", **ns)
102 nt.assert_raises(SyntaxError, f.format, "{n:x}", **ns)
103
103
104 def eval_formatter_no_slicing_check(f):
104 def eval_formatter_no_slicing_check(f):
105 ns = dict(n=12, pi=math.pi, stuff='hello there', os=os)
105 ns = dict(n=12, pi=math.pi, stuff='hello there', os=os)
106
106
107 s = f.format('{n:x} {pi**2:+f}', **ns)
107 s = f.format('{n:x} {pi**2:+f}', **ns)
108 nt.assert_equals(s, "c +9.869604")
108 nt.assert_equal(s, "c +9.869604")
109
109
110 s = f.format('{stuff[slice(1,4)]}', **ns)
110 s = f.format('{stuff[slice(1,4)]}', **ns)
111 nt.assert_equals(s, 'ell')
111 nt.assert_equal(s, 'ell')
112
112
113 nt.assert_raises(SyntaxError, f.format, "{a[:]}")
113 nt.assert_raises(SyntaxError, f.format, "{a[:]}")
114
114
115 def test_eval_formatter():
115 def test_eval_formatter():
116 f = text.EvalFormatter()
116 f = text.EvalFormatter()
117 eval_formatter_check(f)
117 eval_formatter_check(f)
118 eval_formatter_no_slicing_check(f)
118 eval_formatter_no_slicing_check(f)
119
119
120 def test_full_eval_formatter():
120 def test_full_eval_formatter():
121 f = text.FullEvalFormatter()
121 f = text.FullEvalFormatter()
122 eval_formatter_check(f)
122 eval_formatter_check(f)
123 eval_formatter_slicing_check(f)
123 eval_formatter_slicing_check(f)
124
124
125 def test_dollar_formatter():
125 def test_dollar_formatter():
126 f = text.DollarFormatter()
126 f = text.DollarFormatter()
127 eval_formatter_check(f)
127 eval_formatter_check(f)
128 eval_formatter_slicing_check(f)
128 eval_formatter_slicing_check(f)
129
129
130 ns = dict(n=12, pi=math.pi, stuff='hello there', os=os)
130 ns = dict(n=12, pi=math.pi, stuff='hello there', os=os)
131 s = f.format("$n", **ns)
131 s = f.format("$n", **ns)
132 nt.assert_equals(s, "12")
132 nt.assert_equal(s, "12")
133 s = f.format("$n.real", **ns)
133 s = f.format("$n.real", **ns)
134 nt.assert_equals(s, "12")
134 nt.assert_equal(s, "12")
135 s = f.format("$n/{stuff[:5]}", **ns)
135 s = f.format("$n/{stuff[:5]}", **ns)
136 nt.assert_equals(s, "12/hello")
136 nt.assert_equal(s, "12/hello")
137 s = f.format("$n $$HOME", **ns)
137 s = f.format("$n $$HOME", **ns)
138 nt.assert_equals(s, "12 $HOME")
138 nt.assert_equal(s, "12 $HOME")
139 s = f.format("${foo}", foo="HOME")
139 s = f.format("${foo}", foo="HOME")
140 nt.assert_equals(s, "$HOME")
140 nt.assert_equal(s, "$HOME")
141
141
142
142
143 def test_long_substr():
143 def test_long_substr():
144 data = ['hi']
144 data = ['hi']
145 nt.assert_equals(text.long_substr(data), 'hi')
145 nt.assert_equal(text.long_substr(data), 'hi')
146
146
147
147
148 def test_long_substr2():
148 def test_long_substr2():
149 data = ['abc', 'abd', 'abf', 'ab']
149 data = ['abc', 'abd', 'abf', 'ab']
150 nt.assert_equals(text.long_substr(data), 'ab')
150 nt.assert_equal(text.long_substr(data), 'ab')
151
151
152
152
153 def test_strip_email():
153 def test_strip_email():
154 src = """\
154 src = """\
155 >> >>> def f(x):
155 >> >>> def f(x):
156 >> ... return x+1
156 >> ... return x+1
157 >> ...
157 >> ...
158 >> >>> zz = f(2.5)"""
158 >> >>> zz = f(2.5)"""
159 cln = """\
159 cln = """\
160 >>> def f(x):
160 >>> def f(x):
161 ... return x+1
161 ... return x+1
162 ...
162 ...
163 >>> zz = f(2.5)"""
163 >>> zz = f(2.5)"""
164 nt.assert_equals(text.strip_email_quotes(src), cln)
164 nt.assert_equal(text.strip_email_quotes(src), cln)
165
165
166
166
167 def test_strip_email2():
167 def test_strip_email2():
168 src = '> > > list()'
168 src = '> > > list()'
169 cln = 'list()'
169 cln = 'list()'
170 nt.assert_equals(text.strip_email_quotes(src), cln)
170 nt.assert_equal(text.strip_email_quotes(src), cln)
@@ -1,193 +1,193
1 """test IPython.embed_kernel()"""
1 """test IPython.embed_kernel()"""
2
2
3 #-------------------------------------------------------------------------------
3 #-------------------------------------------------------------------------------
4 # Copyright (C) 2012 The IPython Development Team
4 # Copyright (C) 2012 The IPython Development Team
5 #
5 #
6 # Distributed under the terms of the BSD License. The full license is in
6 # Distributed under the terms of the BSD License. The full license is in
7 # the file COPYING, distributed as part of this software.
7 # the file COPYING, distributed as part of this software.
8 #-------------------------------------------------------------------------------
8 #-------------------------------------------------------------------------------
9
9
10 #-------------------------------------------------------------------------------
10 #-------------------------------------------------------------------------------
11 # Imports
11 # Imports
12 #-------------------------------------------------------------------------------
12 #-------------------------------------------------------------------------------
13
13
14 import os
14 import os
15 import shutil
15 import shutil
16 import sys
16 import sys
17 import tempfile
17 import tempfile
18 import time
18 import time
19
19
20 from contextlib import contextmanager
20 from contextlib import contextmanager
21 from subprocess import Popen, PIPE
21 from subprocess import Popen, PIPE
22
22
23 import nose.tools as nt
23 import nose.tools as nt
24
24
25 from IPython.zmq.blockingkernelmanager import BlockingKernelManager
25 from IPython.zmq.blockingkernelmanager import BlockingKernelManager
26 from IPython.utils import path, py3compat
26 from IPython.utils import path, py3compat
27
27
28 #-------------------------------------------------------------------------------
28 #-------------------------------------------------------------------------------
29 # Tests
29 # Tests
30 #-------------------------------------------------------------------------------
30 #-------------------------------------------------------------------------------
31
31
32 def setup():
32 def setup():
33 """setup temporary IPYTHONDIR for tests"""
33 """setup temporary IPYTHONDIR for tests"""
34 global IPYTHONDIR
34 global IPYTHONDIR
35 global env
35 global env
36 global save_get_ipython_dir
36 global save_get_ipython_dir
37
37
38 IPYTHONDIR = tempfile.mkdtemp()
38 IPYTHONDIR = tempfile.mkdtemp()
39
39
40 env = os.environ.copy()
40 env = os.environ.copy()
41 env["IPYTHONDIR"] = IPYTHONDIR
41 env["IPYTHONDIR"] = IPYTHONDIR
42
42
43 save_get_ipython_dir = path.get_ipython_dir
43 save_get_ipython_dir = path.get_ipython_dir
44 path.get_ipython_dir = lambda : IPYTHONDIR
44 path.get_ipython_dir = lambda : IPYTHONDIR
45
45
46
46
47 def teardown():
47 def teardown():
48 path.get_ipython_dir = save_get_ipython_dir
48 path.get_ipython_dir = save_get_ipython_dir
49
49
50 try:
50 try:
51 shutil.rmtree(IPYTHONDIR)
51 shutil.rmtree(IPYTHONDIR)
52 except (OSError, IOError):
52 except (OSError, IOError):
53 # no such file
53 # no such file
54 pass
54 pass
55
55
56
56
57 @contextmanager
57 @contextmanager
58 def setup_kernel(cmd):
58 def setup_kernel(cmd):
59 """start an embedded kernel in a subprocess, and wait for it to be ready
59 """start an embedded kernel in a subprocess, and wait for it to be ready
60
60
61 Returns
61 Returns
62 -------
62 -------
63 kernel_manager: connected KernelManager instance
63 kernel_manager: connected KernelManager instance
64 """
64 """
65 kernel = Popen([sys.executable, '-c', cmd], stdout=PIPE, stderr=PIPE, env=env)
65 kernel = Popen([sys.executable, '-c', cmd], stdout=PIPE, stderr=PIPE, env=env)
66 connection_file = os.path.join(IPYTHONDIR,
66 connection_file = os.path.join(IPYTHONDIR,
67 'profile_default',
67 'profile_default',
68 'security',
68 'security',
69 'kernel-%i.json' % kernel.pid
69 'kernel-%i.json' % kernel.pid
70 )
70 )
71 # wait for connection file to exist, timeout after 5s
71 # wait for connection file to exist, timeout after 5s
72 tic = time.time()
72 tic = time.time()
73 while not os.path.exists(connection_file) and kernel.poll() is None and time.time() < tic + 10:
73 while not os.path.exists(connection_file) and kernel.poll() is None and time.time() < tic + 10:
74 time.sleep(0.1)
74 time.sleep(0.1)
75
75
76 if kernel.poll() is not None:
76 if kernel.poll() is not None:
77 o,e = kernel.communicate()
77 o,e = kernel.communicate()
78 e = py3compat.cast_unicode(e)
78 e = py3compat.cast_unicode(e)
79 raise IOError("Kernel failed to start:\n%s" % e)
79 raise IOError("Kernel failed to start:\n%s" % e)
80
80
81 if not os.path.exists(connection_file):
81 if not os.path.exists(connection_file):
82 if kernel.poll() is None:
82 if kernel.poll() is None:
83 kernel.terminate()
83 kernel.terminate()
84 raise IOError("Connection file %r never arrived" % connection_file)
84 raise IOError("Connection file %r never arrived" % connection_file)
85
85
86 km = BlockingKernelManager(connection_file=connection_file)
86 km = BlockingKernelManager(connection_file=connection_file)
87 km.load_connection_file()
87 km.load_connection_file()
88 km.start_channels()
88 km.start_channels()
89
89
90 try:
90 try:
91 yield km
91 yield km
92 finally:
92 finally:
93 km.stop_channels()
93 km.stop_channels()
94 kernel.terminate()
94 kernel.terminate()
95
95
96 def test_embed_kernel_basic():
96 def test_embed_kernel_basic():
97 """IPython.embed_kernel() is basically functional"""
97 """IPython.embed_kernel() is basically functional"""
98 cmd = '\n'.join([
98 cmd = '\n'.join([
99 'from IPython import embed_kernel',
99 'from IPython import embed_kernel',
100 'def go():',
100 'def go():',
101 ' a=5',
101 ' a=5',
102 ' b="hi there"',
102 ' b="hi there"',
103 ' embed_kernel()',
103 ' embed_kernel()',
104 'go()',
104 'go()',
105 '',
105 '',
106 ])
106 ])
107
107
108 with setup_kernel(cmd) as km:
108 with setup_kernel(cmd) as km:
109 shell = km.shell_channel
109 shell = km.shell_channel
110
110
111 # oinfo a (int)
111 # oinfo a (int)
112 msg_id = shell.object_info('a')
112 msg_id = shell.object_info('a')
113 msg = shell.get_msg(block=True, timeout=2)
113 msg = shell.get_msg(block=True, timeout=2)
114 content = msg['content']
114 content = msg['content']
115 nt.assert_true(content['found'])
115 nt.assert_true(content['found'])
116
116
117 msg_id = shell.execute("c=a*2")
117 msg_id = shell.execute("c=a*2")
118 msg = shell.get_msg(block=True, timeout=2)
118 msg = shell.get_msg(block=True, timeout=2)
119 content = msg['content']
119 content = msg['content']
120 nt.assert_equals(content['status'], u'ok')
120 nt.assert_equal(content['status'], u'ok')
121
121
122 # oinfo c (should be 10)
122 # oinfo c (should be 10)
123 msg_id = shell.object_info('c')
123 msg_id = shell.object_info('c')
124 msg = shell.get_msg(block=True, timeout=2)
124 msg = shell.get_msg(block=True, timeout=2)
125 content = msg['content']
125 content = msg['content']
126 nt.assert_true(content['found'])
126 nt.assert_true(content['found'])
127 nt.assert_equals(content['string_form'], u'10')
127 nt.assert_equal(content['string_form'], u'10')
128
128
129 def test_embed_kernel_namespace():
129 def test_embed_kernel_namespace():
130 """IPython.embed_kernel() inherits calling namespace"""
130 """IPython.embed_kernel() inherits calling namespace"""
131 cmd = '\n'.join([
131 cmd = '\n'.join([
132 'from IPython import embed_kernel',
132 'from IPython import embed_kernel',
133 'def go():',
133 'def go():',
134 ' a=5',
134 ' a=5',
135 ' b="hi there"',
135 ' b="hi there"',
136 ' embed_kernel()',
136 ' embed_kernel()',
137 'go()',
137 'go()',
138 '',
138 '',
139 ])
139 ])
140
140
141 with setup_kernel(cmd) as km:
141 with setup_kernel(cmd) as km:
142 shell = km.shell_channel
142 shell = km.shell_channel
143
143
144 # oinfo a (int)
144 # oinfo a (int)
145 msg_id = shell.object_info('a')
145 msg_id = shell.object_info('a')
146 msg = shell.get_msg(block=True, timeout=2)
146 msg = shell.get_msg(block=True, timeout=2)
147 content = msg['content']
147 content = msg['content']
148 nt.assert_true(content['found'])
148 nt.assert_true(content['found'])
149 nt.assert_equals(content['string_form'], u'5')
149 nt.assert_equal(content['string_form'], u'5')
150
150
151 # oinfo b (str)
151 # oinfo b (str)
152 msg_id = shell.object_info('b')
152 msg_id = shell.object_info('b')
153 msg = shell.get_msg(block=True, timeout=2)
153 msg = shell.get_msg(block=True, timeout=2)
154 content = msg['content']
154 content = msg['content']
155 nt.assert_true(content['found'])
155 nt.assert_true(content['found'])
156 nt.assert_equals(content['string_form'], u'hi there')
156 nt.assert_equal(content['string_form'], u'hi there')
157
157
158 # oinfo c (undefined)
158 # oinfo c (undefined)
159 msg_id = shell.object_info('c')
159 msg_id = shell.object_info('c')
160 msg = shell.get_msg(block=True, timeout=2)
160 msg = shell.get_msg(block=True, timeout=2)
161 content = msg['content']
161 content = msg['content']
162 nt.assert_false(content['found'])
162 nt.assert_false(content['found'])
163
163
164 def test_embed_kernel_reentrant():
164 def test_embed_kernel_reentrant():
165 """IPython.embed_kernel() can be called multiple times"""
165 """IPython.embed_kernel() can be called multiple times"""
166 cmd = '\n'.join([
166 cmd = '\n'.join([
167 'from IPython import embed_kernel',
167 'from IPython import embed_kernel',
168 'count = 0',
168 'count = 0',
169 'def go():',
169 'def go():',
170 ' global count',
170 ' global count',
171 ' embed_kernel()',
171 ' embed_kernel()',
172 ' count = count + 1',
172 ' count = count + 1',
173 '',
173 '',
174 'while True:'
174 'while True:'
175 ' go()',
175 ' go()',
176 '',
176 '',
177 ])
177 ])
178
178
179 with setup_kernel(cmd) as km:
179 with setup_kernel(cmd) as km:
180 shell = km.shell_channel
180 shell = km.shell_channel
181 for i in range(5):
181 for i in range(5):
182 msg_id = shell.object_info('count')
182 msg_id = shell.object_info('count')
183 msg = shell.get_msg(block=True, timeout=2)
183 msg = shell.get_msg(block=True, timeout=2)
184 content = msg['content']
184 content = msg['content']
185 nt.assert_true(content['found'])
185 nt.assert_true(content['found'])
186 nt.assert_equals(content['string_form'], unicode(i))
186 nt.assert_equal(content['string_form'], unicode(i))
187
187
188 # exit from embed_kernel
188 # exit from embed_kernel
189 shell.execute("get_ipython().exit_now = True")
189 shell.execute("get_ipython().exit_now = True")
190 msg = shell.get_msg(block=True, timeout=2)
190 msg = shell.get_msg(block=True, timeout=2)
191 time.sleep(0.2)
191 time.sleep(0.2)
192
192
193
193
@@ -1,452 +1,452
1 """Test suite for our zeromq-based messaging specification.
1 """Test suite for our zeromq-based messaging specification.
2 """
2 """
3 #-----------------------------------------------------------------------------
3 #-----------------------------------------------------------------------------
4 # Copyright (C) 2010-2011 The IPython Development Team
4 # Copyright (C) 2010-2011 The IPython Development Team
5 #
5 #
6 # Distributed under the terms of the BSD License. The full license is in
6 # Distributed under the terms of the BSD License. The full license is in
7 # the file COPYING.txt, distributed as part of this software.
7 # the file COPYING.txt, distributed as part of this software.
8 #-----------------------------------------------------------------------------
8 #-----------------------------------------------------------------------------
9
9
10 import re
10 import re
11 import sys
11 import sys
12 import time
12 import time
13 from subprocess import PIPE
13 from subprocess import PIPE
14 from Queue import Empty
14 from Queue import Empty
15
15
16 import nose.tools as nt
16 import nose.tools as nt
17
17
18 from ..blockingkernelmanager import BlockingKernelManager
18 from ..blockingkernelmanager import BlockingKernelManager
19
19
20
20
21 from IPython.testing import decorators as dec
21 from IPython.testing import decorators as dec
22 from IPython.utils import io
22 from IPython.utils import io
23 from IPython.utils.traitlets import (
23 from IPython.utils.traitlets import (
24 HasTraits, TraitError, Bool, Unicode, Dict, Integer, List, Enum,
24 HasTraits, TraitError, Bool, Unicode, Dict, Integer, List, Enum,
25 )
25 )
26
26
27 #-----------------------------------------------------------------------------
27 #-----------------------------------------------------------------------------
28 # Global setup and utilities
28 # Global setup and utilities
29 #-----------------------------------------------------------------------------
29 #-----------------------------------------------------------------------------
30
30
31 def setup():
31 def setup():
32 global KM
32 global KM
33 KM = BlockingKernelManager()
33 KM = BlockingKernelManager()
34
34
35 KM.start_kernel(stdout=PIPE, stderr=PIPE)
35 KM.start_kernel(stdout=PIPE, stderr=PIPE)
36 KM.start_channels()
36 KM.start_channels()
37
37
38 # wait for kernel to be ready
38 # wait for kernel to be ready
39 KM.shell_channel.execute("pass")
39 KM.shell_channel.execute("pass")
40 KM.shell_channel.get_msg(block=True, timeout=5)
40 KM.shell_channel.get_msg(block=True, timeout=5)
41 flush_channels()
41 flush_channels()
42
42
43
43
44 def teardown():
44 def teardown():
45 KM.stop_channels()
45 KM.stop_channels()
46 KM.shutdown_kernel()
46 KM.shutdown_kernel()
47
47
48
48
49 def flush_channels():
49 def flush_channels():
50 """flush any messages waiting on the queue"""
50 """flush any messages waiting on the queue"""
51 for channel in (KM.shell_channel, KM.sub_channel):
51 for channel in (KM.shell_channel, KM.sub_channel):
52 while True:
52 while True:
53 try:
53 try:
54 msg = channel.get_msg(block=True, timeout=0.1)
54 msg = channel.get_msg(block=True, timeout=0.1)
55 except Empty:
55 except Empty:
56 break
56 break
57 else:
57 else:
58 list(validate_message(msg))
58 list(validate_message(msg))
59
59
60
60
61 def execute(code='', **kwargs):
61 def execute(code='', **kwargs):
62 """wrapper for doing common steps for validating an execution request"""
62 """wrapper for doing common steps for validating an execution request"""
63 shell = KM.shell_channel
63 shell = KM.shell_channel
64 sub = KM.sub_channel
64 sub = KM.sub_channel
65
65
66 msg_id = shell.execute(code=code, **kwargs)
66 msg_id = shell.execute(code=code, **kwargs)
67 reply = shell.get_msg(timeout=2)
67 reply = shell.get_msg(timeout=2)
68 list(validate_message(reply, 'execute_reply', msg_id))
68 list(validate_message(reply, 'execute_reply', msg_id))
69 busy = sub.get_msg(timeout=2)
69 busy = sub.get_msg(timeout=2)
70 list(validate_message(busy, 'status', msg_id))
70 list(validate_message(busy, 'status', msg_id))
71 nt.assert_equals(busy['content']['execution_state'], 'busy')
71 nt.assert_equal(busy['content']['execution_state'], 'busy')
72
72
73 if not kwargs.get('silent'):
73 if not kwargs.get('silent'):
74 pyin = sub.get_msg(timeout=2)
74 pyin = sub.get_msg(timeout=2)
75 list(validate_message(pyin, 'pyin', msg_id))
75 list(validate_message(pyin, 'pyin', msg_id))
76 nt.assert_equals(pyin['content']['code'], code)
76 nt.assert_equal(pyin['content']['code'], code)
77
77
78 return msg_id, reply['content']
78 return msg_id, reply['content']
79
79
80 #-----------------------------------------------------------------------------
80 #-----------------------------------------------------------------------------
81 # MSG Spec References
81 # MSG Spec References
82 #-----------------------------------------------------------------------------
82 #-----------------------------------------------------------------------------
83
83
84
84
85 class Reference(HasTraits):
85 class Reference(HasTraits):
86
86
87 def check(self, d):
87 def check(self, d):
88 """validate a dict against our traits"""
88 """validate a dict against our traits"""
89 for key in self.trait_names():
89 for key in self.trait_names():
90 yield nt.assert_true(key in d, "Missing key: %r, should be found in %s" % (key, d))
90 yield nt.assert_true(key in d, "Missing key: %r, should be found in %s" % (key, d))
91 # FIXME: always allow None, probably not a good idea
91 # FIXME: always allow None, probably not a good idea
92 if d[key] is None:
92 if d[key] is None:
93 continue
93 continue
94 try:
94 try:
95 setattr(self, key, d[key])
95 setattr(self, key, d[key])
96 except TraitError as e:
96 except TraitError as e:
97 yield nt.assert_true(False, str(e))
97 yield nt.assert_true(False, str(e))
98
98
99
99
100 class RMessage(Reference):
100 class RMessage(Reference):
101 msg_id = Unicode()
101 msg_id = Unicode()
102 msg_type = Unicode()
102 msg_type = Unicode()
103 header = Dict()
103 header = Dict()
104 parent_header = Dict()
104 parent_header = Dict()
105 content = Dict()
105 content = Dict()
106
106
107 class RHeader(Reference):
107 class RHeader(Reference):
108 msg_id = Unicode()
108 msg_id = Unicode()
109 msg_type = Unicode()
109 msg_type = Unicode()
110 session = Unicode()
110 session = Unicode()
111 username = Unicode()
111 username = Unicode()
112
112
113 class RContent(Reference):
113 class RContent(Reference):
114 status = Enum((u'ok', u'error'))
114 status = Enum((u'ok', u'error'))
115
115
116
116
117 class ExecuteReply(Reference):
117 class ExecuteReply(Reference):
118 execution_count = Integer()
118 execution_count = Integer()
119 status = Enum((u'ok', u'error'))
119 status = Enum((u'ok', u'error'))
120
120
121 def check(self, d):
121 def check(self, d):
122 for tst in Reference.check(self, d):
122 for tst in Reference.check(self, d):
123 yield tst
123 yield tst
124 if d['status'] == 'ok':
124 if d['status'] == 'ok':
125 for tst in ExecuteReplyOkay().check(d):
125 for tst in ExecuteReplyOkay().check(d):
126 yield tst
126 yield tst
127 elif d['status'] == 'error':
127 elif d['status'] == 'error':
128 for tst in ExecuteReplyError().check(d):
128 for tst in ExecuteReplyError().check(d):
129 yield tst
129 yield tst
130
130
131
131
132 class ExecuteReplyOkay(Reference):
132 class ExecuteReplyOkay(Reference):
133 payload = List(Dict)
133 payload = List(Dict)
134 user_variables = Dict()
134 user_variables = Dict()
135 user_expressions = Dict()
135 user_expressions = Dict()
136
136
137
137
138 class ExecuteReplyError(Reference):
138 class ExecuteReplyError(Reference):
139 ename = Unicode()
139 ename = Unicode()
140 evalue = Unicode()
140 evalue = Unicode()
141 traceback = List(Unicode)
141 traceback = List(Unicode)
142
142
143
143
144 class OInfoReply(Reference):
144 class OInfoReply(Reference):
145 name = Unicode()
145 name = Unicode()
146 found = Bool()
146 found = Bool()
147 ismagic = Bool()
147 ismagic = Bool()
148 isalias = Bool()
148 isalias = Bool()
149 namespace = Enum((u'builtin', u'magics', u'alias', u'Interactive'))
149 namespace = Enum((u'builtin', u'magics', u'alias', u'Interactive'))
150 type_name = Unicode()
150 type_name = Unicode()
151 string_form = Unicode()
151 string_form = Unicode()
152 base_class = Unicode()
152 base_class = Unicode()
153 length = Integer()
153 length = Integer()
154 file = Unicode()
154 file = Unicode()
155 definition = Unicode()
155 definition = Unicode()
156 argspec = Dict()
156 argspec = Dict()
157 init_definition = Unicode()
157 init_definition = Unicode()
158 docstring = Unicode()
158 docstring = Unicode()
159 init_docstring = Unicode()
159 init_docstring = Unicode()
160 class_docstring = Unicode()
160 class_docstring = Unicode()
161 call_def = Unicode()
161 call_def = Unicode()
162 call_docstring = Unicode()
162 call_docstring = Unicode()
163 source = Unicode()
163 source = Unicode()
164
164
165 def check(self, d):
165 def check(self, d):
166 for tst in Reference.check(self, d):
166 for tst in Reference.check(self, d):
167 yield tst
167 yield tst
168 if d['argspec'] is not None:
168 if d['argspec'] is not None:
169 for tst in ArgSpec().check(d['argspec']):
169 for tst in ArgSpec().check(d['argspec']):
170 yield tst
170 yield tst
171
171
172
172
173 class ArgSpec(Reference):
173 class ArgSpec(Reference):
174 args = List(Unicode)
174 args = List(Unicode)
175 varargs = Unicode()
175 varargs = Unicode()
176 varkw = Unicode()
176 varkw = Unicode()
177 defaults = List()
177 defaults = List()
178
178
179
179
180 class Status(Reference):
180 class Status(Reference):
181 execution_state = Enum((u'busy', u'idle'))
181 execution_state = Enum((u'busy', u'idle'))
182
182
183
183
184 class CompleteReply(Reference):
184 class CompleteReply(Reference):
185 matches = List(Unicode)
185 matches = List(Unicode)
186
186
187
187
188 # IOPub messages
188 # IOPub messages
189
189
190 class PyIn(Reference):
190 class PyIn(Reference):
191 code = Unicode()
191 code = Unicode()
192 execution_count = Integer()
192 execution_count = Integer()
193
193
194
194
195 PyErr = ExecuteReplyError
195 PyErr = ExecuteReplyError
196
196
197
197
198 class Stream(Reference):
198 class Stream(Reference):
199 name = Enum((u'stdout', u'stderr'))
199 name = Enum((u'stdout', u'stderr'))
200 data = Unicode()
200 data = Unicode()
201
201
202
202
203 mime_pat = re.compile(r'\w+/\w+')
203 mime_pat = re.compile(r'\w+/\w+')
204
204
205 class DisplayData(Reference):
205 class DisplayData(Reference):
206 source = Unicode()
206 source = Unicode()
207 metadata = Dict()
207 metadata = Dict()
208 data = Dict()
208 data = Dict()
209 def _data_changed(self, name, old, new):
209 def _data_changed(self, name, old, new):
210 for k,v in new.iteritems():
210 for k,v in new.iteritems():
211 nt.assert_true(mime_pat.match(k))
211 nt.assert_true(mime_pat.match(k))
212 nt.assert_true(isinstance(v, basestring), "expected string data, got %r" % v)
212 nt.assert_true(isinstance(v, basestring), "expected string data, got %r" % v)
213
213
214
214
215 class PyOut(Reference):
215 class PyOut(Reference):
216 execution_count = Integer()
216 execution_count = Integer()
217 data = Dict()
217 data = Dict()
218 def _data_changed(self, name, old, new):
218 def _data_changed(self, name, old, new):
219 for k,v in new.iteritems():
219 for k,v in new.iteritems():
220 nt.assert_true(mime_pat.match(k))
220 nt.assert_true(mime_pat.match(k))
221 nt.assert_true(isinstance(v, basestring), "expected string data, got %r" % v)
221 nt.assert_true(isinstance(v, basestring), "expected string data, got %r" % v)
222
222
223
223
224 references = {
224 references = {
225 'execute_reply' : ExecuteReply(),
225 'execute_reply' : ExecuteReply(),
226 'object_info_reply' : OInfoReply(),
226 'object_info_reply' : OInfoReply(),
227 'status' : Status(),
227 'status' : Status(),
228 'complete_reply' : CompleteReply(),
228 'complete_reply' : CompleteReply(),
229 'pyin' : PyIn(),
229 'pyin' : PyIn(),
230 'pyout' : PyOut(),
230 'pyout' : PyOut(),
231 'pyerr' : PyErr(),
231 'pyerr' : PyErr(),
232 'stream' : Stream(),
232 'stream' : Stream(),
233 'display_data' : DisplayData(),
233 'display_data' : DisplayData(),
234 }
234 }
235
235
236
236
237 def validate_message(msg, msg_type=None, parent=None):
237 def validate_message(msg, msg_type=None, parent=None):
238 """validate a message
238 """validate a message
239
239
240 This is a generator, and must be iterated through to actually
240 This is a generator, and must be iterated through to actually
241 trigger each test.
241 trigger each test.
242
242
243 If msg_type and/or parent are given, the msg_type and/or parent msg_id
243 If msg_type and/or parent are given, the msg_type and/or parent msg_id
244 are compared with the given values.
244 are compared with the given values.
245 """
245 """
246 RMessage().check(msg)
246 RMessage().check(msg)
247 if msg_type:
247 if msg_type:
248 yield nt.assert_equals(msg['msg_type'], msg_type)
248 yield nt.assert_equal(msg['msg_type'], msg_type)
249 if parent:
249 if parent:
250 yield nt.assert_equal(msg['parent_header']['msg_id'], parent)
250 yield nt.assert_equal(msg['parent_header']['msg_id'], parent)
251 content = msg['content']
251 content = msg['content']
252 ref = references[msg['msg_type']]
252 ref = references[msg['msg_type']]
253 for tst in ref.check(content):
253 for tst in ref.check(content):
254 yield tst
254 yield tst
255
255
256
256
257 #-----------------------------------------------------------------------------
257 #-----------------------------------------------------------------------------
258 # Tests
258 # Tests
259 #-----------------------------------------------------------------------------
259 #-----------------------------------------------------------------------------
260
260
261 # Shell channel
261 # Shell channel
262
262
263 @dec.parametric
263 @dec.parametric
264 def test_execute():
264 def test_execute():
265 flush_channels()
265 flush_channels()
266
266
267 shell = KM.shell_channel
267 shell = KM.shell_channel
268 msg_id = shell.execute(code='x=1')
268 msg_id = shell.execute(code='x=1')
269 reply = shell.get_msg(timeout=2)
269 reply = shell.get_msg(timeout=2)
270 for tst in validate_message(reply, 'execute_reply', msg_id):
270 for tst in validate_message(reply, 'execute_reply', msg_id):
271 yield tst
271 yield tst
272
272
273
273
274 @dec.parametric
274 @dec.parametric
275 def test_execute_silent():
275 def test_execute_silent():
276 flush_channels()
276 flush_channels()
277 msg_id, reply = execute(code='x=1', silent=True)
277 msg_id, reply = execute(code='x=1', silent=True)
278
278
279 # flush status=idle
279 # flush status=idle
280 status = KM.sub_channel.get_msg(timeout=2)
280 status = KM.sub_channel.get_msg(timeout=2)
281 for tst in validate_message(status, 'status', msg_id):
281 for tst in validate_message(status, 'status', msg_id):
282 yield tst
282 yield tst
283 nt.assert_equals(status['content']['execution_state'], 'idle')
283 nt.assert_equal(status['content']['execution_state'], 'idle')
284
284
285 yield nt.assert_raises(Empty, KM.sub_channel.get_msg, timeout=0.1)
285 yield nt.assert_raises(Empty, KM.sub_channel.get_msg, timeout=0.1)
286 count = reply['execution_count']
286 count = reply['execution_count']
287
287
288 msg_id, reply = execute(code='x=2', silent=True)
288 msg_id, reply = execute(code='x=2', silent=True)
289
289
290 # flush status=idle
290 # flush status=idle
291 status = KM.sub_channel.get_msg(timeout=2)
291 status = KM.sub_channel.get_msg(timeout=2)
292 for tst in validate_message(status, 'status', msg_id):
292 for tst in validate_message(status, 'status', msg_id):
293 yield tst
293 yield tst
294 yield nt.assert_equals(status['content']['execution_state'], 'idle')
294 yield nt.assert_equal(status['content']['execution_state'], 'idle')
295
295
296 yield nt.assert_raises(Empty, KM.sub_channel.get_msg, timeout=0.1)
296 yield nt.assert_raises(Empty, KM.sub_channel.get_msg, timeout=0.1)
297 count_2 = reply['execution_count']
297 count_2 = reply['execution_count']
298 yield nt.assert_equals(count_2, count)
298 yield nt.assert_equal(count_2, count)
299
299
300
300
301 @dec.parametric
301 @dec.parametric
302 def test_execute_error():
302 def test_execute_error():
303 flush_channels()
303 flush_channels()
304
304
305 msg_id, reply = execute(code='1/0')
305 msg_id, reply = execute(code='1/0')
306 yield nt.assert_equals(reply['status'], 'error')
306 yield nt.assert_equal(reply['status'], 'error')
307 yield nt.assert_equals(reply['ename'], 'ZeroDivisionError')
307 yield nt.assert_equal(reply['ename'], 'ZeroDivisionError')
308
308
309 pyerr = KM.sub_channel.get_msg(timeout=2)
309 pyerr = KM.sub_channel.get_msg(timeout=2)
310 for tst in validate_message(pyerr, 'pyerr', msg_id):
310 for tst in validate_message(pyerr, 'pyerr', msg_id):
311 yield tst
311 yield tst
312
312
313
313
314 def test_execute_inc():
314 def test_execute_inc():
315 """execute request should increment execution_count"""
315 """execute request should increment execution_count"""
316 flush_channels()
316 flush_channels()
317
317
318 msg_id, reply = execute(code='x=1')
318 msg_id, reply = execute(code='x=1')
319 count = reply['execution_count']
319 count = reply['execution_count']
320
320
321 flush_channels()
321 flush_channels()
322
322
323 msg_id, reply = execute(code='x=2')
323 msg_id, reply = execute(code='x=2')
324 count_2 = reply['execution_count']
324 count_2 = reply['execution_count']
325 nt.assert_equals(count_2, count+1)
325 nt.assert_equal(count_2, count+1)
326
326
327
327
328 def test_user_variables():
328 def test_user_variables():
329 flush_channels()
329 flush_channels()
330
330
331 msg_id, reply = execute(code='x=1', user_variables=['x'])
331 msg_id, reply = execute(code='x=1', user_variables=['x'])
332 user_variables = reply['user_variables']
332 user_variables = reply['user_variables']
333 nt.assert_equals(user_variables, {u'x' : u'1'})
333 nt.assert_equal(user_variables, {u'x' : u'1'})
334
334
335
335
336 def test_user_expressions():
336 def test_user_expressions():
337 flush_channels()
337 flush_channels()
338
338
339 msg_id, reply = execute(code='x=1', user_expressions=dict(foo='x+1'))
339 msg_id, reply = execute(code='x=1', user_expressions=dict(foo='x+1'))
340 user_expressions = reply['user_expressions']
340 user_expressions = reply['user_expressions']
341 nt.assert_equals(user_expressions, {u'foo' : u'2'})
341 nt.assert_equal(user_expressions, {u'foo' : u'2'})
342
342
343
343
344 @dec.parametric
344 @dec.parametric
345 def test_oinfo():
345 def test_oinfo():
346 flush_channels()
346 flush_channels()
347
347
348 shell = KM.shell_channel
348 shell = KM.shell_channel
349
349
350 msg_id = shell.object_info('a')
350 msg_id = shell.object_info('a')
351 reply = shell.get_msg(timeout=2)
351 reply = shell.get_msg(timeout=2)
352 for tst in validate_message(reply, 'object_info_reply', msg_id):
352 for tst in validate_message(reply, 'object_info_reply', msg_id):
353 yield tst
353 yield tst
354
354
355
355
356 @dec.parametric
356 @dec.parametric
357 def test_oinfo_found():
357 def test_oinfo_found():
358 flush_channels()
358 flush_channels()
359
359
360 shell = KM.shell_channel
360 shell = KM.shell_channel
361
361
362 msg_id, reply = execute(code='a=5')
362 msg_id, reply = execute(code='a=5')
363
363
364 msg_id = shell.object_info('a')
364 msg_id = shell.object_info('a')
365 reply = shell.get_msg(timeout=2)
365 reply = shell.get_msg(timeout=2)
366 for tst in validate_message(reply, 'object_info_reply', msg_id):
366 for tst in validate_message(reply, 'object_info_reply', msg_id):
367 yield tst
367 yield tst
368 content = reply['content']
368 content = reply['content']
369 yield nt.assert_true(content['found'])
369 yield nt.assert_true(content['found'])
370 argspec = content['argspec']
370 argspec = content['argspec']
371 yield nt.assert_true(argspec is None, "didn't expect argspec dict, got %r" % argspec)
371 yield nt.assert_true(argspec is None, "didn't expect argspec dict, got %r" % argspec)
372
372
373
373
374 @dec.parametric
374 @dec.parametric
375 def test_oinfo_detail():
375 def test_oinfo_detail():
376 flush_channels()
376 flush_channels()
377
377
378 shell = KM.shell_channel
378 shell = KM.shell_channel
379
379
380 msg_id, reply = execute(code='ip=get_ipython()')
380 msg_id, reply = execute(code='ip=get_ipython()')
381
381
382 msg_id = shell.object_info('ip.object_inspect', detail_level=2)
382 msg_id = shell.object_info('ip.object_inspect', detail_level=2)
383 reply = shell.get_msg(timeout=2)
383 reply = shell.get_msg(timeout=2)
384 for tst in validate_message(reply, 'object_info_reply', msg_id):
384 for tst in validate_message(reply, 'object_info_reply', msg_id):
385 yield tst
385 yield tst
386 content = reply['content']
386 content = reply['content']
387 yield nt.assert_true(content['found'])
387 yield nt.assert_true(content['found'])
388 argspec = content['argspec']
388 argspec = content['argspec']
389 yield nt.assert_true(isinstance(argspec, dict), "expected non-empty argspec dict, got %r" % argspec)
389 yield nt.assert_true(isinstance(argspec, dict), "expected non-empty argspec dict, got %r" % argspec)
390 yield nt.assert_equals(argspec['defaults'], [0])
390 yield nt.assert_equal(argspec['defaults'], [0])
391
391
392
392
393 @dec.parametric
393 @dec.parametric
394 def test_oinfo_not_found():
394 def test_oinfo_not_found():
395 flush_channels()
395 flush_channels()
396
396
397 shell = KM.shell_channel
397 shell = KM.shell_channel
398
398
399 msg_id = shell.object_info('dne')
399 msg_id = shell.object_info('dne')
400 reply = shell.get_msg(timeout=2)
400 reply = shell.get_msg(timeout=2)
401 for tst in validate_message(reply, 'object_info_reply', msg_id):
401 for tst in validate_message(reply, 'object_info_reply', msg_id):
402 yield tst
402 yield tst
403 content = reply['content']
403 content = reply['content']
404 yield nt.assert_false(content['found'])
404 yield nt.assert_false(content['found'])
405
405
406
406
407 @dec.parametric
407 @dec.parametric
408 def test_complete():
408 def test_complete():
409 flush_channels()
409 flush_channels()
410
410
411 shell = KM.shell_channel
411 shell = KM.shell_channel
412
412
413 msg_id, reply = execute(code="alpha = albert = 5")
413 msg_id, reply = execute(code="alpha = albert = 5")
414
414
415 msg_id = shell.complete('al', 'al', 2)
415 msg_id = shell.complete('al', 'al', 2)
416 reply = shell.get_msg(timeout=2)
416 reply = shell.get_msg(timeout=2)
417 for tst in validate_message(reply, 'complete_reply', msg_id):
417 for tst in validate_message(reply, 'complete_reply', msg_id):
418 yield tst
418 yield tst
419 matches = reply['content']['matches']
419 matches = reply['content']['matches']
420 for name in ('alpha', 'albert'):
420 for name in ('alpha', 'albert'):
421 yield nt.assert_true(name in matches, "Missing match: %r" % name)
421 yield nt.assert_true(name in matches, "Missing match: %r" % name)
422
422
423
423
424 # IOPub channel
424 # IOPub channel
425
425
426
426
427 @dec.parametric
427 @dec.parametric
428 def test_stream():
428 def test_stream():
429 flush_channels()
429 flush_channels()
430
430
431 msg_id, reply = execute("print('hi')")
431 msg_id, reply = execute("print('hi')")
432
432
433 stdout = KM.sub_channel.get_msg(timeout=2)
433 stdout = KM.sub_channel.get_msg(timeout=2)
434 for tst in validate_message(stdout, 'stream', msg_id):
434 for tst in validate_message(stdout, 'stream', msg_id):
435 yield tst
435 yield tst
436 content = stdout['content']
436 content = stdout['content']
437 yield nt.assert_equals(content['name'], u'stdout')
437 yield nt.assert_equal(content['name'], u'stdout')
438 yield nt.assert_equals(content['data'], u'hi\n')
438 yield nt.assert_equal(content['data'], u'hi\n')
439
439
440
440
441 @dec.parametric
441 @dec.parametric
442 def test_display_data():
442 def test_display_data():
443 flush_channels()
443 flush_channels()
444
444
445 msg_id, reply = execute("from IPython.core.display import display; display(1)")
445 msg_id, reply = execute("from IPython.core.display import display; display(1)")
446
446
447 display = KM.sub_channel.get_msg(timeout=2)
447 display = KM.sub_channel.get_msg(timeout=2)
448 for tst in validate_message(display, 'display_data', parent=msg_id):
448 for tst in validate_message(display, 'display_data', parent=msg_id):
449 yield tst
449 yield tst
450 data = display['content']['data']
450 data = display['content']['data']
451 yield nt.assert_equals(data['text/plain'], u'1')
451 yield nt.assert_equal(data['text/plain'], u'1')
452
452
General Comments 0
You need to be logged in to leave comments. Login now