##// END OF EJS Templates
test function kw completer
Piti Ongmongkolkul -
Show More
@@ -1,268 +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 def test_custom_completion_error():
89 def test_custom_completion_error():
89 """Test that errors from custom attribute completers are silenced."""
90 """Test that errors from custom attribute completers are silenced."""
90 ip = get_ipython()
91 ip = get_ipython()
91 class A(object): pass
92 class A(object): pass
92 ip.user_ns['a'] = A()
93 ip.user_ns['a'] = A()
93
94
94 @complete_object.when_type(A)
95 @complete_object.when_type(A)
95 def complete_A(a, existing_completions):
96 def complete_A(a, existing_completions):
96 raise TypeError("this should be silenced")
97 raise TypeError("this should be silenced")
97
98
98 ip.complete("a.")
99 ip.complete("a.")
99
100
100
101
101 def test_unicode_completions():
102 def test_unicode_completions():
102 ip = get_ipython()
103 ip = get_ipython()
103 # Some strings that trigger different types of completion. Check them both
104 # Some strings that trigger different types of completion. Check them both
104 # in str and unicode forms
105 # in str and unicode forms
105 s = ['ru', '%ru', 'cd /', 'floa', 'float(x)/']
106 s = ['ru', '%ru', 'cd /', 'floa', 'float(x)/']
106 for t in s + map(unicode, s):
107 for t in s + map(unicode, s):
107 # 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
108 # 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
109 # 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
110 # values.
111 # values.
111 text, matches = ip.complete(t)
112 text, matches = ip.complete(t)
112 nt.assert_true(isinstance(text, basestring))
113 nt.assert_true(isinstance(text, basestring))
113 nt.assert_true(isinstance(matches, list))
114 nt.assert_true(isinstance(matches, list))
114
115
115
116
116 class CompletionSplitterTestCase(unittest.TestCase):
117 class CompletionSplitterTestCase(unittest.TestCase):
117 def setUp(self):
118 def setUp(self):
118 self.sp = completer.CompletionSplitter()
119 self.sp = completer.CompletionSplitter()
119
120
120 def test_delim_setting(self):
121 def test_delim_setting(self):
121 self.sp.set_delims(' ')
122 self.sp.set_delims(' ')
122 nt.assert_equal(self.sp.get_delims(), ' ')
123 nt.assert_equal(self.sp.get_delims(), ' ')
123 nt.assert_equal(self.sp._delim_expr, '[\ ]')
124 nt.assert_equal(self.sp._delim_expr, '[\ ]')
124
125
125 def test_spaces(self):
126 def test_spaces(self):
126 """Test with only spaces as split chars."""
127 """Test with only spaces as split chars."""
127 self.sp.delims = ' '
128 self.sp.delims = ' '
128 t = [('foo', '', 'foo'),
129 t = [('foo', '', 'foo'),
129 ('run foo', '', 'foo'),
130 ('run foo', '', 'foo'),
130 ('run foo', 'bar', 'foo'),
131 ('run foo', 'bar', 'foo'),
131 ]
132 ]
132 check_line_split(self.sp, t)
133 check_line_split(self.sp, t)
133
134
134
135
135 def test_has_open_quotes1():
136 def test_has_open_quotes1():
136 for s in ["'", "'''", "'hi' '"]:
137 for s in ["'", "'''", "'hi' '"]:
137 nt.assert_equal(completer.has_open_quotes(s), "'")
138 nt.assert_equal(completer.has_open_quotes(s), "'")
138
139
139
140
140 def test_has_open_quotes2():
141 def test_has_open_quotes2():
141 for s in ['"', '"""', '"hi" "']:
142 for s in ['"', '"""', '"hi" "']:
142 nt.assert_equal(completer.has_open_quotes(s), '"')
143 nt.assert_equal(completer.has_open_quotes(s), '"')
143
144
144
145
145 def test_has_open_quotes3():
146 def test_has_open_quotes3():
146 for s in ["''", "''' '''", "'hi' 'ipython'"]:
147 for s in ["''", "''' '''", "'hi' 'ipython'"]:
147 nt.assert_false(completer.has_open_quotes(s))
148 nt.assert_false(completer.has_open_quotes(s))
148
149
149
150
150 def test_has_open_quotes4():
151 def test_has_open_quotes4():
151 for s in ['""', '""" """', '"hi" "ipython"']:
152 for s in ['""', '""" """', '"hi" "ipython"']:
152 nt.assert_false(completer.has_open_quotes(s))
153 nt.assert_false(completer.has_open_quotes(s))
153
154
155
154 @knownfailureif(sys.platform == 'win32', "abspath completions fail on Windows")
156 @knownfailureif(sys.platform == 'win32', "abspath completions fail on Windows")
155 def test_abspath_file_completions():
157 def test_abspath_file_completions():
156 ip = get_ipython()
158 ip = get_ipython()
157 with TemporaryDirectory() as tmpdir:
159 with TemporaryDirectory() as tmpdir:
158 prefix = os.path.join(tmpdir, 'foo')
160 prefix = os.path.join(tmpdir, 'foo')
159 suffixes = map(str, [1,2])
161 suffixes = map(str, [1,2])
160 names = [prefix+s for s in suffixes]
162 names = [prefix+s for s in suffixes]
161 for n in names:
163 for n in names:
162 open(n, 'w').close()
164 open(n, 'w').close()
163
165
164 # Check simple completion
166 # Check simple completion
165 c = ip.complete(prefix)[1]
167 c = ip.complete(prefix)[1]
166 nt.assert_equal(c, names)
168 nt.assert_equal(c, names)
167
169
168 # Now check with a function call
170 # Now check with a function call
169 cmd = 'a = f("%s' % prefix
171 cmd = 'a = f("%s' % prefix
170 c = ip.complete(prefix, cmd)[1]
172 c = ip.complete(prefix, cmd)[1]
171 comp = [prefix+s for s in suffixes]
173 comp = [prefix+s for s in suffixes]
172 nt.assert_equal(c, comp)
174 nt.assert_equal(c, comp)
173
175
176
174 def test_local_file_completions():
177 def test_local_file_completions():
175 ip = get_ipython()
178 ip = get_ipython()
176 cwd = os.getcwdu()
179 cwd = os.getcwdu()
177 try:
180 try:
178 with TemporaryDirectory() as tmpdir:
181 with TemporaryDirectory() as tmpdir:
179 os.chdir(tmpdir)
182 os.chdir(tmpdir)
180 prefix = './foo'
183 prefix = './foo'
181 suffixes = map(str, [1,2])
184 suffixes = map(str, [1,2])
182 names = [prefix+s for s in suffixes]
185 names = [prefix+s for s in suffixes]
183 for n in names:
186 for n in names:
184 open(n, 'w').close()
187 open(n, 'w').close()
185
188
186 # Check simple completion
189 # Check simple completion
187 c = ip.complete(prefix)[1]
190 c = ip.complete(prefix)[1]
188 nt.assert_equal(c, names)
191 nt.assert_equal(c, names)
189
192
190 # Now check with a function call
193 # Now check with a function call
191 cmd = 'a = f("%s' % prefix
194 cmd = 'a = f("%s' % prefix
192 c = ip.complete(prefix, cmd)[1]
195 c = ip.complete(prefix, cmd)[1]
193 comp = [prefix+s for s in suffixes]
196 comp = [prefix+s for s in suffixes]
194 nt.assert_equal(c, comp)
197 nt.assert_equal(c, comp)
195 finally:
198 finally:
196 # prevent failures from making chdir stick
199 # prevent failures from making chdir stick
197 os.chdir(cwd)
200 os.chdir(cwd)
198
201
202
199 def test_greedy_completions():
203 def test_greedy_completions():
200 ip = get_ipython()
204 ip = get_ipython()
201 ip.Completer.greedy = False
205 ip.Completer.greedy = False
202 ip.ex('a=range(5)')
206 ip.ex('a=range(5)')
203 _,c = ip.complete('.',line='a[0].')
207 _,c = ip.complete('.',line='a[0].')
204 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)
205 ip.Completer.greedy = True
209 ip.Completer.greedy = True
206 _,c = ip.complete('.',line='a[0].')
210 _,c = ip.complete('.',line='a[0].')
207 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)
208
212
213
209 def test_omit__names():
214 def test_omit__names():
210 # also happens to test IPCompleter as a configurable
215 # also happens to test IPCompleter as a configurable
211 ip = get_ipython()
216 ip = get_ipython()
212 ip._hidden_attr = 1
217 ip._hidden_attr = 1
213 c = ip.Completer
218 c = ip.Completer
214 ip.ex('ip=get_ipython()')
219 ip.ex('ip=get_ipython()')
215 cfg = Config()
220 cfg = Config()
216 cfg.IPCompleter.omit__names = 0
221 cfg.IPCompleter.omit__names = 0
217 c.update_config(cfg)
222 c.update_config(cfg)
218 s,matches = c.complete('ip.')
223 s,matches = c.complete('ip.')
219 nt.assert_true('ip.__str__' in matches)
224 nt.assert_true('ip.__str__' in matches)
220 nt.assert_true('ip._hidden_attr' in matches)
225 nt.assert_true('ip._hidden_attr' in matches)
221 cfg.IPCompleter.omit__names = 1
226 cfg.IPCompleter.omit__names = 1
222 c.update_config(cfg)
227 c.update_config(cfg)
223 s,matches = c.complete('ip.')
228 s,matches = c.complete('ip.')
224 nt.assert_false('ip.__str__' in matches)
229 nt.assert_false('ip.__str__' in matches)
225 nt.assert_true('ip._hidden_attr' in matches)
230 nt.assert_true('ip._hidden_attr' in matches)
226 cfg.IPCompleter.omit__names = 2
231 cfg.IPCompleter.omit__names = 2
227 c.update_config(cfg)
232 c.update_config(cfg)
228 s,matches = c.complete('ip.')
233 s,matches = c.complete('ip.')
229 nt.assert_false('ip.__str__' in matches)
234 nt.assert_false('ip.__str__' in matches)
230 nt.assert_false('ip._hidden_attr' in matches)
235 nt.assert_false('ip._hidden_attr' in matches)
231 del ip._hidden_attr
236 del ip._hidden_attr
232
237
233
238
234 def test_limit_to__all__False_ok():
239 def test_limit_to__all__False_ok():
235 ip = get_ipython()
240 ip = get_ipython()
236 c = ip.Completer
241 c = ip.Completer
237 ip.ex('class D: x=24')
242 ip.ex('class D: x=24')
238 ip.ex('d=D()')
243 ip.ex('d=D()')
239 cfg = Config()
244 cfg = Config()
240 cfg.IPCompleter.limit_to__all__ = False
245 cfg.IPCompleter.limit_to__all__ = False
241 c.update_config(cfg)
246 c.update_config(cfg)
242 s, matches = c.complete('d.')
247 s, matches = c.complete('d.')
243 nt.assert_true('d.x' in matches)
248 nt.assert_true('d.x' in matches)
244
249
250
245 def test_limit_to__all__True_ok():
251 def test_limit_to__all__True_ok():
246 ip = get_ipython()
252 ip = get_ipython()
247 c = ip.Completer
253 c = ip.Completer
248 ip.ex('class D: x=24')
254 ip.ex('class D: x=24')
249 ip.ex('d=D()')
255 ip.ex('d=D()')
250 ip.ex("d.__all__=['z']")
256 ip.ex("d.__all__=['z']")
251 cfg = Config()
257 cfg = Config()
252 cfg.IPCompleter.limit_to__all__ = True
258 cfg.IPCompleter.limit_to__all__ = True
253 c.update_config(cfg)
259 c.update_config(cfg)
254 s, matches = c.complete('d.')
260 s, matches = c.complete('d.')
255 nt.assert_true('d.z' in matches)
261 nt.assert_true('d.z' in matches)
256 nt.assert_false('d.x' in matches)
262 nt.assert_false('d.x' in matches)
257
263
264
258 def test_get__all__entries_ok():
265 def test_get__all__entries_ok():
259 class A(object):
266 class A(object):
260 __all__ = ['x', 1]
267 __all__ = ['x', 1]
261 words = completer.get__all__entries(A())
268 words = completer.get__all__entries(A())
262 nt.assert_equal(words, ['x'])
269 nt.assert_equal(words, ['x'])
270
263
271
264 def test_get__all__entries_no__all__ok():
272 def test_get__all__entries_no__all__ok():
265 class A(object):
273 class A(object):
266 pass
274 pass
267 words = completer.get__all__entries(A())
275 words = completer.get__all__entries(A())
268 nt.assert_equal(words, [])
276 nt.assert_equal(words, [])
277
278
279 def test_func_kw_completions():
280 ip = get_ipython()
281 c = ip.Completer
282 ip.ex('def myfunc(a=1,b=2): return a+b')
283 s, matches = c.complete(None,'myfunc(1,b')
284 nt.assert_true('b=' in matches)
285 s, matches = c.complete(None,'myfunc(1,b)',10)
286 nt.assert_true('b=' in matches)
General Comments 0
You need to be logged in to leave comments. Login now