xonsh/tests/test_ptk_shell.py

149 lines
4.2 KiB
Python
Raw Normal View History

"""Test initialization of prompt_toolkit shell"""
2020-08-06 13:05:50 +02:00
import sys
2022-01-31 21:26:34 +05:30
import pyte
import pytest
2022-01-31 21:26:34 +05:30
from xonsh.platform import minimum_required_ptk_version
from xonsh.ptk_shell.shell import tokenize_ansi
from xonsh.shell import Shell
2022-01-31 21:26:34 +05:30
# verify error if ptk not installed or below min
@pytest.mark.parametrize(
"ptk_ver, ini_shell_type, exp_shell_type, warn_snip",
[
(None, "prompt_toolkit", "readline", None),
((0, 5, 7), "prompt_toolkit", "readline", "is not supported"),
((1, 0, 0), "prompt_toolkit", "readline", "is not supported"),
((2, 0, 0), "prompt_toolkit", "prompt_toolkit", None),
((2, 0, 0), "best", "prompt_toolkit", None),
((2, 0, 0), "readline", "readline", None),
((3, 0, 0), "prompt_toolkit", "prompt_toolkit", None),
((3, 0, 0), "best", "prompt_toolkit", None),
((3, 0, 0), "readline", "readline", None),
((4, 0, 0), "prompt_toolkit", "prompt_toolkit", None),
],
)
def test_prompt_toolkit_version_checks(
ptk_ver,
ini_shell_type,
exp_shell_type,
warn_snip,
monkeypatch,
update test xsh usage (#4581) * todo * test: remove usage of DummyEnv and setting .env attribute on xession fixture one step closer to making too much of tweaking to xession during tests * test: fix tests vox and gitstatus-prompt * docs: update test-fixture usage * fix: import flake8 error * test: remove direct access to XSH in tests * test: remove usage of XSH in test files * todo * test: use tmp-dir to create stubs * refactor: use fixture factory to mock out XonshSession * refactor: remove direct access of XSH from functions * refactor: remove direct access of XSH from functions * fix: qa checks * refactor: rename variables to match their values * test: update failing tests because it had no PATH set previously * fix: remove builtins usage from pyghooks.py * style: * refactor: update tests to use fixtures * fix: env varialbe is setup per function some tests accidentally update the env variables and that is leaking into next tests * fix: failing vox tests * test: set commands_cache per test * test: fix failing tests * fix: failing tests on linux ptk-highlight * fix: failing tests on Windows cwd-prompt * test: copy env as to not affect original object * fix: lazily evaluate cmds-cache in pyghooks * test: fix failing tests * fix: qa errors import * test: set commands-cache per test while caching path results * test: speedup test_thread_local_swap * fix: failing tests on windows * refactor: Execer doesn't control session * refactor: XSH.unload will take care of reversing builtins attrs set * test: use env.update over monkeypatch * Revert "test: use env.update over monkeypatch" This reverts commit 010a5022247a098f1741966b8af1bf758663480e.
2022-01-08 04:03:22 +05:30
xession,
):
mocked_warn = ""
def mock_warning(msg):
nonlocal mocked_warn
mocked_warn = msg
return
def mock_ptk_above_min_supported():
nonlocal ptk_ver
2020-08-06 13:26:49 +02:00
return ptk_ver and (ptk_ver[:3] >= minimum_required_ptk_version)
def mock_has_prompt_toolkit():
nonlocal ptk_ver
return ptk_ver is not None
monkeypatch.setattr(
"xonsh.shell.warnings.warn", mock_warning
) # hardwon: patch the caller!
monkeypatch.setattr(
"xonsh.shell.ptk_above_min_supported", mock_ptk_above_min_supported
) # have to patch both callers
monkeypatch.setattr(
"xonsh.platform.ptk_above_min_supported", mock_ptk_above_min_supported
)
monkeypatch.setattr("xonsh.platform.has_prompt_toolkit", mock_has_prompt_toolkit)
2020-08-06 13:05:50 +02:00
old_syspath = sys.path.copy()
act_shell_type = Shell.choose_shell_type(ini_shell_type, {})
assert len(old_syspath) == len(sys.path)
2020-08-06 13:26:49 +02:00
2020-08-06 13:05:50 +02:00
sys.path = old_syspath
assert act_shell_type == exp_shell_type
if warn_snip:
assert warn_snip in mocked_warn
pass
@pytest.mark.parametrize(
"prompt_tokens, ansi_string_parts",
[
# no ansi, single token
([("fake style", "no ansi here")], ["no ansi here"]),
# no ansi, multiple tokens
([("s1", "no"), ("s2", "ansi here")], ["no", "ansi here"]),
# ansi only, multiple
([("s1", "\x1b[33mansi \x1b[1monly")], ["", "ansi ", "only"]),
# mixed
(
[("s1", "no ansi"), ("s2", "mixed \x1b[33mansi")],
["no ansi", "mixed ", "ansi"],
),
],
)
def test_tokenize_ansi(prompt_tokens, ansi_string_parts):
ansi_tokens = tokenize_ansi(prompt_tokens)
for token, text in zip(ansi_tokens, ansi_string_parts):
assert token[1] == text
@pytest.mark.parametrize(
"line, exp",
[
[repr("hello"), None],
["2 * 3", "6"],
],
)
def test_ptk_prompt(line, exp, ptk_shell, capsys):
inp, out, shell = ptk_shell
inp.send_text(f"{line}\nexit\n") # note: terminate with '\n'
shell.cmdloop()
screen = pyte.Screen(80, 24)
stream = pyte.Stream(screen)
out, _ = capsys.readouterr()
# this will remove render any color codes
stream.feed(out.strip())
out = screen.display[0].strip()
assert out.strip() == (exp or line)
@pytest.mark.parametrize(
"cmd,exp_append_history",
[
("", False),
("# a comment", False),
("print('yes')", True),
],
)
def test_ptk_default_append_history(cmd, exp_append_history, ptk_shell, monkeypatch):
"""Test that running an empty line or a comment does not append to history.
This test is necessary because the prompt-toolkit shell uses a custom _push() method that is different from the base shell's push() method."""
inp, out, shell = ptk_shell
append_history_calls = []
def mock_append_history(**info):
append_history_calls.append(info)
monkeypatch.setattr(shell, "_append_history", mock_append_history)
shell.default(cmd)
if exp_append_history:
assert len(append_history_calls) == 1
else:
assert len(append_history_calls) == 0