1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
|
"""Tests for the base completer's logic (xonsh/completer.py)"""
import pytest
from xonsh.completer import Completer
from xonsh.completers.tools import (
RichCompletion,
contextual_command_completer,
non_exclusive_completer,
)
from xonsh.parsers.completion_context import CommandContext
@pytest.fixture(scope="session")
def completer():
return Completer()
@pytest.fixture
def completers_mock(xession, monkeypatch):
completers = {}
monkeypatch.setattr(xession, "completers", completers)
return completers
def test_sanity(completer, completers_mock):
# no completions:
completers_mock["a"] = lambda *a: None
assert completer.complete("", "", 0, 0) == ((), 0)
# simple completion:
completers_mock["a"] = lambda *a: {"comp"}
assert completer.complete("pre", "", 0, 0) == (("comp",), 3)
# multiple completions:
completers_mock["a"] = lambda *a: {"comp1", "comp2"}
assert completer.complete("pre", "", 0, 0) == (("comp1", "comp2"), 3)
# custom lprefix:
completers_mock["a"] = lambda *a: ({"comp"}, 2)
assert completer.complete("pre", "", 0, 0) == (("comp",), 2)
# RichCompletion:
completers_mock["a"] = lambda *a: {RichCompletion("comp", prefix_len=5)}
assert completer.complete("pre", "", 0, 0) == (
(RichCompletion("comp", prefix_len=5),),
3,
)
def test_cursor_after_closing_quote(completer, completers_mock):
"""See ``Completer.complete`` in ``xonsh/completer.py``"""
@contextual_command_completer
def comp(context: CommandContext):
return {context.prefix + "1", context.prefix + "2"}
completers_mock["a"] = comp
assert completer.complete(
"", "", 0, 0, {}, multiline_text="'test'", cursor_index=6
) == (("test1'", "test2'"), 5)
assert completer.complete(
"", "", 0, 0, {}, multiline_text="'''test'''", cursor_index=10
) == (("test1'''", "test2'''"), 7)
def test_cursor_after_closing_quote_override(completer, completers_mock):
"""Test overriding the default values"""
@contextual_command_completer
def comp(context: CommandContext):
return {
# replace the closing quote with "a"
RichCompletion(
"a", prefix_len=len(context.closing_quote), append_closing_quote=False
),
# add text after the closing quote
RichCompletion(context.prefix + "_no_quote", append_closing_quote=False),
# sanity
RichCompletion(context.prefix + "1"),
}
completers_mock["a"] = comp
assert completer.complete(
"", "", 0, 0, {}, multiline_text="'test'", cursor_index=6
) == (
(
"a",
"test1'",
"test_no_quote",
),
5,
)
assert completer.complete(
"", "", 0, 0, {}, multiline_text="'''test'''", cursor_index=10
) == (
(
"a",
"test1'''",
"test_no_quote",
),
7,
)
def test_append_space(completer, completers_mock):
@contextual_command_completer
def comp(context: CommandContext):
return {
RichCompletion(context.prefix + "a", append_space=True),
RichCompletion(context.prefix + " ", append_space=False), # bad usage
RichCompletion(
context.prefix + "b", append_space=True, append_closing_quote=False
),
}
completers_mock["a"] = comp
assert completer.complete(
"", "", 0, 0, {}, multiline_text="'test'", cursor_index=6
) == (
(
"test '",
"testa' ",
"testb ",
),
5,
)
@pytest.mark.parametrize(
"middle_result, exp",
(
(
# stop at the first exclusive result
({"b1", "b2"}, ("a1", "a2", "b1", "b2")),
# pass empty exclusive results
({}, ("a1", "a2", "c1", "c2")),
# pass empty exclusive results
(None, ("a1", "a2", "c1", "c2")),
# stop at StopIteration
(StopIteration, ("a1", "a2")),
)
),
)
def test_non_exclusive(completer, completers_mock, middle_result, exp):
completers_mock["a"] = non_exclusive_completer(lambda *a: {"a1", "a2"})
def middle(*a):
if middle_result is StopIteration:
raise StopIteration()
return middle_result
completers_mock["b"] = middle
completers_mock["c"] = non_exclusive_completer(lambda *a: {"c1", "c2"})
assert completer.complete("", "", 0, 0, {})[0] == exp
|