##// END OF EJS Templates
Lint and add more tests
krassowski -
Show More
@@ -389,7 +389,9 b' class TerminalInteractiveShell(InteractiveShell):'
389 389
390 390 def _set_autosuggestions(self, provider):
391 391 # disconnect old handler
392 if self.auto_suggest and isinstance(self.auto_suggest, NavigableAutoSuggestFromHistory):
392 if self.auto_suggest and isinstance(
393 self.auto_suggest, NavigableAutoSuggestFromHistory
394 ):
393 395 self.auto_suggest.disconnect()
394 396 if provider is None:
395 397 self.auto_suggest = None
@@ -660,7 +662,9 b' class TerminalInteractiveShell(InteractiveShell):'
660 662
661 663 def __init__(self, *args, **kwargs):
662 664 super(TerminalInteractiveShell, self).__init__(*args, **kwargs)
663 self.auto_suggest: UnionType[AutoSuggestFromHistory, NavigableAutoSuggestFromHistory, None] = None
665 self.auto_suggest: UnionType[
666 AutoSuggestFromHistory, NavigableAutoSuggestFromHistory, None
667 ] = None
664 668 self._set_autosuggestions(self.autosuggestions_provider)
665 669 self.init_prompt_toolkit_cli()
666 670 self.init_term_title()
@@ -58,7 +58,6 b' class NavigableAutoSuggestFromHistory(AutoSuggestFromHistory):'
58 58 self, text: str, skip_lines: float, history: History, previous: bool
59 59 ):
60 60 line_number = -1
61
62 61 for string in reversed(list(history.get_strings())):
63 62 for line in reversed(string.splitlines()):
64 63 line_number += 1
@@ -167,7 +166,7 b' def accept_and_keep_cursor(event: KeyPressEvent):'
167 166
168 167
169 168 def accept_and_move_cursor_left(event: KeyPressEvent):
170 """Accept autosuggestion and move cursor left"""
169 """Accept autosuggestion and move cursor left in place"""
171 170 accept_and_keep_cursor(event)
172 171 nc.backward_char(event)
173 172
@@ -2,8 +2,18 b' import pytest'
2 2 from IPython.terminal.shortcuts.auto_suggest import (
3 3 accept_in_vi_insert_mode,
4 4 accept_token,
5 accept_character,
6 accept_word,
7 accept_and_keep_cursor,
8 NavigableAutoSuggestFromHistory,
9 swap_autosuggestion_up,
10 swap_autosuggestion_down,
5 11 )
6 12
13 from prompt_toolkit.history import InMemoryHistory
14 from prompt_toolkit.shortcuts import PromptSession
15 from prompt_toolkit.buffer import Buffer
16
7 17 from unittest.mock import patch, Mock
8 18
9 19
@@ -81,6 +91,59 b' def test_autosuggest_token(text, suggestion, expected):'
81 91 assert event.current_buffer.insert_text.call_args[0] == (expected,)
82 92
83 93
94 @pytest.mark.parametrize(
95 "text, suggestion, expected",
96 [
97 ("", "def out(tag: str, n=50):", "d"),
98 ("d", "ef out(tag: str, n=50):", "e"),
99 ("de ", "f out(tag: str, n=50):", "f"),
100 ("def", " out(tag: str, n=50):", " "),
101 ],
102 )
103 def test_accept_character(text, suggestion, expected):
104 event = make_event(text, len(text), suggestion)
105 event.current_buffer.insert_text = Mock()
106 accept_character(event)
107 assert event.current_buffer.insert_text.called
108 assert event.current_buffer.insert_text.call_args[0] == (expected,)
109
110
111 @pytest.mark.parametrize(
112 "text, suggestion, expected",
113 [
114 ("", "def out(tag: str, n=50):", "def "),
115 ("d", "ef out(tag: str, n=50):", "ef "),
116 ("de", "f out(tag: str, n=50):", "f "),
117 ("def", " out(tag: str, n=50):", " "),
118 # (this is why we also have accept_token)
119 ("def ", "out(tag: str, n=50):", "out(tag: "),
120 ],
121 )
122 def test_accept_word(text, suggestion, expected):
123 event = make_event(text, len(text), suggestion)
124 event.current_buffer.insert_text = Mock()
125 accept_word(event)
126 assert event.current_buffer.insert_text.called
127 assert event.current_buffer.insert_text.call_args[0] == (expected,)
128
129
130 @pytest.mark.parametrize(
131 "text, suggestion, expected, cursor",
132 [
133 ("", "def out(tag: str, n=50):", "def out(tag: str, n=50):", 0),
134 ("def ", "out(tag: str, n=50):", "out(tag: str, n=50):", 4),
135 ],
136 )
137 def test_accept_and_keep_cursor(text, suggestion, expected, cursor):
138 event = make_event(text, cursor, suggestion)
139 buffer = event.current_buffer
140 buffer.insert_text = Mock()
141 accept_and_keep_cursor(event)
142 assert buffer.insert_text.called
143 assert buffer.insert_text.call_args[0] == (expected,)
144 assert buffer.cursor_position == cursor
145
146
84 147 def test_autosuggest_token_empty():
85 148 full = "def out(tag: str, n=50):"
86 149 event = make_event(full, len(full), "")
@@ -92,3 +155,79 b' def test_autosuggest_token_empty():'
92 155 accept_token(event)
93 156 assert not event.current_buffer.insert_text.called
94 157 assert forward_word.called
158
159
160 async def test_navigable_provider():
161 provider = NavigableAutoSuggestFromHistory()
162 history = InMemoryHistory(history_strings=["very_a", "very", "very_b", "very_c"])
163 buffer = Buffer(history=history)
164
165 async for _ in history.load():
166 pass
167
168 buffer.cursor_position = 5
169 buffer.text = "very"
170
171 up = swap_autosuggestion_up(provider)
172 down = swap_autosuggestion_down(provider)
173
174 event = Mock()
175 event.current_buffer = buffer
176
177 def get_suggestion():
178 suggestion = provider.get_suggestion(buffer, buffer.document)
179 buffer.suggestion = suggestion
180 return suggestion
181
182 assert get_suggestion().text == "_c"
183
184 # should go up
185 up(event)
186 assert get_suggestion().text == "_b"
187
188 # should skip over 'very' which is identical to buffer content
189 up(event)
190 assert get_suggestion().text == "_a"
191
192 # should cycle back to beginning
193 up(event)
194 assert get_suggestion().text == "_c"
195
196 # should cycle back through end boundary
197 down(event)
198 assert get_suggestion().text == "_a"
199
200 down(event)
201 assert get_suggestion().text == "_b"
202
203 down(event)
204 assert get_suggestion().text == "_c"
205
206 down(event)
207 assert get_suggestion().text == "_a"
208
209
210 def test_navigable_provider_connection():
211 provider = NavigableAutoSuggestFromHistory()
212 provider.skip_lines = 1
213
214 session_1 = PromptSession()
215 provider.connect(session_1)
216
217 assert provider.skip_lines == 1
218 session_1.default_buffer.on_text_insert.fire()
219 assert provider.skip_lines == 0
220
221 session_2 = PromptSession()
222 provider.connect(session_2)
223 provider.skip_lines = 2
224
225 assert provider.skip_lines == 2
226 session_2.default_buffer.on_text_insert.fire()
227 assert provider.skip_lines == 0
228
229 provider.skip_lines = 3
230 provider.disconnect()
231 session_1.default_buffer.on_text_insert.fire()
232 session_2.default_buffer.on_text_insert.fire()
233 assert provider.skip_lines == 3
General Comments 0
You need to be logged in to leave comments. Login now