##// END OF EJS Templates
Add test for no matching shortcut for modification
krassowski -
Show More
@@ -1,450 +1,461
1 import pytest
1 import pytest
2 from IPython.terminal.shortcuts.auto_suggest import (
2 from IPython.terminal.shortcuts.auto_suggest import (
3 accept,
3 accept,
4 accept_in_vi_insert_mode,
4 accept_in_vi_insert_mode,
5 accept_token,
5 accept_token,
6 accept_character,
6 accept_character,
7 accept_word,
7 accept_word,
8 accept_and_keep_cursor,
8 accept_and_keep_cursor,
9 discard,
9 discard,
10 NavigableAutoSuggestFromHistory,
10 NavigableAutoSuggestFromHistory,
11 swap_autosuggestion_up,
11 swap_autosuggestion_up,
12 swap_autosuggestion_down,
12 swap_autosuggestion_down,
13 )
13 )
14 from IPython.terminal.shortcuts.auto_match import skip_over
14 from IPython.terminal.shortcuts.auto_match import skip_over
15 from IPython.terminal.shortcuts import create_ipython_shortcuts
15 from IPython.terminal.shortcuts import create_ipython_shortcuts
16
16
17 from prompt_toolkit.history import InMemoryHistory
17 from prompt_toolkit.history import InMemoryHistory
18 from prompt_toolkit.buffer import Buffer
18 from prompt_toolkit.buffer import Buffer
19 from prompt_toolkit.document import Document
19 from prompt_toolkit.document import Document
20 from prompt_toolkit.auto_suggest import AutoSuggestFromHistory
20 from prompt_toolkit.auto_suggest import AutoSuggestFromHistory
21
21
22 from unittest.mock import patch, Mock
22 from unittest.mock import patch, Mock
23
23
24
24
25 def make_event(text, cursor, suggestion):
25 def make_event(text, cursor, suggestion):
26 event = Mock()
26 event = Mock()
27 event.current_buffer = Mock()
27 event.current_buffer = Mock()
28 event.current_buffer.suggestion = Mock()
28 event.current_buffer.suggestion = Mock()
29 event.current_buffer.text = text
29 event.current_buffer.text = text
30 event.current_buffer.cursor_position = cursor
30 event.current_buffer.cursor_position = cursor
31 event.current_buffer.suggestion.text = suggestion
31 event.current_buffer.suggestion.text = suggestion
32 event.current_buffer.document = Document(text=text, cursor_position=cursor)
32 event.current_buffer.document = Document(text=text, cursor_position=cursor)
33 return event
33 return event
34
34
35
35
36 @pytest.mark.parametrize(
36 @pytest.mark.parametrize(
37 "text, suggestion, expected",
37 "text, suggestion, expected",
38 [
38 [
39 ("", "def out(tag: str, n=50):", "def out(tag: str, n=50):"),
39 ("", "def out(tag: str, n=50):", "def out(tag: str, n=50):"),
40 ("def ", "out(tag: str, n=50):", "out(tag: str, n=50):"),
40 ("def ", "out(tag: str, n=50):", "out(tag: str, n=50):"),
41 ],
41 ],
42 )
42 )
43 def test_accept(text, suggestion, expected):
43 def test_accept(text, suggestion, expected):
44 event = make_event(text, len(text), suggestion)
44 event = make_event(text, len(text), suggestion)
45 buffer = event.current_buffer
45 buffer = event.current_buffer
46 buffer.insert_text = Mock()
46 buffer.insert_text = Mock()
47 accept(event)
47 accept(event)
48 assert buffer.insert_text.called
48 assert buffer.insert_text.called
49 assert buffer.insert_text.call_args[0] == (expected,)
49 assert buffer.insert_text.call_args[0] == (expected,)
50
50
51
51
52 @pytest.mark.parametrize(
52 @pytest.mark.parametrize(
53 "text, suggestion",
53 "text, suggestion",
54 [
54 [
55 ("", "def out(tag: str, n=50):"),
55 ("", "def out(tag: str, n=50):"),
56 ("def ", "out(tag: str, n=50):"),
56 ("def ", "out(tag: str, n=50):"),
57 ],
57 ],
58 )
58 )
59 def test_discard(text, suggestion):
59 def test_discard(text, suggestion):
60 event = make_event(text, len(text), suggestion)
60 event = make_event(text, len(text), suggestion)
61 buffer = event.current_buffer
61 buffer = event.current_buffer
62 buffer.insert_text = Mock()
62 buffer.insert_text = Mock()
63 discard(event)
63 discard(event)
64 assert not buffer.insert_text.called
64 assert not buffer.insert_text.called
65 assert buffer.suggestion is None
65 assert buffer.suggestion is None
66
66
67
67
68 @pytest.mark.parametrize(
68 @pytest.mark.parametrize(
69 "text, cursor, suggestion, called",
69 "text, cursor, suggestion, called",
70 [
70 [
71 ("123456", 6, "123456789", True),
71 ("123456", 6, "123456789", True),
72 ("123456", 3, "123456789", False),
72 ("123456", 3, "123456789", False),
73 ("123456 \n789", 6, "123456789", True),
73 ("123456 \n789", 6, "123456789", True),
74 ],
74 ],
75 )
75 )
76 def test_autosuggest_at_EOL(text, cursor, suggestion, called):
76 def test_autosuggest_at_EOL(text, cursor, suggestion, called):
77 """
77 """
78 test that autosuggest is only applied at end of line.
78 test that autosuggest is only applied at end of line.
79 """
79 """
80
80
81 event = make_event(text, cursor, suggestion)
81 event = make_event(text, cursor, suggestion)
82 event.current_buffer.insert_text = Mock()
82 event.current_buffer.insert_text = Mock()
83 accept_in_vi_insert_mode(event)
83 accept_in_vi_insert_mode(event)
84 if called:
84 if called:
85 event.current_buffer.insert_text.assert_called()
85 event.current_buffer.insert_text.assert_called()
86 else:
86 else:
87 event.current_buffer.insert_text.assert_not_called()
87 event.current_buffer.insert_text.assert_not_called()
88 # event.current_buffer.document.get_end_of_line_position.assert_called()
88 # event.current_buffer.document.get_end_of_line_position.assert_called()
89
89
90
90
91 @pytest.mark.parametrize(
91 @pytest.mark.parametrize(
92 "text, suggestion, expected",
92 "text, suggestion, expected",
93 [
93 [
94 ("", "def out(tag: str, n=50):", "def "),
94 ("", "def out(tag: str, n=50):", "def "),
95 ("d", "ef out(tag: str, n=50):", "ef "),
95 ("d", "ef out(tag: str, n=50):", "ef "),
96 ("de ", "f out(tag: str, n=50):", "f "),
96 ("de ", "f out(tag: str, n=50):", "f "),
97 ("def", " out(tag: str, n=50):", " "),
97 ("def", " out(tag: str, n=50):", " "),
98 ("def ", "out(tag: str, n=50):", "out("),
98 ("def ", "out(tag: str, n=50):", "out("),
99 ("def o", "ut(tag: str, n=50):", "ut("),
99 ("def o", "ut(tag: str, n=50):", "ut("),
100 ("def ou", "t(tag: str, n=50):", "t("),
100 ("def ou", "t(tag: str, n=50):", "t("),
101 ("def out", "(tag: str, n=50):", "("),
101 ("def out", "(tag: str, n=50):", "("),
102 ("def out(", "tag: str, n=50):", "tag: "),
102 ("def out(", "tag: str, n=50):", "tag: "),
103 ("def out(t", "ag: str, n=50):", "ag: "),
103 ("def out(t", "ag: str, n=50):", "ag: "),
104 ("def out(ta", "g: str, n=50):", "g: "),
104 ("def out(ta", "g: str, n=50):", "g: "),
105 ("def out(tag", ": str, n=50):", ": "),
105 ("def out(tag", ": str, n=50):", ": "),
106 ("def out(tag:", " str, n=50):", " "),
106 ("def out(tag:", " str, n=50):", " "),
107 ("def out(tag: ", "str, n=50):", "str, "),
107 ("def out(tag: ", "str, n=50):", "str, "),
108 ("def out(tag: s", "tr, n=50):", "tr, "),
108 ("def out(tag: s", "tr, n=50):", "tr, "),
109 ("def out(tag: st", "r, n=50):", "r, "),
109 ("def out(tag: st", "r, n=50):", "r, "),
110 ("def out(tag: str", ", n=50):", ", n"),
110 ("def out(tag: str", ", n=50):", ", n"),
111 ("def out(tag: str,", " n=50):", " n"),
111 ("def out(tag: str,", " n=50):", " n"),
112 ("def out(tag: str, ", "n=50):", "n="),
112 ("def out(tag: str, ", "n=50):", "n="),
113 ("def out(tag: str, n", "=50):", "="),
113 ("def out(tag: str, n", "=50):", "="),
114 ("def out(tag: str, n=", "50):", "50)"),
114 ("def out(tag: str, n=", "50):", "50)"),
115 ("def out(tag: str, n=5", "0):", "0)"),
115 ("def out(tag: str, n=5", "0):", "0)"),
116 ("def out(tag: str, n=50", "):", "):"),
116 ("def out(tag: str, n=50", "):", "):"),
117 ("def out(tag: str, n=50)", ":", ":"),
117 ("def out(tag: str, n=50)", ":", ":"),
118 ],
118 ],
119 )
119 )
120 def test_autosuggest_token(text, suggestion, expected):
120 def test_autosuggest_token(text, suggestion, expected):
121 event = make_event(text, len(text), suggestion)
121 event = make_event(text, len(text), suggestion)
122 event.current_buffer.insert_text = Mock()
122 event.current_buffer.insert_text = Mock()
123 accept_token(event)
123 accept_token(event)
124 assert event.current_buffer.insert_text.called
124 assert event.current_buffer.insert_text.called
125 assert event.current_buffer.insert_text.call_args[0] == (expected,)
125 assert event.current_buffer.insert_text.call_args[0] == (expected,)
126
126
127
127
128 @pytest.mark.parametrize(
128 @pytest.mark.parametrize(
129 "text, suggestion, expected",
129 "text, suggestion, expected",
130 [
130 [
131 ("", "def out(tag: str, n=50):", "d"),
131 ("", "def out(tag: str, n=50):", "d"),
132 ("d", "ef out(tag: str, n=50):", "e"),
132 ("d", "ef out(tag: str, n=50):", "e"),
133 ("de ", "f out(tag: str, n=50):", "f"),
133 ("de ", "f out(tag: str, n=50):", "f"),
134 ("def", " out(tag: str, n=50):", " "),
134 ("def", " out(tag: str, n=50):", " "),
135 ],
135 ],
136 )
136 )
137 def test_accept_character(text, suggestion, expected):
137 def test_accept_character(text, suggestion, expected):
138 event = make_event(text, len(text), suggestion)
138 event = make_event(text, len(text), suggestion)
139 event.current_buffer.insert_text = Mock()
139 event.current_buffer.insert_text = Mock()
140 accept_character(event)
140 accept_character(event)
141 assert event.current_buffer.insert_text.called
141 assert event.current_buffer.insert_text.called
142 assert event.current_buffer.insert_text.call_args[0] == (expected,)
142 assert event.current_buffer.insert_text.call_args[0] == (expected,)
143
143
144
144
145 @pytest.mark.parametrize(
145 @pytest.mark.parametrize(
146 "text, suggestion, expected",
146 "text, suggestion, expected",
147 [
147 [
148 ("", "def out(tag: str, n=50):", "def "),
148 ("", "def out(tag: str, n=50):", "def "),
149 ("d", "ef out(tag: str, n=50):", "ef "),
149 ("d", "ef out(tag: str, n=50):", "ef "),
150 ("de", "f out(tag: str, n=50):", "f "),
150 ("de", "f out(tag: str, n=50):", "f "),
151 ("def", " out(tag: str, n=50):", " "),
151 ("def", " out(tag: str, n=50):", " "),
152 # (this is why we also have accept_token)
152 # (this is why we also have accept_token)
153 ("def ", "out(tag: str, n=50):", "out(tag: "),
153 ("def ", "out(tag: str, n=50):", "out(tag: "),
154 ],
154 ],
155 )
155 )
156 def test_accept_word(text, suggestion, expected):
156 def test_accept_word(text, suggestion, expected):
157 event = make_event(text, len(text), suggestion)
157 event = make_event(text, len(text), suggestion)
158 event.current_buffer.insert_text = Mock()
158 event.current_buffer.insert_text = Mock()
159 accept_word(event)
159 accept_word(event)
160 assert event.current_buffer.insert_text.called
160 assert event.current_buffer.insert_text.called
161 assert event.current_buffer.insert_text.call_args[0] == (expected,)
161 assert event.current_buffer.insert_text.call_args[0] == (expected,)
162
162
163
163
164 @pytest.mark.parametrize(
164 @pytest.mark.parametrize(
165 "text, suggestion, expected, cursor",
165 "text, suggestion, expected, cursor",
166 [
166 [
167 ("", "def out(tag: str, n=50):", "def out(tag: str, n=50):", 0),
167 ("", "def out(tag: str, n=50):", "def out(tag: str, n=50):", 0),
168 ("def ", "out(tag: str, n=50):", "out(tag: str, n=50):", 4),
168 ("def ", "out(tag: str, n=50):", "out(tag: str, n=50):", 4),
169 ],
169 ],
170 )
170 )
171 def test_accept_and_keep_cursor(text, suggestion, expected, cursor):
171 def test_accept_and_keep_cursor(text, suggestion, expected, cursor):
172 event = make_event(text, cursor, suggestion)
172 event = make_event(text, cursor, suggestion)
173 buffer = event.current_buffer
173 buffer = event.current_buffer
174 buffer.insert_text = Mock()
174 buffer.insert_text = Mock()
175 accept_and_keep_cursor(event)
175 accept_and_keep_cursor(event)
176 assert buffer.insert_text.called
176 assert buffer.insert_text.called
177 assert buffer.insert_text.call_args[0] == (expected,)
177 assert buffer.insert_text.call_args[0] == (expected,)
178 assert buffer.cursor_position == cursor
178 assert buffer.cursor_position == cursor
179
179
180
180
181 def test_autosuggest_token_empty():
181 def test_autosuggest_token_empty():
182 full = "def out(tag: str, n=50):"
182 full = "def out(tag: str, n=50):"
183 event = make_event(full, len(full), "")
183 event = make_event(full, len(full), "")
184 event.current_buffer.insert_text = Mock()
184 event.current_buffer.insert_text = Mock()
185
185
186 with patch(
186 with patch(
187 "prompt_toolkit.key_binding.bindings.named_commands.forward_word"
187 "prompt_toolkit.key_binding.bindings.named_commands.forward_word"
188 ) as forward_word:
188 ) as forward_word:
189 accept_token(event)
189 accept_token(event)
190 assert not event.current_buffer.insert_text.called
190 assert not event.current_buffer.insert_text.called
191 assert forward_word.called
191 assert forward_word.called
192
192
193
193
194 def test_other_providers():
194 def test_other_providers():
195 """Ensure that swapping autosuggestions does not break with other providers"""
195 """Ensure that swapping autosuggestions does not break with other providers"""
196 provider = AutoSuggestFromHistory()
196 provider = AutoSuggestFromHistory()
197 ip = get_ipython()
197 ip = get_ipython()
198 ip.auto_suggest = provider
198 ip.auto_suggest = provider
199 event = Mock()
199 event = Mock()
200 event.current_buffer = Buffer()
200 event.current_buffer = Buffer()
201 assert swap_autosuggestion_up(event) is None
201 assert swap_autosuggestion_up(event) is None
202 assert swap_autosuggestion_down(event) is None
202 assert swap_autosuggestion_down(event) is None
203
203
204
204
205 async def test_navigable_provider():
205 async def test_navigable_provider():
206 provider = NavigableAutoSuggestFromHistory()
206 provider = NavigableAutoSuggestFromHistory()
207 history = InMemoryHistory(history_strings=["very_a", "very", "very_b", "very_c"])
207 history = InMemoryHistory(history_strings=["very_a", "very", "very_b", "very_c"])
208 buffer = Buffer(history=history)
208 buffer = Buffer(history=history)
209 ip = get_ipython()
209 ip = get_ipython()
210 ip.auto_suggest = provider
210 ip.auto_suggest = provider
211
211
212 async for _ in history.load():
212 async for _ in history.load():
213 pass
213 pass
214
214
215 buffer.cursor_position = 5
215 buffer.cursor_position = 5
216 buffer.text = "very"
216 buffer.text = "very"
217
217
218 up = swap_autosuggestion_up
218 up = swap_autosuggestion_up
219 down = swap_autosuggestion_down
219 down = swap_autosuggestion_down
220
220
221 event = Mock()
221 event = Mock()
222 event.current_buffer = buffer
222 event.current_buffer = buffer
223
223
224 def get_suggestion():
224 def get_suggestion():
225 suggestion = provider.get_suggestion(buffer, buffer.document)
225 suggestion = provider.get_suggestion(buffer, buffer.document)
226 buffer.suggestion = suggestion
226 buffer.suggestion = suggestion
227 return suggestion
227 return suggestion
228
228
229 assert get_suggestion().text == "_c"
229 assert get_suggestion().text == "_c"
230
230
231 # should go up
231 # should go up
232 up(event)
232 up(event)
233 assert get_suggestion().text == "_b"
233 assert get_suggestion().text == "_b"
234
234
235 # should skip over 'very' which is identical to buffer content
235 # should skip over 'very' which is identical to buffer content
236 up(event)
236 up(event)
237 assert get_suggestion().text == "_a"
237 assert get_suggestion().text == "_a"
238
238
239 # should cycle back to beginning
239 # should cycle back to beginning
240 up(event)
240 up(event)
241 assert get_suggestion().text == "_c"
241 assert get_suggestion().text == "_c"
242
242
243 # should cycle back through end boundary
243 # should cycle back through end boundary
244 down(event)
244 down(event)
245 assert get_suggestion().text == "_a"
245 assert get_suggestion().text == "_a"
246
246
247 down(event)
247 down(event)
248 assert get_suggestion().text == "_b"
248 assert get_suggestion().text == "_b"
249
249
250 down(event)
250 down(event)
251 assert get_suggestion().text == "_c"
251 assert get_suggestion().text == "_c"
252
252
253 down(event)
253 down(event)
254 assert get_suggestion().text == "_a"
254 assert get_suggestion().text == "_a"
255
255
256
256
257 async def test_navigable_provider_multiline_entries():
257 async def test_navigable_provider_multiline_entries():
258 provider = NavigableAutoSuggestFromHistory()
258 provider = NavigableAutoSuggestFromHistory()
259 history = InMemoryHistory(history_strings=["very_a\nvery_b", "very_c"])
259 history = InMemoryHistory(history_strings=["very_a\nvery_b", "very_c"])
260 buffer = Buffer(history=history)
260 buffer = Buffer(history=history)
261 ip = get_ipython()
261 ip = get_ipython()
262 ip.auto_suggest = provider
262 ip.auto_suggest = provider
263
263
264 async for _ in history.load():
264 async for _ in history.load():
265 pass
265 pass
266
266
267 buffer.cursor_position = 5
267 buffer.cursor_position = 5
268 buffer.text = "very"
268 buffer.text = "very"
269 up = swap_autosuggestion_up
269 up = swap_autosuggestion_up
270 down = swap_autosuggestion_down
270 down = swap_autosuggestion_down
271
271
272 event = Mock()
272 event = Mock()
273 event.current_buffer = buffer
273 event.current_buffer = buffer
274
274
275 def get_suggestion():
275 def get_suggestion():
276 suggestion = provider.get_suggestion(buffer, buffer.document)
276 suggestion = provider.get_suggestion(buffer, buffer.document)
277 buffer.suggestion = suggestion
277 buffer.suggestion = suggestion
278 return suggestion
278 return suggestion
279
279
280 assert get_suggestion().text == "_c"
280 assert get_suggestion().text == "_c"
281
281
282 up(event)
282 up(event)
283 assert get_suggestion().text == "_b"
283 assert get_suggestion().text == "_b"
284
284
285 up(event)
285 up(event)
286 assert get_suggestion().text == "_a"
286 assert get_suggestion().text == "_a"
287
287
288 down(event)
288 down(event)
289 assert get_suggestion().text == "_b"
289 assert get_suggestion().text == "_b"
290
290
291 down(event)
291 down(event)
292 assert get_suggestion().text == "_c"
292 assert get_suggestion().text == "_c"
293
293
294
294
295 def create_session_mock():
295 def create_session_mock():
296 session = Mock()
296 session = Mock()
297 session.default_buffer = Buffer()
297 session.default_buffer = Buffer()
298 return session
298 return session
299
299
300
300
301 def test_navigable_provider_connection():
301 def test_navigable_provider_connection():
302 provider = NavigableAutoSuggestFromHistory()
302 provider = NavigableAutoSuggestFromHistory()
303 provider.skip_lines = 1
303 provider.skip_lines = 1
304
304
305 session_1 = create_session_mock()
305 session_1 = create_session_mock()
306 provider.connect(session_1)
306 provider.connect(session_1)
307
307
308 assert provider.skip_lines == 1
308 assert provider.skip_lines == 1
309 session_1.default_buffer.on_text_insert.fire()
309 session_1.default_buffer.on_text_insert.fire()
310 assert provider.skip_lines == 0
310 assert provider.skip_lines == 0
311
311
312 session_2 = create_session_mock()
312 session_2 = create_session_mock()
313 provider.connect(session_2)
313 provider.connect(session_2)
314 provider.skip_lines = 2
314 provider.skip_lines = 2
315
315
316 assert provider.skip_lines == 2
316 assert provider.skip_lines == 2
317 session_2.default_buffer.on_text_insert.fire()
317 session_2.default_buffer.on_text_insert.fire()
318 assert provider.skip_lines == 0
318 assert provider.skip_lines == 0
319
319
320 provider.skip_lines = 3
320 provider.skip_lines = 3
321 provider.disconnect()
321 provider.disconnect()
322 session_1.default_buffer.on_text_insert.fire()
322 session_1.default_buffer.on_text_insert.fire()
323 session_2.default_buffer.on_text_insert.fire()
323 session_2.default_buffer.on_text_insert.fire()
324 assert provider.skip_lines == 3
324 assert provider.skip_lines == 3
325
325
326
326
327 @pytest.fixture
327 @pytest.fixture
328 def ipython_with_prompt():
328 def ipython_with_prompt():
329 ip = get_ipython()
329 ip = get_ipython()
330 ip.pt_app = Mock()
330 ip.pt_app = Mock()
331 ip.pt_app.key_bindings = create_ipython_shortcuts(ip)
331 ip.pt_app.key_bindings = create_ipython_shortcuts(ip)
332 try:
332 try:
333 yield ip
333 yield ip
334 finally:
334 finally:
335 ip.pt_app = None
335 ip.pt_app = None
336
336
337
337
338 def find_bindings_by_command(command):
338 def find_bindings_by_command(command):
339 ip = get_ipython()
339 ip = get_ipython()
340 return [
340 return [
341 binding
341 binding
342 for binding in ip.pt_app.key_bindings.bindings
342 for binding in ip.pt_app.key_bindings.bindings
343 if binding.handler == command
343 if binding.handler == command
344 ]
344 ]
345
345
346
346
347 def test_modify_unique_shortcut(ipython_with_prompt):
347 def test_modify_unique_shortcut(ipython_with_prompt):
348 original = find_bindings_by_command(accept_token)
348 original = find_bindings_by_command(accept_token)
349 assert len(original) == 1
349 assert len(original) == 1
350
350
351 ipython_with_prompt.shortcuts = [
351 ipython_with_prompt.shortcuts = [
352 {"command": "IPython:auto_suggest.accept_token", "new_keys": ["a", "b", "c"]}
352 {"command": "IPython:auto_suggest.accept_token", "new_keys": ["a", "b", "c"]}
353 ]
353 ]
354 matched = find_bindings_by_command(accept_token)
354 matched = find_bindings_by_command(accept_token)
355 assert len(matched) == 1
355 assert len(matched) == 1
356 assert list(matched[0].keys) == ["a", "b", "c"]
356 assert list(matched[0].keys) == ["a", "b", "c"]
357 assert list(matched[0].keys) != list(original[0].keys)
357 assert list(matched[0].keys) != list(original[0].keys)
358 assert matched[0].filter == original[0].filter
358 assert matched[0].filter == original[0].filter
359
359
360 ipython_with_prompt.shortcuts = [
360 ipython_with_prompt.shortcuts = [
361 {"command": "IPython:auto_suggest.accept_token", "new_filter": "always"}
361 {"command": "IPython:auto_suggest.accept_token", "new_filter": "always"}
362 ]
362 ]
363 matched = find_bindings_by_command(accept_token)
363 matched = find_bindings_by_command(accept_token)
364 assert len(matched) == 1
364 assert len(matched) == 1
365 assert list(matched[0].keys) != ["a", "b", "c"]
365 assert list(matched[0].keys) != ["a", "b", "c"]
366 assert list(matched[0].keys) == list(original[0].keys)
366 assert list(matched[0].keys) == list(original[0].keys)
367 assert matched[0].filter != original[0].filter
367 assert matched[0].filter != original[0].filter
368
368
369
369
370 def test_disable_shortcut(ipython_with_prompt):
370 def test_disable_shortcut(ipython_with_prompt):
371 matched = find_bindings_by_command(accept_token)
371 matched = find_bindings_by_command(accept_token)
372 assert len(matched) == 1
372 assert len(matched) == 1
373
373
374 ipython_with_prompt.shortcuts = [
374 ipython_with_prompt.shortcuts = [
375 {"command": "IPython:auto_suggest.accept_token", "new_keys": []}
375 {"command": "IPython:auto_suggest.accept_token", "new_keys": []}
376 ]
376 ]
377 matched = find_bindings_by_command(accept_token)
377 matched = find_bindings_by_command(accept_token)
378 assert len(matched) == 0
378 assert len(matched) == 0
379
379
380 ipython_with_prompt.shortcuts = []
380 ipython_with_prompt.shortcuts = []
381 matched = find_bindings_by_command(accept_token)
381 matched = find_bindings_by_command(accept_token)
382 assert len(matched) == 1
382 assert len(matched) == 1
383
383
384
384
385 def test_modify_shortcut_with_filters(ipython_with_prompt):
385 def test_modify_shortcut_with_filters(ipython_with_prompt):
386 matched = find_bindings_by_command(skip_over)
386 matched = find_bindings_by_command(skip_over)
387 matched_keys = {m.keys[0] for m in matched}
387 matched_keys = {m.keys[0] for m in matched}
388 assert matched_keys == {")", "]", "}", "'", '"'}
388 assert matched_keys == {")", "]", "}", "'", '"'}
389
389
390 with pytest.raises(ValueError, match="Multiple shortcuts matching"):
390 with pytest.raises(ValueError, match="Multiple shortcuts matching"):
391 ipython_with_prompt.shortcuts = [
391 ipython_with_prompt.shortcuts = [
392 {"command": "IPython:auto_match.skip_over", "new_keys": ["x"]}
392 {"command": "IPython:auto_match.skip_over", "new_keys": ["x"]}
393 ]
393 ]
394
394
395 ipython_with_prompt.shortcuts = [
395 ipython_with_prompt.shortcuts = [
396 {
396 {
397 "command": "IPython:auto_match.skip_over",
397 "command": "IPython:auto_match.skip_over",
398 "new_keys": ["x"],
398 "new_keys": ["x"],
399 "match_filter": "focused_insert & auto_match & followed_by_single_quote",
399 "match_filter": "focused_insert & auto_match & followed_by_single_quote",
400 }
400 }
401 ]
401 ]
402 matched = find_bindings_by_command(skip_over)
402 matched = find_bindings_by_command(skip_over)
403 matched_keys = {m.keys[0] for m in matched}
403 matched_keys = {m.keys[0] for m in matched}
404 assert matched_keys == {")", "]", "}", "x", '"'}
404 assert matched_keys == {")", "]", "}", "x", '"'}
405
405
406
406
407 def example_command():
407 def example_command():
408 pass
408 pass
409
409
410
410
411 def test_add_shortcut_for_new_command(ipython_with_prompt):
411 def test_add_shortcut_for_new_command(ipython_with_prompt):
412 matched = find_bindings_by_command(example_command)
412 matched = find_bindings_by_command(example_command)
413 assert len(matched) == 0
413 assert len(matched) == 0
414
414
415 with pytest.raises(ValueError, match="example_command is not a known"):
415 with pytest.raises(ValueError, match="example_command is not a known"):
416 ipython_with_prompt.shortcuts = [
416 ipython_with_prompt.shortcuts = [
417 {"command": "example_command", "new_keys": ["x"]}
417 {"command": "example_command", "new_keys": ["x"]}
418 ]
418 ]
419 matched = find_bindings_by_command(example_command)
419 matched = find_bindings_by_command(example_command)
420 assert len(matched) == 0
420 assert len(matched) == 0
421
421
422
422
423 def test_modify_shortcut_failure(ipython_with_prompt):
424 with pytest.raises(ValueError, match="No shortcuts matching"):
425 ipython_with_prompt.shortcuts = [
426 {
427 "command": "IPython:auto_match.skip_over",
428 "match_keys": ["x"],
429 "new_keys": ["y"],
430 }
431 ]
432
433
423 def test_add_shortcut_for_existing_command(ipython_with_prompt):
434 def test_add_shortcut_for_existing_command(ipython_with_prompt):
424 matched = find_bindings_by_command(skip_over)
435 matched = find_bindings_by_command(skip_over)
425 assert len(matched) == 5
436 assert len(matched) == 5
426
437
427 with pytest.raises(ValueError, match="Cannot add a shortcut without keys"):
438 with pytest.raises(ValueError, match="Cannot add a shortcut without keys"):
428 ipython_with_prompt.shortcuts = [
439 ipython_with_prompt.shortcuts = [
429 {"command": "IPython:auto_match.skip_over", "new_keys": [], "create": True}
440 {"command": "IPython:auto_match.skip_over", "new_keys": [], "create": True}
430 ]
441 ]
431
442
432 ipython_with_prompt.shortcuts = [
443 ipython_with_prompt.shortcuts = [
433 {"command": "IPython:auto_match.skip_over", "new_keys": ["x"], "create": True}
444 {"command": "IPython:auto_match.skip_over", "new_keys": ["x"], "create": True}
434 ]
445 ]
435 matched = find_bindings_by_command(skip_over)
446 matched = find_bindings_by_command(skip_over)
436 assert len(matched) == 6
447 assert len(matched) == 6
437
448
438 ipython_with_prompt.shortcuts = []
449 ipython_with_prompt.shortcuts = []
439 matched = find_bindings_by_command(skip_over)
450 matched = find_bindings_by_command(skip_over)
440 assert len(matched) == 5
451 assert len(matched) == 5
441
452
442
453
443 def test_setting_shortcuts_before_pt_app_init():
454 def test_setting_shortcuts_before_pt_app_init():
444 ipython = get_ipython()
455 ipython = get_ipython()
445 assert ipython.pt_app is None
456 assert ipython.pt_app is None
446 shortcuts = [
457 shortcuts = [
447 {"command": "IPython:auto_match.skip_over", "new_keys": ["x"], "create": True}
458 {"command": "IPython:auto_match.skip_over", "new_keys": ["x"], "create": True}
448 ]
459 ]
449 ipython.shortcuts = shortcuts
460 ipython.shortcuts = shortcuts
450 assert ipython.shortcuts == shortcuts
461 assert ipython.shortcuts == shortcuts
General Comments 0
You need to be logged in to leave comments. Login now