"""timeout_input 实用函数的单元测试""" import importlib.util from pathlib import Path import pytest PROJECT_SRC = Path(__file__).resolve().parents[2] / "src" MODULE_PATH = PROJECT_SRC / "bidmaster" / "utils" / "timeout_input.py" spec = importlib.util.spec_from_file_location("timeout_input", MODULE_PATH) timeout_input = importlib.util.module_from_spec(spec) assert spec and spec.loader # 保持类型检查 spec.loader.exec_module(timeout_input) @pytest.fixture() def interactive_enabled(monkeypatch): monkeypatch.setattr(timeout_input, "_can_use_interactive_input", lambda: True) def test_timeout_prompt_returns_interactive_result(monkeypatch, interactive_enabled): monkeypatch.setattr( timeout_input, "_interactive_readline", lambda prompt, timeout: (" 用户提示 ", False), ) result = timeout_input.timeout_prompt("输入: ", default="默认", timeout=60) assert result == "用户提示" def test_timeout_prompt_uses_default_on_timeout(monkeypatch, interactive_enabled): monkeypatch.setattr( timeout_input, "_interactive_readline", lambda prompt, timeout: ("", True), ) result = timeout_input.timeout_prompt("输入: ", default="默认", timeout=60) assert result == "默认" def test_timeout_prompt_falls_back_to_threaded(monkeypatch, interactive_enabled): def fake_threaded(prompt, default, timeout, choices): assert prompt == "输入: " assert default == "兜底" assert timeout == 60 assert choices is None return "线程输入" monkeypatch.setattr( timeout_input, "_interactive_readline", lambda prompt, timeout: (_ for _ in ()).throw( timeout_input._InteractiveInputUnavailable() ), ) monkeypatch.setattr(timeout_input, "_threaded_prompt", fake_threaded) result = timeout_input.timeout_prompt("输入: ", default="兜底", timeout=60) assert result == "线程输入" def test_timeout_prompt_invalid_choice_returns_default(monkeypatch, interactive_enabled): monkeypatch.setattr( timeout_input, "_interactive_readline", lambda prompt, timeout: ("3", False), ) result = timeout_input.timeout_prompt( "选择:", default="1", timeout=60, choices=["1", "2"] ) assert result == "1"