tests: cover the basic UI

Drive the line-based UI in-process: input() answers come from a list
and the output is captured. The tests walk the main menu through
creating, playing, querying, deleting, importing and exporting
characters, plus bad menu input and the Ctrl+C handler.

The play loop runs on a fake clock that advances a minute per call and
stops when time.sleep has been called a set number of times, so it
levels up and saves on schedule without waiting.

The test helpers move to tests/helpers.py, which now also holds the
input() feeder.
This commit is contained in:
Dash committed 2026-10-17 19:46:05 +02:00
1 parent 083dbe01c2
commit f8c370cc2e
4 files changed
+501 -18

No files matched your search

+10 -16
View File
@@ -1,11 +1,19 @@
"""pqcli's command line, run in-process so coverage sees it."""
import json
from collections.abc import Callable, Iterable
from collections.abc import Callable
from pathlib import Path
import pytest
from saves import DATA, hero, read_names, save_path, write_pqw, write_roster
from helpers import (
DATA,
feed,
hero,
read_names,
save_path,
write_pqw,
write_roster,
)
import pqcli.__main__ as cli
from pqcli import pqw
@@ -55,20 +63,6 @@ def run(config: Path, monkeypatch: pytest.MonkeyPatch) -> Run:
return run
def feed(monkeypatch: pytest.MonkeyPatch, answers: Iterable[str]) -> None:
"""Answer input() prompts in order; running out is a test failure."""
it = iter(answers)
def fake_input(prompt: str = "") -> str:
print(prompt)
try:
return next(it)
except StopIteration:
raise AssertionError(f"unexpected prompt {prompt!r}") from None
monkeypatch.setattr("builtins.input", fake_input)
def test_defaults_to_the_curses_ui(monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.undo()
monkeypatch.setattr("sys.argv", ["pqcli"])