Files
025-us-states-game/tests/test_main.py
T
Tirsvad 02b537e538 Add Turtle screen, game loop and entry point (MIL-003)
Task: MIL-003#1
Task: MIL-003#2
Task: MIL-003#3
Task: MIL-003#4
Task: MIL-003#5
Task: MIL-003#6
2026-10-13 15:50:45 +08:00

92 lines
2.7 KiB
Python

"""Tests of the entry point in main.py, with a fake screen."""
import subprocess
import sys
from collections.abc import Sequence
from pathlib import Path
import pytest
from us_states_game import main as main_module
from us_states_game.states import State
from us_states_game.storage import load_states
class FakeTurtleScreen:
"""Stands in for TurtleScreen: scripted answers, no display."""
instances: list["FakeTurtleScreen"] = []
answers: Sequence[str | None] = []
def __init__(self) -> None:
self._answers = iter(self.answers)
self.written: list[State] = []
self.coordinates_enabled = False
self.closed = False
FakeTurtleScreen.instances.append(self)
def ask_state_name(self, title: str, prompt: str) -> str | None:
return next(self._answers)
def write_state(self, state: State) -> None:
self.written.append(state)
def enable_click_coordinates(self) -> None:
self.coordinates_enabled = True
def close(self) -> None:
self.closed = True
@pytest.fixture
def fake_screen(
monkeypatch: pytest.MonkeyPatch, tmp_path: Path
) -> type[FakeTurtleScreen]:
FakeTurtleScreen.instances = []
monkeypatch.setattr(main_module, "TurtleScreen", FakeTurtleScreen)
monkeypatch.chdir(tmp_path)
return FakeTurtleScreen
def test_main_writes_states_to_learn_and_returns_zero(
fake_screen: type[FakeTurtleScreen], tmp_path: Path
) -> None:
fake_screen.answers = ["Ohio", "texas", "exit"]
assert main_module.main([]) == 0
lines = (tmp_path / "states_to_learn.csv").read_text(encoding="utf-8").splitlines()
expected = [s.name for s in load_states() if s.name not in {"Ohio", "Texas"}]
assert lines == ["state", *expected]
assert len(expected) == 48
def test_main_closes_screen_after_game(fake_screen: type[FakeTurtleScreen]) -> None:
fake_screen.answers = ["exit"]
main_module.main([])
assert fake_screen.instances[0].closed
def test_main_enables_click_coordinates_with_flag(
fake_screen: type[FakeTurtleScreen],
) -> None:
fake_screen.answers = ["exit"]
main_module.main(["--show-coordinates"])
assert fake_screen.instances[0].coordinates_enabled
def test_main_leaves_click_coordinates_off_by_default(
fake_screen: type[FakeTurtleScreen],
) -> None:
fake_screen.answers = ["exit"]
main_module.main([])
assert not fake_screen.instances[0].coordinates_enabled
def test_game_and_states_modules_do_not_import_turtle() -> None:
code = (
"import sys, us_states_game.game, us_states_game.states, "
"us_states_game.storage; "
"sys.exit(1 if 'turtle' in sys.modules else 0)"
)
result = subprocess.run([sys.executable, "-c", code], check=False)
assert result.returncode == 0