"""Tests for the Dead Souls textual parser.""" from __future__ import annotations from progetto2.deadsouls import ( EXIT_ALIASES, RollingRoomParser, 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"