##// END OF EJS Templates
Reimplemented test_magic_completion_order in test_completer.py
David P. Sanders -
Show More
@@ -1,364 +1,392 b''
1 1 """Tests for the IPython tab-completion machinery.
2 2 """
3 3 #-----------------------------------------------------------------------------
4 4 # Module imports
5 5 #-----------------------------------------------------------------------------
6 6
7 7 # stdlib
8 8 import os
9 9 import sys
10 10 import unittest
11 11
12 12 # third party
13 13 import nose.tools as nt
14 14
15 15 # our own packages
16 16 from IPython.config.loader import Config
17 17 from IPython.core import completer
18 18 from IPython.external.decorators import knownfailureif
19 19 from IPython.utils.tempdir import TemporaryDirectory
20 20 from IPython.utils.generics import complete_object
21 21
22 22 #-----------------------------------------------------------------------------
23 23 # Test functions
24 24 #-----------------------------------------------------------------------------
25 25 def test_protect_filename():
26 26 pairs = [ ('abc','abc'),
27 27 (' abc',r'\ abc'),
28 28 ('a bc',r'a\ bc'),
29 29 ('a bc',r'a\ \ bc'),
30 30 (' bc',r'\ \ bc'),
31 31 ]
32 32 # On posix, we also protect parens and other special characters
33 33 if sys.platform != 'win32':
34 34 pairs.extend( [('a(bc',r'a\(bc'),
35 35 ('a)bc',r'a\)bc'),
36 36 ('a( )bc',r'a\(\ \)bc'),
37 37 ('a[1]bc', r'a\[1\]bc'),
38 38 ('a{1}bc', r'a\{1\}bc'),
39 39 ('a#bc', r'a\#bc'),
40 40 ('a?bc', r'a\?bc'),
41 41 ('a=bc', r'a\=bc'),
42 42 ('a\\bc', r'a\\bc'),
43 43 ('a|bc', r'a\|bc'),
44 44 ('a;bc', r'a\;bc'),
45 45 ('a:bc', r'a\:bc'),
46 46 ("a'bc", r"a\'bc"),
47 47 ('a*bc', r'a\*bc'),
48 48 ('a"bc', r'a\"bc'),
49 49 ('a^bc', r'a\^bc'),
50 50 ('a&bc', r'a\&bc'),
51 51 ] )
52 52 # run the actual tests
53 53 for s1, s2 in pairs:
54 54 s1p = completer.protect_filename(s1)
55 55 nt.assert_equal(s1p, s2)
56 56
57 57
58 58 def check_line_split(splitter, test_specs):
59 59 for part1, part2, split in test_specs:
60 60 cursor_pos = len(part1)
61 61 line = part1+part2
62 62 out = splitter.split_line(line, cursor_pos)
63 63 nt.assert_equal(out, split)
64 64
65 65
66 66 def test_line_split():
67 67 """Basice line splitter test with default specs."""
68 68 sp = completer.CompletionSplitter()
69 69 # The format of the test specs is: part1, part2, expected answer. Parts 1
70 70 # and 2 are joined into the 'line' sent to the splitter, as if the cursor
71 71 # was at the end of part1. So an empty part2 represents someone hitting
72 72 # tab at the end of the line, the most common case.
73 73 t = [('run some/scrip', '', 'some/scrip'),
74 74 ('run scripts/er', 'ror.py foo', 'scripts/er'),
75 75 ('echo $HOM', '', 'HOM'),
76 76 ('print sys.pa', '', 'sys.pa'),
77 77 ('print(sys.pa', '', 'sys.pa'),
78 78 ("execfile('scripts/er", '', 'scripts/er'),
79 79 ('a[x.', '', 'x.'),
80 80 ('a[x.', 'y', 'x.'),
81 81 ('cd "some_file/', '', 'some_file/'),
82 82 ]
83 83 check_line_split(sp, t)
84 84 # Ensure splitting works OK with unicode by re-running the tests with
85 85 # all inputs turned into unicode
86 86 check_line_split(sp, [ map(unicode, p) for p in t] )
87 87
88 88
89 89 def test_custom_completion_error():
90 90 """Test that errors from custom attribute completers are silenced."""
91 91 ip = get_ipython()
92 92 class A(object): pass
93 93 ip.user_ns['a'] = A()
94 94
95 95 @complete_object.when_type(A)
96 96 def complete_A(a, existing_completions):
97 97 raise TypeError("this should be silenced")
98 98
99 99 ip.complete("a.")
100 100
101 101
102 102 def test_unicode_completions():
103 103 ip = get_ipython()
104 104 # Some strings that trigger different types of completion. Check them both
105 105 # in str and unicode forms
106 106 s = ['ru', '%ru', 'cd /', 'floa', 'float(x)/']
107 107 for t in s + map(unicode, s):
108 108 # We don't need to check exact completion values (they may change
109 109 # depending on the state of the namespace, but at least no exceptions
110 110 # should be thrown and the return value should be a pair of text, list
111 111 # values.
112 112 text, matches = ip.complete(t)
113 113 nt.assert_true(isinstance(text, basestring))
114 114 nt.assert_true(isinstance(matches, list))
115 115
116 116
117 117 class CompletionSplitterTestCase(unittest.TestCase):
118 118 def setUp(self):
119 119 self.sp = completer.CompletionSplitter()
120 120
121 121 def test_delim_setting(self):
122 122 self.sp.delims = ' '
123 123 nt.assert_equal(self.sp.delims, ' ')
124 124 nt.assert_equal(self.sp._delim_expr, '[\ ]')
125 125
126 126 def test_spaces(self):
127 127 """Test with only spaces as split chars."""
128 128 self.sp.delims = ' '
129 129 t = [('foo', '', 'foo'),
130 130 ('run foo', '', 'foo'),
131 131 ('run foo', 'bar', 'foo'),
132 132 ]
133 133 check_line_split(self.sp, t)
134 134
135 135
136 136 def test_has_open_quotes1():
137 137 for s in ["'", "'''", "'hi' '"]:
138 138 nt.assert_equal(completer.has_open_quotes(s), "'")
139 139
140 140
141 141 def test_has_open_quotes2():
142 142 for s in ['"', '"""', '"hi" "']:
143 143 nt.assert_equal(completer.has_open_quotes(s), '"')
144 144
145 145
146 146 def test_has_open_quotes3():
147 147 for s in ["''", "''' '''", "'hi' 'ipython'"]:
148 148 nt.assert_false(completer.has_open_quotes(s))
149 149
150 150
151 151 def test_has_open_quotes4():
152 152 for s in ['""', '""" """', '"hi" "ipython"']:
153 153 nt.assert_false(completer.has_open_quotes(s))
154 154
155 155
156 156 @knownfailureif(sys.platform == 'win32', "abspath completions fail on Windows")
157 157 def test_abspath_file_completions():
158 158 ip = get_ipython()
159 159 with TemporaryDirectory() as tmpdir:
160 160 prefix = os.path.join(tmpdir, 'foo')
161 161 suffixes = map(str, [1,2])
162 162 names = [prefix+s for s in suffixes]
163 163 for n in names:
164 164 open(n, 'w').close()
165 165
166 166 # Check simple completion
167 167 c = ip.complete(prefix)[1]
168 168 nt.assert_equal(c, names)
169 169
170 170 # Now check with a function call
171 171 cmd = 'a = f("%s' % prefix
172 172 c = ip.complete(prefix, cmd)[1]
173 173 comp = [prefix+s for s in suffixes]
174 174 nt.assert_equal(c, comp)
175 175
176 176
177 177 def test_local_file_completions():
178 178 ip = get_ipython()
179 179 cwd = os.getcwdu()
180 180 try:
181 181 with TemporaryDirectory() as tmpdir:
182 182 os.chdir(tmpdir)
183 183 prefix = './foo'
184 184 suffixes = map(str, [1,2])
185 185 names = [prefix+s for s in suffixes]
186 186 for n in names:
187 187 open(n, 'w').close()
188 188
189 189 # Check simple completion
190 190 c = ip.complete(prefix)[1]
191 191 nt.assert_equal(c, names)
192 192
193 193 # Now check with a function call
194 194 cmd = 'a = f("%s' % prefix
195 195 c = ip.complete(prefix, cmd)[1]
196 196 comp = [prefix+s for s in suffixes]
197 197 nt.assert_equal(c, comp)
198 198 finally:
199 199 # prevent failures from making chdir stick
200 200 os.chdir(cwd)
201 201
202 202
203 203 def test_greedy_completions():
204 204 ip = get_ipython()
205 205 greedy_original = ip.Completer.greedy
206 206 try:
207 207 ip.Completer.greedy = False
208 208 ip.ex('a=range(5)')
209 209 _,c = ip.complete('.',line='a[0].')
210 210 nt.assert_false('a[0].real' in c,
211 211 "Shouldn't have completed on a[0]: %s"%c)
212 212 ip.Completer.greedy = True
213 213 _,c = ip.complete('.',line='a[0].')
214 214 nt.assert_true('a[0].real' in c, "Should have completed on a[0]: %s"%c)
215 215 finally:
216 216 ip.Completer.greedy = greedy_original
217 217
218 218
219 219 def test_omit__names():
220 220 # also happens to test IPCompleter as a configurable
221 221 ip = get_ipython()
222 222 ip._hidden_attr = 1
223 223 c = ip.Completer
224 224 ip.ex('ip=get_ipython()')
225 225 cfg = Config()
226 226 cfg.IPCompleter.omit__names = 0
227 227 c.update_config(cfg)
228 228 s,matches = c.complete('ip.')
229 229 nt.assert_true('ip.__str__' in matches)
230 230 nt.assert_true('ip._hidden_attr' in matches)
231 231 cfg.IPCompleter.omit__names = 1
232 232 c.update_config(cfg)
233 233 s,matches = c.complete('ip.')
234 234 nt.assert_false('ip.__str__' in matches)
235 235 nt.assert_true('ip._hidden_attr' in matches)
236 236 cfg.IPCompleter.omit__names = 2
237 237 c.update_config(cfg)
238 238 s,matches = c.complete('ip.')
239 239 nt.assert_false('ip.__str__' in matches)
240 240 nt.assert_false('ip._hidden_attr' in matches)
241 241 del ip._hidden_attr
242 242
243 243
244 244 def test_limit_to__all__False_ok():
245 245 ip = get_ipython()
246 246 c = ip.Completer
247 247 ip.ex('class D: x=24')
248 248 ip.ex('d=D()')
249 249 cfg = Config()
250 250 cfg.IPCompleter.limit_to__all__ = False
251 251 c.update_config(cfg)
252 252 s, matches = c.complete('d.')
253 253 nt.assert_true('d.x' in matches)
254 254
255 255
256 256 def test_limit_to__all__True_ok():
257 257 ip = get_ipython()
258 258 c = ip.Completer
259 259 ip.ex('class D: x=24')
260 260 ip.ex('d=D()')
261 261 ip.ex("d.__all__=['z']")
262 262 cfg = Config()
263 263 cfg.IPCompleter.limit_to__all__ = True
264 264 c.update_config(cfg)
265 265 s, matches = c.complete('d.')
266 266 nt.assert_true('d.z' in matches)
267 267 nt.assert_false('d.x' in matches)
268 268
269 269
270 270 def test_get__all__entries_ok():
271 271 class A(object):
272 272 __all__ = ['x', 1]
273 273 words = completer.get__all__entries(A())
274 274 nt.assert_equal(words, ['x'])
275 275
276 276
277 277 def test_get__all__entries_no__all__ok():
278 278 class A(object):
279 279 pass
280 280 words = completer.get__all__entries(A())
281 281 nt.assert_equal(words, [])
282 282
283 283
284 284 def test_func_kw_completions():
285 285 ip = get_ipython()
286 286 c = ip.Completer
287 287 ip.ex('def myfunc(a=1,b=2): return a+b')
288 288 s, matches = c.complete(None, 'myfunc(1,b')
289 289 nt.assert_in('b=', matches)
290 290 # Simulate completing with cursor right after b (pos==10):
291 291 s, matches = c.complete(None, 'myfunc(1,b)', 10)
292 292 nt.assert_in('b=', matches)
293 293 s, matches = c.complete(None, 'myfunc(a="escaped\\")string",b')
294 294 nt.assert_in('b=', matches)
295 295 #builtin function
296 296 s, matches = c.complete(None, 'min(k, k')
297 297 nt.assert_in('key=', matches)
298 298
299 299
300 300 def test_default_arguments_from_docstring():
301 301 doc = min.__doc__
302 302 ip = get_ipython()
303 303 c = ip.Completer
304 304 kwd = c._default_arguments_from_docstring(
305 305 'min(iterable[, key=func]) -> value')
306 306 nt.assert_equal(kwd, ['key'])
307 307 #with cython type etc
308 308 kwd = c._default_arguments_from_docstring(
309 309 'Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)\n')
310 310 nt.assert_equal(kwd, ['ncall', 'resume', 'nsplit'])
311 311 #white spaces
312 312 kwd = c._default_arguments_from_docstring(
313 313 '\n Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)\n')
314 314 nt.assert_equal(kwd, ['ncall', 'resume', 'nsplit'])
315 315
316 316 def test_line_magics():
317 317 ip = get_ipython()
318 318 c = ip.Completer
319 319 s, matches = c.complete(None, 'lsmag')
320 320 nt.assert_in('%lsmagic', matches)
321 321 s, matches = c.complete(None, '%lsmag')
322 322 nt.assert_in('%lsmagic', matches)
323 323
324 324
325 325 def test_cell_magics():
326 326 from IPython.core.magic import register_cell_magic
327 327
328 328 @register_cell_magic
329 329 def _foo_cellm(line, cell):
330 330 pass
331 331
332 332 ip = get_ipython()
333 333 c = ip.Completer
334 334
335 335 s, matches = c.complete(None, '_foo_ce')
336 336 nt.assert_in('%%_foo_cellm', matches)
337 337 s, matches = c.complete(None, '%%_foo_ce')
338 338 nt.assert_in('%%_foo_cellm', matches)
339 339
340 340
341 341 def test_line_cell_magics():
342 342 from IPython.core.magic import register_line_cell_magic
343 343
344 344 @register_line_cell_magic
345 345 def _bar_cellm(line, cell):
346 346 pass
347 347
348 348 ip = get_ipython()
349 349 c = ip.Completer
350 350
351 351 # The policy here is trickier, see comments in completion code. The
352 352 # returned values depend on whether the user passes %% or not explicitly,
353 353 # and this will show a difference if the same name is both a line and cell
354 354 # magic.
355 355 s, matches = c.complete(None, '_bar_ce')
356 356 nt.assert_in('%_bar_cellm', matches)
357 357 nt.assert_in('%%_bar_cellm', matches)
358 358 s, matches = c.complete(None, '%_bar_ce')
359 359 nt.assert_in('%_bar_cellm', matches)
360 360 nt.assert_in('%%_bar_cellm', matches)
361 361 s, matches = c.complete(None, '%%_bar_ce')
362 362 nt.assert_not_in('%_bar_cellm', matches)
363 363 nt.assert_in('%%_bar_cellm', matches)
364 364
365
366 def test_magic_completion_order():
367
368 ip = get_ipython()
369 c = ip.Completer
370
371 # Test ordering of magics and non-magics with the same name
372 # We want the non-magic first
373
374 # Before importing matplotlib, there should only be one option:
375
376 text, matches = c.complete('mat')
377 nt.assert_equal(matches, ["%matplotlib"])
378
379
380 ip.run_cell("matplotlib = 1") # introduce name into namespace
381
382 # After the import, there should be two options, ordered like this:
383 text, matches = c.complete('mat')
384 nt.assert_equal(matches, ["matplotlib", "%matplotlib"])
385
386
387 ip.run_cell("timeit = 1") # define a user variable called 'timeit'
388
389 # Order of user variable and line and cell magics with same name:
390 text, matches = c.complete('timeit')
391 nt.assert_equal(matches, ["timeit", "%timeit","%%timeit"])
392
General Comments 0
You need to be logged in to leave comments. Login now