Files
wehub-resource-sync 4b6817381b
Benchmark image — build + push to ECR (any adapter) / build + push (push) Waiting to run
CI / quality (ubuntu-latest) (push) Waiting to run
CI / test (tools-runtime) (push) Waiting to run
CI / test (e2e-general) (push) Waiting to run
CI / test (cli-runtime) (push) Waiting to run
CI / test (e2e-provider-and-openclaw) (push) Waiting to run
CI / test (integrations-and-misc) (push) Waiting to run
CI / coverage-report (push) Blocked by required conditions
CI / test-kubernetes (push) Waiting to run
CI / should-run-thorough (push) Waiting to run
CI / test-thorough (cloudwatch-demo) (push) Blocked by required conditions
CI / test-thorough (flink-ecs) (push) Blocked by required conditions
CI / test-thorough (upstream-lambda) (push) Blocked by required conditions
CI / test-thorough (prefect-ecs-fargate) (push) Blocked by required conditions
CodeQL / Analyze (python) (push) Waiting to run
Release / build-binaries (zip, opensre.exe, onefile, windows-latest, windows-x64) (push) Blocked by required conditions
Release / publish-release (push) Blocked by required conditions
Release / publish-main-release (push) Blocked by required conditions
Release / prepare (push) Waiting to run
Release / verify (push) Blocked by required conditions
Release / build-python-dist (push) Blocked by required conditions
Release / build-binaries (tar.gz, opensre, onedir, macos-15-intel, darwin-x64) (push) Blocked by required conditions
Release / build-binaries (tar.gz, opensre, onedir, macos-latest, darwin-arm64) (push) Blocked by required conditions
Release / build-binaries (tar.gz, opensre, onedir, ubuntu-22.04, linux-x64) (push) Blocked by required conditions
Release / build-binaries (tar.gz, opensre, onedir, ubuntu-22.04-arm, linux-arm64) (push) Blocked by required conditions
Synthetic Deterministic Tests / Synthetic offline (deterministic) (push) Waiting to run
Interactive Shell Live (PR + post-merge) / turn-checks (no-LLM) (push) Waiting to run
Interactive Shell Live (PR + post-merge) / turn-live shard ${{ matrix.shard_index }} (push) Waiting to run
CI (OpenClaw E2E) / openclaw test (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:10:45 +08:00

186 lines
6.0 KiB
Python

from __future__ import annotations
import time
import pytest
import questionary
from prompt_toolkit.input.defaults import create_pipe_input # type: ignore[import-not-found]
from prompt_toolkit.output import DummyOutput # type: ignore[import-not-found]
from platform.terminal.prompt_support import (
_last_ctrl_c,
handle_ctrl_c_press,
install_questionary_ctrl_c_double_exit,
install_questionary_escape_cancel,
print_session_resume_hint,
)
def test_print_session_resume_hint_includes_repl_and_cli_commands(
monkeypatch: pytest.MonkeyPatch,
) -> None:
from io import StringIO
from rich.console import Console
monkeypatch.setattr("platform.terminal.prompt_support.sys.argv", ["o"])
console = Console(file=StringIO(), force_terminal=False, color_system=None)
print_session_resume_hint(console, "8988e743-87ae-4c4c-a37b-0351e62a4855")
output = console.file.getvalue()
assert "Resume this session with:" in output
assert "/resume 8988e743-87ae-4c4c-a37b-0351e62a4855" in output
assert "o --resume 8988e743-87ae-4c4c-a37b-0351e62a4855" in output
def test_install_questionary_escape_cancel_is_idempotent() -> None:
install_questionary_escape_cancel()
first = questionary.select
install_questionary_escape_cancel()
assert questionary.select is first
def test_stock_questionary_select_escape_cancels() -> None:
install_questionary_escape_cancel()
with create_pipe_input() as pipe_input:
q = questionary.select(
"Pick",
choices=["a", "b"],
input=pipe_input,
output=DummyOutput(),
)
pipe_input.send_bytes(b"\x1b")
app = q.application
app.input = pipe_input
app.output = DummyOutput()
assert app.run() is None
def test_stock_questionary_confirm_escape_cancels() -> None:
"""Verify that pressing Escape cancels a confirm prompt (Issue #1117).
Sends the Escape byte (\\x1b) to a questionary.confirm application
and asserts that it returns None instead of hanging.
"""
install_questionary_escape_cancel()
with create_pipe_input() as pipe_input:
q = questionary.confirm(
"Are you sure?",
input=pipe_input,
output=DummyOutput(),
)
pipe_input.send_bytes(b"\x1b")
app = q.application
app.input = pipe_input
app.output = DummyOutput()
assert app.run() is None
def test_stock_questionary_text_escape_cancels() -> None:
"""Verify that pressing Escape cancels a text input prompt (Issue #1117).
Sends the Escape byte (\\x1b) to a questionary.text application
and asserts that it returns None.
"""
install_questionary_escape_cancel()
with create_pipe_input() as pipe_input:
q = questionary.text(
"Name",
input=pipe_input,
output=DummyOutput(),
)
pipe_input.send_bytes(b"\x1b")
app = q.application
app.input = pipe_input
app.output = DummyOutput()
assert app.run() is None
def test_stock_questionary_path_escape_cancels() -> None:
"""Verify that pressing Escape cancels a path selection prompt (Issue #1117).
Sends the Escape byte (\\x1b) to a questionary.path application
and asserts that it returns None.
"""
install_questionary_escape_cancel()
with create_pipe_input() as pipe_input:
q = questionary.path(
"Path",
input=pipe_input,
output=DummyOutput(),
)
pipe_input.send_bytes(b"\x1b")
app = q.application
app.input = pipe_input
app.output = DummyOutput()
assert app.run() is None
def test_install_questionary_ctrl_c_double_exit_is_idempotent() -> None:
install_questionary_ctrl_c_double_exit()
first = questionary.select
install_questionary_ctrl_c_double_exit()
assert questionary.select is first
def test_ctrl_c_first_press_shows_hint_and_reprompts(capsys) -> None:
"""First Ctrl+C prints the hint and re-displays the prompt; Enter then submits."""
_last_ctrl_c[0] = None
install_questionary_ctrl_c_double_exit()
with create_pipe_input() as pipe_input:
q = questionary.select(
"Pick",
choices=["a", "b"],
input=pipe_input,
output=DummyOutput(),
)
# Ctrl+C cancels the first run; Enter submits the re-displayed prompt.
pipe_input.send_bytes(b"\x03\r")
result = q.ask()
assert "(Press Ctrl+C again to exit)" in capsys.readouterr().out
# After the hint the prompt was re-run and "a" was selected (first choice).
assert result == "a"
def test_ctrl_c_second_press_exits(capsys) -> None:
# Simulate a previous Ctrl+C just now so the second press fires immediately.
_last_ctrl_c[0] = time.monotonic()
with pytest.raises(SystemExit) as exc_info:
handle_ctrl_c_press()
assert exc_info.value.code == 0
assert "Goodbye" in capsys.readouterr().out
def test_ctrl_c_hint_resets_after_window(capsys) -> None:
# A press older than the exit window should show the hint again, not exit.
_last_ctrl_c[0] = None # effectively "long ago"
handle_ctrl_c_press()
out = capsys.readouterr().out
assert "(Press Ctrl+C again to exit)" in out
def test_questionary_ask_inside_running_event_loop_does_not_raise() -> None:
"""q.ask() called from within a running asyncio event loop must not raise.
Regression test for Sentry issue #1650: asyncio.run() cannot be called
from a running event loop — triggered when questionary prompts are shown
inside the async REPL dispatch path.
"""
import asyncio
_last_ctrl_c[0] = None
install_questionary_ctrl_c_double_exit()
async def _run() -> object:
with create_pipe_input() as pipe_input:
q = questionary.select(
"Pick",
choices=["a", "b"],
input=pipe_input,
output=DummyOutput(),
)
pipe_input.send_bytes(b"\r")
return q.ask()
result = asyncio.run(_run())
assert result == "a"