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