"""Tests for the Jedi completer xontrib""" import sys import pytest import builtins import importlib from unittest.mock import MagicMock, call from xonsh.xontribs import find_xontrib from xonsh.completers.tools import RichCompletion @pytest.fixture def jedi_mock(monkeypatch): jedi_mock = MagicMock() jedi_mock.__version__ = '0.16.0' jedi_mock.Interpreter().complete.return_value = [] jedi_mock.reset_mock() monkeypatch.setitem(sys.modules, 'jedi', jedi_mock) yield jedi_mock @pytest.fixture def completer_mock(monkeypatch): completer_mock = MagicMock() # so that args will be passed def comp(args): completer_mock(args) monkeypatch.setitem(builtins.aliases, 'completer', comp) yield completer_mock @pytest.fixture def jedi_xontrib(monkeypatch, source_path, jedi_mock, completer_mock): monkeypatch.syspath_prepend(source_path) spec = find_xontrib('jedi') yield importlib.import_module(spec.name) del sys.modules[spec.name] def test_completer_added(jedi_xontrib, completer_mock): assert completer_mock.call_args_list == [call(['remove', 'python_mode']), call(['add', 'jedi_python', 'complete_jedi', ' int', ('instance', 'instance int')), RichCompletion('x', display='xx', description='instance int') ), ( # from jedi when code is 'xx=3\nx' ('statement', 'xx', 'x', None, ('instance', 'instance int')), RichCompletion('x', display='xx', description='instance int') ), ( # from jedi when code is 'x.' and x=3 ('function', 'from_bytes', 'from_bytes', 'from_bytes(bytes, byteorder, *, signed=False)', ('function', 'def __get__')), RichCompletion('from_bytes', display='from_bytes()', description= 'from_bytes(bytes, byteorder, *, signed=False)') ), ( # from jedi when code is 'x=3\nx.' ('function', 'imag', 'imag', None, ('instance', 'instance int')), RichCompletion('imag', display='imag', description='instance int') ), ( # from '(3).from_bytes(byt' ('param', 'bytes=', 'es=', None, ('instance', 'instance Sequence')), RichCompletion('es=', display='bytes=', description='instance Sequence') ), ( # from 'x.from_bytes(byt' when x=3 ('param', 'bytes=', 'es=', None, None), RichCompletion('es=', display='bytes=', description='param') ), ( # from 'import colle' ('module', 'collections', 'ctions', None, ('module', 'module collections')), RichCompletion('ctions', display='collections', description='module collections') ), ( # from 'NameErr' ('class', 'NameError', 'or', 'NameError(*args: object)', ('class', 'class NameError')), RichCompletion('or', display='NameError', description='NameError(*args: object)') ), ( # from 'a["' when a={'name':None} ('string', '"name"', 'name"', None, None), RichCompletion('name"', display='"name"', description='string') ), ( # from 'open("/etc/pass' ('path', 'passwd"', 'wd"', None, None), RichCompletion('wd"', display='passwd"', description='path') ), ( # from 'cla' ('keyword', 'class', 'ss', None, None), RichCompletion('ss', display='class', description='keyword') ), ]) def test_rich_completions(jedi_xontrib, jedi_mock, completion, rich_completion): comp_type, comp_name, comp_complete, sig, inf = completion comp_mock = MagicMock() comp_mock.type = comp_type comp_mock.name = comp_name comp_mock.complete = comp_complete if sig: sig_mock = MagicMock() sig_mock.to_string.return_value = sig comp_mock.get_signatures.return_value = [sig_mock] else: comp_mock.get_signatures.return_value = [] if inf: inf_type, inf_desc = inf inf_mock = MagicMock() inf_mock.type = inf_type inf_mock.description = inf_desc comp_mock.infer.return_value = [inf_mock] else: comp_mock.infer.return_value = [] jedi_xontrib.XONSH_SPECIAL_TOKENS = [] jedi_mock.Interpreter().complete.return_value = [comp_mock] completions = jedi_xontrib.complete_jedi('', '', 0, 0, {}) assert len(completions) == 1 ret_completion, = completions assert isinstance(ret_completion, RichCompletion) assert ret_completion == rich_completion assert ret_completion.display == rich_completion.display assert ret_completion.description == rich_completion.description def test_special_tokens(jedi_xontrib): assert jedi_xontrib.complete_jedi('', '', 0, 0, {}) == jedi_xontrib.XONSH_SPECIAL_TOKENS assert jedi_xontrib.complete_jedi('@', '@', 0, 1, {}) == {'@', '@(', '@$('} assert jedi_xontrib.complete_jedi('$', '$', 0, 1, {}) == {'$[', '${', '$('}