mirror of
https://github.com/rr-/pq-cli.git
synced 2026-11-12 22:40:36 -07:00
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.
64 lines
1.8 KiB
Python
64 lines
1.8 KiB
Python
"""Characters, saves and prompts shared by the UI and CLI tests."""
|
|
|
|
from collections.abc import Iterable
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
from test_pqw import played
|
|
|
|
from pqcli import pqw
|
|
from pqcli.game_data import load_game_data
|
|
from pqcli.mechanic import Player
|
|
from pqcli.roster import Roster
|
|
|
|
DATA = load_game_data()
|
|
|
|
|
|
def hero(name: str = "Exportée", ticks: int = 300) -> Player:
|
|
"""A character that has played for a while."""
|
|
player = played(ticks).player
|
|
player.name = name
|
|
return player
|
|
|
|
|
|
def save_path(config: Path) -> Path:
|
|
"""Where pqcli keeps its roster with XDG_CONFIG_HOME set to config."""
|
|
return config / "pqcli" / "save.dat"
|
|
|
|
|
|
def write_roster(config: Path, *players: Player) -> Path:
|
|
path = save_path(config)
|
|
Roster(path, list(players)).save()
|
|
return path
|
|
|
|
|
|
def read_names(config: Path) -> list[str]:
|
|
return [player.name for player in Roster.load(save_path(config)).players]
|
|
|
|
|
|
def write_pqw(path: Path, player: Player, *, online: bool = False) -> Path:
|
|
"""Write player as a .pqw; online adds fields the import warns about."""
|
|
game = pqw.export_game(player, DATA)
|
|
if online:
|
|
game["online"] = {"realm": "Alpaquil", "passkey": 1}
|
|
path.write_text(pqw.encode(game), encoding="ascii")
|
|
return path
|
|
|
|
|
|
def feed(monkeypatch: pytest.MonkeyPatch, answers: Iterable[str]) -> None:
|
|
"""Answer input() prompts in order; running out is a test failure.
|
|
|
|
Prompts are echoed so captured output reads like a session.
|
|
"""
|
|
it = iter(answers)
|
|
|
|
def fake_input(prompt: str = "") -> str:
|
|
try:
|
|
answer = next(it)
|
|
except StopIteration:
|
|
raise AssertionError(f"unexpected prompt {prompt!r}") from None
|
|
print(f"{prompt}{answer}")
|
|
return answer
|
|
|
|
monkeypatch.setattr("builtins.input", fake_input)
|