##// END OF EJS Templates
Use TemporaryWorkingDirectory context manager in some tests
Thomas Kluyver -
Show More
@@ -1,683 +1,677 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """Tests for the IPython tab-completion machinery."""
2 """Tests for the IPython tab-completion machinery."""
3
3
4 # Copyright (c) IPython Development Team.
4 # Copyright (c) IPython Development Team.
5 # Distributed under the terms of the Modified BSD License.
5 # Distributed under the terms of the Modified BSD License.
6
6
7 import os
7 import os
8 import sys
8 import sys
9 import unittest
9 import unittest
10
10
11 from contextlib import contextmanager
11 from contextlib import contextmanager
12
12
13 import nose.tools as nt
13 import nose.tools as nt
14
14
15 from IPython.config.loader import Config
15 from IPython.config.loader import Config
16 from IPython.core import completer
16 from IPython.core import completer
17 from IPython.external.decorators import knownfailureif
17 from IPython.external.decorators import knownfailureif
18 from IPython.utils.tempdir import TemporaryDirectory
18 from IPython.utils.tempdir import TemporaryDirectory, TemporaryWorkingDirectory
19 from IPython.utils.generics import complete_object
19 from IPython.utils.generics import complete_object
20 from IPython.utils import py3compat
20 from IPython.utils import py3compat
21 from IPython.utils.py3compat import string_types, unicode_type
21 from IPython.utils.py3compat import string_types, unicode_type
22 from IPython.testing import decorators as dec
22 from IPython.testing import decorators as dec
23
23
24 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
25 # Test functions
25 # Test functions
26 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
27
27
28 @contextmanager
28 @contextmanager
29 def greedy_completion():
29 def greedy_completion():
30 ip = get_ipython()
30 ip = get_ipython()
31 greedy_original = ip.Completer.greedy
31 greedy_original = ip.Completer.greedy
32 try:
32 try:
33 ip.Completer.greedy = True
33 ip.Completer.greedy = True
34 yield
34 yield
35 finally:
35 finally:
36 ip.Completer.greedy = greedy_original
36 ip.Completer.greedy = greedy_original
37
37
38 def test_protect_filename():
38 def test_protect_filename():
39 pairs = [ ('abc','abc'),
39 pairs = [ ('abc','abc'),
40 (' abc',r'\ abc'),
40 (' abc',r'\ abc'),
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 (' bc',r'\ \ bc'),
43 (' bc',r'\ \ bc'),
44 ]
44 ]
45 # On posix, we also protect parens and other special characters
45 # On posix, we also protect parens and other special characters
46 if sys.platform != 'win32':
46 if sys.platform != 'win32':
47 pairs.extend( [('a(bc',r'a\(bc'),
47 pairs.extend( [('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[1]bc', r'a\[1\]bc'),
50 ('a[1]bc', r'a\[1\]bc'),
51 ('a{1}bc', r'a\{1\}bc'),
51 ('a{1}bc', r'a\{1\}bc'),
52 ('a#bc', r'a\#bc'),
52 ('a#bc', r'a\#bc'),
53 ('a?bc', r'a\?bc'),
53 ('a?bc', r'a\?bc'),
54 ('a=bc', r'a\=bc'),
54 ('a=bc', r'a\=bc'),
55 ('a\\bc', r'a\\bc'),
55 ('a\\bc', r'a\\bc'),
56 ('a|bc', r'a\|bc'),
56 ('a|bc', r'a\|bc'),
57 ('a;bc', r'a\;bc'),
57 ('a;bc', r'a\;bc'),
58 ('a:bc', r'a\:bc'),
58 ('a:bc', r'a\:bc'),
59 ("a'bc", r"a\'bc"),
59 ("a'bc", r"a\'bc"),
60 ('a*bc', r'a\*bc'),
60 ('a*bc', r'a\*bc'),
61 ('a"bc', r'a\"bc'),
61 ('a"bc', r'a\"bc'),
62 ('a^bc', r'a\^bc'),
62 ('a^bc', r'a\^bc'),
63 ('a&bc', r'a\&bc'),
63 ('a&bc', r'a\&bc'),
64 ] )
64 ] )
65 # run the actual tests
65 # run the actual tests
66 for s1, s2 in pairs:
66 for s1, s2 in pairs:
67 s1p = completer.protect_filename(s1)
67 s1p = completer.protect_filename(s1)
68 nt.assert_equal(s1p, s2)
68 nt.assert_equal(s1p, s2)
69
69
70
70
71 def check_line_split(splitter, test_specs):
71 def check_line_split(splitter, test_specs):
72 for part1, part2, split in test_specs:
72 for part1, part2, split in test_specs:
73 cursor_pos = len(part1)
73 cursor_pos = len(part1)
74 line = part1+part2
74 line = part1+part2
75 out = splitter.split_line(line, cursor_pos)
75 out = splitter.split_line(line, cursor_pos)
76 nt.assert_equal(out, split)
76 nt.assert_equal(out, split)
77
77
78
78
79 def test_line_split():
79 def test_line_split():
80 """Basic line splitter test with default specs."""
80 """Basic line splitter test with default specs."""
81 sp = completer.CompletionSplitter()
81 sp = completer.CompletionSplitter()
82 # The format of the test specs is: part1, part2, expected answer. Parts 1
82 # The format of the test specs is: part1, part2, expected answer. Parts 1
83 # and 2 are joined into the 'line' sent to the splitter, as if the cursor
83 # and 2 are joined into the 'line' sent to the splitter, as if the cursor
84 # was at the end of part1. So an empty part2 represents someone hitting
84 # was at the end of part1. So an empty part2 represents someone hitting
85 # tab at the end of the line, the most common case.
85 # tab at the end of the line, the most common case.
86 t = [('run some/scrip', '', 'some/scrip'),
86 t = [('run some/scrip', '', 'some/scrip'),
87 ('run scripts/er', 'ror.py foo', 'scripts/er'),
87 ('run scripts/er', 'ror.py foo', 'scripts/er'),
88 ('echo $HOM', '', 'HOM'),
88 ('echo $HOM', '', 'HOM'),
89 ('print sys.pa', '', 'sys.pa'),
89 ('print sys.pa', '', 'sys.pa'),
90 ('print(sys.pa', '', 'sys.pa'),
90 ('print(sys.pa', '', 'sys.pa'),
91 ("execfile('scripts/er", '', 'scripts/er'),
91 ("execfile('scripts/er", '', 'scripts/er'),
92 ('a[x.', '', 'x.'),
92 ('a[x.', '', 'x.'),
93 ('a[x.', 'y', 'x.'),
93 ('a[x.', 'y', 'x.'),
94 ('cd "some_file/', '', 'some_file/'),
94 ('cd "some_file/', '', 'some_file/'),
95 ]
95 ]
96 check_line_split(sp, t)
96 check_line_split(sp, t)
97 # Ensure splitting works OK with unicode by re-running the tests with
97 # Ensure splitting works OK with unicode by re-running the tests with
98 # all inputs turned into unicode
98 # all inputs turned into unicode
99 check_line_split(sp, [ map(unicode_type, p) for p in t] )
99 check_line_split(sp, [ map(unicode_type, p) for p in t] )
100
100
101
101
102 def test_custom_completion_error():
102 def test_custom_completion_error():
103 """Test that errors from custom attribute completers are silenced."""
103 """Test that errors from custom attribute completers are silenced."""
104 ip = get_ipython()
104 ip = get_ipython()
105 class A(object): pass
105 class A(object): pass
106 ip.user_ns['a'] = A()
106 ip.user_ns['a'] = A()
107
107
108 @complete_object.when_type(A)
108 @complete_object.when_type(A)
109 def complete_A(a, existing_completions):
109 def complete_A(a, existing_completions):
110 raise TypeError("this should be silenced")
110 raise TypeError("this should be silenced")
111
111
112 ip.complete("a.")
112 ip.complete("a.")
113
113
114
114
115 def test_unicode_completions():
115 def test_unicode_completions():
116 ip = get_ipython()
116 ip = get_ipython()
117 # Some strings that trigger different types of completion. Check them both
117 # Some strings that trigger different types of completion. Check them both
118 # in str and unicode forms
118 # in str and unicode forms
119 s = ['ru', '%ru', 'cd /', 'floa', 'float(x)/']
119 s = ['ru', '%ru', 'cd /', 'floa', 'float(x)/']
120 for t in s + list(map(unicode_type, s)):
120 for t in s + list(map(unicode_type, s)):
121 # We don't need to check exact completion values (they may change
121 # We don't need to check exact completion values (they may change
122 # depending on the state of the namespace, but at least no exceptions
122 # depending on the state of the namespace, but at least no exceptions
123 # should be thrown and the return value should be a pair of text, list
123 # should be thrown and the return value should be a pair of text, list
124 # values.
124 # values.
125 text, matches = ip.complete(t)
125 text, matches = ip.complete(t)
126 nt.assert_true(isinstance(text, string_types))
126 nt.assert_true(isinstance(text, string_types))
127 nt.assert_true(isinstance(matches, list))
127 nt.assert_true(isinstance(matches, list))
128
128
129
129
130 class CompletionSplitterTestCase(unittest.TestCase):
130 class CompletionSplitterTestCase(unittest.TestCase):
131 def setUp(self):
131 def setUp(self):
132 self.sp = completer.CompletionSplitter()
132 self.sp = completer.CompletionSplitter()
133
133
134 def test_delim_setting(self):
134 def test_delim_setting(self):
135 self.sp.delims = ' '
135 self.sp.delims = ' '
136 nt.assert_equal(self.sp.delims, ' ')
136 nt.assert_equal(self.sp.delims, ' ')
137 nt.assert_equal(self.sp._delim_expr, '[\ ]')
137 nt.assert_equal(self.sp._delim_expr, '[\ ]')
138
138
139 def test_spaces(self):
139 def test_spaces(self):
140 """Test with only spaces as split chars."""
140 """Test with only spaces as split chars."""
141 self.sp.delims = ' '
141 self.sp.delims = ' '
142 t = [('foo', '', 'foo'),
142 t = [('foo', '', 'foo'),
143 ('run foo', '', 'foo'),
143 ('run foo', '', 'foo'),
144 ('run foo', 'bar', 'foo'),
144 ('run foo', 'bar', 'foo'),
145 ]
145 ]
146 check_line_split(self.sp, t)
146 check_line_split(self.sp, t)
147
147
148
148
149 def test_has_open_quotes1():
149 def test_has_open_quotes1():
150 for s in ["'", "'''", "'hi' '"]:
150 for s in ["'", "'''", "'hi' '"]:
151 nt.assert_equal(completer.has_open_quotes(s), "'")
151 nt.assert_equal(completer.has_open_quotes(s), "'")
152
152
153
153
154 def test_has_open_quotes2():
154 def test_has_open_quotes2():
155 for s in ['"', '"""', '"hi" "']:
155 for s in ['"', '"""', '"hi" "']:
156 nt.assert_equal(completer.has_open_quotes(s), '"')
156 nt.assert_equal(completer.has_open_quotes(s), '"')
157
157
158
158
159 def test_has_open_quotes3():
159 def test_has_open_quotes3():
160 for s in ["''", "''' '''", "'hi' 'ipython'"]:
160 for s in ["''", "''' '''", "'hi' 'ipython'"]:
161 nt.assert_false(completer.has_open_quotes(s))
161 nt.assert_false(completer.has_open_quotes(s))
162
162
163
163
164 def test_has_open_quotes4():
164 def test_has_open_quotes4():
165 for s in ['""', '""" """', '"hi" "ipython"']:
165 for s in ['""', '""" """', '"hi" "ipython"']:
166 nt.assert_false(completer.has_open_quotes(s))
166 nt.assert_false(completer.has_open_quotes(s))
167
167
168
168
169 @knownfailureif(sys.platform == 'win32', "abspath completions fail on Windows")
169 @knownfailureif(sys.platform == 'win32', "abspath completions fail on Windows")
170 def test_abspath_file_completions():
170 def test_abspath_file_completions():
171 ip = get_ipython()
171 ip = get_ipython()
172 with TemporaryDirectory() as tmpdir:
172 with TemporaryDirectory() as tmpdir:
173 prefix = os.path.join(tmpdir, 'foo')
173 prefix = os.path.join(tmpdir, 'foo')
174 suffixes = ['1', '2']
174 suffixes = ['1', '2']
175 names = [prefix+s for s in suffixes]
175 names = [prefix+s for s in suffixes]
176 for n in names:
176 for n in names:
177 open(n, 'w').close()
177 open(n, 'w').close()
178
178
179 # Check simple completion
179 # Check simple completion
180 c = ip.complete(prefix)[1]
180 c = ip.complete(prefix)[1]
181 nt.assert_equal(c, names)
181 nt.assert_equal(c, names)
182
182
183 # Now check with a function call
183 # Now check with a function call
184 cmd = 'a = f("%s' % prefix
184 cmd = 'a = f("%s' % prefix
185 c = ip.complete(prefix, cmd)[1]
185 c = ip.complete(prefix, cmd)[1]
186 comp = [prefix+s for s in suffixes]
186 comp = [prefix+s for s in suffixes]
187 nt.assert_equal(c, comp)
187 nt.assert_equal(c, comp)
188
188
189
189
190 def test_local_file_completions():
190 def test_local_file_completions():
191 ip = get_ipython()
191 ip = get_ipython()
192 cwd = py3compat.getcwd()
192 with TemporaryWorkingDirectory():
193 try:
193 prefix = './foo'
194 with TemporaryDirectory() as tmpdir:
194 suffixes = ['1', '2']
195 os.chdir(tmpdir)
195 names = [prefix+s for s in suffixes]
196 prefix = './foo'
196 for n in names:
197 suffixes = ['1', '2']
197 open(n, 'w').close()
198 names = [prefix+s for s in suffixes]
198
199 for n in names:
199 # Check simple completion
200 open(n, 'w').close()
200 c = ip.complete(prefix)[1]
201
201 nt.assert_equal(c, names)
202 # Check simple completion
202
203 c = ip.complete(prefix)[1]
203 # Now check with a function call
204 nt.assert_equal(c, names)
204 cmd = 'a = f("%s' % prefix
205
205 c = ip.complete(prefix, cmd)[1]
206 # Now check with a function call
206 comp = [prefix+s for s in suffixes]
207 cmd = 'a = f("%s' % prefix
207 nt.assert_equal(c, comp)
208 c = ip.complete(prefix, cmd)[1]
209 comp = [prefix+s for s in suffixes]
210 nt.assert_equal(c, comp)
211 finally:
212 # prevent failures from making chdir stick
213 os.chdir(cwd)
214
208
215
209
216 def test_greedy_completions():
210 def test_greedy_completions():
217 ip = get_ipython()
211 ip = get_ipython()
218 ip.ex('a=list(range(5))')
212 ip.ex('a=list(range(5))')
219 _,c = ip.complete('.',line='a[0].')
213 _,c = ip.complete('.',line='a[0].')
220 nt.assert_false('a[0].real' in c,
214 nt.assert_false('a[0].real' in c,
221 "Shouldn't have completed on a[0]: %s"%c)
215 "Shouldn't have completed on a[0]: %s"%c)
222 with greedy_completion():
216 with greedy_completion():
223 _,c = ip.complete('.',line='a[0].')
217 _,c = ip.complete('.',line='a[0].')
224 nt.assert_true('a[0].real' in c, "Should have completed on a[0]: %s"%c)
218 nt.assert_true('a[0].real' in c, "Should have completed on a[0]: %s"%c)
225
219
226
220
227 def test_omit__names():
221 def test_omit__names():
228 # also happens to test IPCompleter as a configurable
222 # also happens to test IPCompleter as a configurable
229 ip = get_ipython()
223 ip = get_ipython()
230 ip._hidden_attr = 1
224 ip._hidden_attr = 1
231 c = ip.Completer
225 c = ip.Completer
232 ip.ex('ip=get_ipython()')
226 ip.ex('ip=get_ipython()')
233 cfg = Config()
227 cfg = Config()
234 cfg.IPCompleter.omit__names = 0
228 cfg.IPCompleter.omit__names = 0
235 c.update_config(cfg)
229 c.update_config(cfg)
236 s,matches = c.complete('ip.')
230 s,matches = c.complete('ip.')
237 nt.assert_in('ip.__str__', matches)
231 nt.assert_in('ip.__str__', matches)
238 nt.assert_in('ip._hidden_attr', matches)
232 nt.assert_in('ip._hidden_attr', matches)
239 cfg.IPCompleter.omit__names = 1
233 cfg.IPCompleter.omit__names = 1
240 c.update_config(cfg)
234 c.update_config(cfg)
241 s,matches = c.complete('ip.')
235 s,matches = c.complete('ip.')
242 nt.assert_not_in('ip.__str__', matches)
236 nt.assert_not_in('ip.__str__', matches)
243 nt.assert_in('ip._hidden_attr', matches)
237 nt.assert_in('ip._hidden_attr', matches)
244 cfg.IPCompleter.omit__names = 2
238 cfg.IPCompleter.omit__names = 2
245 c.update_config(cfg)
239 c.update_config(cfg)
246 s,matches = c.complete('ip.')
240 s,matches = c.complete('ip.')
247 nt.assert_not_in('ip.__str__', matches)
241 nt.assert_not_in('ip.__str__', matches)
248 nt.assert_not_in('ip._hidden_attr', matches)
242 nt.assert_not_in('ip._hidden_attr', matches)
249 del ip._hidden_attr
243 del ip._hidden_attr
250
244
251
245
252 def test_limit_to__all__False_ok():
246 def test_limit_to__all__False_ok():
253 ip = get_ipython()
247 ip = get_ipython()
254 c = ip.Completer
248 c = ip.Completer
255 ip.ex('class D: x=24')
249 ip.ex('class D: x=24')
256 ip.ex('d=D()')
250 ip.ex('d=D()')
257 cfg = Config()
251 cfg = Config()
258 cfg.IPCompleter.limit_to__all__ = False
252 cfg.IPCompleter.limit_to__all__ = False
259 c.update_config(cfg)
253 c.update_config(cfg)
260 s, matches = c.complete('d.')
254 s, matches = c.complete('d.')
261 nt.assert_in('d.x', matches)
255 nt.assert_in('d.x', matches)
262
256
263
257
264 def test_limit_to__all__True_ok():
258 def test_limit_to__all__True_ok():
265 ip = get_ipython()
259 ip = get_ipython()
266 c = ip.Completer
260 c = ip.Completer
267 ip.ex('class D: x=24')
261 ip.ex('class D: x=24')
268 ip.ex('d=D()')
262 ip.ex('d=D()')
269 ip.ex("d.__all__=['z']")
263 ip.ex("d.__all__=['z']")
270 cfg = Config()
264 cfg = Config()
271 cfg.IPCompleter.limit_to__all__ = True
265 cfg.IPCompleter.limit_to__all__ = True
272 c.update_config(cfg)
266 c.update_config(cfg)
273 s, matches = c.complete('d.')
267 s, matches = c.complete('d.')
274 nt.assert_in('d.z', matches)
268 nt.assert_in('d.z', matches)
275 nt.assert_not_in('d.x', matches)
269 nt.assert_not_in('d.x', matches)
276
270
277
271
278 def test_get__all__entries_ok():
272 def test_get__all__entries_ok():
279 class A(object):
273 class A(object):
280 __all__ = ['x', 1]
274 __all__ = ['x', 1]
281 words = completer.get__all__entries(A())
275 words = completer.get__all__entries(A())
282 nt.assert_equal(words, ['x'])
276 nt.assert_equal(words, ['x'])
283
277
284
278
285 def test_get__all__entries_no__all__ok():
279 def test_get__all__entries_no__all__ok():
286 class A(object):
280 class A(object):
287 pass
281 pass
288 words = completer.get__all__entries(A())
282 words = completer.get__all__entries(A())
289 nt.assert_equal(words, [])
283 nt.assert_equal(words, [])
290
284
291
285
292 def test_func_kw_completions():
286 def test_func_kw_completions():
293 ip = get_ipython()
287 ip = get_ipython()
294 c = ip.Completer
288 c = ip.Completer
295 ip.ex('def myfunc(a=1,b=2): return a+b')
289 ip.ex('def myfunc(a=1,b=2): return a+b')
296 s, matches = c.complete(None, 'myfunc(1,b')
290 s, matches = c.complete(None, 'myfunc(1,b')
297 nt.assert_in('b=', matches)
291 nt.assert_in('b=', matches)
298 # Simulate completing with cursor right after b (pos==10):
292 # Simulate completing with cursor right after b (pos==10):
299 s, matches = c.complete(None, 'myfunc(1,b)', 10)
293 s, matches = c.complete(None, 'myfunc(1,b)', 10)
300 nt.assert_in('b=', matches)
294 nt.assert_in('b=', matches)
301 s, matches = c.complete(None, 'myfunc(a="escaped\\")string",b')
295 s, matches = c.complete(None, 'myfunc(a="escaped\\")string",b')
302 nt.assert_in('b=', matches)
296 nt.assert_in('b=', matches)
303 #builtin function
297 #builtin function
304 s, matches = c.complete(None, 'min(k, k')
298 s, matches = c.complete(None, 'min(k, k')
305 nt.assert_in('key=', matches)
299 nt.assert_in('key=', matches)
306
300
307
301
308 def test_default_arguments_from_docstring():
302 def test_default_arguments_from_docstring():
309 doc = min.__doc__
303 doc = min.__doc__
310 ip = get_ipython()
304 ip = get_ipython()
311 c = ip.Completer
305 c = ip.Completer
312 kwd = c._default_arguments_from_docstring(
306 kwd = c._default_arguments_from_docstring(
313 'min(iterable[, key=func]) -> value')
307 'min(iterable[, key=func]) -> value')
314 nt.assert_equal(kwd, ['key'])
308 nt.assert_equal(kwd, ['key'])
315 #with cython type etc
309 #with cython type etc
316 kwd = c._default_arguments_from_docstring(
310 kwd = c._default_arguments_from_docstring(
317 'Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)\n')
311 'Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)\n')
318 nt.assert_equal(kwd, ['ncall', 'resume', 'nsplit'])
312 nt.assert_equal(kwd, ['ncall', 'resume', 'nsplit'])
319 #white spaces
313 #white spaces
320 kwd = c._default_arguments_from_docstring(
314 kwd = c._default_arguments_from_docstring(
321 '\n Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)\n')
315 '\n Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)\n')
322 nt.assert_equal(kwd, ['ncall', 'resume', 'nsplit'])
316 nt.assert_equal(kwd, ['ncall', 'resume', 'nsplit'])
323
317
324 def test_line_magics():
318 def test_line_magics():
325 ip = get_ipython()
319 ip = get_ipython()
326 c = ip.Completer
320 c = ip.Completer
327 s, matches = c.complete(None, 'lsmag')
321 s, matches = c.complete(None, 'lsmag')
328 nt.assert_in('%lsmagic', matches)
322 nt.assert_in('%lsmagic', matches)
329 s, matches = c.complete(None, '%lsmag')
323 s, matches = c.complete(None, '%lsmag')
330 nt.assert_in('%lsmagic', matches)
324 nt.assert_in('%lsmagic', matches)
331
325
332
326
333 def test_cell_magics():
327 def test_cell_magics():
334 from IPython.core.magic import register_cell_magic
328 from IPython.core.magic import register_cell_magic
335
329
336 @register_cell_magic
330 @register_cell_magic
337 def _foo_cellm(line, cell):
331 def _foo_cellm(line, cell):
338 pass
332 pass
339
333
340 ip = get_ipython()
334 ip = get_ipython()
341 c = ip.Completer
335 c = ip.Completer
342
336
343 s, matches = c.complete(None, '_foo_ce')
337 s, matches = c.complete(None, '_foo_ce')
344 nt.assert_in('%%_foo_cellm', matches)
338 nt.assert_in('%%_foo_cellm', matches)
345 s, matches = c.complete(None, '%%_foo_ce')
339 s, matches = c.complete(None, '%%_foo_ce')
346 nt.assert_in('%%_foo_cellm', matches)
340 nt.assert_in('%%_foo_cellm', matches)
347
341
348
342
349 def test_line_cell_magics():
343 def test_line_cell_magics():
350 from IPython.core.magic import register_line_cell_magic
344 from IPython.core.magic import register_line_cell_magic
351
345
352 @register_line_cell_magic
346 @register_line_cell_magic
353 def _bar_cellm(line, cell):
347 def _bar_cellm(line, cell):
354 pass
348 pass
355
349
356 ip = get_ipython()
350 ip = get_ipython()
357 c = ip.Completer
351 c = ip.Completer
358
352
359 # The policy here is trickier, see comments in completion code. The
353 # The policy here is trickier, see comments in completion code. The
360 # returned values depend on whether the user passes %% or not explicitly,
354 # returned values depend on whether the user passes %% or not explicitly,
361 # and this will show a difference if the same name is both a line and cell
355 # and this will show a difference if the same name is both a line and cell
362 # magic.
356 # magic.
363 s, matches = c.complete(None, '_bar_ce')
357 s, matches = c.complete(None, '_bar_ce')
364 nt.assert_in('%_bar_cellm', matches)
358 nt.assert_in('%_bar_cellm', matches)
365 nt.assert_in('%%_bar_cellm', matches)
359 nt.assert_in('%%_bar_cellm', matches)
366 s, matches = c.complete(None, '%_bar_ce')
360 s, matches = c.complete(None, '%_bar_ce')
367 nt.assert_in('%_bar_cellm', matches)
361 nt.assert_in('%_bar_cellm', matches)
368 nt.assert_in('%%_bar_cellm', matches)
362 nt.assert_in('%%_bar_cellm', matches)
369 s, matches = c.complete(None, '%%_bar_ce')
363 s, matches = c.complete(None, '%%_bar_ce')
370 nt.assert_not_in('%_bar_cellm', matches)
364 nt.assert_not_in('%_bar_cellm', matches)
371 nt.assert_in('%%_bar_cellm', matches)
365 nt.assert_in('%%_bar_cellm', matches)
372
366
373
367
374 def test_magic_completion_order():
368 def test_magic_completion_order():
375
369
376 ip = get_ipython()
370 ip = get_ipython()
377 c = ip.Completer
371 c = ip.Completer
378
372
379 # Test ordering of magics and non-magics with the same name
373 # Test ordering of magics and non-magics with the same name
380 # We want the non-magic first
374 # We want the non-magic first
381
375
382 # Before importing matplotlib, there should only be one option:
376 # Before importing matplotlib, there should only be one option:
383
377
384 text, matches = c.complete('mat')
378 text, matches = c.complete('mat')
385 nt.assert_equal(matches, ["%matplotlib"])
379 nt.assert_equal(matches, ["%matplotlib"])
386
380
387
381
388 ip.run_cell("matplotlib = 1") # introduce name into namespace
382 ip.run_cell("matplotlib = 1") # introduce name into namespace
389
383
390 # After the import, there should be two options, ordered like this:
384 # After the import, there should be two options, ordered like this:
391 text, matches = c.complete('mat')
385 text, matches = c.complete('mat')
392 nt.assert_equal(matches, ["matplotlib", "%matplotlib"])
386 nt.assert_equal(matches, ["matplotlib", "%matplotlib"])
393
387
394
388
395 ip.run_cell("timeit = 1") # define a user variable called 'timeit'
389 ip.run_cell("timeit = 1") # define a user variable called 'timeit'
396
390
397 # Order of user variable and line and cell magics with same name:
391 # Order of user variable and line and cell magics with same name:
398 text, matches = c.complete('timeit')
392 text, matches = c.complete('timeit')
399 nt.assert_equal(matches, ["timeit", "%timeit","%%timeit"])
393 nt.assert_equal(matches, ["timeit", "%timeit","%%timeit"])
400
394
401
395
402 def test_dict_key_completion_string():
396 def test_dict_key_completion_string():
403 """Test dictionary key completion for string keys"""
397 """Test dictionary key completion for string keys"""
404 ip = get_ipython()
398 ip = get_ipython()
405 complete = ip.Completer.complete
399 complete = ip.Completer.complete
406
400
407 ip.user_ns['d'] = {'abc': None}
401 ip.user_ns['d'] = {'abc': None}
408
402
409 # check completion at different stages
403 # check completion at different stages
410 _, matches = complete(line_buffer="d[")
404 _, matches = complete(line_buffer="d[")
411 nt.assert_in("'abc'", matches)
405 nt.assert_in("'abc'", matches)
412 nt.assert_not_in("'abc']", matches)
406 nt.assert_not_in("'abc']", matches)
413
407
414 _, matches = complete(line_buffer="d['")
408 _, matches = complete(line_buffer="d['")
415 nt.assert_in("abc", matches)
409 nt.assert_in("abc", matches)
416 nt.assert_not_in("abc']", matches)
410 nt.assert_not_in("abc']", matches)
417
411
418 _, matches = complete(line_buffer="d['a")
412 _, matches = complete(line_buffer="d['a")
419 nt.assert_in("abc", matches)
413 nt.assert_in("abc", matches)
420 nt.assert_not_in("abc']", matches)
414 nt.assert_not_in("abc']", matches)
421
415
422 # check use of different quoting
416 # check use of different quoting
423 _, matches = complete(line_buffer="d[\"")
417 _, matches = complete(line_buffer="d[\"")
424 nt.assert_in("abc", matches)
418 nt.assert_in("abc", matches)
425 nt.assert_not_in('abc\"]', matches)
419 nt.assert_not_in('abc\"]', matches)
426
420
427 _, matches = complete(line_buffer="d[\"a")
421 _, matches = complete(line_buffer="d[\"a")
428 nt.assert_in("abc", matches)
422 nt.assert_in("abc", matches)
429 nt.assert_not_in('abc\"]', matches)
423 nt.assert_not_in('abc\"]', matches)
430
424
431 # check sensitivity to following context
425 # check sensitivity to following context
432 _, matches = complete(line_buffer="d[]", cursor_pos=2)
426 _, matches = complete(line_buffer="d[]", cursor_pos=2)
433 nt.assert_in("'abc'", matches)
427 nt.assert_in("'abc'", matches)
434
428
435 _, matches = complete(line_buffer="d['']", cursor_pos=3)
429 _, matches = complete(line_buffer="d['']", cursor_pos=3)
436 nt.assert_in("abc", matches)
430 nt.assert_in("abc", matches)
437 nt.assert_not_in("abc'", matches)
431 nt.assert_not_in("abc'", matches)
438 nt.assert_not_in("abc']", matches)
432 nt.assert_not_in("abc']", matches)
439
433
440 # check multiple solutions are correctly returned and that noise is not
434 # check multiple solutions are correctly returned and that noise is not
441 ip.user_ns['d'] = {'abc': None, 'abd': None, 'bad': None, object(): None,
435 ip.user_ns['d'] = {'abc': None, 'abd': None, 'bad': None, object(): None,
442 5: None}
436 5: None}
443
437
444 _, matches = complete(line_buffer="d['a")
438 _, matches = complete(line_buffer="d['a")
445 nt.assert_in("abc", matches)
439 nt.assert_in("abc", matches)
446 nt.assert_in("abd", matches)
440 nt.assert_in("abd", matches)
447 nt.assert_not_in("bad", matches)
441 nt.assert_not_in("bad", matches)
448 assert not any(m.endswith((']', '"', "'")) for m in matches), matches
442 assert not any(m.endswith((']', '"', "'")) for m in matches), matches
449
443
450 # check escaping and whitespace
444 # check escaping and whitespace
451 ip.user_ns['d'] = {'a\nb': None, 'a\'b': None, 'a"b': None, 'a word': None}
445 ip.user_ns['d'] = {'a\nb': None, 'a\'b': None, 'a"b': None, 'a word': None}
452 _, matches = complete(line_buffer="d['a")
446 _, matches = complete(line_buffer="d['a")
453 nt.assert_in("a\\nb", matches)
447 nt.assert_in("a\\nb", matches)
454 nt.assert_in("a\\'b", matches)
448 nt.assert_in("a\\'b", matches)
455 nt.assert_in("a\"b", matches)
449 nt.assert_in("a\"b", matches)
456 nt.assert_in("a word", matches)
450 nt.assert_in("a word", matches)
457 assert not any(m.endswith((']', '"', "'")) for m in matches), matches
451 assert not any(m.endswith((']', '"', "'")) for m in matches), matches
458
452
459 # - can complete on non-initial word of the string
453 # - can complete on non-initial word of the string
460 _, matches = complete(line_buffer="d['a w")
454 _, matches = complete(line_buffer="d['a w")
461 nt.assert_in("word", matches)
455 nt.assert_in("word", matches)
462
456
463 # - understands quote escaping
457 # - understands quote escaping
464 _, matches = complete(line_buffer="d['a\\'")
458 _, matches = complete(line_buffer="d['a\\'")
465 nt.assert_in("b", matches)
459 nt.assert_in("b", matches)
466
460
467 # - default quoting should work like repr
461 # - default quoting should work like repr
468 _, matches = complete(line_buffer="d[")
462 _, matches = complete(line_buffer="d[")
469 nt.assert_in("\"a'b\"", matches)
463 nt.assert_in("\"a'b\"", matches)
470
464
471 # - when opening quote with ", possible to match with unescaped apostrophe
465 # - when opening quote with ", possible to match with unescaped apostrophe
472 _, matches = complete(line_buffer="d[\"a'")
466 _, matches = complete(line_buffer="d[\"a'")
473 nt.assert_in("b", matches)
467 nt.assert_in("b", matches)
474
468
475
469
476 def test_dict_key_completion_contexts():
470 def test_dict_key_completion_contexts():
477 """Test expression contexts in which dict key completion occurs"""
471 """Test expression contexts in which dict key completion occurs"""
478 ip = get_ipython()
472 ip = get_ipython()
479 complete = ip.Completer.complete
473 complete = ip.Completer.complete
480 d = {'abc': None}
474 d = {'abc': None}
481 ip.user_ns['d'] = d
475 ip.user_ns['d'] = d
482
476
483 class C:
477 class C:
484 data = d
478 data = d
485 ip.user_ns['C'] = C
479 ip.user_ns['C'] = C
486 ip.user_ns['get'] = lambda: d
480 ip.user_ns['get'] = lambda: d
487
481
488 def assert_no_completion(**kwargs):
482 def assert_no_completion(**kwargs):
489 _, matches = complete(**kwargs)
483 _, matches = complete(**kwargs)
490 nt.assert_not_in('abc', matches)
484 nt.assert_not_in('abc', matches)
491 nt.assert_not_in('abc\'', matches)
485 nt.assert_not_in('abc\'', matches)
492 nt.assert_not_in('abc\']', matches)
486 nt.assert_not_in('abc\']', matches)
493 nt.assert_not_in('\'abc\'', matches)
487 nt.assert_not_in('\'abc\'', matches)
494 nt.assert_not_in('\'abc\']', matches)
488 nt.assert_not_in('\'abc\']', matches)
495
489
496 def assert_completion(**kwargs):
490 def assert_completion(**kwargs):
497 _, matches = complete(**kwargs)
491 _, matches = complete(**kwargs)
498 nt.assert_in("'abc'", matches)
492 nt.assert_in("'abc'", matches)
499 nt.assert_not_in("'abc']", matches)
493 nt.assert_not_in("'abc']", matches)
500
494
501 # no completion after string closed, even if reopened
495 # no completion after string closed, even if reopened
502 assert_no_completion(line_buffer="d['a'")
496 assert_no_completion(line_buffer="d['a'")
503 assert_no_completion(line_buffer="d[\"a\"")
497 assert_no_completion(line_buffer="d[\"a\"")
504 assert_no_completion(line_buffer="d['a' + ")
498 assert_no_completion(line_buffer="d['a' + ")
505 assert_no_completion(line_buffer="d['a' + '")
499 assert_no_completion(line_buffer="d['a' + '")
506
500
507 # completion in non-trivial expressions
501 # completion in non-trivial expressions
508 assert_completion(line_buffer="+ d[")
502 assert_completion(line_buffer="+ d[")
509 assert_completion(line_buffer="(d[")
503 assert_completion(line_buffer="(d[")
510 assert_completion(line_buffer="C.data[")
504 assert_completion(line_buffer="C.data[")
511
505
512 # greedy flag
506 # greedy flag
513 def assert_completion(**kwargs):
507 def assert_completion(**kwargs):
514 _, matches = complete(**kwargs)
508 _, matches = complete(**kwargs)
515 nt.assert_in("get()['abc']", matches)
509 nt.assert_in("get()['abc']", matches)
516
510
517 assert_no_completion(line_buffer="get()[")
511 assert_no_completion(line_buffer="get()[")
518 with greedy_completion():
512 with greedy_completion():
519 assert_completion(line_buffer="get()[")
513 assert_completion(line_buffer="get()[")
520 assert_completion(line_buffer="get()['")
514 assert_completion(line_buffer="get()['")
521 assert_completion(line_buffer="get()['a")
515 assert_completion(line_buffer="get()['a")
522 assert_completion(line_buffer="get()['ab")
516 assert_completion(line_buffer="get()['ab")
523 assert_completion(line_buffer="get()['abc")
517 assert_completion(line_buffer="get()['abc")
524
518
525
519
526
520
527 @dec.onlyif(sys.version_info[0] >= 3, 'This test only applies in Py>=3')
521 @dec.onlyif(sys.version_info[0] >= 3, 'This test only applies in Py>=3')
528 def test_dict_key_completion_bytes():
522 def test_dict_key_completion_bytes():
529 """Test handling of bytes in dict key completion"""
523 """Test handling of bytes in dict key completion"""
530 ip = get_ipython()
524 ip = get_ipython()
531 complete = ip.Completer.complete
525 complete = ip.Completer.complete
532
526
533 ip.user_ns['d'] = {'abc': None, b'abd': None}
527 ip.user_ns['d'] = {'abc': None, b'abd': None}
534
528
535 _, matches = complete(line_buffer="d[")
529 _, matches = complete(line_buffer="d[")
536 nt.assert_in("'abc'", matches)
530 nt.assert_in("'abc'", matches)
537 nt.assert_in("b'abd'", matches)
531 nt.assert_in("b'abd'", matches)
538
532
539 if False: # not currently implemented
533 if False: # not currently implemented
540 _, matches = complete(line_buffer="d[b")
534 _, matches = complete(line_buffer="d[b")
541 nt.assert_in("b'abd'", matches)
535 nt.assert_in("b'abd'", matches)
542 nt.assert_not_in("b'abc'", matches)
536 nt.assert_not_in("b'abc'", matches)
543
537
544 _, matches = complete(line_buffer="d[b'")
538 _, matches = complete(line_buffer="d[b'")
545 nt.assert_in("abd", matches)
539 nt.assert_in("abd", matches)
546 nt.assert_not_in("abc", matches)
540 nt.assert_not_in("abc", matches)
547
541
548 _, matches = complete(line_buffer="d[B'")
542 _, matches = complete(line_buffer="d[B'")
549 nt.assert_in("abd", matches)
543 nt.assert_in("abd", matches)
550 nt.assert_not_in("abc", matches)
544 nt.assert_not_in("abc", matches)
551
545
552 _, matches = complete(line_buffer="d['")
546 _, matches = complete(line_buffer="d['")
553 nt.assert_in("abc", matches)
547 nt.assert_in("abc", matches)
554 nt.assert_not_in("abd", matches)
548 nt.assert_not_in("abd", matches)
555
549
556
550
557 @dec.onlyif(sys.version_info[0] < 3, 'This test only applies in Py<3')
551 @dec.onlyif(sys.version_info[0] < 3, 'This test only applies in Py<3')
558 def test_dict_key_completion_unicode_py2():
552 def test_dict_key_completion_unicode_py2():
559 """Test handling of unicode in dict key completion"""
553 """Test handling of unicode in dict key completion"""
560 ip = get_ipython()
554 ip = get_ipython()
561 complete = ip.Completer.complete
555 complete = ip.Completer.complete
562
556
563 ip.user_ns['d'] = {u'abc': None,
557 ip.user_ns['d'] = {u'abc': None,
564 u'a\u05d0b': None}
558 u'a\u05d0b': None}
565
559
566 _, matches = complete(line_buffer="d[")
560 _, matches = complete(line_buffer="d[")
567 nt.assert_in("u'abc'", matches)
561 nt.assert_in("u'abc'", matches)
568 nt.assert_in("u'a\\u05d0b'", matches)
562 nt.assert_in("u'a\\u05d0b'", matches)
569
563
570 _, matches = complete(line_buffer="d['a")
564 _, matches = complete(line_buffer="d['a")
571 nt.assert_in("abc", matches)
565 nt.assert_in("abc", matches)
572 nt.assert_not_in("a\\u05d0b", matches)
566 nt.assert_not_in("a\\u05d0b", matches)
573
567
574 _, matches = complete(line_buffer="d[u'a")
568 _, matches = complete(line_buffer="d[u'a")
575 nt.assert_in("abc", matches)
569 nt.assert_in("abc", matches)
576 nt.assert_in("a\\u05d0b", matches)
570 nt.assert_in("a\\u05d0b", matches)
577
571
578 _, matches = complete(line_buffer="d[U'a")
572 _, matches = complete(line_buffer="d[U'a")
579 nt.assert_in("abc", matches)
573 nt.assert_in("abc", matches)
580 nt.assert_in("a\\u05d0b", matches)
574 nt.assert_in("a\\u05d0b", matches)
581
575
582 # query using escape
576 # query using escape
583 _, matches = complete(line_buffer=u"d[u'a\\u05d0")
577 _, matches = complete(line_buffer=u"d[u'a\\u05d0")
584 nt.assert_in("u05d0b", matches) # tokenized after \\
578 nt.assert_in("u05d0b", matches) # tokenized after \\
585
579
586 # query using character
580 # query using character
587 _, matches = complete(line_buffer=u"d[u'a\u05d0")
581 _, matches = complete(line_buffer=u"d[u'a\u05d0")
588 nt.assert_in(u"a\u05d0b", matches)
582 nt.assert_in(u"a\u05d0b", matches)
589
583
590 with greedy_completion():
584 with greedy_completion():
591 _, matches = complete(line_buffer="d[")
585 _, matches = complete(line_buffer="d[")
592 nt.assert_in("d[u'abc']", matches)
586 nt.assert_in("d[u'abc']", matches)
593 nt.assert_in("d[u'a\\u05d0b']", matches)
587 nt.assert_in("d[u'a\\u05d0b']", matches)
594
588
595 _, matches = complete(line_buffer="d['a")
589 _, matches = complete(line_buffer="d['a")
596 nt.assert_in("d['abc']", matches)
590 nt.assert_in("d['abc']", matches)
597 nt.assert_not_in("d[u'a\\u05d0b']", matches)
591 nt.assert_not_in("d[u'a\\u05d0b']", matches)
598
592
599 _, matches = complete(line_buffer="d[u'a")
593 _, matches = complete(line_buffer="d[u'a")
600 nt.assert_in("d[u'abc']", matches)
594 nt.assert_in("d[u'abc']", matches)
601 nt.assert_in("d[u'a\\u05d0b']", matches)
595 nt.assert_in("d[u'a\\u05d0b']", matches)
602
596
603 _, matches = complete(line_buffer="d[U'a")
597 _, matches = complete(line_buffer="d[U'a")
604 nt.assert_in("d[U'abc']", matches)
598 nt.assert_in("d[U'abc']", matches)
605 nt.assert_in("d[U'a\\u05d0b']", matches)
599 nt.assert_in("d[U'a\\u05d0b']", matches)
606
600
607 # query using escape
601 # query using escape
608 _, matches = complete(line_buffer=u"d[u'a\\u05d0")
602 _, matches = complete(line_buffer=u"d[u'a\\u05d0")
609 nt.assert_in("d[u'a\\u05d0b']", matches) # tokenized after \\
603 nt.assert_in("d[u'a\\u05d0b']", matches) # tokenized after \\
610
604
611 # query using character
605 # query using character
612 _, matches = complete(line_buffer=u"d[u'a\u05d0")
606 _, matches = complete(line_buffer=u"d[u'a\u05d0")
613 nt.assert_in(u"d[u'a\u05d0b']", matches)
607 nt.assert_in(u"d[u'a\u05d0b']", matches)
614
608
615
609
616 @dec.onlyif(sys.version_info[0] >= 3, 'This test only applies in Py>=3')
610 @dec.onlyif(sys.version_info[0] >= 3, 'This test only applies in Py>=3')
617 def test_dict_key_completion_unicode_py3():
611 def test_dict_key_completion_unicode_py3():
618 """Test handling of unicode in dict key completion"""
612 """Test handling of unicode in dict key completion"""
619 ip = get_ipython()
613 ip = get_ipython()
620 complete = ip.Completer.complete
614 complete = ip.Completer.complete
621
615
622 ip.user_ns['d'] = {u'a\u05d0': None}
616 ip.user_ns['d'] = {u'a\u05d0': None}
623
617
624 # query using escape
618 # query using escape
625 _, matches = complete(line_buffer="d['a\\u05d0")
619 _, matches = complete(line_buffer="d['a\\u05d0")
626 nt.assert_in("u05d0", matches) # tokenized after \\
620 nt.assert_in("u05d0", matches) # tokenized after \\
627
621
628 # query using character
622 # query using character
629 _, matches = complete(line_buffer="d['a\u05d0")
623 _, matches = complete(line_buffer="d['a\u05d0")
630 nt.assert_in(u"a\u05d0", matches)
624 nt.assert_in(u"a\u05d0", matches)
631
625
632 with greedy_completion():
626 with greedy_completion():
633 # query using escape
627 # query using escape
634 _, matches = complete(line_buffer="d['a\\u05d0")
628 _, matches = complete(line_buffer="d['a\\u05d0")
635 nt.assert_in("d['a\\u05d0']", matches) # tokenized after \\
629 nt.assert_in("d['a\\u05d0']", matches) # tokenized after \\
636
630
637 # query using character
631 # query using character
638 _, matches = complete(line_buffer="d['a\u05d0")
632 _, matches = complete(line_buffer="d['a\u05d0")
639 nt.assert_in(u"d['a\u05d0']", matches)
633 nt.assert_in(u"d['a\u05d0']", matches)
640
634
641
635
642
636
643 @dec.skip_without('numpy')
637 @dec.skip_without('numpy')
644 def test_struct_array_key_completion():
638 def test_struct_array_key_completion():
645 """Test dict key completion applies to numpy struct arrays"""
639 """Test dict key completion applies to numpy struct arrays"""
646 import numpy
640 import numpy
647 ip = get_ipython()
641 ip = get_ipython()
648 complete = ip.Completer.complete
642 complete = ip.Completer.complete
649 ip.user_ns['d'] = numpy.array([], dtype=[('hello', 'f'), ('world', 'f')])
643 ip.user_ns['d'] = numpy.array([], dtype=[('hello', 'f'), ('world', 'f')])
650 _, matches = complete(line_buffer="d['")
644 _, matches = complete(line_buffer="d['")
651 nt.assert_in("hello", matches)
645 nt.assert_in("hello", matches)
652 nt.assert_in("world", matches)
646 nt.assert_in("world", matches)
653
647
654
648
655 @dec.skip_without('pandas')
649 @dec.skip_without('pandas')
656 def test_dataframe_key_completion():
650 def test_dataframe_key_completion():
657 """Test dict key completion applies to pandas DataFrames"""
651 """Test dict key completion applies to pandas DataFrames"""
658 import pandas
652 import pandas
659 ip = get_ipython()
653 ip = get_ipython()
660 complete = ip.Completer.complete
654 complete = ip.Completer.complete
661 ip.user_ns['d'] = pandas.DataFrame({'hello': [1], 'world': [2]})
655 ip.user_ns['d'] = pandas.DataFrame({'hello': [1], 'world': [2]})
662 _, matches = complete(line_buffer="d['")
656 _, matches = complete(line_buffer="d['")
663 nt.assert_in("hello", matches)
657 nt.assert_in("hello", matches)
664 nt.assert_in("world", matches)
658 nt.assert_in("world", matches)
665
659
666
660
667 def test_dict_key_completion_invalids():
661 def test_dict_key_completion_invalids():
668 """Smoke test cases dict key completion can't handle"""
662 """Smoke test cases dict key completion can't handle"""
669 ip = get_ipython()
663 ip = get_ipython()
670 complete = ip.Completer.complete
664 complete = ip.Completer.complete
671
665
672 ip.user_ns['no_getitem'] = None
666 ip.user_ns['no_getitem'] = None
673 ip.user_ns['no_keys'] = []
667 ip.user_ns['no_keys'] = []
674 ip.user_ns['cant_call_keys'] = dict
668 ip.user_ns['cant_call_keys'] = dict
675 ip.user_ns['empty'] = {}
669 ip.user_ns['empty'] = {}
676 ip.user_ns['d'] = {'abc': 5}
670 ip.user_ns['d'] = {'abc': 5}
677
671
678 _, matches = complete(line_buffer="no_getitem['")
672 _, matches = complete(line_buffer="no_getitem['")
679 _, matches = complete(line_buffer="no_keys['")
673 _, matches = complete(line_buffer="no_keys['")
680 _, matches = complete(line_buffer="cant_call_keys['")
674 _, matches = complete(line_buffer="cant_call_keys['")
681 _, matches = complete(line_buffer="empty['")
675 _, matches = complete(line_buffer="empty['")
682 _, matches = complete(line_buffer="name_error['")
676 _, matches = complete(line_buffer="name_error['")
683 _, matches = complete(line_buffer="d['\\") # incomplete escape
677 _, matches = complete(line_buffer="d['\\") # incomplete escape
@@ -1,112 +1,109 b''
1 # -*- coding: utf-8
1 # -*- coding: utf-8
2 """Tests for prompt generation."""
2 """Tests for prompt generation."""
3
3
4 import unittest
4 import unittest
5
5
6 import os
6 import os
7
7
8 from IPython.testing import tools as tt, decorators as dec
8 from IPython.testing import tools as tt, decorators as dec
9 from IPython.core.prompts import PromptManager, LazyEvaluate
9 from IPython.core.prompts import PromptManager, LazyEvaluate
10 from IPython.testing.globalipapp import get_ipython
10 from IPython.testing.globalipapp import get_ipython
11 from IPython.utils.tempdir import TemporaryDirectory
11 from IPython.utils.tempdir import TemporaryWorkingDirectory
12 from IPython.utils import py3compat
12 from IPython.utils import py3compat
13 from IPython.utils.py3compat import unicode_type
13 from IPython.utils.py3compat import unicode_type
14
14
15 ip = get_ipython()
15 ip = get_ipython()
16
16
17
17
18 class PromptTests(unittest.TestCase):
18 class PromptTests(unittest.TestCase):
19 def setUp(self):
19 def setUp(self):
20 self.pm = PromptManager(shell=ip, config=ip.config)
20 self.pm = PromptManager(shell=ip, config=ip.config)
21
21
22 def test_multiline_prompt(self):
22 def test_multiline_prompt(self):
23 self.pm.in_template = "[In]\n>>>"
23 self.pm.in_template = "[In]\n>>>"
24 self.pm.render('in')
24 self.pm.render('in')
25 self.assertEqual(self.pm.width, 3)
25 self.assertEqual(self.pm.width, 3)
26 self.assertEqual(self.pm.txtwidth, 3)
26 self.assertEqual(self.pm.txtwidth, 3)
27
27
28 self.pm.in_template = '[In]\n'
28 self.pm.in_template = '[In]\n'
29 self.pm.render('in')
29 self.pm.render('in')
30 self.assertEqual(self.pm.width, 0)
30 self.assertEqual(self.pm.width, 0)
31 self.assertEqual(self.pm.txtwidth, 0)
31 self.assertEqual(self.pm.txtwidth, 0)
32
32
33 def test_translate_abbreviations(self):
33 def test_translate_abbreviations(self):
34 def do_translate(template):
34 def do_translate(template):
35 self.pm.in_template = template
35 self.pm.in_template = template
36 return self.pm.templates['in']
36 return self.pm.templates['in']
37
37
38 pairs = [(r'%n>', '{color.number}{count}{color.prompt}>'),
38 pairs = [(r'%n>', '{color.number}{count}{color.prompt}>'),
39 (r'\T', '{time}'),
39 (r'\T', '{time}'),
40 (r'\n', '\n')
40 (r'\n', '\n')
41 ]
41 ]
42
42
43 tt.check_pairs(do_translate, pairs)
43 tt.check_pairs(do_translate, pairs)
44
44
45 def test_user_ns(self):
45 def test_user_ns(self):
46 self.pm.color_scheme = 'NoColor'
46 self.pm.color_scheme = 'NoColor'
47 ip.ex("foo='bar'")
47 ip.ex("foo='bar'")
48 self.pm.in_template = "In [{foo}]"
48 self.pm.in_template = "In [{foo}]"
49 prompt = self.pm.render('in')
49 prompt = self.pm.render('in')
50 self.assertEqual(prompt, u'In [bar]')
50 self.assertEqual(prompt, u'In [bar]')
51
51
52 def test_builtins(self):
52 def test_builtins(self):
53 self.pm.color_scheme = 'NoColor'
53 self.pm.color_scheme = 'NoColor'
54 self.pm.in_template = "In [{int}]"
54 self.pm.in_template = "In [{int}]"
55 prompt = self.pm.render('in')
55 prompt = self.pm.render('in')
56 self.assertEqual(prompt, u"In [%r]" % int)
56 self.assertEqual(prompt, u"In [%r]" % int)
57
57
58 def test_undefined(self):
58 def test_undefined(self):
59 self.pm.color_scheme = 'NoColor'
59 self.pm.color_scheme = 'NoColor'
60 self.pm.in_template = "In [{foo_dne}]"
60 self.pm.in_template = "In [{foo_dne}]"
61 prompt = self.pm.render('in')
61 prompt = self.pm.render('in')
62 self.assertEqual(prompt, u"In [<ERROR: 'foo_dne' not found>]")
62 self.assertEqual(prompt, u"In [<ERROR: 'foo_dne' not found>]")
63
63
64 def test_render(self):
64 def test_render(self):
65 self.pm.in_template = r'\#>'
65 self.pm.in_template = r'\#>'
66 self.assertEqual(self.pm.render('in',color=False), '%d>' % ip.execution_count)
66 self.assertEqual(self.pm.render('in',color=False), '%d>' % ip.execution_count)
67
67
68 @dec.onlyif_unicode_paths
68 @dec.onlyif_unicode_paths
69 def test_render_unicode_cwd(self):
69 def test_render_unicode_cwd(self):
70 save = py3compat.getcwd()
70 with TemporaryWorkingDirectory(u'ΓΌnicΓΈdΓ©'):
71 with TemporaryDirectory(u'ΓΌnicΓΈdΓ©') as td:
72 os.chdir(td)
73 self.pm.in_template = r'\w [\#]'
71 self.pm.in_template = r'\w [\#]'
74 p = self.pm.render('in', color=False)
72 p = self.pm.render('in', color=False)
75 self.assertEqual(p, u"%s [%i]" % (py3compat.getcwd(), ip.execution_count))
73 self.assertEqual(p, u"%s [%i]" % (py3compat.getcwd(), ip.execution_count))
76 os.chdir(save)
77
74
78 def test_lazy_eval_unicode(self):
75 def test_lazy_eval_unicode(self):
79 u = u'ΓΌnicΓΈdΓ©'
76 u = u'ΓΌnicΓΈdΓ©'
80 lz = LazyEvaluate(lambda : u)
77 lz = LazyEvaluate(lambda : u)
81 # str(lz) would fail
78 # str(lz) would fail
82 self.assertEqual(unicode_type(lz), u)
79 self.assertEqual(unicode_type(lz), u)
83 self.assertEqual(format(lz), u)
80 self.assertEqual(format(lz), u)
84
81
85 def test_lazy_eval_nonascii_bytes(self):
82 def test_lazy_eval_nonascii_bytes(self):
86 u = u'ΓΌnicΓΈdΓ©'
83 u = u'ΓΌnicΓΈdΓ©'
87 b = u.encode('utf8')
84 b = u.encode('utf8')
88 lz = LazyEvaluate(lambda : b)
85 lz = LazyEvaluate(lambda : b)
89 # unicode(lz) would fail
86 # unicode(lz) would fail
90 self.assertEqual(str(lz), str(b))
87 self.assertEqual(str(lz), str(b))
91 self.assertEqual(format(lz), str(b))
88 self.assertEqual(format(lz), str(b))
92
89
93 def test_lazy_eval_float(self):
90 def test_lazy_eval_float(self):
94 f = 0.503
91 f = 0.503
95 lz = LazyEvaluate(lambda : f)
92 lz = LazyEvaluate(lambda : f)
96
93
97 self.assertEqual(str(lz), str(f))
94 self.assertEqual(str(lz), str(f))
98 self.assertEqual(unicode_type(lz), unicode_type(f))
95 self.assertEqual(unicode_type(lz), unicode_type(f))
99 self.assertEqual(format(lz), str(f))
96 self.assertEqual(format(lz), str(f))
100 self.assertEqual(format(lz, '.1'), '0.5')
97 self.assertEqual(format(lz, '.1'), '0.5')
101
98
102 @dec.skip_win32
99 @dec.skip_win32
103 def test_cwd_x(self):
100 def test_cwd_x(self):
104 self.pm.in_template = r"\X0"
101 self.pm.in_template = r"\X0"
105 save = py3compat.getcwd()
102 save = py3compat.getcwd()
106 os.chdir(os.path.expanduser('~'))
103 os.chdir(os.path.expanduser('~'))
107 p = self.pm.render('in', color=False)
104 p = self.pm.render('in', color=False)
108 try:
105 try:
109 self.assertEqual(p, '~')
106 self.assertEqual(p, '~')
110 finally:
107 finally:
111 os.chdir(save)
108 os.chdir(save)
112
109
General Comments 0
You need to be logged in to leave comments. Login now