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