mirror of
https://github.com/Stone-Red-Code/dvc.git
synced 2026-11-08 15:28:26 +01:00
152 lines
4.4 KiB
Python
152 lines
4.4 KiB
Python
import io
|
|
from unittest.mock import call
|
|
|
|
import pytest
|
|
from rich.console import Console as RichConsole
|
|
|
|
from dvc.ui.prompt import Confirm, InvalidResponse, Prompt
|
|
|
|
# pylint: disable=no-member
|
|
|
|
|
|
@pytest.mark.parametrize("side_effect", [EOFError, KeyboardInterrupt])
|
|
@pytest.mark.parametrize("prompt_cls", [Prompt, Confirm])
|
|
def test_prompt_interrupt_message_not_interleaved(
|
|
prompt_cls, side_effect, mocker
|
|
):
|
|
"""Test that the interrupt message is not interleaved with the prompt."""
|
|
prompt = "should print exception in the next line"
|
|
console = RichConsole(file=io.StringIO())
|
|
|
|
with pytest.raises(side_effect):
|
|
mocker.patch.object(console, "input", side_effect=side_effect)
|
|
prompt_cls.ask(prompt=prompt, console=console)
|
|
# as we are raising side_effect on the input, unfortunately we cannot
|
|
# assert for the prompt string, only the newline.
|
|
assert console.file.getvalue() == "\n"
|
|
|
|
|
|
def test_prompt_str():
|
|
console = RichConsole(file=io.StringIO())
|
|
assert (
|
|
Prompt.ask(
|
|
"What is your name?", console=console, stream=io.StringIO("foo")
|
|
)
|
|
== "foo"
|
|
)
|
|
assert console.file.getvalue() == "What is your name?: "
|
|
|
|
|
|
def test_prompt_disallows_empty_response(mocker):
|
|
console = RichConsole(file=io.StringIO())
|
|
Prompt.prompt_(
|
|
"What is your name?",
|
|
console=console,
|
|
stream=io.StringIO("\nfoo"),
|
|
)
|
|
expected = (
|
|
"What is your name?: Response required. Please try again.\n"
|
|
"What is your name?: "
|
|
)
|
|
assert console.file.getvalue() == expected
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"default, brack",
|
|
[
|
|
("default", "[default, n to omit]"),
|
|
(None, "[n to omit]"),
|
|
],
|
|
)
|
|
def test_prompt_with_conditional_skip(mocker, default, brack):
|
|
console = RichConsole(file=io.StringIO())
|
|
mocked_validator = mocker.MagicMock(return_value="something")
|
|
assert (
|
|
Prompt.prompt_(
|
|
"What is your name?",
|
|
console=console,
|
|
allow_omission=True,
|
|
stream=io.StringIO("n\n"),
|
|
default=default,
|
|
validator=mocked_validator,
|
|
)
|
|
is None
|
|
)
|
|
assert console.file.getvalue() == f"What is your name? {brack}: "
|
|
mocked_validator.assert_not_called()
|
|
|
|
|
|
def test_prompt_retries_on_invalid_response_from_validator(mocker):
|
|
console = RichConsole(file=io.StringIO())
|
|
mocked_validator = mocker.MagicMock(
|
|
side_effect=[InvalidResponse("it is a number"), "foo"]
|
|
)
|
|
assert (
|
|
Prompt.ask(
|
|
"what is your name?",
|
|
console=console,
|
|
stream=io.StringIO("3\nfoo"),
|
|
validator=mocked_validator,
|
|
)
|
|
== "foo"
|
|
)
|
|
mocked_validator.assert_has_calls([call("3"), call("foo")])
|
|
|
|
expected = "what is your name?: it is a number\nwhat is your name?: "
|
|
assert console.file.getvalue() == expected
|
|
|
|
|
|
def test_prompt_shows_message_from_validator_response(mocker):
|
|
console = RichConsole(file=io.StringIO())
|
|
mocked_validator = mocker.MagicMock(
|
|
return_value=("foo@email", "failed to send a verification email")
|
|
)
|
|
assert (
|
|
Prompt.ask(
|
|
"what is your email?",
|
|
console=console,
|
|
stream=io.StringIO("foo@email"),
|
|
validator=mocked_validator,
|
|
)
|
|
== "foo@email"
|
|
)
|
|
mocked_validator.assert_has_calls([call("foo@email")])
|
|
|
|
expected = "what is your email?: failed to send a verification email\n"
|
|
assert console.file.getvalue() == expected
|
|
|
|
|
|
def test_prompt_default(mocker):
|
|
console = RichConsole(file=io.StringIO())
|
|
mocked_validator = mocker.MagicMock(return_value="default")
|
|
assert (
|
|
Prompt.ask(
|
|
"What is your name?",
|
|
console=console,
|
|
stream=io.StringIO(""),
|
|
default="default",
|
|
validator=mocked_validator,
|
|
)
|
|
== "default"
|
|
)
|
|
assert console.file.getvalue() == "What is your name? [default]: "
|
|
mocked_validator.assert_has_calls([call("default")])
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"default, inner", [(True, "Y/n"), (False, "y/N"), (Ellipsis, "y/n")]
|
|
)
|
|
def test_prompt_confirm(default, inner):
|
|
console = RichConsole(file=io.StringIO())
|
|
assert (
|
|
Confirm.ask(
|
|
"exit?",
|
|
console=console,
|
|
stream=io.StringIO("y\n"),
|
|
default=default,
|
|
)
|
|
is True
|
|
)
|
|
output = console.file.getvalue()
|
|
assert output == f"exit? [{inner}]: "
|