Files
viandante/tests/test_deadsouls.py
truetype b20f3c0f31
ci / lint (ruff) (push) Has been cancelled
ci / pytest (py3.10) (push) Has been cancelled
ci / pytest (py3.11) (push) Has been cancelled
ci / pytest (py3.12) (push) Has been cancelled
ci(actions): add Gitea Actions ci+release workflows + fix ruff findings
- .gitea/workflows/ci.yml: ruff + matrix pytest on 3.10/3.11/3.12
  on push and PR to main; concurrency cancels superseded runs
- .gitea/workflows/release.yml: gate (ruff + pytest) + build sdist/wheel
  on tag 'v*', uploads via actions/upload-artifact@v4
- README.md: add ci and version badges right under H1
- src/viandante/cli.py: drop unused prompt_toolkit.patch_stdout import
- tests/test_deadsouls.py: add missing RoomBlock import (F821)
- tests/test_logger.py: drop unused local 'raw' in unicode test
- tests/test_mapper.py: rename unused locals to _a/_b/_c (F841) to
  preserve intent (B has 's' back-edge; C is orphan)
2026-07-07 17:15:54 +00:00

68 lines
2.1 KiB
Python

"""Tests for the Dead Souls textual parser."""
from __future__ import annotations
from viandante.deadsouls import (
EXIT_ALIASES,
RollingRoomParser,
RoomBlock,
parse_exits,
parse_room_block,
)
def test_parse_exits_brackets() -> None:
assert parse_exits("[ Exits: n e s ]") == ["n", "e", "s"]
def test_parse_exits_plain() -> None:
assert parse_exits("Exits: north, east") == ["n", "e"]
def test_parse_exits_dedup() -> None:
assert parse_exits("[ Exits: n n n east east ]") == ["n", "e"]
def test_parse_exits_unknown_extra() -> None:
# unknown ids are dropped, but the recognised ones stay
assert parse_exits("[ Exits: n fluffy w ]") == ["n", "w"]
def test_parse_room_block_minimal() -> None:
blk = "Outer Courtyard\n\nThe cobbles are uneven.\n[ Exits: n e ]\n"
room = parse_room_block(blk)
assert room is not None
assert room.name == "Outer Courtyard"
assert set(room.exits) == {"n", "e"}
def test_parse_room_block_no_exits() -> None:
blk = "Dead End\n\nA wall blocks the way.\nNo exits.\n"
room = parse_room_block(blk)
assert room is not None
assert room.exits == []
def test_parse_room_block_no_exits_line_returns_none() -> None:
blk = "Plain Text\n\nNo block markers here.\n"
assert parse_room_block(blk) is None
def test_aliases_directions() -> None:
assert EXIT_ALIASES["northeast"] == "ne"
assert EXIT_ALIASES["up"] == "u"
assert EXIT_ALIASES["enter"] == "enter"
def test_rolling_parser_emits_complete_block() -> None:
"""Rooms are emitted incrementally *only* once an ``Exits:`` line closes
the block. Across two ``feed_text`` calls, the first room completes
on the first call (its Exits: line is observed) and the second room
completes on the second call (its Exits: line is observed there)."""
p = RollingRoomParser()
rooms: list[RoomBlock] = []
rooms.extend(p.feed_text("Outer Courtyard\n\nCobbles. \n[ Exits: n ]\n\nInn "))
rooms.extend(p.feed_text("Hall\n\nA warm fire.\n[ Exits: s ]\n\n"))
assert len(rooms) == 2
assert rooms[0].name == "Outer Courtyard"
assert rooms[1].name == "Inn Hall"