##// END OF EJS Templates
add some comment
Piti Ongmongkolkul -
Show More
@@ -1,286 +1,286 b''
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_equals(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.set_delims(' ')
122 self.sp.set_delims(' ')
123 nt.assert_equal(self.sp.get_delims(), ' ')
123 nt.assert_equal(self.sp.get_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 ip.Completer.greedy = False
205 ip.Completer.greedy = False
206 ip.ex('a=range(5)')
206 ip.ex('a=range(5)')
207 _,c = ip.complete('.',line='a[0].')
207 _,c = ip.complete('.',line='a[0].')
208 nt.assert_false('a[0].real' in c, "Shouldn't have completed on a[0]: %s"%c)
208 nt.assert_false('a[0].real' in c, "Shouldn't have completed on a[0]: %s"%c)
209 ip.Completer.greedy = True
209 ip.Completer.greedy = True
210 _,c = ip.complete('.',line='a[0].')
210 _,c = ip.complete('.',line='a[0].')
211 nt.assert_true('a[0].real' in c, "Should have completed on a[0]: %s"%c)
211 nt.assert_true('a[0].real' in c, "Should have completed on a[0]: %s"%c)
212
212
213
213
214 def test_omit__names():
214 def test_omit__names():
215 # also happens to test IPCompleter as a configurable
215 # also happens to test IPCompleter as a configurable
216 ip = get_ipython()
216 ip = get_ipython()
217 ip._hidden_attr = 1
217 ip._hidden_attr = 1
218 c = ip.Completer
218 c = ip.Completer
219 ip.ex('ip=get_ipython()')
219 ip.ex('ip=get_ipython()')
220 cfg = Config()
220 cfg = Config()
221 cfg.IPCompleter.omit__names = 0
221 cfg.IPCompleter.omit__names = 0
222 c.update_config(cfg)
222 c.update_config(cfg)
223 s,matches = c.complete('ip.')
223 s,matches = c.complete('ip.')
224 nt.assert_true('ip.__str__' in matches)
224 nt.assert_true('ip.__str__' in matches)
225 nt.assert_true('ip._hidden_attr' in matches)
225 nt.assert_true('ip._hidden_attr' in matches)
226 cfg.IPCompleter.omit__names = 1
226 cfg.IPCompleter.omit__names = 1
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_false('ip.__str__' in matches)
229 nt.assert_false('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 = 2
231 cfg.IPCompleter.omit__names = 2
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_false('ip._hidden_attr' in matches)
235 nt.assert_false('ip._hidden_attr' in matches)
236 del ip._hidden_attr
236 del ip._hidden_attr
237
237
238
238
239 def test_limit_to__all__False_ok():
239 def test_limit_to__all__False_ok():
240 ip = get_ipython()
240 ip = get_ipython()
241 c = ip.Completer
241 c = ip.Completer
242 ip.ex('class D: x=24')
242 ip.ex('class D: x=24')
243 ip.ex('d=D()')
243 ip.ex('d=D()')
244 cfg = Config()
244 cfg = Config()
245 cfg.IPCompleter.limit_to__all__ = False
245 cfg.IPCompleter.limit_to__all__ = False
246 c.update_config(cfg)
246 c.update_config(cfg)
247 s, matches = c.complete('d.')
247 s, matches = c.complete('d.')
248 nt.assert_true('d.x' in matches)
248 nt.assert_true('d.x' in matches)
249
249
250
250
251 def test_limit_to__all__True_ok():
251 def test_limit_to__all__True_ok():
252 ip = get_ipython()
252 ip = get_ipython()
253 c = ip.Completer
253 c = ip.Completer
254 ip.ex('class D: x=24')
254 ip.ex('class D: x=24')
255 ip.ex('d=D()')
255 ip.ex('d=D()')
256 ip.ex("d.__all__=['z']")
256 ip.ex("d.__all__=['z']")
257 cfg = Config()
257 cfg = Config()
258 cfg.IPCompleter.limit_to__all__ = True
258 cfg.IPCompleter.limit_to__all__ = True
259 c.update_config(cfg)
259 c.update_config(cfg)
260 s, matches = c.complete('d.')
260 s, matches = c.complete('d.')
261 nt.assert_true('d.z' in matches)
261 nt.assert_true('d.z' in matches)
262 nt.assert_false('d.x' in matches)
262 nt.assert_false('d.x' in matches)
263
263
264
264
265 def test_get__all__entries_ok():
265 def test_get__all__entries_ok():
266 class A(object):
266 class A(object):
267 __all__ = ['x', 1]
267 __all__ = ['x', 1]
268 words = completer.get__all__entries(A())
268 words = completer.get__all__entries(A())
269 nt.assert_equal(words, ['x'])
269 nt.assert_equal(words, ['x'])
270
270
271
271
272 def test_get__all__entries_no__all__ok():
272 def test_get__all__entries_no__all__ok():
273 class A(object):
273 class A(object):
274 pass
274 pass
275 words = completer.get__all__entries(A())
275 words = completer.get__all__entries(A())
276 nt.assert_equal(words, [])
276 nt.assert_equal(words, [])
277
277
278
278
279 def test_func_kw_completions():
279 def test_func_kw_completions():
280 ip = get_ipython()
280 ip = get_ipython()
281 c = ip.Completer
281 c = ip.Completer
282 ip.ex('def myfunc(a=1,b=2): return a+b')
282 ip.ex('def myfunc(a=1,b=2): return a+b')
283 s, matches = c.complete(None,'myfunc(1,b')
283 s, matches = c.complete(None,'myfunc(1,b')
284 nt.assert_true('b=' in matches)
284 nt.assert_true('b=' in matches)
285 s, matches = c.complete(None,'myfunc(1,b)',10)
285 s, matches = c.complete(None,'myfunc(1,b)',10)#cursor is right after b
286 nt.assert_true('b=' in matches)
286 nt.assert_true('b=' in matches)
General Comments 0
You need to be logged in to leave comments. Login now