Skip to content

Commit a73f951

Browse files
Sevrain1kiancross
authored andcommitted
test: add kbi_msg=None tests and restore previous typing imports
This commit adds tests to the `Form` `Prompt` and `Question` classes to ensure no message is printed when a KeyboardInterrupt is raised during an `ask()`/`ask_async()` call where `kbi_msg=None`.
1 parent d179714 commit a73f951

6 files changed

Lines changed: 137 additions & 12 deletions

File tree

questionary/form.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
from typing import TYPE_CHECKING
1+
from typing import Any
2+
from typing import Dict
23
from typing import NamedTuple
3-
4-
if TYPE_CHECKING:
5-
from typing import Any, Dict, Sequence, Union
4+
from typing import Sequence
5+
from typing import Union
66

77
from questionary.constants import DEFAULT_KBI_MESSAGE
88
from questionary.question import Question

questionary/prompt.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
from typing import TYPE_CHECKING
1+
from typing import Any
22
from typing import Callable
3-
4-
if TYPE_CHECKING:
5-
from typing import Any, Dict, Iterable, Mapping, Optional, Union
3+
from typing import Dict
4+
from typing import Iterable
5+
from typing import Mapping
6+
from typing import Optional
7+
from typing import Union
68

79
from prompt_toolkit.output import ColorDepth
810

questionary/question.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
import sys
2-
from typing import TYPE_CHECKING
32
from typing import Any
4-
5-
if TYPE_CHECKING:
6-
from typing import Union
3+
from typing import Union
74

85
import prompt_toolkit.patch_stdout
96
from prompt_toolkit import Application

tests/test_form.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import asyncio
2+
from unittest.mock import patch
3+
14
from prompt_toolkit.output import DummyOutput
25
from pytest import fail
36

@@ -77,3 +80,37 @@ def run(inp):
7780
fail("Keyboard Interrupt should be caught by `ask()`")
7881

7982
execute_with_input_pipe(run)
83+
84+
85+
def test_no_keyboard_interrupt_message_in_ask() -> None:
86+
"""
87+
Test no message printed when `kbi_msg` is None in `ask()`.
88+
"""
89+
def run(inp):
90+
inp.send_text(KeyInputs.CONTROLC)
91+
f = example_form(inp)
92+
93+
with patch("builtins.print") as mock_print:
94+
result = f.ask(kbi_msg=None)
95+
96+
mock_print.assert_not_called()
97+
assert result == {}
98+
99+
execute_with_input_pipe(run)
100+
101+
102+
def test_no_keyboard_interrupt_message_in_ask_async() -> None:
103+
"""
104+
Test no message printed when `kbi_msg` is None in `ask_async()`.
105+
"""
106+
def run(inp):
107+
inp.send_text(KeyInputs.CONTROLC)
108+
f = example_form(inp)
109+
110+
with patch("builtins.print") as mock_print:
111+
result = asyncio.run(f.ask_async(kbi_msg=None))
112+
113+
mock_print.assert_not_called()
114+
assert result == {}
115+
116+
execute_with_input_pipe(run)

tests/test_prompt.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1+
import asyncio
2+
from unittest.mock import patch
3+
14
import pytest
25

36
from questionary.prompt import PromptParameterException
47
from questionary.prompt import prompt
8+
from questionary.prompt import prompt_async
59
from tests.utils import patched_prompt
610

711

@@ -76,3 +80,53 @@ def test_print_with_name():
7680
questions = [{"name": "hello", "type": "print", "message": "Hello World"}]
7781
result = patched_prompt(questions, "")
7882
assert result == {"hello": None}
83+
84+
85+
@patch("builtins.print")
86+
@patch("questionary.prompt.unsafe_prompt", side_effect=KeyboardInterrupt)
87+
def test_no_keyboard_interrupt_message_in_prompt(
88+
mock_unsafe_prompt, mock_print
89+
) -> None:
90+
"""
91+
Test no message printed when `kbi_msg` is None in `prompt()`.
92+
93+
Args:
94+
mock_unsafe_prompt: A mock of the internal `unsafe_prompt()` call.
95+
raises a KeyboardInterrupt.
96+
97+
mock_print: A mock of Python's builtin `print()` function.
98+
"""
99+
# Act
100+
result = prompt(questions={}, kbi_msg=None)
101+
102+
# Verify internal functions were properly called
103+
mock_unsafe_prompt.assert_called_once() # Raises KeyboardInterrupt
104+
mock_print.assert_not_called()
105+
106+
# Verify result
107+
assert result == {}
108+
109+
110+
@patch("builtins.print")
111+
@patch("questionary.prompt.unsafe_prompt_async", side_effect=KeyboardInterrupt)
112+
def test_no_keyboard_interrupt_message_in_prompt_async(
113+
mock_unsafe_prompt_async, mock_print
114+
) -> None:
115+
"""
116+
Test no message printed when `kbi_msg` is None in `prompt_async()`.
117+
118+
Args:
119+
mock_unsafe_prompt_async: A mock of the internal `unsafe_prompt_async()` call.
120+
raises a KeyboardInterrupt.
121+
122+
mock_print: A mock of Python's builtin `print()` function.
123+
"""
124+
# Act
125+
result = asyncio.run(prompt_async(questions={}, kbi_msg=None))
126+
127+
# Verify internal functions were properly called
128+
mock_unsafe_prompt_async.assert_called_once() # Raises KeyboardInterrupt
129+
mock_print.assert_not_called()
130+
131+
# Verify result
132+
assert result == {}

tests/test_question.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import asyncio
22
import platform
3+
from unittest.mock import patch
34

45
import pytest
56
from prompt_toolkit.output import DummyOutput
@@ -94,3 +95,37 @@ def run(inp):
9495
assert response == "Hello\nworld"
9596

9697
execute_with_input_pipe(run)
98+
99+
100+
def test_no_keyboard_interrupt_message_in_ask():
101+
"""
102+
Test no message printed when `kbi_msg` is None in `ask()`.
103+
"""
104+
def run(inp):
105+
inp.send_text(KeyInputs.CONTROLC)
106+
question = text("Hello?", input=inp, output=DummyOutput())
107+
108+
with patch("builtins.print") as mock_print:
109+
result = question.ask(kbi_msg=None)
110+
111+
mock_print.assert_not_called()
112+
assert result is None
113+
114+
execute_with_input_pipe(run)
115+
116+
117+
def test_no_keyboard_interrupt_message_in_ask_async():
118+
"""
119+
Test no message printed when `kbi_msg` is None in `ask_async()`.
120+
"""
121+
def run(inp):
122+
inp.send_text(KeyInputs.CONTROLC)
123+
question = text("Hello?", input=inp, output=DummyOutput())
124+
125+
with patch("builtins.print") as mock_print:
126+
result = asyncio.run(question.ask_async(kbi_msg=None))
127+
128+
mock_print.assert_not_called()
129+
assert result is None
130+
131+
execute_with_input_pipe(run)

0 commit comments

Comments
 (0)