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
|
import errno
from functools import partial
from unittest import mock
import pytest
from snakeoil.cli.input import NoChoice, userquery
from snakeoil.test.argparse_helpers import FakeStreamFormatter
@pytest.fixture
def mocked_input():
with mock.patch("builtins.input") as mocked_input:
yield mocked_input
class TestUserQuery:
@pytest.fixture(autouse=True)
def __setup(self):
self.out = FakeStreamFormatter()
self.err = FakeStreamFormatter()
self.query = partial(userquery, out=self.out, err=self.err)
def test_default_answer(self, mocked_input):
mocked_input.return_value = ""
assert self.query("foo") == True
def test_tuple_prompt(self, mocked_input):
mocked_input.return_value = ""
prompt = "perhaps a tuple"
assert self.query(tuple(prompt.split())) == True
output = "".join(prompt.split())
assert (
self.out.get_text_stream().strip().split("\n")[0][: len(output)] == output
)
def test_no_default_answer(self, mocked_input):
responses = {
"a": ("z", "Yes"),
"b": ("y", "No"),
}
# no default answer returns None for empty input
mocked_input.return_value = ""
assert self.query("foo", responses=responses) == None
mocked_input.return_value = "a"
assert self.query("foo", responses=responses) == "z"
mocked_input.return_value = "b"
assert self.query("foo", responses=responses) == "y"
def test_ambiguous_input(self, mocked_input):
responses = {
"a": ("z", "Yes"),
"A": ("y", "No"),
}
mocked_input.return_value = "a"
with pytest.raises(NoChoice):
self.query("foo", responses=responses)
error_output = self.err.get_text_stream().strip().split("\n")[1]
expected = "Response %r is ambiguous (%s)" % (
mocked_input.return_value,
", ".join(sorted(responses.keys())),
)
assert error_output == expected
def test_default_correct_input(self, mocked_input):
for input, output in (
("no", False),
("No", False),
("yes", True),
("Yes", True),
):
mocked_input.return_value = input
assert self.query("foo") == output
def test_default_answer_no_matches(self, mocked_input):
mocked_input.return_value = ""
with pytest.raises(ValueError):
self.query("foo", default_answer="foo")
assert self.out.stream == []
def test_custom_default_answer(self, mocked_input):
mocked_input.return_value = ""
assert self.query("foo", default_answer=False) == False
def test_eof_nochoice(self, mocked_input):
# user hits ctrl-d
mocked_input.side_effect = EOFError
with pytest.raises(NoChoice):
self.query("foo")
output = self.out.get_text_stream().strip().split("\n")[1]
expected = "Not answerable: EOF on STDIN"
assert output == expected
def test_stdin_closed_nochoice(self, mocked_input):
mocked_input.side_effect = IOError(errno.EBADF, "")
with pytest.raises(NoChoice):
self.query("foo")
output = self.out.get_text_stream().strip().split("\n")[1]
expected = "Not answerable: STDIN is either closed, or not readable"
assert output == expected
def test_unhandled_ioerror(self, mocked_input):
mocked_input.side_effect = IOError(errno.ENODEV, "")
with pytest.raises(IOError):
self.query("foo")
def test_bad_choice_limit(self, mocked_input):
# user hits enters a bad choice 3 times in a row
mocked_input.return_value = "bad"
with pytest.raises(NoChoice):
self.query("foo")
assert mocked_input.call_count == 3
output = self.err.get_text_stream().strip().split("\n")[1]
expected = "Sorry, response %r not understood." % (mocked_input.return_value,)
assert output == expected
def test_custom_choice_limit(self, mocked_input):
# user hits enters a bad choice 5 times in a row
mocked_input.return_value = "haha"
with pytest.raises(NoChoice):
self.query("foo", limit=5)
assert mocked_input.call_count == 5
output = self.err.get_text_stream().strip().split("\n")[1]
expected = "Sorry, response %r not understood." % (mocked_input.return_value,)
assert output == expected
|