##// END OF EJS Templates
Mock session to avoid Windows issues on CI....
krassowski -
Show More
@@ -1,233 +1,238 b''
1 import pytest
1 import pytest
2 from IPython.terminal.shortcuts.auto_suggest import (
2 from IPython.terminal.shortcuts.auto_suggest import (
3 accept_in_vi_insert_mode,
3 accept_in_vi_insert_mode,
4 accept_token,
4 accept_token,
5 accept_character,
5 accept_character,
6 accept_word,
6 accept_word,
7 accept_and_keep_cursor,
7 accept_and_keep_cursor,
8 NavigableAutoSuggestFromHistory,
8 NavigableAutoSuggestFromHistory,
9 swap_autosuggestion_up,
9 swap_autosuggestion_up,
10 swap_autosuggestion_down,
10 swap_autosuggestion_down,
11 )
11 )
12
12
13 from prompt_toolkit.history import InMemoryHistory
13 from prompt_toolkit.history import InMemoryHistory
14 from prompt_toolkit.shortcuts import PromptSession
15 from prompt_toolkit.buffer import Buffer
14 from prompt_toolkit.buffer import Buffer
16
15
17 from unittest.mock import patch, Mock
16 from unittest.mock import patch, Mock
18
17
19
18
20 def make_event(text, cursor, suggestion):
19 def make_event(text, cursor, suggestion):
21 event = Mock()
20 event = Mock()
22 event.current_buffer = Mock()
21 event.current_buffer = Mock()
23 event.current_buffer.suggestion = Mock()
22 event.current_buffer.suggestion = Mock()
24 event.current_buffer.text = text
23 event.current_buffer.text = text
25 event.current_buffer.cursor_position = cursor
24 event.current_buffer.cursor_position = cursor
26 event.current_buffer.suggestion.text = suggestion
25 event.current_buffer.suggestion.text = suggestion
27 event.current_buffer.document = Mock()
26 event.current_buffer.document = Mock()
28 event.current_buffer.document.get_end_of_line_position = Mock(return_value=0)
27 event.current_buffer.document.get_end_of_line_position = Mock(return_value=0)
29 event.current_buffer.document.text = text
28 event.current_buffer.document.text = text
30 event.current_buffer.document.cursor_position = cursor
29 event.current_buffer.document.cursor_position = cursor
31 return event
30 return event
32
31
33
32
34 @pytest.mark.parametrize(
33 @pytest.mark.parametrize(
35 "text, cursor, suggestion, called",
34 "text, cursor, suggestion, called",
36 [
35 [
37 ("123456", 6, "123456789", True),
36 ("123456", 6, "123456789", True),
38 ("123456", 3, "123456789", False),
37 ("123456", 3, "123456789", False),
39 ("123456 \n789", 6, "123456789", True),
38 ("123456 \n789", 6, "123456789", True),
40 ],
39 ],
41 )
40 )
42 def test_autosuggest_at_EOL(text, cursor, suggestion, called):
41 def test_autosuggest_at_EOL(text, cursor, suggestion, called):
43 """
42 """
44 test that autosuggest is only applied at end of line.
43 test that autosuggest is only applied at end of line.
45 """
44 """
46
45
47 event = make_event(text, cursor, suggestion)
46 event = make_event(text, cursor, suggestion)
48 event.current_buffer.insert_text = Mock()
47 event.current_buffer.insert_text = Mock()
49 accept_in_vi_insert_mode(event)
48 accept_in_vi_insert_mode(event)
50 if called:
49 if called:
51 event.current_buffer.insert_text.assert_called()
50 event.current_buffer.insert_text.assert_called()
52 else:
51 else:
53 event.current_buffer.insert_text.assert_not_called()
52 event.current_buffer.insert_text.assert_not_called()
54 # event.current_buffer.document.get_end_of_line_position.assert_called()
53 # event.current_buffer.document.get_end_of_line_position.assert_called()
55
54
56
55
57 @pytest.mark.parametrize(
56 @pytest.mark.parametrize(
58 "text, suggestion, expected",
57 "text, suggestion, expected",
59 [
58 [
60 ("", "def out(tag: str, n=50):", "def "),
59 ("", "def out(tag: str, n=50):", "def "),
61 ("d", "ef out(tag: str, n=50):", "ef "),
60 ("d", "ef out(tag: str, n=50):", "ef "),
62 ("de ", "f out(tag: str, n=50):", "f "),
61 ("de ", "f out(tag: str, n=50):", "f "),
63 ("def", " out(tag: str, n=50):", " "),
62 ("def", " out(tag: str, n=50):", " "),
64 ("def ", "out(tag: str, n=50):", "out("),
63 ("def ", "out(tag: str, n=50):", "out("),
65 ("def o", "ut(tag: str, n=50):", "ut("),
64 ("def o", "ut(tag: str, n=50):", "ut("),
66 ("def ou", "t(tag: str, n=50):", "t("),
65 ("def ou", "t(tag: str, n=50):", "t("),
67 ("def out", "(tag: str, n=50):", "("),
66 ("def out", "(tag: str, n=50):", "("),
68 ("def out(", "tag: str, n=50):", "tag: "),
67 ("def out(", "tag: str, n=50):", "tag: "),
69 ("def out(t", "ag: str, n=50):", "ag: "),
68 ("def out(t", "ag: str, n=50):", "ag: "),
70 ("def out(ta", "g: str, n=50):", "g: "),
69 ("def out(ta", "g: str, n=50):", "g: "),
71 ("def out(tag", ": str, n=50):", ": "),
70 ("def out(tag", ": str, n=50):", ": "),
72 ("def out(tag:", " str, n=50):", " "),
71 ("def out(tag:", " str, n=50):", " "),
73 ("def out(tag: ", "str, n=50):", "str, "),
72 ("def out(tag: ", "str, n=50):", "str, "),
74 ("def out(tag: s", "tr, n=50):", "tr, "),
73 ("def out(tag: s", "tr, n=50):", "tr, "),
75 ("def out(tag: st", "r, n=50):", "r, "),
74 ("def out(tag: st", "r, n=50):", "r, "),
76 ("def out(tag: str", ", n=50):", ", n"),
75 ("def out(tag: str", ", n=50):", ", n"),
77 ("def out(tag: str,", " n=50):", " n"),
76 ("def out(tag: str,", " n=50):", " n"),
78 ("def out(tag: str, ", "n=50):", "n="),
77 ("def out(tag: str, ", "n=50):", "n="),
79 ("def out(tag: str, n", "=50):", "="),
78 ("def out(tag: str, n", "=50):", "="),
80 ("def out(tag: str, n=", "50):", "50)"),
79 ("def out(tag: str, n=", "50):", "50)"),
81 ("def out(tag: str, n=5", "0):", "0)"),
80 ("def out(tag: str, n=5", "0):", "0)"),
82 ("def out(tag: str, n=50", "):", "):"),
81 ("def out(tag: str, n=50", "):", "):"),
83 ("def out(tag: str, n=50)", ":", ":"),
82 ("def out(tag: str, n=50)", ":", ":"),
84 ],
83 ],
85 )
84 )
86 def test_autosuggest_token(text, suggestion, expected):
85 def test_autosuggest_token(text, suggestion, expected):
87 event = make_event(text, len(text), suggestion)
86 event = make_event(text, len(text), suggestion)
88 event.current_buffer.insert_text = Mock()
87 event.current_buffer.insert_text = Mock()
89 accept_token(event)
88 accept_token(event)
90 assert event.current_buffer.insert_text.called
89 assert event.current_buffer.insert_text.called
91 assert event.current_buffer.insert_text.call_args[0] == (expected,)
90 assert event.current_buffer.insert_text.call_args[0] == (expected,)
92
91
93
92
94 @pytest.mark.parametrize(
93 @pytest.mark.parametrize(
95 "text, suggestion, expected",
94 "text, suggestion, expected",
96 [
95 [
97 ("", "def out(tag: str, n=50):", "d"),
96 ("", "def out(tag: str, n=50):", "d"),
98 ("d", "ef out(tag: str, n=50):", "e"),
97 ("d", "ef out(tag: str, n=50):", "e"),
99 ("de ", "f out(tag: str, n=50):", "f"),
98 ("de ", "f out(tag: str, n=50):", "f"),
100 ("def", " out(tag: str, n=50):", " "),
99 ("def", " out(tag: str, n=50):", " "),
101 ],
100 ],
102 )
101 )
103 def test_accept_character(text, suggestion, expected):
102 def test_accept_character(text, suggestion, expected):
104 event = make_event(text, len(text), suggestion)
103 event = make_event(text, len(text), suggestion)
105 event.current_buffer.insert_text = Mock()
104 event.current_buffer.insert_text = Mock()
106 accept_character(event)
105 accept_character(event)
107 assert event.current_buffer.insert_text.called
106 assert event.current_buffer.insert_text.called
108 assert event.current_buffer.insert_text.call_args[0] == (expected,)
107 assert event.current_buffer.insert_text.call_args[0] == (expected,)
109
108
110
109
111 @pytest.mark.parametrize(
110 @pytest.mark.parametrize(
112 "text, suggestion, expected",
111 "text, suggestion, expected",
113 [
112 [
114 ("", "def out(tag: str, n=50):", "def "),
113 ("", "def out(tag: str, n=50):", "def "),
115 ("d", "ef out(tag: str, n=50):", "ef "),
114 ("d", "ef out(tag: str, n=50):", "ef "),
116 ("de", "f out(tag: str, n=50):", "f "),
115 ("de", "f out(tag: str, n=50):", "f "),
117 ("def", " out(tag: str, n=50):", " "),
116 ("def", " out(tag: str, n=50):", " "),
118 # (this is why we also have accept_token)
117 # (this is why we also have accept_token)
119 ("def ", "out(tag: str, n=50):", "out(tag: "),
118 ("def ", "out(tag: str, n=50):", "out(tag: "),
120 ],
119 ],
121 )
120 )
122 def test_accept_word(text, suggestion, expected):
121 def test_accept_word(text, suggestion, expected):
123 event = make_event(text, len(text), suggestion)
122 event = make_event(text, len(text), suggestion)
124 event.current_buffer.insert_text = Mock()
123 event.current_buffer.insert_text = Mock()
125 accept_word(event)
124 accept_word(event)
126 assert event.current_buffer.insert_text.called
125 assert event.current_buffer.insert_text.called
127 assert event.current_buffer.insert_text.call_args[0] == (expected,)
126 assert event.current_buffer.insert_text.call_args[0] == (expected,)
128
127
129
128
130 @pytest.mark.parametrize(
129 @pytest.mark.parametrize(
131 "text, suggestion, expected, cursor",
130 "text, suggestion, expected, cursor",
132 [
131 [
133 ("", "def out(tag: str, n=50):", "def out(tag: str, n=50):", 0),
132 ("", "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),
133 ("def ", "out(tag: str, n=50):", "out(tag: str, n=50):", 4),
135 ],
134 ],
136 )
135 )
137 def test_accept_and_keep_cursor(text, suggestion, expected, cursor):
136 def test_accept_and_keep_cursor(text, suggestion, expected, cursor):
138 event = make_event(text, cursor, suggestion)
137 event = make_event(text, cursor, suggestion)
139 buffer = event.current_buffer
138 buffer = event.current_buffer
140 buffer.insert_text = Mock()
139 buffer.insert_text = Mock()
141 accept_and_keep_cursor(event)
140 accept_and_keep_cursor(event)
142 assert buffer.insert_text.called
141 assert buffer.insert_text.called
143 assert buffer.insert_text.call_args[0] == (expected,)
142 assert buffer.insert_text.call_args[0] == (expected,)
144 assert buffer.cursor_position == cursor
143 assert buffer.cursor_position == cursor
145
144
146
145
147 def test_autosuggest_token_empty():
146 def test_autosuggest_token_empty():
148 full = "def out(tag: str, n=50):"
147 full = "def out(tag: str, n=50):"
149 event = make_event(full, len(full), "")
148 event = make_event(full, len(full), "")
150 event.current_buffer.insert_text = Mock()
149 event.current_buffer.insert_text = Mock()
151
150
152 with patch(
151 with patch(
153 "prompt_toolkit.key_binding.bindings.named_commands.forward_word"
152 "prompt_toolkit.key_binding.bindings.named_commands.forward_word"
154 ) as forward_word:
153 ) as forward_word:
155 accept_token(event)
154 accept_token(event)
156 assert not event.current_buffer.insert_text.called
155 assert not event.current_buffer.insert_text.called
157 assert forward_word.called
156 assert forward_word.called
158
157
159
158
160 async def test_navigable_provider():
159 async def test_navigable_provider():
161 provider = NavigableAutoSuggestFromHistory()
160 provider = NavigableAutoSuggestFromHistory()
162 history = InMemoryHistory(history_strings=["very_a", "very", "very_b", "very_c"])
161 history = InMemoryHistory(history_strings=["very_a", "very", "very_b", "very_c"])
163 buffer = Buffer(history=history)
162 buffer = Buffer(history=history)
164
163
165 async for _ in history.load():
164 async for _ in history.load():
166 pass
165 pass
167
166
168 buffer.cursor_position = 5
167 buffer.cursor_position = 5
169 buffer.text = "very"
168 buffer.text = "very"
170
169
171 up = swap_autosuggestion_up(provider)
170 up = swap_autosuggestion_up(provider)
172 down = swap_autosuggestion_down(provider)
171 down = swap_autosuggestion_down(provider)
173
172
174 event = Mock()
173 event = Mock()
175 event.current_buffer = buffer
174 event.current_buffer = buffer
176
175
177 def get_suggestion():
176 def get_suggestion():
178 suggestion = provider.get_suggestion(buffer, buffer.document)
177 suggestion = provider.get_suggestion(buffer, buffer.document)
179 buffer.suggestion = suggestion
178 buffer.suggestion = suggestion
180 return suggestion
179 return suggestion
181
180
182 assert get_suggestion().text == "_c"
181 assert get_suggestion().text == "_c"
183
182
184 # should go up
183 # should go up
185 up(event)
184 up(event)
186 assert get_suggestion().text == "_b"
185 assert get_suggestion().text == "_b"
187
186
188 # should skip over 'very' which is identical to buffer content
187 # should skip over 'very' which is identical to buffer content
189 up(event)
188 up(event)
190 assert get_suggestion().text == "_a"
189 assert get_suggestion().text == "_a"
191
190
192 # should cycle back to beginning
191 # should cycle back to beginning
193 up(event)
192 up(event)
194 assert get_suggestion().text == "_c"
193 assert get_suggestion().text == "_c"
195
194
196 # should cycle back through end boundary
195 # should cycle back through end boundary
197 down(event)
196 down(event)
198 assert get_suggestion().text == "_a"
197 assert get_suggestion().text == "_a"
199
198
200 down(event)
199 down(event)
201 assert get_suggestion().text == "_b"
200 assert get_suggestion().text == "_b"
202
201
203 down(event)
202 down(event)
204 assert get_suggestion().text == "_c"
203 assert get_suggestion().text == "_c"
205
204
206 down(event)
205 down(event)
207 assert get_suggestion().text == "_a"
206 assert get_suggestion().text == "_a"
208
207
209
208
209 def create_session_mock():
210 session = Mock()
211 session.default_buffer = Buffer()
212 return session
213
214
210 def test_navigable_provider_connection():
215 def test_navigable_provider_connection():
211 provider = NavigableAutoSuggestFromHistory()
216 provider = NavigableAutoSuggestFromHistory()
212 provider.skip_lines = 1
217 provider.skip_lines = 1
213
218
214 session_1 = PromptSession()
219 session_1 = create_session_mock()
215 provider.connect(session_1)
220 provider.connect(session_1)
216
221
217 assert provider.skip_lines == 1
222 assert provider.skip_lines == 1
218 session_1.default_buffer.on_text_insert.fire()
223 session_1.default_buffer.on_text_insert.fire()
219 assert provider.skip_lines == 0
224 assert provider.skip_lines == 0
220
225
221 session_2 = PromptSession()
226 session_2 = create_session_mock()
222 provider.connect(session_2)
227 provider.connect(session_2)
223 provider.skip_lines = 2
228 provider.skip_lines = 2
224
229
225 assert provider.skip_lines == 2
230 assert provider.skip_lines == 2
226 session_2.default_buffer.on_text_insert.fire()
231 session_2.default_buffer.on_text_insert.fire()
227 assert provider.skip_lines == 0
232 assert provider.skip_lines == 0
228
233
229 provider.skip_lines = 3
234 provider.skip_lines = 3
230 provider.disconnect()
235 provider.disconnect()
231 session_1.default_buffer.on_text_insert.fire()
236 session_1.default_buffer.on_text_insert.fire()
232 session_2.default_buffer.on_text_insert.fire()
237 session_2.default_buffer.on_text_insert.fire()
233 assert provider.skip_lines == 3
238 assert provider.skip_lines == 3
General Comments 0
You need to be logged in to leave comments. Login now