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