Skip to content

Commit

Permalink
Merge pull request #10630 from kiteco/FIX-bug-10605
Browse files Browse the repository at this point in the history
PR: Fix completions bug in Kite introduced by PR 10605
  • Loading branch information
ccordoba12 authored Nov 7, 2019
2 parents 052f5a1 + 496ab26 commit 147ca12
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 1 deletion.
3 changes: 3 additions & 0 deletions spyder/plugins/completion/kite/providers/document.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,9 @@ def request_document_completions(self, params):

@handles(LSPRequestTypes.DOCUMENT_COMPLETION)
def convert_completion_request(self, response):
# The response schema is tested via mocking in
# spyder/plugins/editor/widgets/tests/test_introspection.py

logger.debug(response)
if response is None:
return {'params': []}
Expand Down
3 changes: 2 additions & 1 deletion spyder/plugins/editor/widgets/codeeditor.py
Original file line number Diff line number Diff line change
Expand Up @@ -1071,7 +1071,8 @@ def process_completion(self, params):
completions = params['params']
completions = ([] if completions is None else
[completion for completion in completions
if completion['insertText']])
if completion.get('insertText')
or completion.get('textEdit', {}).get('newText')])

replace_end = self.textCursor().position()
under_cursor = self.get_current_word_and_position(completion=True)
Expand Down
34 changes: 34 additions & 0 deletions spyder/plugins/editor/widgets/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,40 @@ def teardown():
return completions


@pytest.fixture
def mock_completions_codeeditor(qtbot_module, request):
"""CodeEditor instance with ability to mock the completions response.
Returns a tuple of (editor, mock_response). Tests using this fixture should
set `mock_response.side_effect = lambda lang, method, params: {}`.
"""
# Create a CodeEditor instance
editor = codeeditor_factory()
qtbot_module.addWidget(editor)
editor.show()

mock_response = Mock()

def perform_request(lang, method, params):
resp = mock_response(lang, method, params)
print("DEBUG {}".format(resp))
if resp is not None:
editor.handle_response(method, resp)
editor.sig_perform_completion_request.connect(perform_request)

editor.filename = 'test.py'
editor.language = 'Python'
editor.completions_available = True
qtbot_module.wait(2000)

def teardown():
editor.hide()
editor.completion_widget.hide()
request.addfinalizer(teardown)

return editor, mock_response


@pytest.fixture
def lsp_codeeditor(lsp_plugin, qtbot_module, request):
"""CodeEditor instance with LSP services activated."""
Expand Down
52 changes: 52 additions & 0 deletions spyder/plugins/editor/widgets/tests/test_introspection.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@
rtree_available = False

# Local imports
from spyder.plugins.completion.languageserver import (
LSPRequestTypes, CompletionItemKind)
from spyder.plugins.completion.kite.providers.document import KITE_COMPLETION
from spyder.py3compat import PY2
from spyder.config.manager import CONF

Expand Down Expand Up @@ -764,6 +767,55 @@ def test_fallback_completions(fallback_codeeditor, qtbot):
code_editor.toggle_code_snippets(True)


@pytest.mark.slow
@pytest.mark.first
@flaky(max_runs=5)
def test_kite_textEdit_completions(mock_completions_codeeditor, qtbot):
"""Test textEdit completions such as those returned by the Kite provider.
This mocks out the completions response, and does not test the Kite
provider directly.
"""
code_editor, mock_response = mock_completions_codeeditor
completion = code_editor.completion_widget

code_editor.toggle_automatic_completions(False)
code_editor.toggle_code_snippets(False)

# Set cursor to start
code_editor.go_to_line(1)

qtbot.keyClicks(code_editor, 'my_dict.')

# Complete my_dict. -> my_dict["dict-key"]
mock_response.side_effect = lambda lang, method, params: {'params': [{
'kind': CompletionItemKind.TEXT,
'label': '["dict-key"]',
'textEdit': {
'newText': '["dict-key"]',
'range': {
'start': 7,
'end': 8,
},
},
'filterText': '',
'sortText': '',
'documentation': '',
'provider': KITE_COMPLETION,
}]} if method == LSPRequestTypes.DOCUMENT_COMPLETION else None
with qtbot.waitSignal(completion.sig_show_completions,
timeout=10000) as sig:
qtbot.keyPress(code_editor, Qt.Key_Tab, delay=300)
mock_response.side_effect = None

assert '["dict-key"]' in [x['label'] for x in sig.args[0]]
qtbot.keyPress(code_editor, Qt.Key_Enter, delay=300)
assert code_editor.toPlainText() == 'my_dict["dict-key"]\n'

code_editor.toggle_automatic_completions(True)
code_editor.toggle_code_snippets(True)


if __name__ == '__main__':
pytest.main(['test_introspection.py', '--run-slow'])

Expand Down

0 comments on commit 147ca12

Please sign in to comment.